diff --git a/_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm b/_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm index 2c6eda9f90..d01e4f8da1 100644 --- a/_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm +++ b/_maps/RandomRuins/LavaRuins/lavaland_surface_golem_ship.dmm @@ -18,6 +18,9 @@ /obj/item/mining_scanner, /obj/item/flashlight/lantern, /obj/item/card/id/mining, +/obj/item/gps/mining{ + tracking = 0 + }, /turf/open/floor/plating, /area/ruin/powered/golem_ship) "d" = ( @@ -31,6 +34,9 @@ /obj/item/mining_scanner, /obj/item/flashlight/lantern, /obj/item/card/id/mining, +/obj/item/gps/mining{ + tracking = 0 + }, /turf/open/floor/plating, /area/ruin/powered/golem_ship) "e" = ( @@ -150,6 +156,9 @@ "x" = ( /obj/structure/table/wood, /obj/machinery/reagentgrinder, +/obj/item/gps/mining{ + tracking = 0 + }, /turf/open/floor/mineral/titanium/purple, /area/ruin/powered/golem_ship) "z" = ( diff --git a/code/__DEFINES/robots.dm b/code/__DEFINES/robots.dm index a05e6f6160..affa23d30a 100644 --- a/code/__DEFINES/robots.dm +++ b/code/__DEFINES/robots.dm @@ -53,4 +53,10 @@ //Checks to determine borg availability depending on the server's config. These are defines in the interest of reducing copypasta -#define BORG_SEC_AVAILABLE (!CONFIG_GET(flag/disable_secborg) && GLOB.security_level >= CONFIG_GET(number/minimum_secborg_alert)) \ No newline at end of file +#define BORG_SEC_AVAILABLE (!CONFIG_GET(flag/disable_secborg) && GLOB.security_level >= CONFIG_GET(number/minimum_secborg_alert)) + +//silicon_priviledges flags +#define PRIVILEDGES_SILICON (1<<0) +#define PRIVILEDGES_PAI (1<<1) +#define PRIVILEDGES_BOT (1<<2) +#define PRIVILEDGES_DRONE (1<<3) diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm index fe994facdc..606aca2d3a 100755 --- a/code/controllers/subsystem/ticker.dm +++ b/code/controllers/subsystem/ticker.dm @@ -486,8 +486,9 @@ SUBSYSTEM_DEF(ticker) SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = INSTANT_RUNOFF_VOTING) if("SCORE") SSvote.initiate_vote("map","server",hideresults=TRUE,votesystem = MAJORITY_JUDGEMENT_VOTING) + else + SSvote.initiate_vote("map","server",hideresults=TRUE) // fallback - SSvote.initiate_vote("map","server",hideresults=TRUE) /datum/controller/subsystem/ticker/proc/HasRoundStarted() return current_state >= GAME_STATE_PLAYING diff --git a/code/datums/components/crafting/guncrafting.dm b/code/datums/components/crafting/guncrafting.dm index d96be9be10..d421a6e42a 100644 --- a/code/datums/components/crafting/guncrafting.dm +++ b/code/datums/components/crafting/guncrafting.dm @@ -13,3 +13,9 @@ desc = "A classic rifle stock that doubles as a grip, roughly carved out of wood." icon = 'icons/obj/improvised.dmi' icon_state = "riflestock" + +/obj/item/weaponcrafting/silkstring + name = "silkstring" + desc = "A long pice of silk looks like cable coil." + icon = 'icons/obj/improvised.dmi' + icon_state = "silkstring" \ No newline at end of file diff --git a/code/datums/components/crafting/recipes/recipes_primal.dm b/code/datums/components/crafting/recipes/recipes_primal.dm index 1fc684eddc..ae611e5855 100644 --- a/code/datums/components/crafting/recipes/recipes_primal.dm +++ b/code/datums/components/crafting/recipes/recipes_primal.dm @@ -89,4 +89,31 @@ parts = list(/obj/item/bodypart/head = 1, /obj/item/twohanded/bonespear = 1) result = /obj/structure/headpike/bone + category = CAT_PRIMAL + +/datum/crafting_recipe/quiver + name = "Quiver" + always_availible = FALSE + result = /obj/item/storage/belt/quiver + time = 80 + reqs = list(/obj/item/stack/sheet/leather = 3, + /obj/item/stack/sheet/sinew = 4) + category = CAT_PRIMAL + +/datum/crafting_recipe/bone_bow + name = "Bone Bow" + result = /obj/item/gun/ballistic/bow/ashen + time = 200 + always_availible = FALSE + reqs = list(/obj/item/stack/sheet/bone = 8, + /obj/item/stack/sheet/sinew = 4) + category = CAT_PRIMAL + +/datum/crafting_recipe/bow_tablet + name = "Sandstone Bow Making Manual" + result = /obj/item/book/granter/crafting_recipe/bone_bow + time = 600 //Scribing + always_availible = FALSE + reqs = list(/obj/item/stack/rods = 1, + /obj/item/stack/sheet/mineral/sandstone = 4) category = CAT_PRIMAL \ No newline at end of file diff --git a/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm b/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm index 104b58ca28..76f8f119e0 100644 --- a/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm +++ b/code/datums/components/crafting/recipes/recipes_weapon_and_ammo.dm @@ -199,6 +199,16 @@ ////////////////// +/datum/crafting_recipe/pipebow + name = "Pipe Bow" + result = /obj/item/gun/ballistic/bow/pipe + reqs = list(/obj/item/pipe = 5, + /obj/item/stack/sheet/plastic = 15, + /obj/item/weaponcrafting/silkstring = 10) + time = 450 + category = CAT_WEAPONRY + subcategory = CAT_WEAPON + /datum/crafting_recipe/smartdartgun name = "Smart dartgun" result = /obj/item/gun/syringe/dart @@ -278,6 +288,37 @@ ///AMMO CRAFTING// ////////////////// +/datum/crafting_recipe/arrow + name = "Arrow" + result = /obj/item/ammo_casing/caseless/arrow + time = 40 + reqs = list(/obj/item/stack/sheet/mineral/wood = 1, + /obj/item/weaponcrafting/silkstring = 1, + /obj/item/stack/rods = 3) // 1 metal sheet is worth 1.5 arrows + category = CAT_WEAPONRY + subcategory = CAT_AMMO + +/datum/crafting_recipe/bone_arrow + name = "Bone Arrow" + result = /obj/item/ammo_casing/caseless/arrow/bone + time = 40 + always_availible = FALSE + reqs = list(/obj/item/stack/sheet/bone = 1, + /obj/item/stack/sheet/sinew = 1, + /obj/item/ammo_casing/caseless/arrow/ashen = 1) + category = CAT_WEAPONRY + subcategory = CAT_AMMO + +/datum/crafting_recipe/ashen_arrow + name = "Harden Arrow" + result = /obj/item/ammo_casing/caseless/arrow/ashen + tools = list(/obj/structure/bonfire) + time = 20 + always_availible = FALSE + reqs = list(/obj/item/ammo_casing/caseless/arrow = 1) + category = CAT_WEAPONRY + subcategory = CAT_AMMO + /datum/crafting_recipe/smartdart name = "Medical smartdart" result = /obj/item/reagent_containers/syringe/dart diff --git a/code/datums/elements/mob_holder.dm b/code/datums/elements/mob_holder.dm index e33c430198..8687d89b2f 100644 --- a/code/datums/elements/mob_holder.dm +++ b/code/datums/elements/mob_holder.dm @@ -93,7 +93,7 @@ lefthand_file = left_hand if(right_hand) righthand_file = right_hand - slot_flags = slots + slot_flags = slots /obj/item/clothing/head/mob_holder/proc/assimilate(mob/living/target) target.setDir(SOUTH) @@ -114,16 +114,14 @@ w_class = WEIGHT_CLASS_NORMAL if(MOB_SIZE_LARGE) w_class = WEIGHT_CLASS_HUGE - RegisterSignal(src, COMSIG_CLICK_SHIFT, .proc/examine_held_mob) /obj/item/clothing/head/mob_holder/Destroy() if(held_mob) release() return ..() -/obj/item/clothing/head/mob_holder/proc/examine_held_mob(datum/source, mob/user) - held_mob.ShiftClick(user) - return COMPONENT_DENY_EXAMINATE +/obj/item/clothing/head/mob_holder/examine(mob/user) + return held_mob?.examine(user) || ..() /obj/item/clothing/head/mob_holder/Exited(atom/movable/AM, atom/newloc) . = ..() diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm index 459ff2f3d6..20a45b2102 100644 --- a/code/game/gamemodes/objective.dm +++ b/code/game/gamemodes/objective.dm @@ -1096,7 +1096,7 @@ GLOBAL_LIST_EMPTY(possible_sabotages) var/approved_targets = list() check_sabotages: for(var/datum/sabotage_objective/possible_sabotage in GLOB.possible_sabotages) - if(!is_unique_objective(possible_sabotage.sabotage_type) || possible_sabotage.check_conditions()) + if(!is_unique_objective(possible_sabotage.sabotage_type) || possible_sabotage.check_conditions() || !possible_sabotage.can_run()) continue for(var/datum/mind/M in owners) if(M.current.mind.assigned_role in possible_sabotage.excludefromjob) diff --git a/code/game/gamemodes/objective_sabotage.dm b/code/game/gamemodes/objective_sabotage.dm index 248524f1d2..1094dd2f36 100644 --- a/code/game/gamemodes/objective_sabotage.dm +++ b/code/game/gamemodes/objective_sabotage.dm @@ -12,6 +12,9 @@ /datum/sabotage_objective/proc/check_conditions() return TRUE +/datum/sabotage_objective/proc/can_run() + return TRUE + /datum/sabotage_objective/processing var/won = FALSE @@ -79,6 +82,9 @@ won = max(1-((S.get_integrity()-50)/50),won) return FALSE +/datum/sabotage_objective/processing/supermatter/can_run() + return (locate(/obj/machinery/power/supermatter_crystal) in GLOB.machines) + /datum/sabotage_objective/station_integrity name = "Make sure the station is at less than 80% integrity by the end. Smash walls, windows etc. to reach this goal." sabotage_type = "integrity" diff --git a/code/game/machinery/Sleeper.dm b/code/game/machinery/Sleeper.dm index b5ab859797..19a20f0cfa 100644 --- a/code/game/machinery/Sleeper.dm +++ b/code/game/machinery/Sleeper.dm @@ -264,7 +264,7 @@ if(blood_id) data["occupant"]["blood"] = list() // We can start populating this list. var/blood_type = C.dna.blood_type - if(blood_id != "blood") // special blood substance + if(!(blood_id in GLOB.blood_reagent_types)) // special blood substance var/datum/reagent/R = GLOB.chemical_reagents_list[blood_id] if(R) blood_type = R.name diff --git a/code/game/machinery/bloodbankgen.dm b/code/game/machinery/bloodbankgen.dm index cb25adc126..19632711fc 100644 --- a/code/game/machinery/bloodbankgen.dm +++ b/code/game/machinery/bloodbankgen.dm @@ -274,20 +274,20 @@ return TRUE -/obj/machinery/bloodbankgen/proc/detachinput() +/obj/machinery/bloodbankgen/proc/detachinput(mob/user) if(bag) bag.forceMove(drop_location()) - if(usr && Adjacent(usr) && !issiliconoradminghost(usr)) - usr.put_in_hands(bag) + if(user && Adjacent(usr) && user.can_hold_items()) + user.put_in_hands(bag) bag = null draining = null update_icon() -/obj/machinery/bloodbankgen/proc/detachoutput() +/obj/machinery/bloodbankgen/proc/detachoutput(mob/user) if(outbag) outbag.forceMove(drop_location()) - if(usr && Adjacent(usr) && !issiliconoradminghost(usr)) - usr.put_in_hands(outbag) + if(user && Adjacent(user) && user.can_hold_items()) + user.put_in_hands(outbag) outbag = null filling = null update_icon() @@ -325,12 +325,12 @@ activateinput() else if(href_list["detachinput"]) - detachinput() + detachinput(usr) else if(href_list["activateoutput"]) activateoutput() else if(href_list["detachoutput"]) - detachoutput() + detachoutput(usr) updateUsrDialog() diff --git a/code/game/machinery/computer/camera_advanced.dm b/code/game/machinery/computer/camera_advanced.dm index e5ac9a0f78..5fe62ebb76 100644 --- a/code/game/machinery/computer/camera_advanced.dm +++ b/code/game/machinery/computer/camera_advanced.dm @@ -72,7 +72,7 @@ playsound(src, 'sound/machines/terminal_off.ogg', 25, 0) /obj/machinery/computer/camera_advanced/check_eye(mob/user) - if( (stat & (NOPOWER|BROKEN)) || (!Adjacent(user) && !user.has_unlimited_silicon_privilege) || user.eye_blind || user.incapacitated() ) + if( (stat & (NOPOWER|BROKEN)) || (!Adjacent(user) && hasSiliconAccessInArea(user)) || user.eye_blind || user.incapacitated() ) user.unset_machine() /obj/machinery/computer/camera_advanced/Destroy() diff --git a/code/game/machinery/cryopod.dm b/code/game/machinery/cryopod.dm index b33b87f8b1..92927d047d 100644 --- a/code/game/machinery/cryopod.dm +++ b/code/game/machinery/cryopod.dm @@ -116,7 +116,7 @@ playsound(src, 'sound/machines/terminal_prompt_confirm.ogg', 50, 0) I.forceMove(drop_location()) - if(user && Adjacent(user) && !issiliconoradminghost(user)) + if(user && Adjacent(user) && user.can_hold_items()) user.put_in_hands(I) frozen_items -= I updateUsrDialog() diff --git a/code/game/machinery/iv_drip.dm b/code/game/machinery/iv_drip.dm index 6d19776d86..b3f0ce9693 100644 --- a/code/game/machinery/iv_drip.dm +++ b/code/game/machinery/iv_drip.dm @@ -184,7 +184,7 @@ if(usr.incapacitated()) return if(beaker) - if(usr && Adjacent(usr) && !issiliconoradminghost(usr)) + if(usr && Adjacent(usr) && usr.can_hold_items()) if(!usr.put_in_hands(beaker)) beaker.forceMove(drop_location()) beaker = null diff --git a/code/game/objects/items/RCD.dm b/code/game/objects/items/RCD.dm index 3f57fa7cdf..3fad8cc53d 100644 --- a/code/game/objects/items/RCD.dm +++ b/code/game/objects/items/RCD.dm @@ -196,7 +196,7 @@ RLD /obj/item/construction/rcd/verb/change_airlock_access(mob/user) - if (!ishuman(user) && !user.has_unlimited_silicon_privilege) + if (!ishuman(user) && !user.silicon_privileges) return var/t1 = "" diff --git a/code/game/objects/items/granters.dm b/code/game/objects/items/granters.dm index 004dc1d5e5..55d8453ff2 100644 --- a/code/game/objects/items/granters.dm +++ b/code/game/objects/items/granters.dm @@ -490,7 +490,13 @@ oneuse = FALSE remarks = list("Looks like these would sell much better in a plasma fire...", "Using glass bowls rather then cones?", "Mixing soda and ice-cream?", "Tall glasses with of liquids and solids...", "Just add a bit of icecream and cherry on top?") -//Later content when I have free time - Trilby Date:24-Aug-2019 +/obj/item/book/granter/crafting_recipe/bone_bow //Bow crafting for non-ashwalkers + name = "Sandstone manual on bows" + desc = "A standstone slab with everything you need to know for making bows and arrows just like an ashwalker would." + crafting_recipe_types = list(/datum/crafting_recipe/bone_arrow, /datum/crafting_recipe/bone_bow, /datum/crafting_recipe/ashen_arrow, /datum/crafting_recipe/quiver, /datum/crafting_recipe/bow_tablet) + icon_state = "stone_tablet" + oneuse = FALSE + remarks = list("Sticking burning arrows into the sand makes them stronger?", "Breaking the bone apart to get shards, not sharpening the bone.", "Sinew is just like rope?") /obj/item/book/granter/crafting_recipe/under_the_oven //Illegal cook book name = "Under The Oven" diff --git a/code/game/objects/items/implants/implant_hijack.dm b/code/game/objects/items/implants/implant_hijack.dm index 8a08232859..5dd610059c 100644 --- a/code/game/objects/items/implants/implant_hijack.dm +++ b/code/game/objects/items/implants/implant_hijack.dm @@ -37,18 +37,18 @@ eye_color = H.eye_color return TRUE -/obj/item/implant/hijack/removed(mob/target, silent = FALSE, special = 0) +/obj/item/implant/hijack/removed(mob/living/source, silent = FALSE, special = 0) if(..()) - REMOVE_TRAIT(target, TRAIT_HIJACKER, "implant") - for (var/area/area in imp_in.siliconaccessareas) - imp_in.toggleSiliconAccessArea(area) + REMOVE_TRAIT(source, TRAIT_HIJACKER, "implant") + for (var/area/area in source.siliconaccessareas) + source.toggleSiliconAccessArea(area) var/obj/machinery/power/apc/apc = area.get_apc() if (apc) apc.hijacker = null apc.set_hijacked_lighting() apc.update_icon() - if (ishuman(target)) - var/mob/living/carbon/human/H = target + if (ishuman(source)) + var/mob/living/carbon/human/H = source H.eye_color = eye_color return TRUE @@ -118,4 +118,4 @@ imp_in.light_range = 0 imp_in.light_color = COLOR_YELLOW imp_in.update_light() - return TRUE \ No newline at end of file + return TRUE diff --git a/code/game/objects/items/stacks/sheets/sheet_types.dm b/code/game/objects/items/stacks/sheets/sheet_types.dm index 45911afc73..64875a4cc3 100644 --- a/code/game/objects/items/stacks/sheets/sheet_types.dm +++ b/code/game/objects/items/stacks/sheets/sheet_types.dm @@ -376,6 +376,14 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ /* * Silk */ + + GLOBAL_LIST_INIT(silk_recipes, list ( \ + new/datum/stack_recipe("white jumpsuit", /obj/item/clothing/under/color/white, 4, time = 40), \ + new/datum/stack_recipe("white gloves", /obj/item/clothing/gloves/color/white, 2, time = 40), \ + null, \ + new/datum/stack_recipe("silk string", /obj/item/weaponcrafting/silkstring, 2, time = 40), \ + )) + /obj/item/stack/sheet/silk name = "silk" desc = "A long soft material. This one is just made out of cotton rather then any spiders or wyrms" @@ -385,14 +393,14 @@ GLOBAL_LIST_INIT(cloth_recipes, list ( \ novariants = TRUE merge_type = /obj/item/stack/sheet/silk -//obj/item/stack/sheet/silk/Initialize(mapload, new_amount, merge = TRUE) -// recipes = GLOB.silk_recipes -// return ..() +/obj/item/stack/sheet/silk/Initialize(mapload, new_amount, merge = TRUE) + recipes = GLOB.silk_recipes + return ..() /* * Durathread */ - GLOBAL_LIST_INIT(durathread_recipes, list ( \ +GLOBAL_LIST_INIT(durathread_recipes, list ( \ new/datum/stack_recipe("durathread jumpsuit", /obj/item/clothing/under/durathread, 4, time = 40), new/datum/stack_recipe("durathread beret", /obj/item/clothing/head/beret/durathread, 2, time = 40), \ new/datum/stack_recipe("durathread beanie", /obj/item/clothing/head/beanie/durathread, 2, time = 40), \ diff --git a/code/game/objects/structures/ghost_role_spawners.dm b/code/game/objects/structures/ghost_role_spawners.dm index 8c91b905a0..116c598235 100644 --- a/code/game/objects/structures/ghost_role_spawners.dm +++ b/code/game/objects/structures/ghost_role_spawners.dm @@ -66,6 +66,14 @@ var/datum/language_holder/holder = new_spawn.get_language_holder() holder.selected_default_language = /datum/language/draconic +//Ash walkers on birth understand how to make bone bows, bone arrows and ashen arrows + + new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/bone_arrow) + new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/bone_bow) + new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/ashen_arrow) + new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/quiver) + new_spawn.mind.teach_crafting_recipe(/datum/crafting_recipe/bow_tablet) + if(ishuman(new_spawn)) var/mob/living/carbon/human/H = new_spawn H.underwear = "Nude" diff --git a/code/game/turfs/turf.dm b/code/game/turfs/turf.dm index e8f53f551d..578d6d10ae 100755 --- a/code/game/turfs/turf.dm +++ b/code/game/turfs/turf.dm @@ -552,6 +552,8 @@ //if the vomit combined, apply toxicity and reagents to the old vomit if (QDELETED(V)) V = locate() in src + if(!V) //the decal was spawned on a wall or groundless turf and promptly qdeleted. + return // Make toxins and blazaam vomit look different if(toxvomit == VOMIT_PURPLE) V.icon_state = "vomitpurp_[pick(1,4)]" diff --git a/code/modules/admin/admin_verbs.dm b/code/modules/admin/admin_verbs.dm index f23fc5c070..3ccd113864 100644 --- a/code/modules/admin/admin_verbs.dm +++ b/code/modules/admin/admin_verbs.dm @@ -714,7 +714,7 @@ GLOBAL_PROTECT(admin_verbs_hideable) AI_Interact = !AI_Interact if(mob && IsAdminGhost(mob)) - mob.has_unlimited_silicon_privilege = AI_Interact + mob.silicon_privileges = AI_Interact ? ALL : NONE log_admin("[key_name(usr)] has [AI_Interact ? "activated" : "deactivated"] Admin AI Interact") message_admins("[key_name_admin(usr)] has [AI_Interact ? "activated" : "deactivated"] their AI interaction") diff --git a/code/modules/antagonists/bloodsucker/powers/bs_feed.dm b/code/modules/antagonists/bloodsucker/powers/bs_feed.dm index cc295280e5..bbce221d91 100644 --- a/code/modules/antagonists/bloodsucker/powers/bs_feed.dm +++ b/code/modules/antagonists/bloodsucker/powers/bs_feed.dm @@ -170,7 +170,7 @@ // Warn Feeder about Witnesses... var/was_unnoticed = TRUE for(var/mob/living/M in viewers(notice_range, owner)) - if(M != owner && M != target && iscarbon(M) && M.mind && !M.has_unlimited_silicon_privilege && !M.eye_blind && !M.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)) + if(M != owner && M != target && iscarbon(M) && M.mind && !M.silicon_privileges && !M.eye_blind && !M.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)) was_unnoticed = FALSE break if(was_unnoticed) diff --git a/code/modules/antagonists/bloodsucker/powers/bs_gohome.dm b/code/modules/antagonists/bloodsucker/powers/bs_gohome.dm index 383b7f940b..4788d7639e 100644 --- a/code/modules/antagonists/bloodsucker/powers/bs_gohome.dm +++ b/code/modules/antagonists/bloodsucker/powers/bs_gohome.dm @@ -28,9 +28,9 @@ to_chat(owner, "Your coffin has been destroyed!") return FALSE return TRUE - + /datum/action/bloodsucker/gohome/proc/flicker_lights(var/flicker_range, var/beat_volume) - for(var/obj/machinery/light/L in view(flicker_range, get_turf(owner))) + for(var/obj/machinery/light/L in view(flicker_range, get_turf(owner))) playsound(get_turf(owner), 'sound/effects/singlebeat.ogg', beat_volume, 1) @@ -45,7 +45,7 @@ flicker_lights(4, 40) sleep(50) flicker_lights(4, 60) - for(var/obj/machinery/light/L in view(6, get_turf(owner))) + for(var/obj/machinery/light/L in view(6, get_turf(owner))) L.flicker(5) playsound(get_turf(owner), 'sound/effects/singlebeat.ogg', 60, 1) // ( STEP TWO: Lights OFF? ) @@ -56,7 +56,7 @@ if(!owner) return // SEEN?: (effects ONLY if there are witnesses! Otherwise you just POOF) - + var/am_seen = FALSE // Do Effects (seen by anyone) var/drop_item = FALSE // Drop Stuff (seen by non-vamp) if(isturf(owner.loc)) // Only check if I'm not in a Locker or something. @@ -65,7 +65,7 @@ if(T && T.lighting_object && T.get_lumcount()>= 0.1) // B) Check for Viewers for(var/mob/living/M in viewers(get_turf(owner))) - if(M != owner && isliving(M) && M.mind && !M.has_unlimited_silicon_privilege && !M.eye_blind) // M.client <--- add this in after testing! + if(M != owner && isliving(M) && M.mind && !M.silicon_privileges && !M.eye_blind) // M.client <--- add this in after testing! am_seen = TRUE if (!M.mind.has_antag_datum(ANTAG_DATUM_BLOODSUCKER)) drop_item = TRUE @@ -95,13 +95,13 @@ puff.effect_type = /obj/effect/particle_effect/smoke/vampsmoke puff.set_up(3, 0, get_turf(owner)) puff.start() - + //STEP FIVE: Create animal at prev location var/mob/living/simple_animal/SA = pick(/mob/living/simple_animal/mouse,/mob/living/simple_animal/mouse,/mob/living/simple_animal/mouse, /mob/living/simple_animal/hostile/retaliate/bat) //prob(300) /mob/living/simple_animal/mouse, new SA (owner.loc) // TELEPORT: Move to Coffin & Close it! - do_teleport(owner, bloodsuckerdatum.coffin, no_effects = TRUE, forced = TRUE, channel = TELEPORT_CHANNEL_QUANTUM) user.set_resting(TRUE, TRUE, FALSE) + do_teleport(owner, bloodsuckerdatum.coffin, no_effects = TRUE, forced = TRUE, channel = TELEPORT_CHANNEL_QUANTUM) user.Stun(30,1) // CLOSE LID: If fail, force me in. if(!bloodsuckerdatum.coffin.close(owner)) @@ -112,4 +112,4 @@ bloodsuckerdatum.coffin.update_icon() // Lock Coffin bloodsuckerdatum.coffin.LockMe(owner) - + diff --git a/code/modules/antagonists/clockcult/clockcult.dm b/code/modules/antagonists/clockcult/clockcult.dm index d68e9b594d..1869414ab6 100644 --- a/code/modules/antagonists/clockcult/clockcult.dm +++ b/code/modules/antagonists/clockcult/clockcult.dm @@ -120,7 +120,7 @@ hierophant_network.Grant(current) current.throw_alert("clockinfo", /obj/screen/alert/clockwork/infodump) var/obj/structure/destructible/clockwork/massive/celestial_gateway/G = GLOB.ark_of_the_clockwork_justiciar - if(G.active && ishuman(current)) + if(G && G.active && ishuman(current)) current.add_overlay(mutable_appearance('icons/effects/genetics.dmi', "servitude", -MUTATIONS_LAYER)) /datum/antagonist/clockcult/remove_innate_effects(mob/living/mob_override) @@ -174,9 +174,12 @@ log_admin("[key_name(admin)] has made [new_owner.current] into a servant of Ratvar.") /datum/antagonist/clockcult/admin_remove(mob/user) - remove_servant_of_ratvar(owner.current, TRUE) - message_admins("[key_name_admin(user)] has removed clockwork servant status from [owner.current].") - log_admin("[key_name(user)] has removed clockwork servant status from [owner.current].") + var/mob/target = owner.current + if(!target) + return + remove_servant_of_ratvar(target, TRUE) + message_admins("[key_name_admin(user)] has removed clockwork servant status from [target].") + log_admin("[key_name(user)] has removed clockwork servant status from [target].") /datum/antagonist/clockcult/get_admin_commands() . = ..() diff --git a/code/modules/atmospherics/machinery/airalarm.dm b/code/modules/atmospherics/machinery/airalarm.dm index e85cf1efa6..36a128f2eb 100644 --- a/code/modules/atmospherics/machinery/airalarm.dm +++ b/code/modules/atmospherics/machinery/airalarm.dm @@ -229,7 +229,7 @@ . += "Alt-click to [locked ? "unlock" : "lock"] the interface." /obj/machinery/airalarm/ui_status(mob/user) - if(user.has_unlimited_silicon_privilege && aidisabled) + if(hasSiliconAccessInArea(user) && aidisabled) to_chat(user, "AI control has been disabled.") else if(!shorted) return ..() @@ -245,7 +245,7 @@ /obj/machinery/airalarm/ui_data(mob/user) var/data = list( "locked" = locked, - "siliconUser" = user.has_unlimited_silicon_privilege || hasSiliconAccessInArea(user), + "siliconUser" = hasSiliconAccessInArea(user), "emagged" = (obj_flags & EMAGGED ? 1 : 0), "danger_level" = danger_level, ) @@ -288,7 +288,7 @@ "danger_level" = cur_tlv.get_danger_level(environment.gases[gas_id] * partial_pressure) )) - if(!locked || user.has_unlimited_silicon_privilege || hasSiliconAccessInArea(user)) + if(!locked || hasSiliconAccessInArea(user, PRIVILEDGES_SILICON|PRIVILEDGES_DRONE)) data["vents"] = list() for(var/id_tag in A.air_vent_names) var/long_name = A.air_vent_names[id_tag] @@ -368,12 +368,14 @@ /obj/machinery/airalarm/ui_act(action, params) if(..() || buildstage != 2) return - if((locked && !usr.has_unlimited_silicon_privilege && !hasSiliconAccessInArea(usr)) || (usr.has_unlimited_silicon_privilege && aidisabled)) + var/silicon_access = hasSiliconAccessInArea(usr) + var/bot_priviledges = silicon_access || (usr.silicon_privileges & PRIVILEDGES_DRONE) + if((locked && !bot_priviledges) || (silicon_access && aidisabled)) return var/device_id = params["id_tag"] switch(action) if("lock") - if(usr.has_unlimited_silicon_privilege && !wires.is_cut(WIRE_IDSCAN)) + if(bot_priviledges && !wires.is_cut(WIRE_IDSCAN)) locked = !locked . = TRUE if("power", "toggle_filter", "widenet", "scrubbing") diff --git a/code/modules/cargo/exports/large_objects.dm b/code/modules/cargo/exports/large_objects.dm index bf67286f11..b7bdcb1f59 100644 --- a/code/modules/cargo/exports/large_objects.dm +++ b/code/modules/cargo/exports/large_objects.dm @@ -24,13 +24,13 @@ export_types = list(/obj/structure/ore_box) /datum/export/large/crate/wood - cost = 140 // + cost = 140 unit_name = "wooden crate" export_types = list(/obj/structure/closet/crate/wooden) exclude_types = list() /datum/export/large/barrel - cost = 500 //150 to make meaning proffit of 350 + cost = 300 //double the wooden cost of a coffin. unit_name = "wooden barrel" export_types = list(/obj/structure/fermenting_barrel) @@ -40,19 +40,11 @@ export_types = list(/obj/structure/closet/crate/coffin) /datum/export/large/reagent_dispenser - cost = 100 // +0-400 depending on amount of reagents left - var/contents_cost = 400 - -/datum/export/large/reagent_dispenser/get_cost(obj/O) - var/obj/structure/reagent_dispensers/D = O - var/ratio = D.reagents.total_volume / D.reagents.maximum_volume - - return ..() + round(contents_cost * ratio) + cost = 100 /datum/export/large/reagent_dispenser/water unit_name = "watertank" export_types = list(/obj/structure/reagent_dispensers/watertank) - contents_cost = 200 /datum/export/large/reagent_dispenser/fuel unit_name = "fueltank" @@ -60,7 +52,6 @@ /datum/export/large/reagent_dispenser/beer unit_name = "beer keg" - contents_cost = 700 export_types = list(/obj/structure/reagent_dispensers/beerkeg) /datum/export/large/pipedispenser diff --git a/code/modules/cargo/exports/weapons.dm b/code/modules/cargo/exports/weapons.dm index 5b78a5d630..c75a1c0bff 100644 --- a/code/modules/cargo/exports/weapons.dm +++ b/code/modules/cargo/exports/weapons.dm @@ -199,6 +199,31 @@ unit_name = "advanced shotgun shell" export_types = list(/obj/item/ammo_casing/shotgun/dragonsbreath, /obj/item/ammo_casing/shotgun/meteorslug, /obj/item/ammo_casing/shotgun/pulseslug, /obj/item/ammo_casing/shotgun/frag12, /obj/item/ammo_casing/shotgun/ion, /obj/item/ammo_casing/shotgun/laserslug) +///////////////////////// +//Bow and Arrows///////// +///////////////////////// + +/datum/export/weapon/bows + cost = 450 + unit_name = "bow" + export_types = list(/obj/item/gun/ballistic/bow) + +/datum/export/weapon/arrows + cost = 150 + unit_name = "arrow" + export_types = list(/obj/item/ammo_casing/caseless/arrow, /obj/item/ammo_casing/caseless/arrow/bone, /obj/item/ammo_casing/caseless/arrow/ashen) + +/datum/export/weapon/bow_teaching + cost = 500 + unit_name = "stone tablets" + export_types = list(/obj/item/book/granter/crafting_recipe/bone_bow) + +/datum/export/weapon/quiver + cost = 100 + unit_name = "quiver" + export_types = list(/obj/item/storage/belt/quiver) + + ///////////////////////// //The Traitor Sell Outs// ///////////////////////// diff --git a/code/modules/cargo/expressconsole.dm b/code/modules/cargo/expressconsole.dm index 264f9ac22e..a65d8cad40 100644 --- a/code/modules/cargo/expressconsole.dm +++ b/code/modules/cargo/expressconsole.dm @@ -97,7 +97,7 @@ var/canBeacon = beacon && (isturf(beacon.loc) || ismob(beacon.loc))//is the beacon in a valid location? var/list/data = list() data["locked"] = locked//swipe an ID to unlock - data["siliconUser"] = user.has_unlimited_silicon_privilege + data["siliconUser"] = hasSiliconAccessInArea(user) data["beaconzone"] = beacon ? get_area(beacon) : ""//where is the beacon located? outputs in the tgui data["usingBeacon"] = usingBeacon //is the mode set to deliver to the beacon or the cargobay? data["canBeacon"] = !usingBeacon || canBeacon //is the mode set to beacon delivery, and is the beacon in a valid location? diff --git a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm index 71becf0542..4fc55ba4c3 100644 --- a/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm +++ b/code/modules/food_and_drinks/kitchen_machinery/icecream_vat.dm @@ -319,7 +319,7 @@ /obj/machinery/icecream_vat/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker) if(beaker) beaker.forceMove(drop_location()) - if(user && Adjacent(user) && !issiliconoradminghost(user)) + if(user && Adjacent(user) && user.can_hold_items()) user.put_in_hands(beaker) if(new_beaker) beaker = new_beaker diff --git a/code/modules/mob/dead/observer/login.dm b/code/modules/mob/dead/observer/login.dm index 1b328dbc69..8daf8ec052 100644 --- a/code/modules/mob/dead/observer/login.dm +++ b/code/modules/mob/dead/observer/login.dm @@ -6,7 +6,7 @@ var/preferred_form = null if(IsAdminGhost(src)) - has_unlimited_silicon_privilege = 1 + silicon_privileges = ALL if(client.prefs.unlock_content) preferred_form = client.prefs.ghost_form diff --git a/code/modules/mob/dead/observer/observer.dm b/code/modules/mob/dead/observer/observer.dm index 05d8db05db..9165462677 100644 --- a/code/modules/mob/dead/observer/observer.dm +++ b/code/modules/mob/dead/observer/observer.dm @@ -11,7 +11,7 @@ GLOBAL_VAR_INIT(observer_default_invisibility, INVISIBILITY_OBSERVER) layer = GHOST_LAYER stat = DEAD density = FALSE - anchored = TRUE // don't get pushed around + move_resist = INFINITY see_invisible = SEE_INVISIBLE_OBSERVER see_in_dark = 100 invisibility = INVISIBILITY_OBSERVER diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm index 8b61390153..30d9fab56b 100644 --- a/code/modules/mob/living/carbon/carbon.dm +++ b/code/modules/mob/living/carbon/carbon.dm @@ -987,3 +987,6 @@ return TRUE if(isclothing(wear_mask) && (wear_mask.clothing_flags & SCAN_REAGENTS)) return TRUE + +/mob/living/carbon/can_hold_items() + return TRUE diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 3a202853e9..e16b1d9ef6 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -823,9 +823,6 @@ . += dna.species.check_weakness(weapon, attacker) /mob/living/carbon/human/is_literate() - return 1 - -/mob/living/carbon/human/can_hold_items() return TRUE /mob/living/carbon/human/update_gravity(has_gravity,override = 0) @@ -834,7 +831,7 @@ ..() /mob/living/carbon/human/vomit(lost_nutrition = 10, blood = 0, stun = 1, distance = 0, message = 1, toxic = 0) - if(blood && (NOBLOOD in dna.species.species_traits)) + if(blood && dna?.species && (NOBLOOD in dna.species.species_traits)) if(message) visible_message("[src] dry heaves!", \ "You try to throw up, but there's nothing in your stomach!") diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 85c4f8125d..db91fa1169 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -20,7 +20,7 @@ /mob/living/carbon/human/proc/checkarmor(obj/item/bodypart/def_zone, d_type) - if(!d_type) + if(!d_type || !def_zone) return 0 var/protection = 0 var/list/body_parts = list(head, wear_mask, wear_suit, w_uniform, back, gloves, shoes, belt, s_store, glasses, ears, wear_id, wear_neck) //Everything but pockets. Pockets are l_store and r_store. (if pockets were allowed, putting something armored, gloves or hats for example, would double up on the armor) diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm index bbae050bba..24acccdd2e 100644 --- a/code/modules/mob/living/carbon/inventory.dm +++ b/code/modules/mob/living/carbon/inventory.dm @@ -72,7 +72,7 @@ put_in_hands(I) update_inv_hands() if(SLOT_IN_BACKPACK) - if(!SEND_SIGNAL(back, COMSIG_TRY_STORAGE_INSERT, I, src, TRUE)) + if(!back || !SEND_SIGNAL(back, COMSIG_TRY_STORAGE_INSERT, I, src, TRUE)) not_handled = TRUE else not_handled = TRUE diff --git a/code/modules/mob/living/silicon/pai/pai.dm b/code/modules/mob/living/silicon/pai/pai.dm index ea07b6464a..8a95ee7da4 100644 --- a/code/modules/mob/living/silicon/pai/pai.dm +++ b/code/modules/mob/living/silicon/pai/pai.dm @@ -11,6 +11,7 @@ health = 500 maxHealth = 500 layer = BELOW_MOB_LAYER + silicon_privileges = PRIVILEDGES_PAI var/datum/element/mob_holder/current_mob_holder //because only a few of their chassis can be actually held. var/network = "ss13" diff --git a/code/modules/mob/living/silicon/silicon.dm b/code/modules/mob/living/silicon/silicon.dm index 72e98e348c..531faff056 100644 --- a/code/modules/mob/living/silicon/silicon.dm +++ b/code/modules/mob/living/silicon/silicon.dm @@ -1,6 +1,6 @@ /mob/living/silicon gender = NEUTER - has_unlimited_silicon_privilege = 1 + silicon_privileges = PRIVILEDGES_SILICON verb_say = "states" verb_ask = "queries" verb_exclaim = "declares" diff --git a/code/modules/mob/living/simple_animal/bot/bot.dm b/code/modules/mob/living/simple_animal/bot/bot.dm index 8703788959..75364b2845 100644 --- a/code/modules/mob/living/simple_animal/bot/bot.dm +++ b/code/modules/mob/living/simple_animal/bot/bot.dm @@ -15,7 +15,7 @@ maxbodytemp = INFINITY minbodytemp = 0 blood_volume = 0 - has_unlimited_silicon_privilege = 1 + silicon_privileges = PRIVILEDGES_BOT sentience_type = SENTIENCE_ARTIFICIAL status_flags = NONE //no default canpush verb_say = "states" @@ -194,10 +194,12 @@ if(locked) //First emag application unlocks the bot's interface. Apply a screwdriver to use the emag again. locked = FALSE emagged = 1 - to_chat(user, "You bypass [src]'s controls.") + if(user) + to_chat(user, "You bypass [src]'s controls.") return TRUE if(!open) - to_chat(user, "You need to open maintenance panel first!") + if(user) + to_chat(user, "You need to open maintenance panel first!") return emagged = 2 remote_disabled = 1 //Manually emagging the bot locks out the AI built in panel. @@ -205,7 +207,8 @@ bot_reset() turn_on() //The bot automatically turns on when emagged, unless recently hit with EMP. to_chat(src, "(#$*#$^^( OVERRIDE DETECTED") - log_combat(user, src, "emagged") + if(user) + log_combat(user, src, "emagged") return TRUE /mob/living/simple_animal/bot/examine(mob/user) diff --git a/code/modules/mob/living/simple_animal/bot/mulebot.dm b/code/modules/mob/living/simple_animal/bot/mulebot.dm index 9f6b984014..4ebbfde318 100644 --- a/code/modules/mob/living/simple_animal/bot/mulebot.dm +++ b/code/modules/mob/living/simple_animal/bot/mulebot.dm @@ -123,7 +123,8 @@ emagged = TRUE if(!open) locked = !locked - to_chat(user, "You [locked ? "lock" : "unlock"] [src]'s controls!") + if(user) + to_chat(user, "You [locked ? "lock" : "unlock"] [src]'s controls!") flick("mulebot-emagged", src) playsound(src, "sparks", 100, FALSE) @@ -180,7 +181,7 @@ var/list/data = list() data["on"] = on data["locked"] = locked - data["siliconUser"] = user.has_unlimited_silicon_privilege + data["siliconUser"] = hasSiliconAccessInArea(usr) data["mode"] = mode ? mode_name[mode] : "Ready" data["modeStatus"] = "" switch(mode) @@ -205,11 +206,12 @@ return data /mob/living/simple_animal/bot/mulebot/ui_act(action, params) - if(..() || (locked && !usr.has_unlimited_silicon_privilege)) + var/silicon_access = hasSiliconAccessInArea(usr) + if(..() || (locked && silicon_access)) return switch(action) if("lock") - if(usr.has_unlimited_silicon_privilege) + if(silicon_access) locked = !locked . = TRUE if("power") @@ -766,4 +768,3 @@ /obj/machinery/bot_core/mulebot req_access = list(ACCESS_CARGO) - \ No newline at end of file diff --git a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm index 7dd373b49f..43149e6ba7 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/_drone.dm @@ -41,7 +41,7 @@ bubble_icon = "machine" initial_language_holder = /datum/language_holder/drone mob_size = MOB_SIZE_SMALL - has_unlimited_silicon_privilege = 1 + silicon_privileges = PRIVILEDGES_DRONE damage_coeff = list(BRUTE = 1, BURN = 1, TOX = 0, CLONE = 0, STAMINA = 0, OXY = 0) hud_possible = list(DIAG_STAT_HUD, DIAG_HUD, ANTAG_HUD) unique_name = TRUE diff --git a/code/modules/mob/living/simple_animal/hostile/statue.dm b/code/modules/mob/living/simple_animal/hostile/statue.dm index 5ad787b143..2bab332cd0 100644 --- a/code/modules/mob/living/simple_animal/hostile/statue.dm +++ b/code/modules/mob/living/simple_animal/hostile/statue.dm @@ -126,7 +126,7 @@ // This loop will, at most, loop twice. for(var/atom/check in check_list) for(var/mob/living/M in viewers(world.view + 1, check) - src) - if(M.client && CanAttack(M) && !M.has_unlimited_silicon_privilege) + if(M.client && CanAttack(M) && !M.silicon_privileges) if(!M.eye_blind) return M for(var/obj/mecha/M in view(world.view + 1, check)) //assuming if you can see them they can see you diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index c149b158fc..638a3aa0e2 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -94,7 +94,7 @@ var/digitalinvis = 0 //Are they ivisible to the AI? var/image/digitaldisguise = null //what does the AI see instead of them? - var/has_unlimited_silicon_privilege = 0 // Can they interact with station electronics + var/silicon_privileges = NONE // Can they interact with station electronics var/obj/control_object //Used by admins to possess objects. All mobs should have this var var/atom/movable/remote_control //Calls relaymove() to whatever it is diff --git a/code/modules/mob/mob_helpers.dm b/code/modules/mob/mob_helpers.dm index b25531f0e0..12d74d2f8f 100644 --- a/code/modules/mob/mob_helpers.dm +++ b/code/modules/mob/mob_helpers.dm @@ -406,8 +406,8 @@ It's fairly easy to fix if dealing with single letters but not so much with comp return return TRUE -/atom/proc/hasSiliconAccessInArea(mob/user) - return user && (issilicon(user) || (user.siliconaccesstoggle && (get_area(src) in user.siliconaccessareas))) +/atom/proc/hasSiliconAccessInArea(mob/user, flags = PRIVILEDGES_SILICON) + return user.silicon_privileges & (flags) || (user.siliconaccesstoggle && (get_area(src) in user.siliconaccessareas)) /mob/proc/toggleSiliconAccessArea(area/area) if (area in siliconaccessareas) @@ -555,4 +555,4 @@ It's fairly easy to fix if dealing with single letters but not so much with comp //Can the mob see reagents inside of containers? /mob/proc/can_see_reagents() - return stat == DEAD || has_unlimited_silicon_privilege //Dead guys and silicons can always see reagents + return stat == DEAD || silicon_privileges //Dead guys and silicons can always see reagents diff --git a/code/modules/oracle_ui/hookup_procs.dm b/code/modules/oracle_ui/hookup_procs.dm index 18d7bbfd8c..30db9d92b9 100644 --- a/code/modules/oracle_ui/hookup_procs.dm +++ b/code/modules/oracle_ui/hookup_procs.dm @@ -5,7 +5,7 @@ return "Default Implementation" /datum/proc/oui_canuse(mob/user) - if(isobserver(user) && !user.has_unlimited_silicon_privilege) + if(isobserver(user) && !user.silicon_privileges) return FALSE return oui_canview(user) @@ -35,7 +35,7 @@ return ..() /obj/machinery/oui_canview(mob/user) - if(user.has_unlimited_silicon_privilege || hasSiliconAccessInArea(user)) + if(hasSiliconAccessInArea(user, ALL)) return TRUE if(!can_interact(user)) return FALSE diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 982afa49c8..db3e3c83c6 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -846,7 +846,7 @@ return /obj/machinery/power/apc/oui_canview(mob/user) - if(user.has_unlimited_silicon_privilege || area.hasSiliconAccessInArea(user)) + if(area.hasSiliconAccessInArea(user)) //some APCs are mapped outside their assigned area, so this is required. return TRUE return ..() @@ -864,7 +864,7 @@ if (H && !H.stealthmode && H.toggled) abilitiesavail = TRUE var/list/data = list( - "locked" = locked && !(integration_cog && is_servant_of_ratvar(user)) && !area.hasSiliconAccessInArea(user), + "locked" = locked && !(integration_cog && is_servant_of_ratvar(user)) && !area.hasSiliconAccessInArea(user, PRIVILEDGES_SILICON|PRIVILEDGES_DRONE), "lock_nightshift" = nightshift_requires_auth, "failTime" = failure_timer, "isOperating" = operating, @@ -874,7 +874,7 @@ "chargingStatus" = charging, "totalLoad" = DisplayPower(lastused_total), "coverLocked" = coverlocked, - "siliconUser" = user.has_unlimited_silicon_privilege || user.using_power_flow_console() || area.hasSiliconAccessInArea(user), + "siliconUser" = user.using_power_flow_console() || area.hasSiliconAccessInArea(user), "malfStatus" = get_malf_status(user), "emergencyLights" = !emergency_lights, "nightshiftLights" = nightshift_lights, @@ -951,7 +951,7 @@ return TRUE if (user == hijacker || (area.hasSiliconAccessInArea(user) && !aidisabled)) return TRUE - if(user.has_unlimited_silicon_privilege) + if(user.silicon_privileges & PRIVILEDGES_SILICON) var/mob/living/silicon/ai/AI = user var/mob/living/silicon/robot/robot = user if (src.aidisabled || malfhack && istype(malfai) && ((istype(AI) && (malfai!=AI && malfai != AI.parent)) || (istype(robot) && (robot in malfai.connected_robots)))) @@ -985,7 +985,7 @@ if (action == "hijack" && can_use(usr, 1)) //don't need auth for hijack button hijack(usr) return - var/authorized = (!locked || usr.has_unlimited_silicon_privilege || area.hasSiliconAccessInArea(usr) || (integration_cog && (is_servant_of_ratvar(usr)))) + var/authorized = (!locked || area.hasSiliconAccessInArea(usr, PRIVILEDGES_SILICON|PRIVILEDGES_DRONE) || (integration_cog && (is_servant_of_ratvar(usr)))) if((action == "toggle_nightshift") && (!nightshift_requires_auth || authorized)) toggle_nightshift_lights() return TRUE @@ -993,7 +993,7 @@ return switch(action) if("lock") - if(usr.has_unlimited_silicon_privilege || area.hasSiliconAccessInArea(usr)) + if(area.hasSiliconAccessInArea(usr)) if((obj_flags & EMAGGED) || (stat & (BROKEN|MAINT))) to_chat(usr, "The APC does not respond to the command.") else @@ -1027,7 +1027,7 @@ update() return TRUE if("overload") - if(usr.has_unlimited_silicon_privilege || area.hasSiliconAccessInArea(usr)) + if(area.hasSiliconAccessInArea(usr)) overload_lighting() return TRUE if("hack") diff --git a/code/modules/projectiles/ammunition/caseless/arrow.dm b/code/modules/projectiles/ammunition/caseless/arrow.dm index e0ca637a8b..57f47e2ad9 100644 --- a/code/modules/projectiles/ammunition/caseless/arrow.dm +++ b/code/modules/projectiles/ammunition/caseless/arrow.dm @@ -5,4 +5,22 @@ caliber = "arrow" icon_state = "arrow" throwforce = 3 //good luck hitting someone with the pointy end of the arrow - throw_speed = 3 \ No newline at end of file + throw_speed = 3 + +/obj/item/ammo_casing/caseless/arrow/ashen + name = "ashen arrow" + desc = "Fire harderned wooden arrow." + icon_state = "asharrow" + projectile_type = /obj/item/projectile/bullet/reusable/arrow/ashen + +/obj/item/ammo_casing/caseless/arrow/bone + name = "bone arrow" + desc = "Arrow made of bone and sinew. The tip is sharp enough to pierce into a goliath plate." + icon_state = "bonearrow" + projectile_type = /obj/item/projectile/bullet/reusable/arrow/bone + +/obj/item/ammo_casing/caseless/arrow/bronze + name = "bronze arrow" + desc = "Bronze tipped arrow." + icon_state = "bronzearrow" + projectile_type = /obj/item/projectile/bullet/reusable/arrow/bronze diff --git a/code/modules/projectiles/guns/ballistic/bow.dm b/code/modules/projectiles/guns/ballistic/bow.dm index 448e2915d9..540ea722b9 100644 --- a/code/modules/projectiles/guns/ballistic/bow.dm +++ b/code/modules/projectiles/guns/ballistic/bow.dm @@ -50,4 +50,19 @@ icon_state = "bow_[get_ammo() ? (chambered ? "firing" : "loaded") : "unloaded"]" /obj/item/gun/ballistic/bow/can_shoot() - return chambered \ No newline at end of file + return chambered + +/obj/item/gun/ballistic/bow/ashen + name = "bone bow" + desc = "Some sort of primitive projectile weapon made of bone and sinew. Used to fire arrows." + icon_state = "ashenbow" + item_state = "ashenbow" + force = 8 + +/obj/item/gun/ballistic/bow/pipe + name = "pipe bow" + desc = "Some sort of pipe made projectile weapon made of a silk string and lots of bending. Used to fire arrows." + icon_state = "pipebow" + item_state = "pipebow" + inaccuracy_modifier = 1.1 //Made of pipe and in a rush + force = 0 \ No newline at end of file diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index be43bc48fd..401678512b 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -67,7 +67,8 @@ /obj/item/gun/energy/Destroy() if(flags_1 & INITIALIZED_1) QDEL_NULL(cell) - QDEL_LIST(ammo_type) + if(!(flags_1 & HOLOGRAM_1)) //holodeck stuff. + QDEL_LIST(ammo_type) STOP_PROCESSING(SSobj, src) return ..() diff --git a/code/modules/projectiles/projectile/energy/tesla.dm b/code/modules/projectiles/projectile/energy/tesla.dm index 43c31816cd..2439cee429 100644 --- a/code/modules/projectiles/projectile/energy/tesla.dm +++ b/code/modules/projectiles/projectile/energy/tesla.dm @@ -7,10 +7,11 @@ var/zap_range = 3 var/power = 10000 -/obj/item/projectile/energy/tesla/fire(setAngle) - if(firer) - chain = firer.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY) - ..() +/obj/item/projectile/energy/tesla/fire(setAngle, atom/direct_target) + var/atom/source = fired_from || firer + if(source) + chain = source.Beam(src, icon_state = "lightning[rand(1, 12)]", time = INFINITY, maxdistance = INFINITY) + return ..() /obj/item/projectile/energy/tesla/on_hit(atom/target) . = ..() diff --git a/code/modules/projectiles/projectile/reusable/arrow.dm b/code/modules/projectiles/projectile/reusable/arrow.dm index f1c9638fd9..d00de79eb1 100644 --- a/code/modules/projectiles/projectile/reusable/arrow.dm +++ b/code/modules/projectiles/projectile/reusable/arrow.dm @@ -3,4 +3,23 @@ desc = "Woosh!" damage = 15 icon_state = "arrow" - ammo_type = /obj/item/ammo_casing/caseless/arrow \ No newline at end of file + ammo_type = /obj/item/ammo_casing/caseless/arrow + +/obj/item/projectile/bullet/reusable/arrow/ashen + name = "ashen arrow" + desc = "Fire harderned arrow." + damage = 25 + ammo_type = /obj/item/ammo_casing/caseless/arrow/ashen + +/obj/item/projectile/bullet/reusable/arrow/bone //AP for ashwalkers + name = "bone arrow" + desc = "Arrow made of bone and sinew." + damage = 35 + armour_penetration = 40 + ammo_type = /obj/item/ammo_casing/caseless/arrow/bone + +/obj/item/projectile/bullet/reusable/arrow/bronze //Just some AP shots + name = "bronze arrow" + desc = "Bronze tipped arrow." + armour_penetration = 10 + ammo_type = /obj/item/ammo_casing/caseless/arrow/bronze diff --git a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm index ed68c25cb6..be15bb70cf 100644 --- a/code/modules/reagents/chemistry/machinery/chem_dispenser.dm +++ b/code/modules/reagents/chemistry/machinery/chem_dispenser.dm @@ -408,7 +408,7 @@ if(beaker) var/obj/item/reagent_containers/B = beaker B.forceMove(drop_location()) - if(user && Adjacent(user) && !issiliconoradminghost(user)) + if(user && Adjacent(user) && user.can_hold_items()) user.put_in_hands(B) if(new_beaker) beaker = new_beaker diff --git a/code/modules/reagents/chemistry/machinery/chem_heater.dm b/code/modules/reagents/chemistry/machinery/chem_heater.dm index 189d09b06f..4c4d0fdb6e 100644 --- a/code/modules/reagents/chemistry/machinery/chem_heater.dm +++ b/code/modules/reagents/chemistry/machinery/chem_heater.dm @@ -38,7 +38,7 @@ /obj/machinery/chem_heater/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker) if(beaker) beaker.forceMove(drop_location()) - if(user && Adjacent(user) && !issiliconoradminghost(user)) + if(user && Adjacent(user) && user.can_hold_items()) user.put_in_hands(beaker) if(new_beaker) beaker = new_beaker diff --git a/code/modules/reagents/chemistry/machinery/chem_master.dm b/code/modules/reagents/chemistry/machinery/chem_master.dm index 66c663e2e4..abfd00ed90 100644 --- a/code/modules/reagents/chemistry/machinery/chem_master.dm +++ b/code/modules/reagents/chemistry/machinery/chem_master.dm @@ -129,7 +129,7 @@ if(beaker) var/obj/item/reagent_containers/B = beaker B.forceMove(drop_location()) - if(user && Adjacent(user) && !issiliconoradminghost(user)) + if(user && Adjacent(user) && user.can_hold_items()) user.put_in_hands(B) if(new_beaker) beaker = new_beaker @@ -139,7 +139,7 @@ if(bottle) var/obj/item/storage/pill_bottle/B = bottle B.forceMove(drop_location()) - if(user && Adjacent(user) && !issiliconoradminghost(user)) + if(user && Adjacent(user) && user.can_hold_items()) user.put_in_hands(B) else adjust_item_drop_location(B) diff --git a/code/modules/reagents/chemistry/machinery/pandemic.dm b/code/modules/reagents/chemistry/machinery/pandemic.dm index 3dea44cf40..7b25aa769d 100644 --- a/code/modules/reagents/chemistry/machinery/pandemic.dm +++ b/code/modules/reagents/chemistry/machinery/pandemic.dm @@ -192,7 +192,7 @@ update_icon() var/turf/source_turf = get_turf(src) log_virus("A culture bottle was printed for the virus [A.admin_details()] at [loc_name(source_turf)] by [key_name(usr)]") - + . = TRUE if("create_vaccine_bottle") wait = TRUE @@ -202,9 +202,9 @@ var/obj/item/reagent_containers/glass/bottle/B = new(drop_location()) B.name = "[D.name] vaccine bottle" B.reagents.add_reagent(/datum/reagent/vaccine, 15, list(id)) - + update_icon() - + . = TRUE /obj/machinery/computer/pandemic/attackby(obj/item/I, mob/user, params) @@ -229,7 +229,7 @@ /obj/machinery/computer/pandemic/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker) if(beaker) - if(user && Adjacent(user) && !issiliconoradminghost(user)) + if(user && Adjacent(user) && user.can_hold_items()) if(!user.put_in_hands(beaker)) beaker.forceMove(drop_location()) if(new_beaker) diff --git a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm index b17c2dfb37..85cdc33e72 100644 --- a/code/modules/reagents/chemistry/machinery/reagentgrinder.dm +++ b/code/modules/reagents/chemistry/machinery/reagentgrinder.dm @@ -75,7 +75,7 @@ /obj/machinery/reagentgrinder/proc/replace_beaker(mob/living/user, obj/item/reagent_containers/new_beaker) if(beaker) beaker.forceMove(drop_location()) - if(user && Adjacent(user) && !issiliconoradminghost(user)) + if(user && Adjacent(user) && user.can_hold_items()) user.put_in_hands(beaker) if(new_beaker) beaker = new_beaker diff --git a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm index cc8ef2ebd8..025587bc2a 100644 --- a/code/modules/reagents/chemistry/reagents/toxin_reagents.dm +++ b/code/modules/reagents/chemistry/reagents/toxin_reagents.dm @@ -504,7 +504,7 @@ toxpwr = 0 /datum/reagent/toxin/itching_powder/reaction_mob(mob/living/M, method=TOUCH, reac_volume) - if(method == TOUCH || method == VAPOR) + if((method == TOUCH || method == VAPOR) && M.reagents) M.reagents.add_reagent(/datum/reagent/toxin/itching_powder, reac_volume) /datum/reagent/toxin/itching_powder/on_mob_life(mob/living/carbon/M) diff --git a/code/modules/reagents/reagent_containers/bottle.dm b/code/modules/reagents/reagent_containers/bottle.dm index c05f4f3e78..e4741bb858 100644 --- a/code/modules/reagents/reagent_containers/bottle.dm +++ b/code/modules/reagents/reagent_containers/bottle.dm @@ -431,4 +431,4 @@ /obj/item/reagent_containers/glass/bottle/hexacamphor name = "Hexacamphor bottle" desc = "A bottle of strong anaphrodisiac. Reduces libido." - list_reagents = list(/datum/reagent/drug/anaphrodisiacplus = 30) \ No newline at end of file + list_reagents = list(/datum/reagent/drug/anaphrodisiacplus = 30) diff --git a/code/modules/research/designs/biogenerator_designs.dm b/code/modules/research/designs/biogenerator_designs.dm index dd55697bee..ab0460974c 100644 --- a/code/modules/research/designs/biogenerator_designs.dm +++ b/code/modules/research/designs/biogenerator_designs.dm @@ -3,7 +3,7 @@ /////////////////////////////////// /datum/design/milk - name = "10 Milk" + name = "10u Milk" id = "milk" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 20) @@ -11,7 +11,7 @@ category = list("initial","Food") /datum/design/cream - name = "10 Cream" + name = "10u Cream" id = "cream" build_type = BIOGENERATOR materials = list(MAT_BIOMASS = 30) @@ -123,6 +123,22 @@ build_path = /obj/item/reagent_containers/glass/bottle/killer/pestkiller category = list("initial","Botany Chemicals") +/datum/design/ammonia + name = "10u Ammonia" + id = "ammonia_biogen" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 25) + make_reagents = list(/datum/reagent/ammonia = 10) + category = list("initial","Botany Chemicals") + +/datum/design/saltpetre + name = "10u Saltpetre" + id = "saltpetre_biogen" + build_type = BIOGENERATOR + materials = list(MAT_BIOMASS = 75) + make_reagents = list(/datum/reagent/saltpetre = 10) + category = list("initial","Botany Chemicals") + /datum/design/botany_bottle name = "Empty Bottle" id = "botany_bottle" diff --git a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm index 0838e70bfd..9efbe58a29 100644 --- a/code/modules/research/xenobiology/crossbreeding/_status_effects.dm +++ b/code/modules/research/xenobiology/crossbreeding/_status_effects.dm @@ -890,8 +890,8 @@ datum/status_effect/stabilized/blue/on_remove() healing_types += TOX if(owner.getCloneLoss() > 0) healing_types += CLONE - - owner.apply_damage_type(-heal_amount, damagetype=pick(healing_types)) + if(length(healing_types)) + owner.apply_damage_type(-heal_amount, damagetype=pick(healing_types)) owner.nutrition += 3 M.adjustCloneLoss(heal_amount * 1.2) //This way, two people can't just convert each other's damage away. else diff --git a/code/modules/surgery/organs/eyes.dm b/code/modules/surgery/organs/eyes.dm index 44e92e464b..bdd1a444bb 100644 --- a/code/modules/surgery/organs/eyes.dm +++ b/code/modules/surgery/organs/eyes.dm @@ -56,7 +56,7 @@ var/mob/living/carbon/human/H = C H.eye_color = old_eye_color if(!special) - H.dna.species.handle_body() + H.dna.species.handle_body(H) if(!special) C.update_tint() C.update_sight() diff --git a/html/changelogs/AutoChangeLog-pr-10904.yml b/html/changelogs/AutoChangeLog-pr-10904.yml new file mode 100644 index 0000000000..112c0bc593 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10904.yml @@ -0,0 +1,4 @@ +author: "Hatterhat" +delete-after: True +changes: + - rscadd: "The ships often crashed by Free Golems on Lavaland now have GPSes. They're off, by default, but an awakening Golem could easily turn one on." diff --git a/html/changelogs/AutoChangeLog-pr-10910.yml b/html/changelogs/AutoChangeLog-pr-10910.yml new file mode 100644 index 0000000000..2b11650c80 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10910.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Fixed a little issue with sleeper UI and blood types." diff --git a/html/changelogs/AutoChangeLog-pr-10953.yml b/html/changelogs/AutoChangeLog-pr-10953.yml new file mode 100644 index 0000000000..67c2c915ad --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-10953.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "Missing words replacement file for the gondola mask." diff --git a/html/changelogs/AutoChangeLog-pr-11098.yml b/html/changelogs/AutoChangeLog-pr-11098.yml new file mode 100644 index 0000000000..5ca7b7dd1e --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11098.yml @@ -0,0 +1,4 @@ +author: "Raiq & Linzolle" +delete-after: True +changes: + - rscadd: "Bone bow - Ash walkers crafting , bone arrows - Ash walkers crafting, silk string used in bow crafting, harden arrows - Ash walkers crafting, ash walker only crafting book, basic pipe bow, and bow & arrow selling. Quivers for ash walkers as well, just to hold some arrows well out on the hunt!" diff --git a/html/changelogs/AutoChangeLog-pr-11113.yml b/html/changelogs/AutoChangeLog-pr-11113.yml new file mode 100644 index 0000000000..b3c0bb34a8 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11113.yml @@ -0,0 +1,4 @@ +author: "CameronWoof" +delete-after: True +changes: + - rscadd: "Ammonia and saltpetre can now be made at the biogenerator." diff --git a/html/changelogs/AutoChangeLog-pr-11133.yml b/html/changelogs/AutoChangeLog-pr-11133.yml new file mode 100644 index 0000000000..8cedc300c7 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11133.yml @@ -0,0 +1,5 @@ +author: "Ghommie" +delete-after: True +changes: + - balance: "Nerfed the fermenting barrel export industry." + - tweak: "Reagent dispensers selling price no longer takes in account the reagents volume. It's already handled by reagents export." diff --git a/html/changelogs/AutoChangeLog-pr-11145.yml b/html/changelogs/AutoChangeLog-pr-11145.yml new file mode 100644 index 0000000000..2ad26003fb --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11145.yml @@ -0,0 +1,4 @@ +author: "Ghommie" +delete-after: True +changes: + - bugfix: "pAIs are yet again unable to perform certain silicon interactions with machineries yet again." diff --git a/html/changelogs/AutoChangeLog-pr-11147.yml b/html/changelogs/AutoChangeLog-pr-11147.yml new file mode 100644 index 0000000000..0978b2b184 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-11147.yml @@ -0,0 +1,4 @@ +author: "Putnam3145" +delete-after: True +changes: + - tweak: "Supermatter sabotage objective no longer shows up with no supermatter" diff --git a/icons/obj/ammo.dmi b/icons/obj/ammo.dmi index 55cbcc66e0..a26b01883e 100644 Binary files a/icons/obj/ammo.dmi and b/icons/obj/ammo.dmi differ diff --git a/icons/obj/guns/projectile.dmi b/icons/obj/guns/projectile.dmi index b85c769bcd..58e427a3fb 100644 Binary files a/icons/obj/guns/projectile.dmi and b/icons/obj/guns/projectile.dmi differ diff --git a/icons/obj/improvised.dmi b/icons/obj/improvised.dmi index a6dfa330e8..b90e3cb3bb 100644 Binary files a/icons/obj/improvised.dmi and b/icons/obj/improvised.dmi differ diff --git a/icons/obj/library.dmi b/icons/obj/library.dmi index 45181b7c8d..be12ab5f8b 100644 Binary files a/icons/obj/library.dmi and b/icons/obj/library.dmi differ diff --git a/strings/spurdo_replacement.json b/strings/spurdo_replacement.json new file mode 100644 index 0000000000..71c7c8d356 --- /dev/null +++ b/strings/spurdo_replacement.json @@ -0,0 +1,14 @@ +{ + + "spurdo": { + "epic": "ebin", + "c": "g", + "ck": "gg", + "k": "g", + "t": "d", + "p": "b", + "x": "gs" + } + + +} \ No newline at end of file