diff --git a/CONTRIBUTORS.md b/CONTRIBUTORS.md index 5f4e247..34a2d2d 100644 --- a/CONTRIBUTORS.md +++ b/CONTRIBUTORS.md @@ -65,4 +65,5 @@ NOTE: This list only includes people who have contributed code as part of the co * Gannets * SLthePyro * Sundance +* Flaborized * A bunch of awesome people from the forums! \ No newline at end of file diff --git a/_std/_setup.dm b/_std/_setup.dm index a2ad678..888008a 100644 --- a/_std/_setup.dm +++ b/_std/_setup.dm @@ -294,6 +294,7 @@ var/list/RARITY_COLOR = list( #define SLEEVELESS 64 // ain't got no sleeeeeves #define BLOCKSMOKE 128 //block smoke inhalations (gas mask) #define IS_JETPACK 256 +#define EQUIPPED_WHILE_HELD 512 //doesn't need to be worn to appear in the 'get_equipped_items' list and apply itemproperties (protections resistances etc)! for stuff like shields //clothing dirty flags (not used for anything other than submerged overlay update currently. eventually merge into update_clothing) #define C_BACK 1 @@ -359,10 +360,29 @@ var/list/RARITY_COLOR = list( #define SPEECH_BLOB 8 //yes #define SEE_THRU_CAMERAS 16 //for ai eye #define IS_BONER 32 //for skeletals +#define AT_GUNPOINT 64 //quick check for guns holding me at gunpoint //object_flags #define BOTS_DIRBLOCK 1 //bot considers this solid in pathfinding DirBlockedWithAccess #define NO_ARM_ATTACH 2 //illegal for arm attaching +#define CAN_REPROGRAM_ACCESS 4 //access gun can reprog + +//deconstruction_flags +#define DECON_NONE 0 +#define DECON_SIMPLE 1 //no reqs, just deconstruct! +#define DECON_SCREWDRIVER 2 +#define DECON_WRENCH 4 +#define DECON_CROWBAR 8 +#define DECON_WELDER 16 +#define DECON_WIRECUTTERS 32 +#define DECON_MULTITOOL 64 +#define DECON_BUILT 128 //flag added to something that is player-built +#define DECON_ACCESS 256 //can only be deconstructed if access required is null + +//THROW flags (what kind of throw, we can have ddifferent kinds of throws ok) +#define THROW_NORMAL 1 +#define THROW_CHAIRFLIP 2 +#define THROW_GUNIMPACT 4 //various sprint flags go here #define SPRINT_NORMAL 0 @@ -383,6 +403,8 @@ var/list/RARITY_COLOR = list( #define IS_TYPE_SIMULATED 4 //lol idk this kind of sucks, but i guess i can avoid some type checks in atmos processing #define CAN_BE_SPACE_SAMPLE 8 //can atmos use this tile as a space sample? #define MANTA_PUSH 16 //turf is pushy. for manta +#define FLUID_MOVE 32 //fluid move gear suffers no penalty on these turfs +#define SPACE_MOVE 64 //space move gear suffers no penalty on these turfs // channel numbers for power #define EQUIP 1 @@ -735,6 +757,7 @@ var/list/RARITY_COLOR = list( #define GRAB_AGGRESSIVE 1 #define GRAB_NECK 2 #define GRAB_KILL 3 +#define GRAB_PIN 4 #define DISORIENT_MISSTEP_CHANCE 40 @@ -886,6 +909,9 @@ var/list/RARITY_COLOR = list( //anyway just putting this define here for the client framerate toggle button between SMOOTH AND CHUNKY OH YEAH #define CLIENTSIDE_TICK_LAG_CHUNKY 0.4 +//its the future now +#define CLIENTSIDE_TICK_LAG_CREAMY 0.15 + //MBC : I should have added defines like these earlier - most widescreen bits aren't using them as of now! #define WIDE_TILE_WIDTH 21 diff --git a/_std/pathfinding.dm b/_std/pathfinding.dm index 30afd39..14a806b 100644 --- a/_std/pathfinding.dm +++ b/_std/pathfinding.dm @@ -243,7 +243,7 @@ return 0 return 1 - if(!DirWalkableWithAccess(A,adir, ID)) + if(!DirWalkableWithAccess(A,adir, ID, exiting_this_tile = 1)) return 1 var/DirWalkableB = DirWalkableWithAccess(B,rdir, ID) @@ -260,14 +260,19 @@ if (M.anchored) return 1 return 0 - return 1 + + if (O.flags & ON_BORDER) + if (rdir == O.dir) + return 1 + else + return 1 return 0 // Returns true if direction is accessible from loc // If we found a door we could open, return 2 instead of 1. // Checks doors against access with given ID -/proc/DirWalkableWithAccess(turf/loc,var/dir,var/obj/item/card/id/ID) +/proc/DirWalkableWithAccess(turf/loc,var/dir,var/obj/item/card/id/ID, var/exiting_this_tile = 0) .= 1 for (var/atom in loc) @@ -281,19 +286,23 @@ if (D.check_access(ID) == 0) return 0 else - .= 2 + return 2 else - return 0 - else //other solid objects + return 2 + else if (!exiting_this_tile) //other solid objects. dont bother checking if we are EXITING this tile if (D.has_access_requirements()) if (D.check_access(ID) == 0) return 0 else - .= 2 + return 2 else + return 2 + else + if (D.flags & ON_BORDER) + if (dir == D.dir) return 0 - - + else if (!exiting_this_tile) //dont bother checking if we are EXITING this tile + return 0 diff --git a/browserassets/images/tooltips/protdisorient.png b/browserassets/images/tooltips/protdisorient.png new file mode 100644 index 0000000..31c6f5f Binary files /dev/null and b/browserassets/images/tooltips/protdisorient.png differ diff --git a/browserassets/images/tooltips/protdisorient_ear.png b/browserassets/images/tooltips/protdisorient_ear.png new file mode 100644 index 0000000..b1ec731 Binary files /dev/null and b/browserassets/images/tooltips/protdisorient_ear.png differ diff --git a/browserassets/images/tooltips/protdisorient_eye.png b/browserassets/images/tooltips/protdisorient_eye.png new file mode 100644 index 0000000..c52adda Binary files /dev/null and b/browserassets/images/tooltips/protdisorient_eye.png differ diff --git a/browserassets/images/tooltips/stun.png b/browserassets/images/tooltips/stun.png new file mode 100644 index 0000000..206981b Binary files /dev/null and b/browserassets/images/tooltips/stun.png differ diff --git a/code/SimpleLight.dm b/code/SimpleLight.dm new file mode 100644 index 0000000..7c2c1e5 --- /dev/null +++ b/code/SimpleLight.dm @@ -0,0 +1,83 @@ +atom + var + list/simple_light_rgbas = null + + image/simple_light = null + + proc/add_simple_light(var/id, var/list/rgba) + if (!simple_light_rgbas) + simple_light_rgbas = list() + + simple_light_rgbas[id] = rgba + + show_simple_light() + + if (simple_light_rgbas.len == 1) //dont loop/average if list only contains 1 thing + simple_light.color = rgb(rgba[1], rgba[2], rgba[3], rgba[4]) + else + update_simple_light_color() + + + proc/remove_simple_light(var/id) + if (!simple_light_rgbas) + return + + if (id in simple_light_rgbas) + //simple_light_rgbas -= simple_light_rgbas[id] + simple_light_rgbas.Remove(id) + + if (simple_light_rgbas.len <= 0) + hide_simple_light() + else + update_simple_light_color() + + proc/update_simple_light_color() + var/avg_r = 0 + var/avg_g = 0 + var/avg_b = 0 + var/sum_a = 0 + + for (var/id in simple_light_rgbas) + avg_r += simple_light_rgbas[id][1] + avg_g += simple_light_rgbas[id][2] + avg_b += simple_light_rgbas[id][3] + sum_a += simple_light_rgbas[id][4] + + avg_r /= simple_light_rgbas.len + avg_g /= simple_light_rgbas.len + avg_b /= simple_light_rgbas.len + sum_a = min(255,sum_a) + + simple_light.color = rgb(avg_r, avg_g, avg_b, sum_a) + + proc/show_simple_light() + if (!simple_light) + simple_light = image('icons/effects/overlays/simplelight.dmi') + simple_light.loc = src + + simple_light.icon_state = "3x3" + simple_light.plane = PLANE_LIGHTING + simple_light.blend_mode = BLEND_ADD + simple_light.appearance_flags = RESET_COLOR | RESET_TRANSFORM | RESET_ALPHA | TILE_BOUND | NO_CLIENT_COLOR | KEEP_APART + simple_light.pixel_x = -32 + simple_light.pixel_y = -32 + simple_light.layer = LIGHTING_LAYER_BASE + simple_light.mouse_opacity = 0 + + addGlobalImage(simple_light, "simplelight_\ref[src]") + + proc/hide_simple_light() + if (simple_light) + removeGlobalImage("simplelight_\ref[src]") + + proc/destroy_simple_light() + if (simple_light_rgbas && simple_light_rgbas.len) + hide_simple_light() + simple_light.loc = null + simple_light_rgbas = null + qdel(simple_light) + + disposing() + ..() + if (simple_light) + destroy_simple_light() \ No newline at end of file diff --git a/code/WorkInProgress/AbilityItem.dm b/code/WorkInProgress/AbilityItem.dm index 65749ed..108c60b 100644 --- a/code/WorkInProgress/AbilityItem.dm +++ b/code/WorkInProgress/AbilityItem.dm @@ -114,7 +114,7 @@ if(W.up) W.up = !W.up W.icon_state = "welding" - boutput(the_mob, "You flip the mask down.") + boutput(the_mob, "You flip the mask down. The mask is now protecting you from eye damage.") if (!W.nodarken) //Used for The Welder W.see_face = !W.see_face W.color_r = 0.3 // darken @@ -122,17 +122,21 @@ W.color_b = 0.3 the_mob.set_clothing_icon_dirty() icon_state = "weldup" + + W.flip_down() else W.up = !W.up W.see_face = !W.see_face W.icon_state = "welding-up" - boutput(the_mob, "You flip the mask up.") + boutput(the_mob, "You flip the mask up. The mask is now providing greater armor to your head.") W.color_r = 1 // default W.color_g = 1 W.color_b = 1 the_mob.set_clothing_icon_dirty() icon_state = "welddown" + W.flip_up() + //////////////////////////////////////////////////////////// /obj/ability_button/tank_valve_toggle @@ -673,20 +677,6 @@ SPAWN_DBG(10) check_abilities() */ - proc/dropped(mob/user as mob) - if(src.material) src.material.triggerDrop(user, src) - if (islist(src.ability_buttons)) - for(var/obj/ability_button/B in ability_buttons) - B.OnDrop() - hide_buttons() - clear_mob() - return - - proc/pickup(mob/user) - if(src.material) src.material.triggerPickup(user, src) - set_mob(user) - show_buttons() - return proc/clear_buttons() if(!the_mob) return diff --git a/code/WorkInProgress/AnimationLibrary.dm b/code/WorkInProgress/AnimationLibrary.dm index a598499..5808cac 100644 --- a/code/WorkInProgress/AnimationLibrary.dm +++ b/code/WorkInProgress/AnimationLibrary.dm @@ -294,6 +294,79 @@ SPAWN_DBG(1) animate(M.attack_particle, alpha = 0, time = 1, flags = ANIMATION_PARALLEL) + +/proc/pull_particle(var/mob/M, var/atom/target) + if (!M || !target) return + if (world.time <= M.last_interact_particle + M.combat_click_delay) return + + var/diff_x = target.x + var/diff_y = target.y + SPAWN_DBG(0) + if (target && M) //I want these to be recent, but sometimes they can be deleted during course of a spawn + diff_x = diff_x - M.x + diff_y = diff_y - M.y + + M.last_interact_particle = world.time + + if (!M || !M.attack_particle) //ZeWaka: Fix for Cannot modify null.icon. + return + + var/atom/I = target + + M.attack_particle.icon = 'icons/mob/mob.dmi' + M.attack_particle.icon_state = "pull" + + M.attack_particle.alpha = 230 + M.attack_particle.loc = M.loc + M.attack_particle.pixel_x = I.pixel_x + (diff_x*32) + M.attack_particle.pixel_y = I.pixel_y + (diff_y*32) + + var/matrix/start = matrix()//(I.transform) + M.attack_particle.transform = start + var/matrix/t_size = matrix() + t_size.Scale(0.3,0.3) + t_size.Turn(rand(-40,40)) + + animate(M.attack_particle, pixel_x = M.get_hand_pixel_x(), pixel_y = M.get_hand_pixel_y(), time = 2, easing = LINEAR_EASING) + sleep(5) + M.attack_particle.alpha = 0 + +/proc/unpull_particle(var/mob/M, var/atom/target) + if (!M || !target) return + if (world.time <= M.last_interact_particle + M.combat_click_delay) return + + var/diff_x = target.x + var/diff_y = target.y + SPAWN_DBG(0) + if (target && M) //I want these to be recent, but sometimes they can be deleted during course of a spawn + diff_x = diff_x - M.x + diff_y = diff_y - M.y + + M.last_interact_particle = world.time + + if (!M || !M.attack_particle) //ZeWaka: Fix for Cannot modify null.icon. + return + + var/atom/I = target + + M.attack_particle.icon = 'icons/mob/mob.dmi' + M.attack_particle.icon_state = "unpull" + + M.attack_particle.alpha = 230 + M.attack_particle.loc = M.loc + M.attack_particle.pixel_x = M.get_hand_pixel_x() + M.attack_particle.pixel_y = M.get_hand_pixel_y() + + var/matrix/start = matrix()//(I.transform) + M.attack_particle.transform = start + var/matrix/t_size = matrix() + t_size.Scale(0.3,0.3) + t_size.Turn(rand(-40,40)) + + animate(M.attack_particle, pixel_x = I.pixel_x + (diff_x*32), pixel_y = I.pixel_y + (diff_y*32), time = 2, easing = LINEAR_EASING) + sleep(5) + M.attack_particle.alpha = 0 + /proc/attack_twitch(var/atom/A) if (!istype(A) || istype(A, /mob/living/object)) return //^ possessed objects use an animate loop that is important for readability. let's not interrupt that with this dumb animation @@ -344,10 +417,10 @@ return A:twitching = 1 - var/which + var/which = 0 if (usr) which = get_dir(usr,A) - else + if (!which) which = pick(alldirs) SPAWN_DBG(1) if (A) @@ -878,13 +951,13 @@ var/matrix/M1 = matrix(0.1, 0.1, MATRIX_SCALE) A.transform = M1 A.pixel_y = 300 - + animate(A, transform = M1, time = 10, pixel_y = -16, alpha = 255, easing = QUAD_EASING) M1.Scale(10, 1) animate(transform = M1, time = 2, easing = SINE_EASING) - - + + M1.Scale(1, 10) animate(transform = null, time = 2, pixel_y = 0, easing = SINE_EASING) diff --git a/code/WorkInProgress/DiscountDans.dm b/code/WorkInProgress/DiscountDans.dm index 5b4e266..12f25c7 100644 --- a/code/WorkInProgress/DiscountDans.dm +++ b/code/WorkInProgress/DiscountDans.dm @@ -116,6 +116,8 @@ opacity = 0 anchored = 1 + deconstruct_flags = DECON_MULTITOOL + var/current_tickets = 0 var/temp = null var/datum/light/light @@ -336,7 +338,7 @@ We're getting harassed by some nosey activists. Save the sea unicorns or whatever bullshit. Like, seriously dude, we have a license and everything. Calm the fuck down. The sea's already fucked up and some more sewage won't make it worse. Can you figure out a way to stop them from picketing and clogging up our lines and all that shit? It's seriously affecting my ability to concentrate on my work! - Cathy Gladys + Cathy Gladys cgladys@delightfuldans Delightful Dan's Central Division General Manager diff --git a/code/WorkInProgress/Electronics.dm b/code/WorkInProgress/Electronics.dm index 96ea6c4..f15b32c 100644 --- a/code/WorkInProgress/Electronics.dm +++ b/code/WorkInProgress/Electronics.dm @@ -133,6 +133,13 @@ //var/list/parts = new/list() var/list/needed_parts = new/list() module_research = list("electronics" = 3, "engineering" = 1) + var/obj/deconstructed_thing = null + + + disposing() + deconstructed_thing = null + store_type = null + ..() /obj/item/electronics/frame/verb/rotate() set src in view(1) @@ -159,7 +166,6 @@ viewstat = 0 boutput(user, "You unsecure the [src].") else if(secured == 2) - secured = 0 boutput(user, "You deploy the [src]!") logTheThing("station", user, null, "deploys a [src.name] in [user.loc.loc] ([showCoords(src.x, src.y, src.z)])") if (!istype(user.loc,/turf) && store_type in typesof(/obj/critter)) @@ -168,6 +174,9 @@ actions.start(new/datum/action/bar/icon/build_electronics_frame(src), user) //deploy() return + if (iswrenchingtool(W)) + boutput(user, "You deconstruct [src] into its base materials!") + src.drop_resources(W,user) ..() /obj/item/electronics/frame/MouseDrop_T(atom/movable/O as obj, mob/user as mob) @@ -268,17 +277,60 @@ /obj/item/electronics/frame/proc/deploy() var/turf/T = get_turf(src) - var/obj/O = new store_type(T) + var/obj/O = null + if (deconstructed_thing) + O = deconstructed_thing + O.set_loc(T) + O.was_built_from_frame(usr) + deconstructed_thing = null + else + O = new store_type(T) + O.dir = src.dir - O.mats = "Built" + //O.mats = "Built" + O.deconstruct_flags |= DECON_BUILT qdel(src) return +/obj/item/electronics/frame/proc/drop_resources(obj/item/W as obj, mob/user as mob) + var/datum/manufacture/mechanics/R = null + + if (src.deconstructed_thing) + for (var/datum/manufacture/mechanics/M in manuf_controls.custom_schematics) + if (M.frame_path == deconstructed_thing.type) + R = M + break + else + for (var/datum/manufacture/mechanics/M in manuf_controls.custom_schematics) + if (M.frame_path == src.store_type) + R = M + break + + if (istype(R)) + var/looper = round(R.item_amounts[1] / 10, 1) + while (looper > 0) + var/obj/item/material_piece/mauxite/M = unpool(/obj/item/material_piece/mauxite) + M.set_loc(get_turf(src)) + looper-- + looper = round(R.item_amounts[2] / 10, 1) + while (looper > 0) + var/obj/item/material_piece/pharosium/P = unpool(/obj/item/material_piece/pharosium) + P.set_loc(get_turf(src)) + looper-- + looper = round(R.item_amounts[3] / 10, 1) + while (looper > 0) + var/obj/item/material_piece/molitz/M = unpool(/obj/item/material_piece/molitz) + M.set_loc(get_turf(src)) + looper-- + else + boutput(user, "Could not reclaim resources.") + qdel(src) + /datum/action/bar/icon/build_electronics_frame duration = 10 - interrupt_flags = INTERRUPT_STUNNED - id = "build_vent_capture" + interrupt_flags = INTERRUPT_MOVE | INTERRUPT_ACT | INTERRUPT_STUNNED | INTERRUPT_ACTION + id = "build_electronics_frame" icon = 'icons/ui/actions.dmi' icon_state = "working" var/obj/item/electronics/frame/F @@ -364,6 +416,17 @@ pressure_resistance = 40 module_research = list("electronics" = 3, "engineering" = 1) + afterattack(atom/target as mob|obj|turf|area, mob/user as mob) + if (!isobj(target)) + return + var/obj/O = target + var/decon_len = O.decon_contexts ? O.decon_contexts.len : 0 + O.decon_contexts = null + if (O.build_deconstruction_buttons() != decon_len) + boutput(user, "You repair [target]'s deconstructed state.") + return + ..() + ////////////////////////////////////////////////////////////////no /obj/item/electronics/disk name = "data module" @@ -398,10 +461,6 @@ boutput(user, "The structure of this object is not compatible with the scanner.") return - if (O.mats == "Built" && (ticker && ticker.mode && !istype(ticker.mode, /datum/game_mode/construction))) - boutput(user, "You cannot scan an object that was already deployed by a mechanic.") - return - user.visible_message("[user.name] scans [O].") var/final_type = O.mechanics_type_override ? O.mechanics_type_override : O.type @@ -437,7 +496,7 @@ /obj/machinery/rkit/New() ..() //link = mechanic_controls - SPAWN_DBG(8) + SPAWN_DBG(0.8 SECONDS) if(radio_controller) radio_connection = radio_controller.add_object(src, "[frequency]") if(!src.net_id) @@ -465,7 +524,7 @@ var/target = signal.data["sender"] if((signal.data["address_1"] == "ping") && target) - SPAWN_DBG(5) //Send a reply for those curious jerks + SPAWN_DBG(0.5 SECONDS) //Send a reply for those curious jerks var/datum/signal/newsignal = get_free_signal() newsignal.source = src @@ -487,7 +546,7 @@ var/datum/computer/file/electronics_scan/scanFile = signal.data_file for(var/datum/electronics/scanned_item/O in mechanic_controls.scanned_items) if(scanFile.scannedPath == O.item_type) - SPAWN_DBG(5) + SPAWN_DBG(0.5 SECONDS) var/datum/signal/newsignal = get_free_signal() newsignal.source = src @@ -503,7 +562,7 @@ return mechanic_controls.scan_in(scanFile.scannedName, scanFile.scannedPath, scanFile.scannedMats) - SPAWN_DBG(5) + SPAWN_DBG(0.5 SECONDS) var/datum/signal/newsignal = get_free_signal() newsignal.source = src @@ -535,7 +594,7 @@ if (!match_check) var/obj/tempobj = new X (src) mechanic_controls.scan_in(tempobj.name,tempobj.type,tempobj.mats) - SPAWN_DBG(40) + SPAWN_DBG(4 SECONDS) qdel(tempobj) S.scanned -= X add_count++ @@ -598,7 +657,7 @@ src.no_print_spam = world.time SPAWN_DBG (50) if (src) - new /obj/item/paper/manufacturer_blueprint(src.loc, M.name) + new /obj/item/paper/manufacturer_blueprint(src.loc, M) updateDialog() else @@ -622,48 +681,154 @@ spark_system.attach(src) return - afterattack(atom/target as mob|obj|turf|area, mob/user as mob) - if (!istype(target,/obj/)) + proc/finish_decon(atom/target,mob/user) + if (!isobj(target)) return var/obj/O = target - if (O.mats != "Built") - boutput(user, "This fixture cannot be deconstructed.") + logTheThing("station", user, null, "deconstructs [target] in [user.loc.loc] ([showCoords(user.x, user.y, user.z)])") + playsound(user.loc, 'sound/items/Deconstruct.ogg', 50, 1) + user.visible_message("[user.name] deconstructs [target].") + + + var/obj/item/electronics/frame/F = new(get_turf(target)) + F.name = "[target.name] frame" + F.deconstructed_thing = target + O.set_loc(F) + F.viewstat = 2 + F.secured = 2 + F.icon_state = "dbox_big" + F.w_class = 4 + + spark_system.set_up(5, 0, src) + spark_system.start() + + O.was_deconstructed_to_frame(user) + + MouseDrop_T(atom/target, mob/user) + if (!isobj(target)) return - boutput(user, "Deconstructing [O], please remain still...") - playsound(user.loc, 'sound/effects/pop.ogg', 50, 1) - if(do_after(user, 20)) - logTheThing("station", user, null, "deconstructs [O] in [user.loc.loc] ([showCoords(user.x, user.y, user.z)])") - playsound(user.loc, 'sound/items/Deconstruct.ogg', 50, 1) - user.visible_message("[user.name] deconstructs [O].") + src.afterattack(target,user) + ..() - var/datum/manufacture/mechanics/R = null - for (var/datum/manufacture/mechanics/M in manuf_controls.custom_schematics) - if (M.frame_path == O.type) - R = M - break + afterattack(atom/target as mob|obj|turf|area, mob/user as mob) + if (!isobj(target)) + return + var/obj/O = target - if (istype(R)) - var/looper = round(R.item_amounts[1] / 10, 1) - while (looper > 0) - var/obj/item/material_piece/mauxite/M = unpool(/obj/item/material_piece/mauxite) - M.set_loc(O.loc) - looper-- - looper = round(R.item_amounts[2] / 10, 1) - while (looper > 0) - var/obj/item/material_piece/pharosium/P = unpool(/obj/item/material_piece/pharosium) - P.set_loc(O.loc) - looper-- - looper = round(R.item_amounts[3] / 10, 1) - while (looper > 0) - var/obj/item/material_piece/molitz/M = unpool(/obj/item/material_piece/molitz) - M.set_loc(O.loc) - looper-- - else - boutput(user, "Could not reclaim resources.") - spark_system.set_up(5, 0, src) - spark_system.start() - qdel(O) + var/decon_complexity = O.build_deconstruction_buttons() + if (!decon_complexity) + boutput(user, "[target] cannot be deconstructed.") + if (O.deconstruct_flags & DECON_ACCESS) + boutput(user, "[target] is under an access lock and must have its access requirements removed first.") + return + if (!O.allowed(user) || O.is_syndicate) + boutput(user, "You cannot deconstruct [target] without sufficient access to operate it.") + return + + if (isrestrictedz(O.z) && !isitem(target)) + boutput(user, "You cannot bring yourself to deconstruct [target] in this area.") + return + + if (O.decon_contexts && O.decon_contexts.len <= 0) //ready!!! + boutput(user, "Deconstructing [O], please remain still...") + playsound(user.loc, 'sound/effects/pop.ogg', 50, 1) + actions.start(new/datum/action/bar/icon/deconstruct_obj(target,src,(decon_complexity * 2.5 SECONDS)), user) else - boutput(user, "Deconstruction of [O] interrupted!") - return \ No newline at end of file + user.showContextActions(O.decon_contexts, O) + boutput(user, "You need to use some tools on [target] before it can be deconstructed.") + return + +/obj/var/list/decon_contexts = null + +/obj/disposing() + if (src.decon_contexts) + for(var/datum/contextAction/C in src.decon_contexts) + C.disposing() + ..() + +/obj/proc/was_deconstructed_to_frame(mob/user) + .= 0 + +/obj/proc/was_built_from_frame(mob/user) + .= 0 + +/obj/proc/build_deconstruction_buttons() + .= 0 + + if (deconstruct_flags & DECON_ACCESS) + if (src.has_access_requirements()) + return + + if (deconstruct_flags) + .= 1 + + if (src.decon_contexts != null) //dont need rebuild + return + + src.decon_contexts = list() //empty list would mean we are ready for deconstruction. otherwise you need to clear contexts by tool usage + + if (deconstruct_flags & DECON_SCREWDRIVER) + var/datum/contextAction/deconstruction/screw/newcon = new + decon_contexts += newcon + if (deconstruct_flags & DECON_WRENCH) + var/datum/contextAction/deconstruction/wrench/newcon = new + decon_contexts += newcon + if (deconstruct_flags & DECON_CROWBAR) + var/datum/contextAction/deconstruction/pry/newcon = new + decon_contexts += newcon + if (deconstruct_flags & DECON_WELDER) + var/datum/contextAction/deconstruction/weld/newcon = new + decon_contexts += newcon + if (deconstruct_flags & DECON_WIRECUTTERS) + var/datum/contextAction/deconstruction/cut/newcon = new + decon_contexts += newcon + if (deconstruct_flags & DECON_MULTITOOL) + var/datum/contextAction/deconstruction/pulse/newcon = new + decon_contexts += newcon + + .+= decon_contexts.len + + +/datum/action/bar/icon/deconstruct_obj + duration = 20 + interrupt_flags = INTERRUPT_MOVE | INTERRUPT_ACT | INTERRUPT_STUNNED | INTERRUPT_ACTION + id = "deconstruct_obj" + icon = 'icons/ui/actions.dmi' + icon_state = "decon" + var/obj/O + var/obj/item/deconstructor/D + New(Obj, Decon, ExtraTime) + O = Obj + D = Decon + duration += ExtraTime + ..() + + onUpdate() + ..() + if(get_dist(owner, O) > 1 || O == null || owner == null || D == null) + interrupt(INTERRUPT_ALWAYS) + return + + onStart() + ..() + if(get_dist(owner, O) > 1 || O == null || owner == null || D == null) + interrupt(INTERRUPT_ALWAYS) + return + + onEnd() + ..() + if(get_dist(owner, O) > 1 || O == null || owner == null || D == null) + interrupt(INTERRUPT_ALWAYS) + return + if (ismob(owner)) + var/mob/M = owner + if (!D in M.equipped_list()) + interrupt(INTERRUPT_ALWAYS) + return + D.finish_decon(O,owner) + + onInterrupt() + if (O && owner) + boutput(owner, "Deconstruction of [O] interrupted!") + ..() diff --git a/code/WorkInProgress/ObjectProperties.dm b/code/WorkInProgress/ObjectProperties.dm index afdf274..a29263c 100644 --- a/code/WorkInProgress/ObjectProperties.dm +++ b/code/WorkInProgress/ObjectProperties.dm @@ -179,13 +179,20 @@ var/list/globalPropList = null movement name = "Speed" id = "movespeed" - desc = "Increases movement speed." //Value is additional movement speed delay. (how much slower - negative value for speed increase) + desc = "Modifies movement speed." //Value is additional movement speed delay. (how much slower - negative value for speed increase) tooltipImg = "movement.png" defaultValue = 1 goodDirection = -1 getTooltipDesc(var/obj/propOwner, var/propVal) return "[propVal] movement delay" + space + name = "Speed" + id = "space_movespeed" + + getTooltipDesc(var/obj/propOwner, var/propVal) + return "[propVal] movement delay - 0 when worn in space." + radiationprot name = "Resistance (Radiation)" id = "radprot" @@ -293,7 +300,7 @@ var/list/globalPropList = null defaultValue = 1 getTooltipDesc(var/obj/propOwner, var/propVal) return "Negates fluid speed penalties.
+[propVal] movement delay on dry land." - + momentum // force increases as you attack players. name = "Momentum" id = "momentum" @@ -301,4 +308,31 @@ var/list/globalPropList = null tooltipImg = "stamcost.png" defaultValue = 0 getTooltipDesc(var/obj/propOwner, var/propVal) - return "+[propVal] damage increased." \ No newline at end of file + return "+[propVal] damage increased." + + disorient_resist + name = "Body Insulation (Disorient Resist)" + id = "disorient_resist" + desc = "Reduces disorient effects on the wearer." //Value is % protection. + tooltipImg = "protdisorient.png" + defaultValue = 0 + getTooltipDesc(var/obj/propOwner, var/propVal) + return "[propVal]%" + + disorient_resist_eye + name = "Eye Insulation (Disorient Resist)" + id = "disorient_resist_eye" + desc = "Reduces disorient effects that apply through vision on the wearer." //Value is % protection. + tooltipImg = "protdisorient_eye.png" + defaultValue = 0 + getTooltipDesc(var/obj/propOwner, var/propVal) + return "[propVal]%" + + disorient_resist_ear + name = "Ear Insulation (Disorient Resist)" + id = "disorient_resist_ear" + desc = "Reduces disorient effects that apply through sound on the wearer." //Value is % protection. + tooltipImg = "protdisorient_ear.png" + defaultValue = 0 + getTooltipDesc(var/obj/propOwner, var/propVal) + return "[propVal]%" \ No newline at end of file diff --git a/code/WorkInProgress/SpyGuyStuff.dm b/code/WorkInProgress/SpyGuyStuff.dm index b7bdb05..d1d8849 100644 --- a/code/WorkInProgress/SpyGuyStuff.dm +++ b/code/WorkInProgress/SpyGuyStuff.dm @@ -921,10 +921,7 @@ proc/Create_Tommyname() icon_state = "garrote0" event_handler_flags = USE_GRAB_CHOKE | USE_FLUID_ENTER - - // The actual grab in charge of maintaining the chokehold - // Will be stored inside the garroteing player's mob because grabs are horrid - var/obj/item/grab/garrote_grab/chokehold = null + special_grab = /obj/item/grab/garrote_grab // Are we ready to do something mean here? var/wire_readied = 0 @@ -953,8 +950,8 @@ proc/Create_Tommyname() /obj/item/garrote/proc/update_state() if(src.chokehold) - - if(!src.chokehold.extra_deadly) + var/obj/item/grab/garrote_grab/GG = src.chokehold + if(!GG.extra_deadly) icon_state = "garrote2" //We're choking someone out - apply a hefty slowdown src.setProperty("movespeed", 6) @@ -1001,30 +998,17 @@ proc/Create_Tommyname() return 1 // Actually apply the grab (called via action bar) -/obj/item/garrote/proc/do_grab(var/mob/living/assailant, var/mob/living/target) - if(!chokehold && istype(target) && istype(assailant)) - //Apply the grab +/obj/item/garrote/try_grab(var/mob/living/target, var/mob/living/assailant) + if(..()) assailant.visible_message("[assailant] wraps \the [src] around [target]'s neck!") - src.chokehold = new /obj/item/grab/garrote_grab(src) - - chokehold.assailant = assailant - chokehold.affecting = target chokehold.state = GRAB_NECK - target.grabbed_by += chokehold - chokehold.upgrade_to_kill() - update_state() - processing_items.Add(src) - // Drop the grab -/obj/item/garrote/proc/drop_grab() - if(src.chokehold) - qdel(chokehold) - chokehold = null - update_state() - processing_items.Remove(src) +/obj/item/garrote/drop_grab() + ..() + update_state() // It will crumple when dropped /obj/item/garrote/dropped() @@ -1037,17 +1021,15 @@ proc/Create_Tommyname() ..() // Repeatedly process when in a chokehold, to verify things are as they should be -/obj/item/garrote/process() +/obj/item/garrote/process_grab() ..() if(src.chokehold && src.loc != src.chokehold.assailant) set_readiness(0) - else if (!src.chokehold) - processing_items.Remove(src) // Change the size of the garrote or the posture /obj/item/garrote/attack_self() - ..() if(!chokehold) + ..() toggle_wire_readiness() else var/obj/item/grab/garrote_grab/GG = src.chokehold @@ -1119,7 +1101,7 @@ proc/Create_Tommyname() if(check_conditions()) return - the_garrote.do_grab(owner, target) + the_garrote.try_grab(target, owner) // Special grab obj that doesn't care if it's in someone's hands /obj/item/grab/garrote_grab @@ -1147,6 +1129,8 @@ proc/Create_Tommyname() take_bleeding_damage(affecting, assailant, rand(0, 20) * mult) ..() + attack_self(user) + /proc/trigger_anti_cheat(var/mob/M, var/message, var/external_alert = 1) if(M) diff --git a/code/WorkInProgress/TempEngine.dm b/code/WorkInProgress/TempEngine.dm index 5548007..8cf200a 100644 --- a/code/WorkInProgress/TempEngine.dm +++ b/code/WorkInProgress/TempEngine.dm @@ -499,6 +499,7 @@ anchored = 1 density = 1 mats = 20 + deconstruct_flags = DECON_WRENCH | DECON_CROWBAR | DECON_WELDER var/obj/machinery/atmospherics/unary/furnace_connector/f_connector = null diff --git a/code/WorkInProgress/actuallyKeelinsStuff.dm b/code/WorkInProgress/actuallyKeelinsStuff.dm index e1c2d82..bcfc21c 100644 --- a/code/WorkInProgress/actuallyKeelinsStuff.dm +++ b/code/WorkInProgress/actuallyKeelinsStuff.dm @@ -3011,6 +3011,12 @@ var/list/electiles = list() icon = 'icons/obj/stationobjs.dmi' icon_state = "pool" flags = FPRINT | ALWAYS_SOLID_FLUID | IS_PERSPECTIVE_FLUID + event_handler_flags = USE_CANPASS + + CanPass(atom/movable/mover, turf/target, height=0, air_group=0) + if (mover && mover.throwing) + return 1 + return ..() /obj/pool/ladder name = "pool ladder" @@ -3042,6 +3048,10 @@ var/list/electiles = list() attackby(obj/item/W as obj, mob/user as mob) return attack_hand(user) + MouseDrop_T(atom/target, mob/user) + if (get_dist(user,src) < 1 && target == user) + src.attack_hand(user) + attack_hand(mob/user as mob) if(in_use) boutput(user, "Its already in use - wait a bit.") @@ -3059,6 +3069,7 @@ var/list/electiles = list() user.pixel_y = 15 user.layer = EFFECTS_LAYER_UNDER_1 user.set_loc(src.loc) + user.buckled = src sleep(3) user.pixel_x = -3 sleep(3) @@ -3075,6 +3086,7 @@ var/list/electiles = list() playsound(user, "sound/effects/spring.ogg", 60, 1) sleep(5) user.pixel_y = 25 + user.start_chair_flip_targeting(extrarange = 2) sleep(5) user.pixel_y = 15 playsound(user, "sound/effects/spring.ogg", 60, 1) @@ -3084,8 +3096,11 @@ var/list/electiles = list() sleep(2) if(range == 1) boutput(user, "You slip...") user.layer = MOB_LAYER - user.throw_at(target, 5, 1) - user:changeStatus("weakened", 2 SECONDS) + user.buckled = null + if (user.targeting_spell == user.chair_flip_ability) //we havent chair flipped, just do normal jump + user.throw_at(target, 5, 1) + user:changeStatus("weakened", 2 SECONDS) + user.end_chair_flip_targeting() if(suiciding || deadly) src.visible_message("[user.name] dives headfirst at the [target.name]!") SPAWN_DBG(3) //give them time to land diff --git a/code/WorkInProgress/laundry.dm b/code/WorkInProgress/laundry.dm index 41aeb39..4cdf929 100644 --- a/code/WorkInProgress/laundry.dm +++ b/code/WorkInProgress/laundry.dm @@ -10,6 +10,7 @@ icon_state = "laundry" anchored = 1 density = 1 + deconstruct_flags = DECON_WELDER | DECON_WRENCH var/on = 0 var/open = 0 var/cycle = PRE diff --git a/code/WorkInProgress/multiContext.dm b/code/WorkInProgress/multiContext.dm index 76f4bc1..4ff6eb7 100644 --- a/code/WorkInProgress/multiContext.dm +++ b/code/WorkInProgress/multiContext.dm @@ -591,7 +591,7 @@ var/list/globalContextActions = null spawn(1) ghost.enter_ghostdrone_queue() ..() - + ghost_respawn/afterlife_bar name = "Afterlife Bar" desc = "Enter the afterlife Bar" @@ -730,3 +730,175 @@ var/list/globalContextActions = null .= "PRICE : [GBP.cost]
[GBP.desc]

There are [GBP.uses] applications left." else ..() + + deconstruction + icon = 'icons/ui/context16x16.dmi' + name = "Deconstruct with Tool" + desc = "You shouldn't be reading this, bug." + icon_state = "wrench" + + execute(var/atom/target, var/mob/user) + if (isobj(target)) + var/obj/O = target + if (O.decon_contexts) + O.decon_contexts -= src + if (O.decon_contexts.len <= 0) + user.show_text("Looks like [target] is ready to be deconstructed with the device.", "blue") + else + user.showContextActions(O.decon_contexts, O) + else + target.removeContextAction(src.type) + + checkRequirements(var/atom/target, var/mob/user) + .= 0 + for (var/obj/item/deconstructor/D in user.equipped_list()) + return 1 + + wrench + name = "Wrench" + desc = "Wrenching required to deconstruct." + icon_state = "wrench" + + execute(var/atom/target, var/mob/user) + for (var/obj/item/I in user.equipped_list()) + if (iswrenchingtool(I)) + user.show_text("You wrench [target]'s bolts.", "blue") + playsound(get_turf(target), "sound/items/Ratchet.ogg", 50, 1) + return ..() + + cut + name = "Cut" + desc = "Cutting required to deconstruct." + icon_state = "cut" + + execute(var/atom/target, var/mob/user) + for (var/obj/item/I in user.equipped_list()) + if (iscuttingtool(I) || issnippingtool(I)) + user.show_text("You cut some vestigial wires from [target].", "blue") + playsound(get_turf(target), "sound/items/Wirecutter.ogg", 50, 1) + return ..() + weld + name = "Weld" + desc = "Welding required to deconstruct." + icon_state = "weld" + + execute(var/atom/target, var/mob/user) + user.show_text("You weld [target] carefully.", "blue") + for (var/obj/item/weldingtool/W in user.equipped_list()) + if (W.get_fuel()) + W.use_fuel(2) + playsound(get_turf(target), "sound/items/Welder.ogg", 50, 1) + return ..() + + pry + name = "Pry" + desc = "Prying required to deconstruct. Try a crowbar." + icon_state = "bar" + + execute(var/atom/target, var/mob/user) + for (var/obj/item/I in user.equipped_list()) + if (ispryingtool(I)) + user.show_text("You pry on [target] without remorse.", "blue") + playsound(get_turf(target), "sound/items/Crowbar.ogg", 50, 1) + return ..() + + screw + name = "Screw" + desc = "Screwing required to deconstruct." + icon_state = "screw" + + execute(var/atom/target, var/mob/user) + for (var/obj/item/I in user.equipped_list()) + if (isscrewingtool(I)) + user.show_text("You unscrew some of the screws on [target].", "blue") + playsound(get_turf(target), "sound/items/Screwdriver.ogg", 50, 1) + return ..() + + pulse + name = "Pulse" + desc = "Pulsing required to deconstruct. Try a multitool." + icon_state = "pulse" + + execute(var/atom/target, var/mob/user) + for (var/obj/item/I in user.equipped_list()) + if (ispulsingtool(I)) + user.show_text("You pulse [target]. In a general sense.", "blue") + playsound(get_turf(target), "sound/items/penclick.ogg", 50, 1) + return ..() + +/* + offered + icon = null + icon_background = null + + maptext = "Do you want to?" + charge.maptext_y = -5 + charge.maptext_width = 96 + charge.maptext_x = -9 + + execute(var/atom/target, var/mob/user) + .= 0 + + checkRequirements(var/atom/target, var/mob/user) + .= 0 + + item + var/obj/item/I = null + + disposing() + I = null + ..() + + buildBackgroundIcon-(var/atom/target, var/mob/user) + var/image/background = image('icons/ui/context32x32.dmi', src, "[getBackground(target, user)]0") + background.appearance_flags = RESET_COLOR + .= background + + + getIcon() + if (I) + .= I.icon + else + ..() + + getIconState() + if (I) + .= I.icon_state + else + ..() + + getName(var/atom/target, var/mob/user) + if (I) + .= I.name + else + ..() + + getDesc(var/atom/target, var/mob/user) + if (I) + .= I.desc + else + ..() + + accept + icon_state = "yes" + var/datum/yesno_dialog/give_dialog = null + + checkRequirements(var/atom/target, var/mob/user) + return 1 + + execute(var/atom/target, var/mob/user) + target.addContextAction(/datum/contextAction/testfour) + return 0 + + refuse + icon_state = "no" + var/datum/yesno_dialog/give_dialog = null + + + checkRequirements(var/atom/target, var/mob/user) + return 1 + + execute(var/atom/target, var/mob/user) + target.addContextAction(/datum/contextAction/testfour) + return 0 +*/ \ No newline at end of file diff --git a/code/WorkInProgress/recycling/disposal_chute.dm b/code/WorkInProgress/recycling/disposal_chute.dm index f1ef023..750ae1c 100644 --- a/code/WorkInProgress/recycling/disposal_chute.dm +++ b/code/WorkInProgress/recycling/disposal_chute.dm @@ -24,6 +24,7 @@ var/image/handle_image = null var/destination_tag = null mats = 20 // whats the point of letting people build trunk pipes if they cant build new disposals? + deconstruct_flags = DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_SCREWDRIVER power_usage = 100 var/is_processing = 1 //optimization thingy. kind of dumb. mbc fault. only process chute when flushed or recharging. diff --git a/code/WorkInProgress/simroom.dm b/code/WorkInProgress/simroom.dm index 9c84c85..6988fd8 100644 --- a/code/WorkInProgress/simroom.dm +++ b/code/WorkInProgress/simroom.dm @@ -184,6 +184,7 @@ icon_state = "vrbed"//_0" anchored = 1 density = 1 + deconstruct_flags = DECON_MULTITOOL var/active = 0 var/internal_id = 0 var/network = "none" diff --git a/code/area.dm b/code/area.dm index 0f64239..76a589c 100644 --- a/code/area.dm +++ b/code/area.dm @@ -612,9 +612,10 @@ M.addOverlayComposition(/datum/overlayComposition/shuttle_warp/ew) if (!isobserver(Obj) && !isintangible(Obj) && !iswraith(Obj) && !istype(Obj,/obj/machinery/vehicle/escape_pod)) var/atom/target = get_edge_target_turf(src, src.throw_dir) - SPAWN_DBG(0) - if (target && Obj) - Obj.throw_at(target, 1, 1) + if (OldLoc && OldLoc.z == src.z) + SPAWN_DBG(0) + if (target && Obj) + Obj.throw_at(target, 1, 1) Exited(atom/movable/Obj) ..() diff --git a/code/atom.dm b/code/atom.dm index d03b53f..9e8033a 100644 --- a/code/atom.dm +++ b/code/atom.dm @@ -238,26 +238,6 @@ proc/return_air() return null - proc/grab_smash(obj/item/grab/G as obj, mob/user as mob) - var/mob/M = G.affecting - - if (!(ismob(G.affecting))) - return 0 - - if (get_dist(src, M) > 1) - return 0 - - user.visible_message("[M] has been smashed against [src] by [user]!") - logTheThing("combat", user, M, "smashes %target% against [src]") - - random_brute_damage(G.affecting, rand(2,3)) - G.affecting.TakeDamage("chest", 0, rand(4,5)) - playsound(G.affecting.loc, "punch", 25, 1, -1) - - user.u_equip(G) - G.dispose() - return 1 - // Convenience proc to see if a container is open for chemistry handling // returns true if open // false if closed @@ -647,8 +627,10 @@ if (!( src.anchored )) var/mob/user = usr user.set_pulling(src) - if (user.at_gunpoint && usr.at_gunpoint.holding_at_gunpoint != user) - user.at_gunpoint.shoot_at_gunpoint(user) + + if (user.mob_flags & AT_GUNPOINT) + for(var/obj/item/grab/gunpoint/G in user.grabbed_by) + G.shoot() return /atom/proc/get_desc(dist) diff --git a/code/atom/throwing.dm b/code/atom/throwing.dm index 538b3c6..368f963 100644 --- a/code/atom/throwing.dm +++ b/code/atom/throwing.dm @@ -28,10 +28,14 @@ src.throw_impact(A) src.throwing = 0 + /atom/proc/throw_begin(atom/target) return -/atom/proc/throw_impact(atom/hit_atom, list/params) +/atom/proc/throw_end() //throw ends (callback regardless of whether we impacted something) + return + +/atom/movable/proc/throw_impact(atom/hit_atom, list/params) var/turf/t = get_turf(hit_atom) if( t && t.loc && t.loc:sanctuary ) return var/impact_sfx = 0 @@ -91,7 +95,7 @@ if(((C.in_throw_mode && C.a_intent == "help") || (C.client && C.client.check_key(KEY_THROW))) && !C.equipped()) if((C.hand && (!C.limbs.l_arm)) || (!C.hand && (!C.limbs.r_arm)) || C.handcuffed || (prob(60) && C.bioHolder.HasEffect("clumsy")) || ismob(src) || (throw_traveled <= 1 && last_throw_x == src.x && last_throw_y == src.y)) - C.visible_message("[C] has been hit by [src].") + C.visible_message("[C] has been hit by [src].") //you're all thumbs!!! // Added log_reagents() calls for drinking glasses. Also the location (Convair880). logTheThing("combat", C, null, "is struck by [src] [src.is_open_container() ? "[log_reagents(src)]" : ""] at [log_loc(C)].") if(src.vars.Find("throwforce")) @@ -105,7 +109,7 @@ C.throw_at(get_edge_target_turf(C,get_dir(src, C)), 10, 1) C.changeStatus("stunned", 3 SECONDS) - if(ismob(src)) src:throw_impacted() + if(ismob(src)) src:throw_impacted(hit_atom) else src.attack_hand(C) // nice catch, hayes. don't ever fuckin do it again @@ -116,11 +120,15 @@ game_stats.Increment("catches") #endif - else //you're all thumbs!!! - C.visible_message("[C] has been hit by [src].") - logTheThing("combat", C, null, "is struck by [src] [src.is_open_container() ? "[log_reagents(src)]" : ""] at [log_loc(C)].") - if(src.vars.Find("throwforce")) - random_brute_damage(C, src:throwforce) + else //normmal thingy hit me + if (src.throwing & THROW_CHAIRFLIP) + C.visible_message("[src] slams into [C] midair!") + else + C.visible_message("[C] has been hit by [src].") + if(src.vars.Find("throwforce")) + random_brute_damage(C, src:throwforce) + + logTheThing("combat", C, null, "is struck by [src] [src.is_open_container() ? "[log_reagents(src)]" : ""] at [log_loc(C)].") //bleed check here if (isitem(src)) @@ -137,7 +145,7 @@ C.throw_at(get_edge_target_turf(C,get_dir(src, C)), 10, 1) C.changeStatus("stunned", 3 SECONDS) - if(ismob(src)) src:throw_impacted() + if(ismob(src)) src:throw_impacted(hit_atom) else if(issilicon(hit_atom)) @@ -154,7 +162,7 @@ if(src.vars.Find("throwforce") && src:throwforce >= 40) S.throw_at(get_edge_target_turf(S,get_dir(src, S)), 10, 1) - if(ismob(src)) src:throw_impacted() + if(ismob(src)) src:throw_impacted(hit_atom) impact_sfx = impact_sfx = 'sound/impact_sounds/Metal_Clang_3.ogg' @@ -163,7 +171,7 @@ var/obj/O = hit_atom if(!O.anchored) step(O, src.dir) O.hitby(src) - if(ismob(src)) src:throw_impacted() + if(ismob(src)) src:throw_impacted(hit_atom) if(O && src.vars.Find("throwforce") && src:throwforce >= 40) if(!O.anchored && !O.throwing) O.throw_at(get_edge_target_turf(O,get_dir(src, O)), 10, 1) @@ -174,7 +182,7 @@ var/turf/T = hit_atom if(T.density) //SPAWN_DBG(2) step(src, turn(src.dir, 180)) - if(ismob(src)) src:throw_impacted() + if(ismob(src)) src:throw_impacted(hit_atom) /*if(istype(hit_atom, /turf/simulated/wall) && isitem(src)) var/turf/simulated/wall/W = hit_atom W.take_hit(src)*/ @@ -192,12 +200,18 @@ src.throwing = 0 ..() -/atom/movable/proc/throw_at(atom/target, range, speed, list/params, turf/thrown_from) +/atom/movable/proc/throw_at(atom/target, range, speed, list/params, turf/thrown_from, throw_type = 1) //use a modified version of Bresenham's algorithm to get from the atom's current position to that of the target if (!target) return if (reagents) reagents.physical_shock(14) - src.throwing = 1 + src.throwing = throw_type + + if (src.throwing & (THROW_CHAIRFLIP | THROW_GUNIMPACT)) + if (ismob(src)) + var/mob/M = src + M.force_laydown_standup() + src.throw_traveled = 0 src.last_throw_x = src.x src.last_throw_y = src.y @@ -250,9 +264,11 @@ var/atom/step = get_step(src, dy) if(!step || step == src.loc) // going off the edge of the map makes get_step return null, don't let things go off the edge break + src.glide_size = (32 / (1/speed)) * world.tick_lag if (!Move(step)) // Grayshift: Race condition fix. Bump proc calls are delayed past the end of the loop and won't trigger end condition hitAThing = 1 // of !throwing on their own, so manually checking if Move failed as end condition break + src.glide_size = (32 / (1/speed)) * world.tick_lag hit_check() error += dist_x dist_travelled++ @@ -265,9 +281,11 @@ var/atom/step = get_step(src, dx) if(!step || step == src.loc) // going off the edge of the map makes get_step return null, don't let things go off the edge break + src.glide_size = (32 / (1/speed)) * world.tick_lag if (!Move(step)) hitAThing = 1 break + src.glide_size = (32 / (1/speed)) * world.tick_lag hit_check() error -= dist_y dist_travelled++ @@ -286,9 +304,11 @@ var/atom/step = get_step(src, dx) if(!step || step == src.loc) // going off the edge of the map makes get_step return null, don't let things go off the edge break + src.glide_size = (32 / (1/speed)) * world.tick_lag if (!Move(step)) hitAThing = 1 break + src.glide_size = (32 / (1/speed)) * world.tick_lag hit_check() error += dist_y dist_travelled++ @@ -301,9 +321,11 @@ var/atom/step = get_step(src, dy) if(!step || step == src.loc) // going off the edge of the map makes get_step return null, don't let things go off the edge break + src.glide_size = (32 / (1/speed)) * world.tick_lag if (!Move(step)) hitAThing = 1 break + src.glide_size = (32 / (1/speed)) * world.tick_lag hit_check() error -= dist_x dist_travelled++ @@ -315,6 +337,7 @@ T = src.loc //done throwing, either because it hit something or it finished moving + src.throw_end() if (!hitAThing) // Bump proc requires throwing flag to be set, so if we hit a thing, leave it on and let Bump turn it off src.throwing = 0 else // if we hit something don't use the pixel x/y from the click params diff --git a/code/client.dm b/code/client.dm index 5e7dbfd..5ac28e3 100644 --- a/code/client.dm +++ b/code/client.dm @@ -441,9 +441,13 @@ use_chui = winget( src, "menu.use_chui", "is-checked" ) == "true" use_chui_custom_frames = winget( src, "menu.use_chui_custom_frames", "is-checked" ) == "true" - //wow its the future we can choose between 2 fps values omg - src.tick_lag = CLIENTSIDE_TICK_LAG_SMOOTH - src.tick_lag = (winget( src, "menu.fps_chunky", "is-checked" ) == "true") ? CLIENTSIDE_TICK_LAG_CHUNKY : CLIENTSIDE_TICK_LAG_SMOOTH + //wow its the future we can choose between 3 fps values omg + if (winget( src, "menu.fps_chunky", "is-checked" ) == "true") + src.tick_lag = CLIENTSIDE_TICK_LAG_CHUNKY + else if (winget( src, "menu.fps_creamy", "is-checked" ) == "true") + src.tick_lag = CLIENTSIDE_TICK_LAG_CREAMY + else + src.tick_lag = CLIENTSIDE_TICK_LAG_SMOOTH //sound if (winget( src, "menu.speech_sounds", "is-checked" ) == "true") @@ -1079,7 +1083,14 @@ var/global/curr_day = null /client/verb/set_fps() set hidden = 1 set name = "set-fps" - src.tick_lag = (winget( src, "menu.fps_smooth", "is-checked" ) == "true") ? CLIENTSIDE_TICK_LAG_SMOOTH : CLIENTSIDE_TICK_LAG_CHUNKY + + if (winget( src, "menu.fps_chunky", "is-checked" ) == "true") + src.tick_lag = CLIENTSIDE_TICK_LAG_CHUNKY + else if (winget( src, "menu.fps_creamy", "is-checked" ) == "true") + src.tick_lag = CLIENTSIDE_TICK_LAG_CREAMY + else + src.tick_lag = CLIENTSIDE_TICK_LAG_SMOOTH + /client/verb/set_wasd_controls() set hidden = 1 diff --git a/code/datums/abilities/ability_parent.dm b/code/datums/abilities/ability_parent.dm index a8c6659..cb66826 100644 --- a/code/datums/abilities/ability_parent.dm +++ b/code/datums/abilities/ability_parent.dm @@ -31,6 +31,8 @@ // cirr's effort to make these work like normal huds, take 1 var/datum/hud/hud + var/next_update = 0 + New(var/mob/M) owner = M hud = new() @@ -671,13 +673,14 @@ New() ..() - var/obj/screen/ability/topBar/B = new /obj/screen/ability/topBar(null) - B.icon = src.icon - B.icon_state = src.icon_state - B.owner = src - B.name = src.name - B.desc = src.desc - src.object = B + if (src.icon && src.icon_state) + var/obj/screen/ability/topBar/B = new /obj/screen/ability/topBar(null) + B.icon = src.icon + B.icon_state = src.icon_state + B.owner = src + B.name = src.name + B.desc = src.desc + src.object = B disposing() if (object && object.owner == src) @@ -851,7 +854,10 @@ return targets display_available() - .= 1 + .= (src.icon && src.icon_state) + + flip_callback() + .= 0 /obj/screen/pseudo_overlay // this is hack as all get out @@ -937,10 +943,11 @@ y_occupied = 0 any_abilities_displayed = 0 for (var/datum/abilityHolder/H in holders) - H.updateButtons(called_by_owner = 1, start_x = x_occupied, start_y = y_occupied) - x_occupied = H.x_occupied - y_occupied = H.y_occupied - any_abilities_displayed = any_abilities_displayed || H.any_abilities_displayed + if (H.topBarRendered || H.rendered) + H.updateButtons(called_by_owner = 1, start_x = x_occupied, start_y = y_occupied) + x_occupied = H.x_occupied + y_occupied = H.y_occupied + any_abilities_displayed = any_abilities_displayed || H.any_abilities_displayed addBonus(var/value) for (var/datum/abilityHolder/H in holders) @@ -984,7 +991,7 @@ H.abilities += A A.onAttach(H) //H.updateButtons() - return + return A var/datum/abilityHolder/X = holders[1] A.holder = X X.abilities += A diff --git a/code/datums/abilities/generic.dm b/code/datums/abilities/generic.dm new file mode 100644 index 0000000..6ec2c64 --- /dev/null +++ b/code/datums/abilities/generic.dm @@ -0,0 +1,154 @@ +/mob/var/datum/targetable/chairflip/chair_flip_ability = null + +/mob/proc/start_chair_flip_targeting(var/extrarange = 0) + if (src.abilityHolder) + if (istype(src.abilityHolder,/datum/abilityHolder/composite)) + var/datum/abilityHolder/composite/C = src.abilityHolder + if (!C.getHolder(/datum/abilityHolder/generic)) + C.addHolder(/datum/abilityHolder/generic) + if (!chair_flip_ability) + chair_flip_ability = src.abilityHolder.addAbility(/datum/targetable/chairflip) + + chair_flip_ability.extrarange = extrarange + src.targeting_spell = chair_flip_ability + src.update_cursor() + + playsound(src.loc, "sound/effects/chair_step.ogg", 50, 1) + +/mob/proc/end_chair_flip_targeting() + src.targeting_spell = null + src.update_cursor() + if (src.chair_flip_ability) + src.chair_flip_ability.extrarange = 0 + +/datum/abilityHolder/generic + usesPoints = 0 + regenRate = 0 + topBarRendered = 0 + rendered = 0 + + //updateButtons(var/called_by_owner = 0, var/start_x = 1, var/start_y = 0) + // any_abilities_displayed = 0 + // x_occupied = start_x + // y_occupied = start_y + // return + +/datum/targetable/chairflip + name = "Chair Flip" + desc = "Click to launch yourself off of a chair." + //icon_state = "fireball" + targeted = 1 + target_anything = 1 + cooldown = 1 + preferred_holder_type = /datum/abilityHolder/generic + icon = null + icon_state = null + var/extrarange = 0 //affects next flip only + + + flip_callback() + var/turf/T = get_turf(holder.owner) + var/dist = 3 + extrarange + while (T && dist > 0) + T = get_step(T,holder.owner.dir) + dist -= 1 + + src.cast(T) + + cast(atom/target) //the effect is in throw_impact at the bottom of mob.dm + ..() + + var/mob/M = holder.owner + + + if (get_dist(M,target) > 3 + extrarange) + var/steps = 0 + var/turf/T = get_turf(M) + while (steps < 3 + extrarange) + T = get_step(T,get_dir(T,target)) + steps += 1 + + target = T + + extrarange = 0 + + + if (istype(M.buckled,/obj/stool/chair)) + var/obj/stool/chair/C = M.buckled + C.buckledIn = 0 + M.pixel_y = 0 + M.buckled = null + M.anchored = 0 + + M.targeting_spell = null + M.update_cursor() + + if (ishuman(M)) + var/mob/living/carbon/human/H = M + H.on_chair = 0 + + playsound(M.loc, "sound/effects/flip.ogg", 50, 1) + M.throw_at(target, 10, 1, throw_type = THROW_CHAIRFLIP) + + + if (!iswrestler(M) && M.traitHolder && !M.traitHolder.hasTrait("glasscannon")) + M.remove_stamina(STAMINA_FLIP_COST) + M.stamina_stun() + + //if (!M.reagents.has_reagent("fliptonium")) + //animate_spin(src, prob(50) ? "L" : "R", 1, 0) + + +/mob/throw_impact(atom/hit_atom, list/params) + ..(hit_atom,params) + + if (src.throwing & THROW_CHAIRFLIP) + var/turf/T = locate(src.last_throw_x, src.last_throw_y, src.z) + var/dist_traveled = get_dist(hit_atom,T) + var/effect_mult = 1 + if (dist_traveled <=1) + effect_mult = 0.6 + else if (dist_traveled >= 3) + effect_mult = 1.5 + + + if (isliving(hit_atom)) + var/mob/living/M = hit_atom + + playsound(src.loc, "sound/impact_sounds/Flesh_Break_1.ogg", 75, 1) + if (prob(25)) + M.emote("scream") + + logTheThing("combat", src, M, "[src] chairflips into %target%, [showCoords(M.x, M.y, M.z)].") + M.lastattacker = src + M.lastattackertime = world.time + + if (iswrestler(src)) + if (prob(33)) + M.ex_act(3) + else + random_brute_damage(M, 20 * effect_mult) + M.changeStatus("weakened", 7 SECONDS * effect_mult) + M.force_laydown_standup() + else if (M.traitHolder.hasTrait("training_security")) //consider rremoving this, prrobably not necessarry any more + M.visible_message("[src] does a flying flip into [M], but [M] skillfully slings them away!") + src.changeStatus("weakened", 6 SECONDS) + var/atom/target = get_edge_target_turf(M, M.dir) + src.throw_at(target, 3, 10) + src.force_laydown_standup() + else + random_brute_damage(M, 10 * effect_mult) + if (!M.hasStatus("weakened")) + M.changeStatus("weakened", 4 SECONDS * effect_mult) + M.force_laydown_standup() + + if (src.hasStatus("weakened") && src.getStatusDuration("weakened") < 3 SECONDS * effect_mult) //address race of thus throw_end() happening before this proc lands due to Bump() timing + src.setStatus("weakened", 3 SECONDS * effect_mult) + else + src.changeStatus("weakened", 3 SECONDS * effect_mult) + src.force_laydown_standup() + +/mob/throw_end() + if (src.throwing & THROW_CHAIRFLIP) + src.changeStatus("weakened", 1.7 SECONDS) + src.force_laydown_standup() diff --git a/code/datums/abilities/revenant.dm b/code/datums/abilities/revenant.dm index 96edb12..c64021d 100644 --- a/code/datums/abilities/revenant.dm +++ b/code/datums/abilities/revenant.dm @@ -48,7 +48,7 @@ var/ghoulTouchActive = 0 var/list/abilities icon_state = "evilaura" - + OnAdd() if (ishuman(owner) && isdead(owner)) switch (owner:decomp_stage) @@ -82,6 +82,14 @@ owner.set_face_icon_dirty() owner.set_body_icon_dirty() animate_levitate(owner) + + owner.add_stun_resist_mod("revenant", 1000) + + ..() + + OnRemove() + if (owner) + owner.remove_stun_resist_mod("revenant") ..() proc/ghoulTouch(var/mob/living/carbon/human/poorSob, var/obj/item/affecting) @@ -178,9 +186,7 @@ owner.take_eye_damage(-INFINITY) owner.take_eye_damage(-INFINITY, 1) owner.losebreath = 0 - owner.delStatus("paralysis") - owner.delStatus("stunned") - owner.delStatus("weakened") + owner.delStatus("disorient") owner.delStatus("slowed") owner.delStatus("radiation") owner.take_ear_damage(-INFINITY) diff --git a/code/datums/abilities/vampire/call_bats.dm b/code/datums/abilities/vampire/call_bats.dm index 1f5d693..54c278b 100644 --- a/code/datums/abilities/vampire/call_bats.dm +++ b/code/datums/abilities/vampire/call_bats.dm @@ -22,6 +22,10 @@ unlock_message = "You have gained Call Frost Bats, a protection spell." var/datum/projectile/special/homing/orbiter/spiritbat/P = new + flip_callback() + var/datum/abilityHolder/vampire/H = holder + H.launch_bat_orbiters() + cast(mob/target) if (!holder) return 1 diff --git a/code/datums/abilities/vampire/glare.dm b/code/datums/abilities/vampire/glare.dm index 09c96ee..4b603a2 100644 --- a/code/datums/abilities/vampire/glare.dm +++ b/code/datums/abilities/vampire/glare.dm @@ -53,8 +53,8 @@ boutput(target, __blue("[M]'s foul gaze falters as it stares upon your righteousness!")) target.visible_message("[target] glares right back at [M]!") else - target.apply_flash(30, 15, stamina_damage = 250) - + target.apply_flash(30, 15, stamina_damage = 350) + if (ishuman(target)) target:was_harmed(M, special = "vamp") diff --git a/code/datums/abilities/werewolf.dm b/code/datums/abilities/werewolf.dm index 1b7488c..88aae05 100644 --- a/code/datums/abilities/werewolf.dm +++ b/code/datums/abilities/werewolf.dm @@ -65,6 +65,7 @@ M.delStatus("weakened") M.delStatus("paralysis") M.delStatus("slowed") + M.delStatus("disorient") M.change_misstep_chance(-INFINITY) M.stuttering = 0 M.drowsyness = 0 diff --git a/code/datums/abilities/wizard/phaseshift.dm b/code/datums/abilities/wizard/phaseshift.dm index efbb9e8..3a4d3fc 100644 --- a/code/datums/abilities/wizard/phaseshift.dm +++ b/code/datums/abilities/wizard/phaseshift.dm @@ -281,6 +281,8 @@ if (i > 20) break + actions.interrupt(user, INTERRUPT_MOVE) + .= delay ex_act(severity) diff --git a/code/datums/banking.dm b/code/datums/banking.dm index 5ba08fc..7e80760 100644 --- a/code/datums/banking.dm +++ b/code/datums/banking.dm @@ -399,6 +399,7 @@ name = "Bank Records" icon_state = "databank" req_access = list(access_heads) + object_flags = CAN_REPROGRAM_ACCESS var/obj/item/card/id/scan = null var/authenticated = null var/rank = null @@ -608,6 +609,8 @@ opacity = 0 anchored = 1 + deconstruct_flags = DECON_MULTITOOL + var/datum/data/record/accessed_record = null var/obj/item/card/id/scan = null diff --git a/code/datums/controllers/action_controls.dm b/code/datums/controllers/action_controls.dm index cd8b8f0..58ce2ef 100644 --- a/code/datums/controllers/action_controls.dm +++ b/code/datums/controllers/action_controls.dm @@ -443,13 +443,17 @@ var/datum/action_controller/actions var/obj/item/item //The item if any. If theres no item, we tried to remove something from that slot instead of putting an item there. var/slot //The slot number - New(var/Source, var/Target, var/Item, var/Slot) + + New(var/Source, var/Target, var/Item, var/Slot, var/ExtraDuration = 0) source = Source target = Target item = Item slot = Slot if(item) + + + if(item.duration_put > 0) duration = item.duration_put else @@ -461,6 +465,10 @@ var/datum/action_controller/actions duration = I.duration_remove else duration = 25 + + duration += ExtraDuration + + ..() onStart() @@ -468,8 +476,9 @@ var/datum/action_controller/actions target.add_fingerprint(source) // Added for forensics (Convair880). - if (source.at_gunpoint && source.at_gunpoint.holding_at_gunpoint != source) - source.at_gunpoint.shoot_at_gunpoint(source) + if (source.mob_flags & AT_GUNPOINT) + for(var/obj/item/grab/gunpoint/G in source.grabbed_by) + G.shoot() if(item) if(!target.can_equip(item, slot)) @@ -983,7 +992,7 @@ var/datum/action_controller/actions O.show_message("[owner] butchers [target].[target.butcherable == 2 ? "WHAT A MONSTER" : null]", 1) /datum/action/bar/icon/rev_flash - duration = 18 SECONDS + duration = 13 SECONDS interrupt_flags = INTERRUPT_MOVE | INTERRUPT_STUNNED id = "rev_flash" icon = 'icons/ui/actions.dmi' @@ -1180,3 +1189,48 @@ var/datum/action_controller/actions ..() if (M) M.pixel_y = 0 + + +/datum/action/bar/private/icon/pickup //Delayed pickup, used for mousedrags to prevent 'auto clicky' exploits but allot us to pickup with mousedrag as a possibel action + duration = 10 + interrupt_flags = INTERRUPT_MOVE | INTERRUPT_STUNNED + id = "pickup" + var/obj/item/target + icon = 'icons/ui/actions.dmi' + icon_state = "pickup" + + New(Target) + target = Target + ..() + + onUpdate() + ..() + if(get_dist(owner, target) > 1 || target == null || owner == null) + interrupt(INTERRUPT_ALWAYS) + return + + onStart() + ..() + if(get_dist(owner, target) > 1 || target == null || owner == null) + interrupt(INTERRUPT_ALWAYS) + return + + onEnd() + ..() + target.pick_up_by(owner) + + + then_hud_click + + var/atom/over_object + var/params + + New(Target, Over, Parameters) + target = Target + over_object = Over + params = Parameters + ..() + + onEnd() + ..() + target.try_equip_to_inventory_object(owner, over_object, params) \ No newline at end of file diff --git a/code/datums/controllers/process/mob_ui.dm b/code/datums/controllers/process/mob_ui.dm new file mode 100644 index 0000000..4197578 --- /dev/null +++ b/code/datums/controllers/process/mob_ui.dm @@ -0,0 +1,10 @@ + +datum/controller/process/mob_ui + setup() + name = "Mob UI" + schedule_interval = 1 SECONDS + + doWork() + for(var/mob/M in mobs) + M.handle_stamina_updates() + scheck() diff --git a/code/datums/controllers/process/mobs.dm b/code/datums/controllers/process/mobs.dm index 24468fa..0e0c0d5 100644 --- a/code/datums/controllers/process/mobs.dm +++ b/code/datums/controllers/process/mobs.dm @@ -4,7 +4,6 @@ datum/controller/process/mobs var/tmp/tick_counter var/list/mobs - var/list/living = list() var/list/wraiths = list() var/list/adminghosts = list() @@ -33,7 +32,7 @@ datum/controller/process/mobs // For periodic antag overlay updates (Convair880). for (var/mob/dead/G in src.mobs) -#ifdef HALLOWEEN +#ifdef HALLOWEEN if (TRUE) #else if (isadminghost(G) || IS_TWITCH_CONTROLLED(G)) diff --git a/code/datums/controllers/sea_hotspot_controls.dm b/code/datums/controllers/sea_hotspot_controls.dm index f1505e1..30f915f 100644 --- a/code/datums/controllers/sea_hotspot_controls.dm +++ b/code/datums/controllers/sea_hotspot_controls.dm @@ -612,6 +612,7 @@ item_state = "vent" inhand_image_icon = 'icons/mob/inhand/hand_tools.dmi' mats = 8 + deconstruct_flags = DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_WIRECUTTERS attackby(var/obj/item/W, var/mob/user) if (istype(W,/obj/item/electronics/soldering) || isscrewingtool(W) || ispryingtool(W) || iswrenchingtool(W)) @@ -767,6 +768,7 @@ var/powerdownsfx = 'sound/machines/engine_alert3.ogg' mats = 8 + deconstruct_flags = DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_WIRECUTTERS flags = FPRINT var/mode_toggle = 0 diff --git a/code/datums/disease.dm b/code/datums/disease.dm index 3707f1d..a5492a9 100644 --- a/code/datums/disease.dm +++ b/code/datums/disease.dm @@ -295,7 +295,8 @@ var/mob/living/carbon/human/H = src resist_prob = H.get_disease_protection(ailment_path, ailment_name) else - for(var/obj/item/clothing/C in src.get_equipped_items()) + for(var/atom in src.get_equipped_items()) + var/obj/item/C = atom resist_prob += C.getProperty("viralprot") if (ispath(ailment_path) || istext(ailment_name)) diff --git a/code/datums/effects/system/foam_spread.dm b/code/datums/effects/system/foam_spread.dm index 20050d3..a4cc462 100644 --- a/code/datums/effects/system/foam_spread.dm +++ b/code/datums/effects/system/foam_spread.dm @@ -40,7 +40,7 @@ DEBUG_MESSAGE("Located [F] in [location]") F.repeated_applications += 1 //var/min = max(27 - (F.repeated_applications * 3),0) - var/amt_change = min((amount - (F.repeated_applications*2) ),amount) + var/amt_change = min((amount - (F.repeated_applications*3) ),amount) amt_change = max(amt_change,0) F.amount += amt_change diff --git a/code/datums/gamemodes/revolution.dm b/code/datums/gamemodes/revolution.dm index 06d1dd2..02d6cf4 100644 --- a/code/datums/gamemodes/revolution.dm +++ b/code/datums/gamemodes/revolution.dm @@ -119,7 +119,7 @@ rev_mob.put_in_hand_or_drop(F2) the_slot = "hand" */ - rev_mob.show_text("You've been supplied with a flash in your [the_slot] with which to convert others to the cause!", "blue") + rev_mob.show_text("You can use any flash or order items on your Uplink to convert others to the cause!", "blue") return /datum/game_mode/revolution/send_intercept() diff --git a/code/datums/gauntlet/podcolosseum.dm b/code/datums/gauntlet/podcolosseum.dm index 451ace3..1ae1dd3 100644 --- a/code/datums/gauntlet/podcolosseum.dm +++ b/code/datums/gauntlet/podcolosseum.dm @@ -535,9 +535,6 @@ var/global/datum/arena/colosseumController/colosseum_controller = new() else add_counter(barBits.len, health_value, "#000000") - proc/lerp(var/a, var/b, var/t) - return a * (1 - t) + b * t - proc/add_overlay(value, max_value, r0, g0, b0, r1, g1, b1) var/percentage = value / max_value var/remaining = round(percentage * 100) diff --git a/code/datums/hud.dm b/code/datums/hud.dm index 62c82ab..9b728f4 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -13,8 +13,11 @@ var/obj/item/item clicked(list/params) - if (master && (!master.click_check || (usr in master.mobs))) - master.clicked(src.id, usr, params) + sendclick(params, usr) + + proc/sendclick(list/params,mob/user = null) + if (master && (!master.click_check || (user in master.mobs))) + master.clicked(src.id, user, params) //WIRE TOOLTIPS MouseEntered(location, control, params) diff --git a/code/datums/hud/critter.dm b/code/datums/hud/critter.dm index a68827d..baecd41 100644 --- a/code/datums/hud/critter.dm +++ b/code/datums/hud/critter.dm @@ -154,6 +154,8 @@ src.update_mintent() if ("pull") + if (master.pulling) + unpull_particle(master,pulling) master.pulling = null src.update_pulling() diff --git a/code/datums/hud/ghostdrone.dm b/code/datums/hud/ghostdrone.dm index d36c616..9dfafd8 100644 --- a/code/datums/hud/ghostdrone.dm +++ b/code/datums/hud/ghostdrone.dm @@ -243,6 +243,8 @@ if ("store") master.uneq_slot() if ("pulling") + if (master.pulling) + unpull_particle(master,pulling) master.pulling = null update_pulling() if ("face") diff --git a/code/datums/hud/human.dm b/code/datums/hud/human.dm index 1c184c5..83614fb 100644 --- a/code/datums/hud/human.dm +++ b/code/datums/hud/human.dm @@ -370,6 +370,8 @@ src.update_mintent() if ("pull") + if (master.pulling) + unpull_particle(master,pulling) master.pulling = null src.update_pulling() @@ -519,6 +521,25 @@ newDesc += "
Total Resistance (Cold): [master.get_cold_protection()]%
" newDesc += "
Total Resistance (Radiation): [master.get_rad_protection()]%
" newDesc += "
Total Resistance (Disease): [master.get_disease_protection()]%
" + + var/prot = master.get_disorient_protection() + var/disorientprot = 0 + if (prot >= 90) + disorientprot = "[prot]% (MAX)" + else + disorientprot = "[prot]%" + + newDesc += "
Total Resistance (Body Disorient): [disorientprot]
" + + prot = master.get_disorient_protection_eye() + newDesc += "
Total Resistance (Eye Disorient): [prot]%
" + + prot = master.get_disorient_protection_ear() + newDesc += "
Total Resistance (Ear Disorient): [prot]%
" + + newDesc += "
Total Resistance (Stuns): [master.get_stun_resist_mod()]%
" + + //newDesc += "
Bonus: [master.get_food_bonus()]
" stats.desc = newDesc diff --git a/code/datums/hud/robot.dm b/code/datums/hud/robot.dm index c8348f4..0f7dc22 100644 --- a/code/datums/hud/robot.dm +++ b/code/datums/hud/robot.dm @@ -306,6 +306,8 @@ master.a_intent = INTENT_HELP update_intent() if ("pulling") + if (master.pulling) + unpull_particle(master,pulling) master.pulling = null update_pulling() if ("upgrades") diff --git a/code/datums/hud/vision.dm b/code/datums/hud/vision.dm index f9e30cb..28d8854 100644 --- a/code/datums/hud/vision.dm +++ b/code/datums/hud/vision.dm @@ -42,7 +42,7 @@ flash.icon_state = "white" set_scan(scanline) - scan.alpha = scanline ? 200 : 0 + scan.alpha = scanline ? 50 : 0 set_color_mod(color) color_mod.color = color diff --git a/code/datums/hud/yesno_dialog.dm b/code/datums/hud/yesno_dialog.dm new file mode 100644 index 0000000..96ccec3 --- /dev/null +++ b/code/datums/hud/yesno_dialog.dm @@ -0,0 +1,36 @@ + +//silly incomplete thingyh + +/* +/datum/yesno_dialog + + var/list/contextActions = null + + var/mob/user + var/maptext = "Do you want to?" + var/charge.maptext_y = -5 + var/charge.maptext_width = 96 + var/charge.maptext_x = -9 + + var/datum/contextLayout/contextLayout = null + + //you could enter some maptext stuff here and then have buttons auto expand + New(var/mob/M, var/question) + user = M + contextLayout = new /datum/contextLayout/flexdefault(4, 32, 32) + + user.showContextActions(contextActions, src) + + ..() + + disposing() + ..() + + + //override these + proc/accept + qdel(src) + + proc/deny + qdel(src) +*/ \ No newline at end of file diff --git a/code/datums/movement_controller/movement_controller.dm b/code/datums/movement_controller/movement_controller.dm index f17c665..b21e366 100644 --- a/code/datums/movement_controller/movement_controller.dm +++ b/code/datums/movement_controller/movement_controller.dm @@ -11,5 +11,8 @@ modify_keymap(datum/keymap/keymap, client/C) // stub + update_owner_dir(var/atom/movable/owner) + + disposing() ..() diff --git a/code/datums/movement_controller/pod.dm b/code/datums/movement_controller/pod.dm index fa158e3..bd9bbf5 100644 --- a/code/datums/movement_controller/pod.dm +++ b/code/datums/movement_controller/pod.dm @@ -20,8 +20,16 @@ min_delay = 14 + matrix/M + + braking = 0 + brake_decel_mult = 0.8 + + last_dir = 0 + New(owner) src.owner = owner + M = matrix() disposing() owner = null @@ -31,11 +39,13 @@ if (istype(src.owner, /obj/machinery/vehicle/escape_pod)) return - if (changed & (KEY_FORWARD|KEY_BACKWARD|KEY_RIGHT|KEY_LEFT)) + if (changed & (KEY_FORWARD|KEY_BACKWARD|KEY_RIGHT|KEY_LEFT|KEY_RUN)) if (!owner.engine) // fuck it, no better place to put this, only triggers on presses boutput(user, "[owner.ship_message("WARNING! No engine detected!")]") return + braking = keys & KEY_RUN + input_x = 0 input_y = 0 if (keys & KEY_FORWARD) @@ -56,10 +66,21 @@ owner.dir = input_dir owner.facing = input_dir + if (input_magnitude) + if (input_dir & (input_dir-1)) + owner.dir = NORTH + owner.transform = turn(M,atan2(input_y,input_x)) + else + owner.transform = null + last_dir = owner.dir + if (input_x || input_y) user.attempt_move() + update_owner_dir(var/atom/movable/ship) //after move, update ddir + owner.dir = last_dir + process_move(mob/user, keys) if (istype(src.owner, /obj/machinery/vehicle/escape_pod)) return @@ -74,6 +95,15 @@ velocity_x += input_x * accel velocity_y += input_y * accel + //braking + if (braking) + velocity_x = velocity_x * brake_decel_mult + velocity_y = velocity_y * brake_decel_mult + + if (velocity_x + velocity_y < 0.2) + velocity_x = 0 + velocity_y = 0 + //normalize and force speed cap velocity_magnitude = vector_magnitude(velocity_x, velocity_y) var/vel_max = velocity_max + max(owner.speed,0) @@ -107,6 +137,10 @@ if (delay) var/target_turf = get_step(owner, velocity_dir) + for(var/mob/M in owner) //hey maybe move this somewhere better later. idk man its all chill thou, its all cool, dont worry about it buddy + M.glide_size = owner.glide_size + M.animate_movement = SYNC_STEPS + owner.glide_size = (32 / delay) * world.tick_lag step(owner, velocity_dir) owner.glide_size = (32 / delay) * world.tick_lag diff --git a/code/datums/movement_controller/tank.dm b/code/datums/movement_controller/tank.dm index d6dcf1b..19013cb 100644 --- a/code/datums/movement_controller/tank.dm +++ b/code/datums/movement_controller/tank.dm @@ -149,6 +149,10 @@ next_move = world.time + delay return min(delay, next_rot-world.time) + update_owner_dir(var/atom/movable/ship) //after move, update ddir + if (owner.flying && owner.facing != owner.flying) + owner.dir = owner.facing + hotkey(mob/user, name) switch (name) if ("fire") diff --git a/code/datums/mutantraces.dm b/code/datums/mutantraces.dm index dcf7cdc..18cf6b9 100644 --- a/code/datums/mutantraces.dm +++ b/code/datums/mutantraces.dm @@ -211,7 +211,7 @@ H.limbs.l_arm = limb limb.holder = H limb.remove_stage = 0 - + //////////////LEGS////////////////// if (src.r_limb_leg_type_mutantrace) if (H.limbs.r_leg || src.ignore_missing_limbs == 1) @@ -688,7 +688,7 @@ if(ruff_tuff_and_ultrabuff && M) M.add_stam_mod_max("abomination", 1000) M.add_stam_mod_regen("abomination", 1000) - + M.add_stun_resist_mod("abomination", 1000) last_drain = world.time return ..(M) @@ -696,6 +696,7 @@ if(mob) mob.remove_stam_mod_max("abomination") mob.remove_stam_mod_regen("abomination") + mob.remove_stun_resist_mod("abomination") return ..() movement_delay() @@ -704,9 +705,6 @@ onLife(var/mult = 1) //Bringing it more in line with how it was before it got broken (in a hilarious fashion) if (ruff_tuff_and_ultrabuff && !(mob.getStatusDuration("burning") && prob(90))) //Are you a macho abomination or not? - mob.delStatus("paralysis") - mob.delStatus("weakened") - mob.delStatus("stunned") mob.delStatus("disorient") mob.drowsyness = 0 mob.change_misstep_chance(-INFINITY) @@ -774,6 +772,7 @@ if (mob) mob.add_stam_mod_max("werewolf", 40) // Gave them a significant stamina boost, as they're melee-orientated (Convair880). mob.add_stam_mod_regen("werewolf", 9) //mbc : these increase as they feast now. reduced! + mob.add_stun_resist_mod("werewolf", 40) mob.max_health += 50 src.original_name = mob.real_name mob.real_name = "werewolf" @@ -792,6 +791,7 @@ if (mob) mob.remove_stam_mod_max("werewolf") mob.remove_stam_mod_regen("werewolf") + mob.remove_stun_resist_mod("werewolf") mob.max_health -= 30 if (!isnull(src.original_name)) @@ -809,9 +809,6 @@ // Werewolves (being a melee-focused role) are quite buff. onLife(var/mult = 1) if (mob && ismob(mob)) - mob.changeStatus("paralysis", -20 * mult) - mob.changeStatus("stunned", -20 * mult) - mob.changeStatus("weakened", -20 * mult) if (mob.drowsyness) mob.drowsyness = max(0, mob.drowsyness - 2) if (mob.misstep_chance) diff --git a/code/datums/syndicate_buylist.dm b/code/datums/syndicate_buylist.dm index 34beef5..4944197 100644 --- a/code/datums/syndicate_buylist.dm +++ b/code/datums/syndicate_buylist.dm @@ -927,7 +927,23 @@ This is basically useless for anyone but miners. /datum/syndicate_buylist/generic/revsign name = "Revolutionary Sign" item = /obj/item/revolutionary_sign - cost = 5 + cost = 4 desc = "This large revolutionary sign will inspire all nearby revolutionaries and grant them small combat buffs. A rev head needs to be holding this sign for it to have any effect." exclusivemode = list(/datum/game_mode/revolution) not_in_crates = 1 + +/datum/syndicate_buylist/generic/rev_dagger + name = "Sacrificial Dagger" + item = /obj/item/dagger + cost = 2 + desc = "An ornamental dagger for stabbing people with." + exclusivemode = list(/datum/game_mode/revolution) + not_in_crates = 1 + +/datum/syndicate_buylist/generic/rev_normal_flash + name = "Flash" + item = /obj/item/device/flash + cost = 1 + desc = "Just a standard-issue flash. Won't remove implants like the Revolutionary Flash." + exclusivemode = list(/datum/game_mode/revolution) + not_in_crates = 1 diff --git a/code/mob.dm b/code/mob.dm index b48f7f3..e1258db 100644 --- a/code/mob.dm +++ b/code/mob.dm @@ -101,7 +101,6 @@ var/obj/item/clothing/ears/ears = null var/network_device = null var/Vnetwork = null - var/obj/item/gun/at_gunpoint = null var/lastDamageIconUpdate var/say_language = "english" var/literate = 1 // im liturit i kin reed an riet @@ -235,8 +234,11 @@ src.buckled.Move(a, b, flag) src.buckled.glide_size = glide_size // dumb hack else - if (src.at_gunpoint) - src.at_gunpoint.shoot_at_gunpoint(src) + if (mob_flags & AT_GUNPOINT) + for(var/obj/item/grab/gunpoint/G in grabbed_by) + //if (usr == G.assailant) + continue + G.shoot() . = ..() src.closeContextActions() @@ -611,7 +613,7 @@ //hud.update_pulling() // FIXME else pulling += src.pulling - for (var/obj/item/grab/G in src) + for (var/obj/item/grab/G in src.equipped_list(check_for_magtractor = 0)) pulling += G.affecting for (var/atom/movable/A in pulling) if (get_dist(src, A) == 0) // if we're moving onto the same tile as what we're pulling, don't pull @@ -950,7 +952,6 @@ /mob/proc/set_pulling(atom/movable/A) pulling = A - //robust grab : a dirty DIRTY trick on mbc's part. When I am being chokeholded by someone, redirect pulls to the captor. //this is so much simpler than pulling the victim and invoking movment on the captor through that chain of events. if (ishuman(pulling)) @@ -960,6 +961,8 @@ if (G.state < GRAB_NECK) continue pulling = G.assailant + pull_particle(src,pulling) + // less icon caching maybe?! #define FACE 1 @@ -1100,6 +1103,8 @@ if (!islist(params)) params = params2list(params) if(params["ctrl"]) + if (src.pulling) + unpull_particle(src,pulling) src.pulling = null //circumvented by some rude hack in client.dm; uncomment if hack ceases to exist @@ -1120,6 +1125,8 @@ src.dir = WEST if ("stop_pull") + if (src.pulling) + unpull_particle(src,pulling) src.pulling = null /mob/proc/build_keymap(client/C) @@ -1225,24 +1232,34 @@ return /mob/proc/equipped_list(check_for_magtractor = 1) - . = list(src.r_hand, src.l_hand) + . = list() - if (src.r_hand && src.r_hand.event_handler_flags & USE_GRAB_CHOKE) - for(var/obj/item/grab/G in src.r_hand) - . += G + if (src.r_hand) + . += src.r_hand + if (src.r_hand.chokehold) + . += src.r_hand.chokehold - if (src.l_hand && src.l_hand.event_handler_flags & USE_GRAB_CHOKE) - for(var/obj/item/grab/G in src.l_hand) - . += G + if (src.l_hand) + . += src.l_hand + if (src.l_hand.chokehold) + . += src.l_hand.chokehold //handle mag tracktor if (check_for_magtractor) for (var/I in .) if (istype(I,/obj/item/magtractor)) var/obj/item/magtractor/M = I - .+= M.holding + if (M.holding) + .+= M.holding .-= I +/mob/living/critter/equipped_list(check_for_magtractor = 1) + .= ..() + if (hands) + for(var/datum/handHolder/H in hands) + if (H.item) + .+= H.item + /mob/living/silicon/equipped_list(check_for_magtractor = 1) //lool copy paste fix later .= 0 if (ishivebot(src)||isrobot(src)) @@ -2166,13 +2183,14 @@ /mob/onVarChanged(variable, oldval, newval) update_clothing() -/mob/proc/throw_impacted() //Called when mob hits something after being thrown. +/mob/proc/throw_impacted(var/atom/hit) //Called when mob hits something after being thrown. if (throw_count <= 410) - random_brute_damage(src, min((6 + (throw_count / 5)), (src.health - 5) < 0 ? src.health : (src.health - 5))) - if (!src.hasStatus("weakened")) - src.changeStatus("weakened", 2 SECONDS) - src.force_laydown_standup() + if (!((src.throwing & THROW_CHAIRFLIP) && ismob(hit))) + random_brute_damage(src, min((6 + (throw_count / 5)), (src.health - 5) < 0 ? src.health : (src.health - 5))) + if (!src.hasStatus("weakened")) + src.changeStatus("weakened", 2 SECONDS) + src.force_laydown_standup() else if (src.gib_flag) return src.gib_flag = 1 @@ -2739,3 +2757,6 @@ /mob/proc/get_random_equipped_thing_name() //FOR FLAVOR USE ONLY .= 0 + +/mob/proc/handle_stamina_updates() + .= 0 diff --git a/code/mob/input.dm b/code/mob/input.dm index e883a04..de4e20c 100644 --- a/code/mob/input.dm +++ b/code/mob/input.dm @@ -185,6 +185,11 @@ mob //robust grab : Assailant gets moved here (do_step shit). this is messy, i'm sorry, blame MBC if (!do_step || src.loc != old_loc) + + if (mob_flags & AT_GUNPOINT) //we do this check here because if we DID take a step, we aren't tight-grabbed and the gunpoint shot will be triggered by Mob/Move(). messy i know, fix later + for(var/obj/item/grab/gunpoint/G in grabbed_by) + G.shoot() + for(var/grab in src.grabbed_by) var/obj/item/grab/G = grab if (G.state < GRAB_NECK) continue diff --git a/code/mob/living.dm b/code/mob/living.dm index cca529d..b2c7188 100644 --- a/code/mob/living.dm +++ b/code/mob/living.dm @@ -344,8 +344,11 @@ var/atom/movable/movable = target if (istype(movable)) movable.pull() - if (src.at_gunpoint && src.at_gunpoint.holding_at_gunpoint != src) - src.at_gunpoint.shoot_at_gunpoint(src) + + if (mob_flags & AT_GUNPOINT) + for(var/obj/item/grab/gunpoint/G in grabbed_by) + G.shoot() + .= 0 return else diff --git a/code/mob/living/carbon.dm b/code/mob/living/carbon.dm index 4b90a80..955533e 100644 --- a/code/mob/living/carbon.dm +++ b/code/mob/living/carbon.dm @@ -1,4 +1,7 @@ -// carbon-based lifeforms + +/mob/ + var/list/stun_resist_mods = list() + /mob/living/carbon/ gender = MALE // WOW RUDE @@ -61,7 +64,8 @@ val += stamina_mods_max[x] var/stam_mod_items = 0 - for(var/obj/item/C in src.get_equipped_items()) + for(var/atom in src.get_equipped_items()) + var/obj/item/C = atom stam_mod_items += C.getProperty("stammax") return (val + stam_mod_items) @@ -97,10 +101,42 @@ val += stamina_mods_regen[x] var/stam_mod_items = 0 - for(var/obj/item/C in src.get_equipped_items()) + for(var/atom in src.get_equipped_items()) + var/obj/item/C = atom stam_mod_items += C.getProperty("stamregen") return val + +/mob/proc/add_stun_resist_mod(var/key, var/value) + if(!isnum(value)) return + if(stun_resist_mods.Find(key)) return 0 + stun_resist_mods.Add(key) + stun_resist_mods[key] = value + return 1 + +//Removes a stamina max modifier with the given key. +/mob/proc/remove_stun_resist_mod(var/key) + if(!stun_resist_mods.Find(key)) return 0 + stun_resist_mods.Remove(key) + return 1 + +//Returns the total modifier for stamina max +/mob/proc/get_stun_resist_mod() + .= 0 + var/highest = 0 + for(var/x in stun_resist_mods) + . += stun_resist_mods[x] + if (stun_resist_mods[x] > highest) + highest = stun_resist_mods[x] + + + var/max_allowed = 80 //basically if we dont have a singular 100% or above protection moddifier, we wont allow the user to completely ignore stuns + if (highest > 80) + max_allowed = min(highest, 100) + + .= clamp(., 0, max_allowed) + + //Restores stamina /mob/proc/add_stamina(var/x) return @@ -125,7 +161,8 @@ del(src.client) var/stam_mod_items = 0 - for(var/obj/item/C in src.get_equipped_items()) + for(var/atom in src.get_equipped_items()) + var/obj/item/C = atom stam_mod_items += C.getProperty("stamcost") var/percReduction = 0 @@ -202,10 +239,79 @@ //new disorient thing + +#define DISORIENT_BODY 1 +#define DISORIENT_EYE 2 +#define DISORIENT_EAR 4 + +/mob/proc/get_disorient_protection() + .= 0 + + var/res = 0 + for(var/atom in src.get_equipped_items()) + var/obj/item/C = atom + if(C.hasProperty("disorient_resist")) + res = C.getProperty("disorient_resist") + if (res >= 100) + return 100 //a singular item with resistance 100 or higher will block ALL + . += res + + .= clamp(.,0,90) //0 to 90 range + +/mob/proc/get_disorient_protection_eye() + .= 0 + + var/res = 0 + for(var/atom in src.get_equipped_items()) + var/obj/item/C = atom + if(C.hasProperty("disorient_resist_eye")) + res = C.getProperty("disorient_resist_eye") + if (res >= 100) + return 100 //a singular item with resistance 100 or higher will block ALL + . += res + + .= clamp(.,0,90) //90 max! + +/mob/living/get_disorient_protection_eye() + .= ..() + + if (. >= 100) + return . + + if (organHolder)//factor in me eyes + if (organHolder.left_eye) + var/res = organHolder.left_eye.getProperty("disorient_resist_eye") + if (res >= 100) + return 100 + .+= res + if (organHolder.right_eye) + var/res = organHolder.right_eye.getProperty("disorient_resist_eye") + if (res >= 100) + return 100 + .+= res + + .= clamp(.,0,90) + +/mob/proc/get_disorient_protection_ear() + .= 0 + + var/res = 0 + for(var/atom in src.get_equipped_items()) + var/obj/item/C = atom + if(C.hasProperty("disorient_resist_ear")) + res = C.getProperty("disorient_resist_ear") + if (res >= 100) + return 100 //a singular item with resistance 100 or higher will block ALL + . += res + + .= clamp(.,0,90) //0 to 90 range + + /mob/proc/force_laydown_standup() //the real force laydown lives in Life.dm .=0 -/mob/proc/do_disorient(var/stamina_damage, var/weakened, var/stunned, var/paralysis, var/disorient = 60, var/remove_stamina_below_zero = 0) +/mob/proc/do_disorient(var/stamina_damage, var/weakened, var/stunned, var/paralysis, var/disorient = 60, var/remove_stamina_below_zero = 0, var/target_type = DISORIENT_BODY) + .= 1 if (stunned) src.changeStatus("stunned", stunned) if (weakened) @@ -213,12 +319,31 @@ if (paralysis) src.changeStatus("paralysis", paralysis) - if (weakened || paralysis) - src.force_laydown_standup() + src.force_laydown_standup() + if (src.canmove) + .= 0 //Do stamina damage + disorient above 0 stamina. Stun/Weaken/Paralyze when we hit or drop below 0. -/mob/living/carbon/do_disorient(var/stamina_damage, var/weakened, var/stunned, var/paralysis, var/disorient = 60, var/remove_stamina_below_zero = 0) +/mob/living/carbon/do_disorient(var/stamina_damage, var/weakened, var/stunned, var/paralysis, var/disorient = 60, var/remove_stamina_below_zero = 0, var/target_type = DISORIENT_BODY) + var/protection = 0 + + if (target_type & DISORIENT_BODY) + protection = max (protection, get_disorient_protection()) + if (target_type & DISORIENT_EYE) + protection = max (protection, get_disorient_protection_eye()) + if (target_type & DISORIENT_EAR) + protection = max (protection, get_disorient_protection_ear()) + + if (protection >= 100) + return + + var/disorient_mult = 1 - (protection/100) + var/stamdmg_mult = lerp(disorient_mult, 1, 0.25) // apply 3/4 the reduction effect to the stamina damage + + disorient *= disorient_mult + stamina_damage *= stamdmg_mult + if (remove_stamina_below_zero) src.remove_stamina(stamina_damage) else if (src.stamina > 0) @@ -226,7 +351,8 @@ if(src.stamina <= 0) .= 1 - ..() + if (! ..()) //stun failed, do a disorient! + src.changeStatus("disorient", disorient) else .= 0 src.changeStatus("disorient", disorient) diff --git a/code/mob/living/carbon/human.dm b/code/mob/living/carbon/human.dm index 82e46b4..6a1f07e 100644 --- a/code/mob/living/carbon/human.dm +++ b/code/mob/living/carbon/human.dm @@ -122,8 +122,6 @@ var/breathtimer = 0 var/breathstate = 0 - var/datum/light/burning_light - var/obj/item/trinket = null //Used for spy_theft mode - this is an item that is eligible to have a bounty on it //dismemberment stuff @@ -201,10 +199,6 @@ arrestIcon = image('icons/effects/sechud.dmi',src,null,10) arrestIconsAll.Add(arrestIcon) - burning_light = new /datum/light/point - burning_light.attach(src) - burning_light.set_color(0.94, 0.69, 0.27) - src.organHolder = new(src) if (!bioHolder) @@ -834,7 +828,7 @@ if (/obj/item/clothing/suit/armor/heavy) tally += 2 if (/obj/item/clothing/suit/armor/EOD) - tally += 0.5 // i'd like people to actually consider using these + tally += 0.6 // i'd like people to actually consider using these if (/obj/item/clothing/suit/armor/ancient) // cogwerks - new evil armor thing tally += 2 if (/obj/item/clothing/suit/space/emerg) @@ -904,17 +898,7 @@ if (src.limbs.r_leg) tally -= src.limbs.r_leg.effect_modifier - if (src.r_hand && istype(src.r_hand, /obj/item/grab)) - var/obj/item/grab/G = src.r_hand - var/mob/living/carbon/human/H = G.affecting - if (G.state == 0) - if (get_dist(src,H) > 0 && get_dist(move_target,H) > 0) //pasted into living.dm pull slow as well (consider merge somehow) - if(istype(H) && H.intent != INTENT_HELP && H.lying) - tally *= max(H.p_class, 1) - else - tally *= max(H.p_class, 1) - if (src.l_hand && istype(src.l_hand, /obj/item/grab)) - var/obj/item/grab/G = src.l_hand + for (var/obj/item/grab/G in src.equipped_list(check_for_magtractor=0)) var/mob/living/carbon/human/H = G.affecting if (G.state == 0) if (get_dist(src,H) > 0 && get_dist(move_target,H) > 0) //pasted into living.dm pull slow as well (consider merge somehow) @@ -924,14 +908,15 @@ tally *= max(H.p_class, 1) var/has_fluid_move_gear = 0 - for (var/obj/item/I in get_equipped_items()) + for(var/atom in src.get_equipped_items()) + var/obj/item/I = atom tally += I.getProperty("movespeed") has_fluid_move_gear += I.getProperty("negate_fluid_speed_penalty") if (!(src.mutantrace && src.mutantrace.aquatic)) //aquatic race suffers no penalty on dry land OR in fluid var/turf/T = get_turf(src) if (T && has_fluid_move_gear) //add tally : we are on dry land and have gear on - if (! (T.active_liquid || istype(T,/turf/space/fluid)) ) + if (! (T.active_liquid || istype(T,/turf/space/fluid) || istype(T,/turf/simulated/floor/plating/airless/asteroid)) ) tally += has_fluid_move_gear else if (T && !has_fluid_move_gear) //add tally : we are in fluid but have no gear if (T.active_liquid) @@ -1195,9 +1180,10 @@ for(var/mob/M in view(7, item.loc)) shake_camera(M, 20, 1) + if (mob_flags & AT_GUNPOINT) + for(var/obj/item/grab/gunpoint/G in grabbed_by) + G.shoot() - if (src.at_gunpoint) - src.at_gunpoint.shoot_at_gunpoint(src) src.next_click = world.time + src.combat_click_delay /mob/living/carbon/human/click(atom/target, list/params) @@ -1341,8 +1327,9 @@ A.material.triggerOnAttacked(A, M, src, gloves) if (M.a_intent != INTENT_HELP) - if (M.at_gunpoint && M.at_gunpoint.holding_at_gunpoint != M) - M.at_gunpoint.shoot_at_gunpoint(M) + if (M.mob_flags & AT_GUNPOINT) + for(var/obj/item/grab/gunpoint/G in M.grabbed_by) + G.shoot() switch(M.a_intent) if (INTENT_HELP) @@ -2671,10 +2658,19 @@ for (var/obj/item/grab/G in src.grabbed_by) G.do_resist() playsound(src.loc, 'sound/impact_sounds/Generic_Shove_1.ogg', 50, 1) + else + for (var/obj/item/grab/G in src.grabbed_by) + if (G.stunned_targets_can_break()) + G.do_resist() + playsound(src.loc, 'sound/impact_sounds/Generic_Shove_1.ogg', 50, 1) if (!src.grabbed_by || !src.grabbed_by.len) if (src.buckled) src.buckled.attack_hand(src) + src.force_laydown_standup() //safety because buckle code is a mess + if (src.targeting_spell == src.chair_flip_ability) //fuCKKK + src.targeting_spell = null + src.update_cursor() else if (!src.getStatusDuration("burning")) for (var/mob/O in AIviewers(src, null)) @@ -3403,7 +3399,7 @@ else if (priority < 0) priority = src.shoes ? src.shoes.step_sound : "step_barefoot" - playsound(NewLoc, "[priority]", src.m_intent == "run" ? 55 : 35, 1, extrarange = 3) + playsound(NewLoc, "[priority]", src.m_intent == "run" ? 65 : 40, 1, extrarange = 3) //STEP SOUND HANDLING OVER diff --git a/code/mob/living/carbon/human/procs/Life.dm b/code/mob/living/carbon/human/procs/Life.dm index cfcb04f..0c67bc0 100644 --- a/code/mob/living/carbon/human/procs/Life.dm +++ b/code/mob/living/carbon/human/procs/Life.dm @@ -249,7 +249,7 @@ //Status updates, death etc. clamp_values() parent.setLastTask("handle_regular_status_updates", src) - handle_regular_status_updates(parent) + handle_regular_status_updates(parent,mult = (life_time_passed / tick_spacing)) parent.setLastTask("handle_stuns_lying", src) handle_stuns_lying(parent) @@ -414,7 +414,6 @@ if (x.client) src.updateOverlaysClient(x.client) - // Grabbing for (var/obj/item/grab/G in src.equipped_list(check_for_magtractor = 0)) parent.setLastTask("obj/item/grab.process() for [G]") G.process((life_time_passed / tick_spacing)) @@ -423,10 +422,12 @@ //rev mutiny - if (prob(50)) - if (src.mind && ticker.mode && ticker.mode.type == /datum/game_mode/revolution) - var/datum/game_mode/revolution/R = ticker.mode - var/role = src.mind.assigned_role + + if (src.mind && ticker.mode && ticker.mode.type == /datum/game_mode/revolution) + var/datum/game_mode/revolution/R = ticker.mode + var/role = src.mind.assigned_role + + if (prob(50)) if(role in list("Captain", "Head of Security", "Head of Personnel", "Chief Engineer", "Research Director", "Medical Director","Communications Officer")) var/found = 0 for (var/datum/mind/M in R.revolutionaries) @@ -436,23 +437,23 @@ break for (var/datum/mind/M in R.head_revolutionaries) if (M.current && ishuman(M.current)) - if (get_dist(src,M.current) <= 2) + if (get_dist(src,M.current) <= 0) //only if we're being strangled ;) found = 1 break if (found) src.changeStatus("mutiny", 30 SECONDS) - if (src.mind in R.revolutionaries) - var/found = 0 - for (var/datum/mind/M in R.head_revolutionaries) - if (M.current && ishuman(M.current)) - if (get_dist(src,M.current) <= 5) - for (var/obj/item/revolutionary_sign/RS in M.current.equipped_list(check_for_magtractor = 0)) - found = 1 - break - if (found) - src.changeStatus("revspirit", 20 SECONDS) + if (src.mind in R.revolutionaries || src.mind in R.head_revolutionaries) + var/found = 0 + for (var/datum/mind/M in R.head_revolutionaries) + if (M.current && ishuman(M.current)) + if (get_dist(src,M.current) <= 5) + for (var/obj/item/revolutionary_sign/RS in M.current.equipped_list(check_for_magtractor = 0)) + found = 1 + break + if (found) + src.changeStatus("revspirit", 20 SECONDS) @@ -748,43 +749,47 @@ boutput(src, "You are drowning!") var/datum/gas_mixture/environment = loc.return_air() - var/datum/air_group/breath + var/datum/air_group/breath = null // HACK NEED CHANGING LATER //if (src.oxymax == 0 || (breathtimer > 15)) if (breathtimer > 15) src.losebreath += (0.7 * (breath_time_passed / tick_spacing)) - if (losebreath>0) //Suffocating so do not take a breath - src.losebreath -= (1.3 * (breath_time_passed / tick_spacing)) - src.losebreath = max(src.losebreath,0) - if (prob(75)) //High chance of gasping for air - if (underwater) - emote("gurgle") - else emote("gasp") - if (isobj(loc)) - var/obj/location_as_object = loc - location_as_object.handle_internal_lifeform(src, 0) - if (src.losebreath <= 0) - boutput(src, "You catch your breath.") - else - //First, check for air from internal atmosphere (using an air tank and mask generally) - breath = get_breath_from_internal(BREATH_VOLUME) + if (src.grabbed_by && src.grabbed_by.len) + breath = get_breath_grabbed_by(BREATH_VOLUME) - //No breath from internal atmosphere so get breath from location - if (!breath) - if (isobj(loc)) - var/obj/location_as_object = loc - breath = location_as_object.handle_internal_lifeform(src, BREATH_VOLUME) - else if (isturf(loc)) - var/breath_moles = (environment.total_moles()*BREATH_PERCENTAGE) - - breath = loc.remove_air(breath_moles) - - else //Still give containing object the chance to interact - underwater = 0 // internals override underwater state + if (!breath) + if (losebreath>0) //Suffocating so do not take a breath + src.losebreath -= (1.3 * (breath_time_passed / tick_spacing)) + src.losebreath = max(src.losebreath,0) + if (prob(75)) //High chance of gasping for air + if (underwater) + emote("gurgle") + else emote("gasp") if (isobj(loc)) var/obj/location_as_object = loc location_as_object.handle_internal_lifeform(src, 0) + if (src.losebreath <= 0) + boutput(src, "You catch your breath.") + else + //First, check for air from internal atmosphere (using an air tank and mask generally) + breath = get_breath_from_internal(BREATH_VOLUME) + + //No breath from internal atmosphere so get breath from location + if (!breath) + if (isobj(loc)) + var/obj/location_as_object = loc + breath = location_as_object.handle_internal_lifeform(src, BREATH_VOLUME) + else if (isturf(loc)) + var/breath_moles = (environment.total_moles()*BREATH_PERCENTAGE) + + breath = loc.remove_air(breath_moles) + + else //Still give containing object the chance to interact + underwater = 0 // internals override underwater state + if (isobj(loc)) + var/obj/location_as_object = loc + location_as_object.handle_internal_lifeform(src, 0) handle_breath(breath, underwater, mult = (breath_time_passed / tick_spacing)) @@ -793,6 +798,12 @@ last_breath_process = world.timeofday + proc/get_breath_grabbed_by(volume_needed) + .= null + for(var/obj/item/grab/force_mask/G in src.grabbed_by) + .= G.get_breath(volume_needed) + if (.) + break proc/get_breath_from_internal(volume_needed) if (internal) @@ -809,10 +820,11 @@ else if (src.internals) src.internals.icon_state = "internal0" + return null proc/update_canmove() - if (hasStatus("paralysis") || hasStatus("stunned") || hasStatus("weakened")) + if (hasStatus("paralysis") || hasStatus("stunned") || hasStatus("weakened") || hasStatus("pinned")) canmove = 0 return @@ -825,6 +837,16 @@ canmove = 0 return + if (throwing & (THROW_CHAIRFLIP | THROW_GUNIMPACT)) + canmove = 0 + return + + //cant move while we pin someone down + for (var/obj/item/grab/G in src.equipped_list(check_for_magtractor = 0)) + if (G.state == GRAB_PIN) + canmove = 0 + return + canmove = 1 proc/handle_breath(datum/gas_mixture/breath, var/atom/underwater = 0, var/mult = 1) //'underwater' really applies for any reagent that gets deep enough. but what ever @@ -894,6 +916,9 @@ take_oxygen_deprivation(3 * mult) hud.update_oxy_indicator(1) else // We're in safe limits + //if (breath.oxygen/breath.total_moles() >= 0.95) //high oxygen concentration. lets slightly heal oxy damage because it feels right + // take_oxygen_deprivation(-6 * mult) + take_oxygen_deprivation(-6 * mult) oxygen_used = breath.oxygen/6 hud.update_oxy_indicator(0) @@ -1045,7 +1070,8 @@ thermal_protection += 10 // Resistance from Clothing - for (var/obj/item/C in src.get_equipped_items()) + for(var/atom in src.get_equipped_items()) + var/obj/item/C = atom thermal_protection += C.getProperty("coldprot") /* @@ -1093,7 +1119,8 @@ if (src.eyes_protected_from_light()) resist_prob += 190 - for (var/obj/item/C in src.get_equipped_items()) + for(var/atom in src.get_equipped_items()) + var/obj/item/C = atom resist_prob += C.getProperty("viralprot") if(src.getStatusDuration("food_disease_resist")) @@ -1110,7 +1137,8 @@ var/rad_protection = 0 // Resistance from Clothing - for (var/obj/item/C in src.get_equipped_items()) + for(var/atom in src.get_equipped_items()) + var/obj/item/C = atom rad_protection += C.getProperty("radprot") if (bioHolder && bioHolder.HasEffect("food_rad_resist")) @@ -1126,7 +1154,8 @@ var/protection = 1 // Resistance from Clothing - for (var/obj/item/C in src.get_equipped_items()) + for(var/atom in src.get_equipped_items()) + var/obj/item/C = atom if(C.hasProperty("rangedprot")) var/curr = C.getProperty("rangedprot") protection += curr @@ -1146,7 +1175,8 @@ thermal_protection += 10 // Resistance from Clothing - for (var/obj/item/C in src.get_equipped_items()) + for(var/atom in src.get_equipped_items()) + var/obj/item/C = atom thermal_protection += C.getProperty("heatprot") /* @@ -1519,15 +1549,9 @@ oH.heart = null else if (oH.heart.robotic && oH.heart.emagged && !oH.heart.broken) src.drowsyness = max (src.drowsyness - 8, 0) - changeStatus("paralysis", -2 SECONDS) - changeStatus("stunned", -2 SECONDS) - changeStatus("weakened", -2 SECONDS) if (src.sleeping) src.sleeping = 0 else if (oH.heart.robotic && !oH.heart.broken) src.drowsyness = max (src.drowsyness - 4, 0) - changeStatus("paralysis", -1 SECONDS) - changeStatus("stunned", -1 SECONDS) - changeStatus("weakened", -1 SECONDS) if (src.sleeping) src.sleeping = 0 else if (oH.heart.broken) if (src.get_oxygen_deprivation()) @@ -1544,21 +1568,10 @@ // lungs are skipped until they can be removed/whatever - proc/handle_regular_status_updates(datum/controller/process/mobs/parent) - - health = max_health - (get_oxygen_deprivation() + get_toxin_damage() + get_burn_damage() + get_brute_damage()) - - // I don't think the revenant needs any of this crap - Marq - if (src.bioHolder && src.bioHolder.HasEffect("revenant") || isdead(src)) //You also don't need to do a whole lot of this if the dude's dead. - return - + handle_stamina_updates() if (stamina == STAMINA_NEG_CAP) setStatus("paralysis", max(getStatusDuration("paralysis"), STAMINA_NEG_CAP_STUN_TIME)) - //maximum modifiers. - stamina_max = max((STAMINA_MAX + src.get_stam_mod_max()), 0) - stamina = min(stamina, stamina_max) - //Modify stamina. var/stam_time_passed = max(tick_spacing, world.timeofday - last_stam_change) @@ -1570,9 +1583,25 @@ last_stam_change = world.timeofday + if (src.stamina_bar && src.client) + src.stamina_bar.update_value(src) + + + proc/handle_regular_status_updates(datum/controller/process/mobs/parent,var/mult = 1) + + health = max_health - (get_oxygen_deprivation() + get_toxin_damage() + get_burn_damage() + get_brute_damage()) + + // I don't think the revenant needs any of this crap - Marq + if (src.bioHolder && src.bioHolder.HasEffect("revenant") || isdead(src)) //You also don't need to do a whole lot of this if the dude's dead. + return + + //maximum stamina modifiers. + stamina_max = max((STAMINA_MAX + src.get_stam_mod_max()), 0) + stamina = min(stamina, stamina_max) + parent.setLastTask("status_updates implants organs and augmentations check", src) for (var/obj/item/implant/I in src.implant) - I.on_life((stam_time_passed / tick_spacing)) + I.on_life(mult) //parent.setLastTask("status_updates max value calcs", src) @@ -1796,13 +1825,13 @@ changeling_fakedeath = 1 if (!isdead(src)) //Alive. - if (src.hasStatus("paralysis") || src.hasStatus("stunned") || src.hasStatus("weakened") || changeling_fakedeath || src.resting) //Stunned etc. + if (src.hasStatus("paralysis") || src.hasStatus("stunned") || src.hasStatus("weakened") || hasStatus("pinned") || changeling_fakedeath || src.resting) //Stunned etc. parent.setLastTask("status_updates lying/standing checks stun calcs") var/setStat = src.stat var/oldStat = src.stat if (src.hasStatus("stunned")) setStat = 0 - if (src.hasStatus("weakened") && !src.fakedead) + if (src.hasStatus("weakened") || src.hasStatus("pinned") && !src.fakedead) if (!cant_lie) src.lying = 1 setStat = 0 if (src.hasStatus("paralysis")) diff --git a/code/mob/living/carbon/human/procs/emote.dm b/code/mob/living/carbon/human/procs/emote.dm index aa5ca3c..0e0c0b9 100644 --- a/code/mob/living/carbon/human/procs/emote.dm +++ b/code/mob/living/carbon/human/procs/emote.dm @@ -883,7 +883,8 @@ m_type = 1 if ("wink") - for (var/obj/item/clothing/C in src.get_equipped_items()) + for(var/atom in src.get_equipped_items()) + var/obj/item/C = atom if ((locate(/obj/item/gun/kinetic/derringer) in C) != null) var/obj/item/gun/kinetic/derringer/D = (locate(/obj/item/gun/kinetic/derringer) in C) var/drophand = (src.hand == 0 ? slot_r_hand : slot_l_hand) @@ -1074,7 +1075,7 @@ playsound(get_turf(src), "sound/effects/bubbles.ogg", 80, 1) if ("flip") - if (src.emote_check(voluntary, 50) && !src.shrunk) + if (src.emote_check(voluntary, 50)) //TODO: space flipping //if ((!src.restrained()) && (!src.lying) && (istype(src.loc, /turf/space))) @@ -1100,11 +1101,13 @@ src.changeStatus("weakened", 2 SECONDS) src.set_stamina(min(1, src.stamina)) src.emote_allowed = 0 + SPAWN_DBG(1 SECONDS) + src.emote_allowed = 1 goto showmessage - if (isvampire(src)) - var/datum/abilityHolder/vampire/V = get_ability_holder(/datum/abilityHolder/vampire) - V.launch_bat_orbiters() + + if (src.targeting_spell) + src.targeting_spell.flip_callback() if ((!istype(src.loc, /turf/space)) && (!src.on_chair)) if (!src.lying) @@ -1125,12 +1128,12 @@ src.remove_stamina(STAMINA_FLIP_COST * 2.0) message = "[src] does a tactical flip!" src.stance = "dodge" - SPAWN_DBG(2) //I'm sorry for my transgressions there's probably a way better way to do this + SPAWN_DBG(0.2 SECONDS) //I'm sorry for my transgressions there's probably a way better way to do this if(src && src.stance == "dodge") src.stance = "normal" //FLIP OVER TABLES - if (iswrestler(src) && !istype(usr.equipped(), /obj/item/grab)) + if (iswrestler(src) && !istype(src.equipped(), /obj/item/grab)) for (var/obj/table/T in oview(1, null)) if ((src.dir == get_dir(src, T))) T.set_density(0) @@ -1142,168 +1145,103 @@ src.set_loc(newloc) message = "[src] flips onto [T]!" - - for (var/mob/living/M in view(1, null)) - var/obj/item/grab/G = usr.equipped() + var/flipped_a_guy = 0 + for (var/obj/item/grab/G in src.equipped_list(check_for_magtractor = 0)) + var/mob/living/M = G.affecting if (M == src) continue - if (istype(usr.equipped(), /obj/item/grab)) - if (!G.affecting) //Wire note: Fix for Cannot read null.loc + if (!G.affecting) //Wire note: Fix for Cannot read null.loc + continue + flipped_a_guy = 1 + if (G.state >= 1 && isturf(src.loc) && isturf(G.affecting.loc)) + var/obj/table/tabl = locate() in src.loc.contents + var/turf/newloc = src.loc + G.affecting.set_loc(newloc) + if (!G.affecting.reagents.has_reagent("fliptonium")) + animate_spin(src, prob(50) ? "L" : "R", 1, 0) + + if (!iswrestler(src) && src.traitHolder && !src.traitHolder.hasTrait("glasscannon")) + src.remove_stamina(STAMINA_FLIP_COST) + src.stamina_stun() + + src.emote("scream") + message = "[src] suplexes [G.affecting][tabl ? " into [tabl]" : null]!" + logTheThing("combat", src, G.affecting, "suplexes %target%[tabl ? " into \an [tabl]" : null] [log_loc(src)]") + M.lastattacker = src + M.lastattackertime = world.time + if (iswrestler(src)) + if (prob(50)) + M.ex_act(3) // this is hilariously overpowered, but WHATEVER!!! + else + G.affecting.changeStatus("stunned", 50) + G.affecting.changeStatus("weakened", 5 SECONDS) + G.affecting.force_laydown_standup() + G.affecting.TakeDamage("head", 10, 0, 0, DAMAGE_BLUNT) + playsound(src.loc, "sound/impact_sounds/Flesh_Break_1.ogg", 75, 1) + else + src.changeStatus("weakened", 3.5 SECONDS) + + if (client && client.hellbanned) + src.changeStatus("weakened", 4 SECONDS) + if (!G.affecting.hasStatus("weakened")) + G.affecting.changeStatus("weakened", 4.5 SECONDS) + + + G.affecting.force_laydown_standup() + SPAWN_DBG(1 SECONDS) //let us do that combo shit people like with throwing + src.force_laydown_standup() + + G.affecting.TakeDamage("head", 9, 0, 0, DAMAGE_BLUNT) + playsound(src.loc, "sound/impact_sounds/Flesh_Break_1.ogg", 75, 1) + if (tabl) + if (istype(tabl, /obj/table/glass)) + var/obj/table/glass/g_tabl = tabl + if (!g_tabl.glass_broken) + if ((prob(g_tabl.reinforced ? 60 : 80)) || (src.bioHolder.HasEffect("clumsy") && (!g_tabl.reinforced || prob(90))) || ((src.bioHolder.HasEffect("fat") || G.affecting.bioHolder.HasEffect("fat")) && (!g_tabl.reinforced || prob(90)))) + SPAWN_DBG(0) + g_tabl.smash() + src.changeStatus("stunned", 7 SECONDS) + src.changeStatus("weakened", 6 SECONDS) + random_brute_damage(src, rand(20,40)) + take_bleeding_damage(src, src, rand(20,40)) + + G.affecting.changeStatus("stunned", 2 SECONDS) + G.affecting.changeStatus("weakened", 4 SECONDS) + random_brute_damage(G.affecting, rand(20,40)) + take_bleeding_damage(G.affecting, src, rand(20,40)) + + + G.affecting.force_laydown_standup() + SPAWN_DBG(1 SECONDS) //let us do that combo shit people like with throwing + src.force_laydown_standup() + + if (G && G.state < 1) //ZeWaka: Fix for null.state + var/turf/oldloc = src.loc + var/turf/newloc = G.affecting.loc + src.set_loc(newloc) + G.affecting.set_loc(oldloc) + message = "[src] flips over [G.affecting]!" + if (!flipped_a_guy) + for (var/mob/living/M in view(1, null)) + if (M == src) continue - - if (G.state >= 1 && isturf(src.loc) && isturf(G.affecting.loc)) - var/obj/table/tabl = locate() in src.loc.contents - var/turf/newloc = src.loc - G.affecting.set_loc(newloc) - if (!G.affecting.reagents.has_reagent("fliptonium")) - animate_spin(src, prob(50) ? "L" : "R", 1, 0) - + if (src.reagents && src.reagents.get_reagent_amount("ethanol") > 10) if (!iswrestler(src) && src.traitHolder && !src.traitHolder.hasTrait("glasscannon")) src.remove_stamina(STAMINA_FLIP_COST) src.stamina_stun() - src.emote("scream") - message = "[src] suplexes [G.affecting][tabl ? " into [tabl]" : null]!" - logTheThing("combat", src, G.affecting, "suplexes %target%[tabl ? " into \an [tabl]" : null] [log_loc(src)]") - M.lastattacker = src - M.lastattackertime = world.time - if (iswrestler(src)) - if (prob(50)) - M.ex_act(3) // this is hilariously overpowered, but WHATEVER!!! - else - G.affecting.changeStatus("stunned", 50) - G.affecting.changeStatus("weakened", 5 SECONDS) - G.affecting.force_laydown_standup() - G.affecting.TakeDamage("head", 10, 0, 0, DAMAGE_BLUNT) - playsound(src.loc, "sound/impact_sounds/Flesh_Break_1.ogg", 75, 1) - else - src.changeStatus("weakened", 3 SECONDS) - - if (client && client.hellbanned) - src.changeStatus("weakened", 4 SECONDS) - if (!G.affecting.hasStatus("weakened")) - G.affecting.changeStatus("weakened", 5 SECONDS) - - - G.affecting.force_laydown_standup() - SPAWN_DBG(10) //let us do that combo shit people like with throwing - src.force_laydown_standup() - - G.affecting.TakeDamage("head", 9, 0, 0, DAMAGE_BLUNT) - playsound(src.loc, "sound/impact_sounds/Flesh_Break_1.ogg", 75, 1) - if (tabl) - if (istype(tabl, /obj/table/glass)) - var/obj/table/glass/g_tabl = tabl - if (!g_tabl.glass_broken) - if ((prob(g_tabl.reinforced ? 60 : 80)) || (src.bioHolder.HasEffect("clumsy") && (!g_tabl.reinforced || prob(90))) || ((src.bioHolder.HasEffect("fat") || G.affecting.bioHolder.HasEffect("fat")) && (!g_tabl.reinforced || prob(90)))) - SPAWN_DBG(0) - g_tabl.smash() - src.changeStatus("stunned", 7 SECONDS) - src.changeStatus("weakened", 6 SECONDS) - random_brute_damage(src, rand(20,40)) - take_bleeding_damage(src, src, rand(20,40)) - - G.affecting.changeStatus("stunned", 2 SECONDS) - G.affecting.changeStatus("weakened", 4 SECONDS) - random_brute_damage(G.affecting, rand(20,40)) - take_bleeding_damage(G.affecting, src, rand(20,40)) - - - G.affecting.force_laydown_standup() - SPAWN_DBG(10) //let us do that combo shit people like with throwing - src.force_laydown_standup() - - if (G && G.state < 1) //ZeWaka: Fix for null.state - var/turf/oldloc = src.loc - var/turf/newloc = G.affecting.loc + message = "[src] flips into [M]!" + logTheThing("combat", src, M, "flips into %target%") + src.changeStatus("weakened", 6 SECONDS) + src.TakeDamage("head", 4, 0, 0, DAMAGE_BLUNT) + M.changeStatus("weakened", 2 SECONDS) + M.TakeDamage("head", 2, 0, 0, DAMAGE_BLUNT) + playsound(src.loc, pick(sounds_punch), 100, 1) + var/turf/newloc = M.loc src.set_loc(newloc) - G.affecting.set_loc(oldloc) - message = "[src] flips over [G.affecting]!" - else if (src.reagents && src.reagents.get_reagent_amount("ethanol") > 10) - if (!iswrestler(src) && src.traitHolder && !src.traitHolder.hasTrait("glasscannon")) - src.remove_stamina(STAMINA_FLIP_COST) - src.stamina_stun() - - message = "[src] flips into [M]!" - logTheThing("combat", src, M, "flips into %target%") - src.changeStatus("weakened", 6 SECONDS) - src.TakeDamage("head", 4, 0, 0, DAMAGE_BLUNT) - M.changeStatus("weakened", 2 SECONDS) - M.TakeDamage("head", 2, 0, 0, DAMAGE_BLUNT) - playsound(src.loc, pick(sounds_punch), 100, 1) - var/turf/newloc = M.loc - src.set_loc(newloc) - else - message = "[src] flips in [M]'s general direction." - break - - if (src.on_chair)// == 1) - if (src.on_chair.loc != src.loc) - src.pixel_y = 0 - src.anchored = 0 - src.on_chair = 0 - src.buckled = null - else - //CHAIR FLIPPING LOOP - for (var/mob/living/M in oview(3)) - if (M == src) - continue - - if (!istype(usr.equipped(), /obj/item/grab)) - src.pixel_y = 0 - src.buckled = null - src.anchored = 0 - . = 1 - if (M && M.loc != src.loc) // just in case, so the user doesn't fall into nullspace if they fly at a person mid-gibbing or whatever - var/list/flipLine = getline(src, M) - for (var/turf/T in flipLine) - if (!istype(src.loc, /turf) || T.density || T.loc:sanctuary || LinkBlockedWithAccess(src.loc, T)) - message = "[src] does a flying flip...into the ground. Like a big doofus." - src.changeStatus("weakened", 5 SECONDS) - . = 0 - break - else - src.set_loc(T) - - src.emote("scream") - src.on_chair = 0 - - if (!iswrestler(src) && src.traitHolder && !src.traitHolder.hasTrait("glasscannon")) - src.remove_stamina(STAMINA_FLIP_COST) - src.stamina_stun() - - if (.) - playsound(src.loc, "sound/impact_sounds/Flesh_Break_1.ogg", 75, 1) - message = "[src] does a flying flip into [M]!" - logTheThing("combat", src, M, "[src] chairflips into %target%, [showCoords(M.x, M.y, M.z)].") - M.lastattacker = src - M.lastattackertime = world.time - - if (iswrestler(src)) - if (prob(33)) - M.ex_act(3) - else - random_brute_damage(M, 25) - M.changeStatus("weakened", 7 SECONDS) - M.changeStatus("stunned", 7 SECONDS) - else if (M.traitHolder.hasTrait("training_security")) - message = "[src] does a flying flip into [M], but [M] skillfully slings them away!" - src.changeStatus("weakened", 6 SECONDS) - src.changeStatus("stunned", 6 SECONDS) - var/atom/target = get_edge_target_turf(M, M.dir) - src.throw_at(target, 3, 10) - else - random_brute_damage(M, 10) - if (!M.hasStatus("weakened")) - M.changeStatus("weakened", 4 SECONDS) - M.changeStatus("stunned", 4 SECONDS) - src.changeStatus("weakened", 3 SECONDS) - src.changeStatus("stunned", 3 SECONDS) - - if (!src.reagents.has_reagent("fliptonium")) - animate_spin(src, prob(50) ? "L" : "R", 1, 0) - break - + else + message = "[src] flips in [M]'s general direction." + break if (src.lying) message = "[src] flops on the floor like a fish." @@ -1360,9 +1298,9 @@ M.TakeDamage("chest", 0, 20, 0, DAMAGE_BURN) src.charges -= 1 if (narrator_mode) - playsound(src.loc, 'sound/vox/bloop.ogg', 100, 0, 0, src.get_age_pitch()) + playsound(src.loc, 'sound/vox/bloop.ogg', 70, 0, 0, src.get_age_pitch()) else - playsound(get_turf(src), src.sound_burp, 100, 0, 0, src.get_age_pitch()) + playsound(get_turf(src), src.sound_burp, 70, 0, 0, src.get_age_pitch()) return else if ((src.charges >= 1) && (muzzled)) for (var/mob/O in viewers(src, null)) @@ -1374,12 +1312,12 @@ message = "[src] burps." m_type = 2 if (narrator_mode) - playsound(src.loc, 'sound/vox/bloop.ogg', 100, 0, 0, src.get_age_pitch()) + playsound(src.loc, 'sound/vox/bloop.ogg', 70, 0, 0, src.get_age_pitch()) else if (src.getStatusDuration("food_deep_burp")) - playsound(get_turf(src), src.sound_burp, 100, 0, 0, src.get_age_pitch() * 0.5) + playsound(get_turf(src), src.sound_burp, 70, 0, 0, src.get_age_pitch() * 0.5) else - playsound(get_turf(src), src.sound_burp, 100, 0, 0, src.get_age_pitch()) + playsound(get_turf(src), src.sound_burp, 70, 0, 0, src.get_age_pitch()) var/datum/statusEffect/fire_burp/FB = src.hasStatus("food_fireburp") if (!FB) @@ -1520,17 +1458,17 @@ if (iscluwne(src)) playsound(get_turf(src), "sound/voice/farts/poo.ogg", 50, 1) else if (src.organ_istype("butt", /obj/item/clothing/head/butt/cyberbutt)) - playsound(get_turf(src), "sound/voice/farts/poo2_robot.ogg", 100, 1, 0, src.get_age_pitch()) + playsound(get_turf(src), "sound/voice/farts/poo2_robot.ogg", 50, 1, 0, src.get_age_pitch()) else if (src.reagents && src.reagents.has_reagent("honk_fart")) playsound(src.loc, 'sound/musical_instruments/Bikehorn_1.ogg', 50, 1, -1) else if (narrator_mode) - playsound(get_turf(src), 'sound/vox/fart.ogg', 100, 0, 0, src.get_age_pitch()) + playsound(get_turf(src), 'sound/vox/fart.ogg', 50, 0, 0, src.get_age_pitch()) else if (src.getStatusDuration("food_deep_fart")) - playsound(get_turf(src), src.sound_fart, 100, 0, 0, src.get_age_pitch() - 0.3) + playsound(get_turf(src), src.sound_fart, 50, 0, 0, src.get_age_pitch() - 0.3) else - playsound(get_turf(src), src.sound_fart, 100, 0, 0, src.get_age_pitch()) + playsound(get_turf(src), src.sound_fart, 50, 0, 0, src.get_age_pitch()) if(src.loc && istype(src.loc, /turf/simulated/floor/specialroom/freezer) && prob(10)) //ZeWaka: Fix for null.loc message = "[src] farts. The fart freezes in MID-AIR!!!" diff --git a/code/mob/living/carbon/human/procs/update_icon.dm b/code/mob/living/carbon/human/procs/update_icon.dm index 9484124..4171119 100644 --- a/code/mob/living/carbon/human/procs/update_icon.dm +++ b/code/mob/living/carbon/human/procs/update_icon.dm @@ -696,11 +696,10 @@ src.fire_standing = SafeGetOverlayImage("fire", 'icons/mob/human.dmi', istate, MOB_EFFECT_LAYER) //make them light up! - burning_light.set_brightness(round(0.5 + (getStatusDuration("burning")/ 10) / 150, 0.1)) - burning_light.enable() + add_simple_light("burning", list(255,110,135,255/2 + (round(0.5 + (getStatusDuration("burning")/ 10) / 150, 0.1))*255/2 )) else src.fire_standing = null - burning_light.disable() + remove_simple_light("burning") UpdateOverlays(src.fire_standing, "fire", 0, 1) diff --git a/code/mob/living/critter.dm b/code/mob/living/critter.dm index 8000560..a0a8311 100644 --- a/code/mob/living/critter.dm +++ b/code/mob/living/critter.dm @@ -500,8 +500,9 @@ else if (HH.can_attack) if (ismob(target)) if (a_intent != INTENT_HELP) - if (src.at_gunpoint && src.at_gunpoint.holding_at_gunpoint != src) - src.at_gunpoint.shoot_at_gunpoint(src) + if (mob_flags & AT_GUNPOINT) + for(var/obj/item/grab/gunpoint/G in grabbed_by) + G.shoot() switch (a_intent) if (INTENT_HELP) if (can_help) @@ -729,7 +730,7 @@ var/datum/healthHolder/HH = healthlist[T] HH.Life() - for (var/obj/item/grab/G in src) + for (var/obj/item/grab/G in src.equipped_list(check_for_magtractor = 0)) G.process() if (stat) diff --git a/code/mob/living/object.dm b/code/mob/living/object.dm index 692966b..99e4dbb 100644 --- a/code/mob/living/object.dm +++ b/code/mob/living/object.dm @@ -96,6 +96,11 @@ src.visible_message("[possessed] comes to life!") // was [src] but: "the living space thing comes alive!" animate_levitate(src, -1, 20, 1) + src.add_stun_resist_mod("living_object", 1000) + + disposing() + src.remove_stun_resist_mod("living_object") + ..() equipped() if (canattack) @@ -137,9 +142,6 @@ // if (owner.abilityHolder.usesPoints) // owner.abilityHolder.generatePoints(mult = (life_time_passed / life_tick_spacing)) - delStatus("weakened") - delStatus("paralysis") - delStatus("stunned") delStatus("slowed") sleeping = 0 change_misstep_chance(-INFINITY) diff --git a/code/mob/living/silicon/robot.dm b/code/mob/living/silicon/robot.dm index 29de912..b07be4c 100644 --- a/code/mob/living/silicon/robot.dm +++ b/code/mob/living/silicon/robot.dm @@ -13,6 +13,7 @@ icon = 'icons/mob/robots.dmi' icon_state = "robot" health = 300 + // max_health = 300 emaggable = 1 syndicate_possible = 1 @@ -217,6 +218,7 @@ process_killswitch() process_locks() + process_oil() if (src.client) //ov1 // overlays @@ -670,7 +672,7 @@ if (src.shell && src.mainframe) src.real_name = "SHELL/[src.mainframe]" src.name = src.real_name - + update_clothing() update_appearance() return @@ -1147,7 +1149,7 @@ SPAWN_DBG(10) qdel(oldmob) else if (isalive(oldmob)) // if they're not in the afterlife bar or a VR ghost and still alive, then maybe don't pull them into this borg - return + return if (B.owner.current.client) src.lastKnownIP = B.owner.current.client.address B.owner.transfer_to(src) @@ -1636,6 +1638,10 @@ if (src.part_leg_r) tally *= 0.75 if (src.part_leg_l) tally *= 0.75 + //This is how it's done in humans, but since borg max health is a bunch of nonsense, I'm not going to add it. + // var/health_deficiency = (src.max_health - src.health) + // if (health_deficiency >= 90) tally += (health_deficiency / 25) + tally *= pull_speed_modifier(move_target) return tally @@ -2246,12 +2252,6 @@ if (isalive(src)) src.lastgasp() // calling lastgasp() here because we just got knocked out setunconscious(src) - if (src.getStatusDuration("stunned") > 0) - if (src.oil) src.changeStatus("stunned", -10) - if (src.getStatusDuration("weakened") > 0) - if (src.oil) src.changeStatus("weakened", -10) - if (src.getStatusDuration("paralysis")) - if (src.oil) src.changeStatus("paralysis", -10) else setalive(src) if (src.misstep_chance > 0) @@ -2265,7 +2265,16 @@ if (src.dizziness) dizziness-- - if (src.oil) src.oil-- + proc/add_oil(var/amt) + if (oil <= 0) + src.add_stun_resist_mod("robot_oil", 25) + src.oil += amt + + proc/process_oil() + src.oil -= 1 + if (oil <= 0) + oil = 0 + src.remove_stun_resist_mod("robot_oil", 25) proc/handle_regular_status_updates() if(src.stat) src.camera.camera_status = 0.0 @@ -3153,3 +3162,65 @@ /client/proc/set_screen_color_to_red() src.color = "#ff0000" + + +#define can_step_sfx(H) (H.footstep >= 4 || (H.m_intent != "run" && H.footstep >= 3)) + +/mob/living/silicon/robot/Move(var/turf/NewLoc, direct) + //var/oldloc = loc + . = ..() + + if (.) + //STEP SOUND HANDLING + if ((src.part_leg_r || src.part_leg_l) && isturf(NewLoc) && NewLoc.turf_flags & MOB_STEP) + /*if (NewLoc.active_liquid) //todo : hydraulic robot fluid splash step + if (NewLoc.active_liquid.step_sound) + if (src.m_intent == "run") + if (src.footstep >= 4) + src.footstep = 0 + else + src.footstep++ + if (src.footstep == 0) + playsound(NewLoc, NewLoc.active_liquid.step_sound, 50, 1) + else + if (src.footstep >= 2) + src.footstep = 0 + else + src.footstep++ + if (src.footstep == 0) + playsound(NewLoc, NewLoc.active_liquid.step_sound, 20, 1) + */ + src.footstep++ + if (can_step_sfx(src)) + var/obj/item/parts/robot_parts/leg/leg = null + if (prob(50) && part_leg_l) + leg = part_leg_l + else if (part_leg_r) + leg = part_leg_r + + src.footstep = 0 + if (NewLoc.step_material || !leg || (leg && leg.step_sound)) + var/priority = 0 + + if (!NewLoc.step_material) + priority = -1 + else if (leg && !leg.step_sound) + priority = 1 + + if (!priority) //now we must resolve bc the floor and the shoe both wanna make noise + if (!leg) //barefoot + priority = (STEP_PRIORITY_MAX > NewLoc.step_priority) ? -1 : 1 + else //shoed + priority = (leg.step_priority > NewLoc.step_priority) ? -1 : 1 + + if (priority) + if (priority > 0) + priority = NewLoc.step_material + else if (priority < 0) + priority = leg ? leg.step_sound : "step_robo" + + playsound(NewLoc, "[priority]", src.m_intent == "run" ? 65 : 40, 1, extrarange = 3) + + //STEP SOUND HANDLING OVER + +#undef can_step_sfx diff --git a/code/mob/melee_attack_procs.dm b/code/mob/melee_attack_procs.dm index 08509ef..60d42cb 100644 --- a/code/mob/melee_attack_procs.dm +++ b/code/mob/melee_attack_procs.dm @@ -165,7 +165,7 @@ src.visible_message("[src] tweaks [his_or_her(src)] own nipples! That's [pick_string("tweak_yo_self.txt", "tweakadj")] [pick_string("tweak_yo_self.txt", "tweak")]!") -/mob/living/proc/grab_other(var/mob/living/target, var/suppress_final_message = 0) +/mob/living/proc/grab_other(var/mob/living/target, var/suppress_final_message = 0, var/obj/item/grab_item = null) if(!src || !target) return 0 @@ -213,15 +213,30 @@ var/datum/pathogen/P = H.pathogens[uid] P.ongrab(target) - var/obj/item/grab/G = new /obj/item/grab(src) - G.assailant = src - src.put_in_hand(G, src.hand) - G.affecting = target - target.grabbed_by += G + if (!grab_item) + var/obj/item/grab/G = new /obj/item/grab(src) + G.assailant = src + src.put_in_hand(G, src.hand) + G.affecting = target + target.grabbed_by += G + else// special. return it too + if (!grab_item.special_grab) + return + var/obj/item/grab/G = new grab_item.special_grab(grab_item) + G.assailant = src + G.affecting = target + target.grabbed_by += G + G.loc = grab_item + .= G playsound(target.loc, 'sound/impact_sounds/Generic_Shove_1.ogg', 50, 1, -1) - if (suppress_final_message != 1) // Melee-focused roles (resp. their limb datums) grab the target aggressively (Convair880). - target.visible_message("[src] grabs hold of [target]!") + if (!suppress_final_message) // Melee-focused roles (resp. their limb datums) grab the target aggressively (Convair880). + if (grab_item) + target.visible_message("[src] grabs hold of [target] with [grab_item]!") + else + target.visible_message("[src] grabs hold of [target]!") + + ///////////////////////////////////////////////////// Disarm intent //////////////////////////////////////////////// @@ -408,12 +423,9 @@ var/ret = 0 if(getStatusDuration("stonerit")) ret += 20 - for(var/obj/item/C in src.get_equipped_items()) + for(var/atom in src.get_equipped_items()) + var/obj/item/C = atom ret += C.getProperty("block") - if(istype(l_hand, /obj/item)) - ret += l_hand.getProperty("block") - if(istype(r_hand, /obj/item)) - ret += r_hand.getProperty("block") return ret /////////////////////////////////////////////////// Harm intent //////////////////////////////////////////////////////// diff --git a/code/modules/atmospherics/machinery/retrofilter.dm b/code/modules/atmospherics/machinery/retrofilter.dm index 36f5174..8a1c7d6 100644 --- a/code/modules/atmospherics/machinery/retrofilter.dm +++ b/code/modules/atmospherics/machinery/retrofilter.dm @@ -11,6 +11,7 @@ obj/machinery/atmospherics/retrofilter initialize_directions = SOUTH|NORTH|WEST req_access = list(access_engineering_atmos) + object_flags = CAN_REPROGRAM_ACCESS var/datum/gas_mixture/air_in var/datum/gas_mixture/air_out1 diff --git a/code/modules/atmospherics/portable/pump.dm b/code/modules/atmospherics/portable/pump.dm index fe2e5be..f40510b 100644 --- a/code/modules/atmospherics/portable/pump.dm +++ b/code/modules/atmospherics/portable/pump.dm @@ -5,6 +5,7 @@ icon_state = "psiphon:0" density = 1 mats = 12 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_WELDER var/on = 0 var/direction_out = 0 //0 = siphoning, 1 = releasing var/target_pressure = 100 diff --git a/code/modules/atmospherics/portable/scrubber.dm b/code/modules/atmospherics/portable/scrubber.dm index 151cd99..c94125d 100644 --- a/code/modules/atmospherics/portable/scrubber.dm +++ b/code/modules/atmospherics/portable/scrubber.dm @@ -8,6 +8,7 @@ var/on = 0 var/volume_rate = 800 mats = 12 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_WELDER volume = 750 desc = "A device which filters out harmful air from an area." p_class = 1.5 diff --git a/code/modules/chemistry/Chemistry-Dispenser.dm b/code/modules/chemistry/Chemistry-Dispenser.dm index 06d33a5..825c82b 100644 --- a/code/modules/chemistry/Chemistry-Dispenser.dm +++ b/code/modules/chemistry/Chemistry-Dispenser.dm @@ -42,6 +42,7 @@ var/icon_base = "dispenser" flags = NOSPLASH mats = 30 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_WIRECUTTERS | DECON_MULTITOOL var/beaker = null var/list/dispensable_reagents = list("aluminium","barium","bromine","carbon","calcium","chlorine", \ "chromium","copper","ethanol","fluorine","hydrogen", \ diff --git a/code/modules/chemistry/Chemistry-Holder.dm b/code/modules/chemistry/Chemistry-Holder.dm index 71344bc..68d2204 100644 --- a/code/modules/chemistry/Chemistry-Holder.dm +++ b/code/modules/chemistry/Chemistry-Holder.dm @@ -55,6 +55,7 @@ datum var/covered_cache_volume = 0 var/temperature_cap = 10000 + var/temperature_min = 0 var/postfoam = 0 //attempt at killing infinite foam @@ -120,7 +121,7 @@ datum else if (exposed_temperature < total_temperature) total_temperature -= change - total_temperature = max(min(total_temperature, temperature_cap), 0) //Cap for the moment. + total_temperature = max(min(total_temperature, temperature_cap), temperature_min) //Cap for the moment. temperature_react() handle_reactions() @@ -975,7 +976,8 @@ datum //there were two different implementations, one of which didn't work, so i moved the working one here and both call it now - IM proc/smoke_start(var/volume, var/classic = 0) del_reagent("thalmerite") - //del_reagent("big_bang") //remove this later when we fix rreaction order stuff etc + del_reagent("big_bang") //remove later if we can get a better fix + del_reagent("big_bang_precursor") var/list/covered = covered_turf() diff --git a/code/modules/chemistry/Chemistry-Machinery.dm b/code/modules/chemistry/Chemistry-Machinery.dm index 2d9b56c..ea09328 100644 --- a/code/modules/chemistry/Chemistry-Machinery.dm +++ b/code/modules/chemistry/Chemistry-Machinery.dm @@ -17,6 +17,7 @@ icon_state = "heater" flags = NOSPLASH mats = 15 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER power_usage = 50 var/obj/beaker = null var/active = 0 @@ -297,6 +298,7 @@ icon_state = "mixer0" flags = NOSPLASH mats = 15 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_MULTITOOL var/obj/item/beaker = null var/list/whitelist = list() var/emagged = 0 @@ -666,6 +668,7 @@ datum/chemicompiler_core/stationaryCore icon = 'icons/obj/chemical.dmi' icon_state = "chemicompiler_st_off" mats = 15 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_MULTITOOL var/datum/chemicompiler_executor/executor var/datum/light/light diff --git a/code/modules/chemistry/Chemistry-Reagents.dm b/code/modules/chemistry/Chemistry-Reagents.dm index 79b835e..ad62472 100644 --- a/code/modules/chemistry/Chemistry-Reagents.dm +++ b/code/modules/chemistry/Chemistry-Reagents.dm @@ -108,8 +108,10 @@ datum if (penetrates_skin) var/modifier = touch_modifier if(!src.pierces_outerwear) - for(var/obj/item/clothing/C in M.get_equipped_items()) - modifier -= (1 - C.permeability_coefficient)/4 + for(var/atom in M.get_equipped_items()) + if (istype(atom, /obj/item/clothing)) + var/obj/item/clothing/C = atom + modifier -= (1 - C.permeability_coefficient)/4 if(M.reagents) M.reagents.add_reagent(self.id,volume*modifier,self.data) diff --git a/code/modules/chemistry/Chemistry-Recipes.dm b/code/modules/chemistry/Chemistry-Recipes.dm index dca0e8d..f6f136e 100644 --- a/code/modules/chemistry/Chemistry-Recipes.dm +++ b/code/modules/chemistry/Chemistry-Recipes.dm @@ -585,6 +585,7 @@ datum inhibitors = list("stabiliser") instant = 1 mix_phrase = "The mixture implodes suddenly." + priority = 20 on_reaction(var/datum/reagents/holder, var/created_volume) ldmatter_reaction(holder, created_volume) return diff --git a/code/modules/chemistry/Reagents-Base.dm b/code/modules/chemistry/Reagents-Base.dm index 4d1dbf3..867455d 100644 --- a/code/modules/chemistry/Reagents-Base.dm +++ b/code/modules/chemistry/Reagents-Base.dm @@ -532,22 +532,24 @@ datum on_add() if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"add_stam_mod_regen")) remove_buff = holder.my_atom:add_stam_mod_regen("consumable_good", 2) + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_sugar", 4) return on_remove() if(remove_buff) if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"remove_stam_mod_regen")) holder.my_atom:remove_stam_mod_regen("consumable_good") + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_sugar") return on_mob_life(var/mob/M, var/mult = 1) if(!M) M = holder.my_atom M.make_jittery(2 ) M.drowsyness = max(M.drowsyness-(5), 0) - if(prob(50)) - M.changeStatus("paralysis", -10 * mult) - M.changeStatus("stunned", -10 * mult) - M.changeStatus("weakened", -10 * mult) if(prob(4)) M.reagents.add_reagent("epinephrine", 1.2 * mult) // let's not metabolize into meth anymore //if(prob(2)) diff --git a/code/modules/chemistry/Reagents-Drugs.dm b/code/modules/chemistry/Reagents-Drugs.dm index 3bc3a3a..5d30a9a 100644 --- a/code/modules/chemistry/Reagents-Drugs.dm +++ b/code/modules/chemistry/Reagents-Drugs.dm @@ -222,6 +222,18 @@ datum overdose = 20 value = 20 // 10 2 1 3 1 heat explosion :v + on_add() + if (holder && ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_crank", 50) + return + + on_remove() + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_crank") + return + on_mob_life(var/mob/M, var/mult = 1) if(!M) M = holder.my_atom if(ishuman(M)) @@ -233,9 +245,6 @@ datum H.sims.affectMotive("hunger", -0.5) H.sims.affectMotive("thirst", -0.5) H.sims.affectMotive("comfort", -0.25) - M.changeStatus("paralysis", -20 * mult) - M.changeStatus("stunned", -20 * mult) - M.changeStatus("weakened", -20 * mult) if(prob(15)) M.emote(pick("twitch", "twitch_s", "grumble", "laugh")) if(prob(8)) boutput(M, "You feel great!") @@ -494,14 +503,21 @@ datum on_add() if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"add_stam_mod_regen")) remove_buff = holder.my_atom:add_stam_mod_regen("consumable_good", 1) + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_nicotine", 4) return on_remove() if(remove_buff) if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"remove_stam_mod_regen")) holder.my_atom:remove_stam_mod_regen("consumable_good") + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_nicotine") return + on_mob_life(var/mob/M, var/mult = 1) if(ishuman(M)) var/mob/living/carbon/human/H = M @@ -509,9 +525,6 @@ datum H.sims.affectMotive("fun", 0.2) if(prob(50)) M.make_jittery(5) - M.changeStatus("paralysis", -10 * mult) - M.changeStatus("stunned", -10 * mult) - M.changeStatus("stunned", -10 * mult) if(src.volume > src.overdose) M.take_toxin_damage(1 * mult) @@ -574,12 +587,18 @@ datum on_add() if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"add_stam_mod_regen")) remove_buff = holder.my_atom:add_stam_mod_regen("nicotine2", 3) + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_nicotine2", 6) return on_remove() if(remove_buff) if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"remove_stam_mod_regen")) holder.my_atom:remove_stam_mod_regen("nicotine2") + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_nicotine2") return on_mob_life(var/mob/M, var/mult = 1) @@ -589,9 +608,6 @@ datum H.sims.affectMotive("fun", 2) if(prob(75)) M.make_jittery(10) - M.changeStatus("paralysis", -10 * mult) - M.changeStatus("stunned", -10 * mult) - M.changeStatus("weakened", -10 * mult) if(prob(25)) M.emote(pick("drool","shudder","groan","moan","shiver")) boutput(M, "You feel... pretty good... and calm... weird.") @@ -862,7 +878,9 @@ datum value = 39 // 13c * 3 :v on_add() - return + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_triplemeth", 1000) on_remove() if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"remove_stam_mod_regen")) @@ -871,8 +889,12 @@ datum if(hascall(holder.my_atom,"removeOverlayComposition")) holder.my_atom:removeOverlayComposition(/datum/overlayComposition/triplemeth) + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_triplemeth") return + on_mob_life(var/mob/M, var/mult = 1) if(!M) M = holder.my_atom if(ishuman(M)) @@ -897,9 +919,6 @@ datum M.make_dizzy(5 * mult) M.change_misstep_chance(15 * mult) M.take_brain_damage(1 * mult) - if(M.getStatusDuration("paralysis")) M.delStatus("paralysis") - M.delStatus("stunned") - M.delStatus("weakened") M.delStatus("disorient") if(M.sleeping) M.sleeping = 0 ..() @@ -958,12 +977,18 @@ datum on_add() if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"add_stam_mod_regen")) remove_buff = holder.my_atom:add_stam_mod_regen("consumable_good", 3) + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_meth", 50) return on_remove() if(remove_buff) if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"remove_stam_mod_regen")) holder.my_atom:remove_stam_mod_regen("consumable_good") + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_meth") if(holder && ismob(holder.my_atom)) holder.del_reagent("triplemeth") @@ -983,9 +1008,6 @@ datum if(prob(5)) M.emote(pick("twitch","blink_r","shiver")) M.make_jittery(5) M.drowsyness = max(M.drowsyness-10, 0) - M.changeStatus("paralysis", -20 * mult) - M.changeStatus("stunned", -20 * mult) - M.changeStatus("weakened", -20 * mult) if(M.sleeping) M.sleeping = 0 if(prob(50)) M.take_brain_damage(1 * mult) diff --git a/code/modules/chemistry/Reagents-FoodDrink.dm b/code/modules/chemistry/Reagents-FoodDrink.dm index 6d926fc..c12d20e 100644 --- a/code/modules/chemistry/Reagents-FoodDrink.dm +++ b/code/modules/chemistry/Reagents-FoodDrink.dm @@ -933,17 +933,25 @@ datum taste = "FAST" bladder_value = -5 + on_add() + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_sonic", 15) + return + + on_remove() + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_sonic") + return + on_mob_life(var/mob/M, var/mult = 1) if(!M) M = holder.my_atom M.make_jittery(2) M.drowsyness = max(M.drowsyness-5, 0) - if(prob(25)) - M.changeStatus("paralysis", -10 * mult) - M.changeStatus("stunned", -10 * mult) - M.changeStatus("weakened", -10 * mult) if(prob(8)) M.reagents.add_reagent("methamphetamine", 1.2 * mult) - var/speed_message = pick("Gotta go fast!", "Time to speed, keed!", "I feel a need for speed!", "Let's juice.", "Juice time.", "Way Past Cool!") + var/speed_message = pick("Gotta go fast!", "Time to speed, keed!", "I feel a need for speed!", "Let's juice.", "Juice time.", "Way Past Cool!", "I'll make you eat those words!") if (prob(50)) M.say( speed_message ) else @@ -1215,14 +1223,19 @@ datum description = "Mmm, tastes like heart attacks." reagent_state = LIQUID - on_mob_life(var/mob/M, var/mult = 1) - if(!M) M = holder.my_atom - if(prob(33)) M.changeStatus("paralysis", -10 * mult) - if(prob(33)) M.changeStatus("stunned", -10 * mult) - if(prob(33)) M.changeStatus("weakened", -10 * mult) - ..() + on_add() + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_bull", 8) return + on_remove() + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_bull") + return + + fooddrink/alcoholic/longisland name = "Long Island Iced Tea" id = "longisland" @@ -2046,12 +2059,18 @@ datum on_add() if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"add_stam_mod_regen")) remove_buff = holder.my_atom:add_stam_mod_regen("consumable_good", 2) + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_coffee", 3) return on_remove() if(remove_buff) if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"remove_stam_mod_regen")) holder.my_atom:remove_stam_mod_regen("consumable_good") + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_coffee") return on_mob_life(var/mob/M, var/mult = 1) @@ -2066,10 +2085,6 @@ datum M.sleeping = 0 M.bodytemperature = min(M.base_body_temp, M.bodytemperature+(5 * mult)) M.make_jittery(3) - if(prob(50)) - M.changeStatus("paralysis", -10 * mult) - M.changeStatus("stunned", -10 * mult) - M.changeStatus("weakened", -10 * mult) fooddrink/coffee/espresso //the good stuff name = "espresso" @@ -2085,25 +2100,28 @@ datum on_add() if (istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"add_stam_mod_regen")) //gotta get hyped holder.my_atom:add_stam_mod_regen("caffeine rush", src.caffeine_rush) + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_espresso", caffeine_jitters / 2) return on_remove() if (istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"remove_stam_mod_regen")) holder.my_atom:remove_stam_mod_regen("caffeine rush") + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_espresso") return on_mob_life(var/mob/M, var/mult = 1) ..() M.make_jittery(1) - if(prob(src.caffeine_jitters)) - M.changeStatus("paralysis", -10 * mult) - M.changeStatus("stunned", -10 * mult) - M.changeStatus("weakened", -10 * mult) fooddrink/coffee/espresso/expresso // the stupid stuff name = "expresso" id = "expresso" description = "An expresso is a strong black coffee with more stupid." + caffeine_jitters = 15 on_mob_life(var/mob/M, var/mult = 1) ..() M.take_brain_damage(2 * mult) @@ -2137,6 +2155,18 @@ datum ..() tickcounter = 0 + on_add() + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_energydrink", 10) + return + + on_remove() + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_energydrink") + return + on_mob_life(var/mob/M, var/mult = 1) if(!M) M = holder.my_atom if (ishuman(M)) @@ -2147,10 +2177,6 @@ datum ..() // basically, make it twice as effective - if (prob(50)) - M.changeStatus("paralysis", -10 * mult) - M.changeStatus("stunned", -10 * mult) - M.changeStatus("weakened", -10 * mult) on_mob_life_complete(var/mob/M) if(M) @@ -3199,7 +3225,10 @@ datum overdose = 33 depletion_rate = 0.6 - on_add(var/mob/M) + on_add() + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_cocktail_triple", 1000) return reaction_mob(var/mob/M, var/method=INGEST, var/volume) @@ -3217,8 +3246,13 @@ datum if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"remove_stam_mod_regen")) holder.my_atom:remove_stam_mod_regen("tripletriple") + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_cocktail_triple") + return + on_mob_life(var/mob/M, var/mult = 1) if(!M) M = holder.my_atom if(ishuman(M)) @@ -3267,9 +3301,6 @@ datum M.make_dizzy(5 * mult) M.change_misstep_chance(50 * mult) M.take_brain_damage(1 * mult) - if(M.getStatusDuration("paralysis")) M.delStatus("paralysis") - M.delStatus("stunned") - M.delStatus("weakened") M.delStatus("disorient") if(M.sleeping) M.sleeping = 0 ..(M) diff --git a/code/modules/chemistry/Reagents-Medical.dm b/code/modules/chemistry/Reagents-Medical.dm index 36bf70e..0bc002e 100644 --- a/code/modules/chemistry/Reagents-Medical.dm +++ b/code/modules/chemistry/Reagents-Medical.dm @@ -428,20 +428,23 @@ datum on_add() if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"add_stam_mod_regen")) remove_buff = holder.my_atom:add_stam_mod_regen("consumable_good", 2) + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_synaptizine", 25) return on_remove() if(remove_buff) if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"remove_stam_mod_regen")) holder.my_atom:remove_stam_mod_regen("consumable_good") + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_synaptizine") return on_mob_life(var/mob/M, var/mult = 1) if(!M) M = holder.my_atom M.drowsyness = max(M.drowsyness-5, 0) - M.changeStatus("paralysis", -10 * mult) - M.changeStatus("stunned", -10 * mult) - M.changeStatus("weakened", -10 * mult) if(M.sleeping) M.sleeping = 0 if(M.get_brain_damage() && prob(50)) M.take_brain_damage(-1 * mult) ..() @@ -750,12 +753,18 @@ datum on_add() if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"add_stam_mod_regen")) remove_buff = holder.my_atom:add_stam_mod_regen("epinephrine", 3) + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_epinephrine", 3) return on_remove() if(remove_buff) if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"remove_stam_mod_regen")) holder.my_atom:remove_stam_mod_regen("epinephrine") + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_epinephrine") return on_mob_life(var/mob/M, var/mult = 1) @@ -764,9 +773,6 @@ datum if(prob(10)) M.make_jittery(4) M.drowsyness = max(M.drowsyness-5, 0) - if(prob(20)) M.changeStatus("paralysis", -10 * mult) - if(prob(20)) M.changeStatus("stunned", -10 * mult) - if(prob(20)) M.changeStatus("weakened", -10 * mult) if(M.sleeping && prob(5)) M.sleeping = 0 if(M.get_brain_damage() && prob(5)) M.take_brain_damage(-1) if(holder.has_reagent("histamine")) @@ -1054,12 +1060,18 @@ datum on_add() if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"add_stam_mod_regen")) remove_buff = holder.my_atom:add_stam_mod_regen("consumable_good", 2) + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_ephedrine", 10) return on_remove() if(remove_buff) if(istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"remove_stam_mod_regen")) holder.my_atom:remove_stam_mod_regen("consumable_good") + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_ephedrine") return on_mob_life(var/mob/M, var/mult = 1) @@ -1067,9 +1079,6 @@ datum M.bodytemperature = min(M.base_body_temp, M.bodytemperature+(5 * mult)) M.make_jittery(4) M.drowsyness = max(M.drowsyness-5, 0) - M.changeStatus("paralysis", -10 * mult) - M.changeStatus("stunned", -10 * mult) - M.changeStatus("weakened", -10 * mult) if(M.losebreath > 3) M.losebreath = max(5, M.losebreath-(1 * mult)) if(M.get_oxygen_deprivation() > 75) diff --git a/code/modules/chemistry/Reagents-Misc.dm b/code/modules/chemistry/Reagents-Misc.dm index 5adc74a..f8a3bb5 100644 --- a/code/modules/chemistry/Reagents-Misc.dm +++ b/code/modules/chemistry/Reagents-Misc.dm @@ -290,6 +290,9 @@ datum holder.my_atom:add_stam_mod_regen("stims", 500) if (istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"add_stam_mod_max")) holder.my_atom:add_stam_mod_max("stims", 500) + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_stimulants", 1000) return on_remove() @@ -297,6 +300,9 @@ datum holder.my_atom:remove_stam_mod_regen("stims") if (istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"remove_stam_mod_max")) holder.my_atom:remove_stam_mod_max("stims") + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_stimulants") return on_mob_life(var/mob/living/M, var/mult = 1) @@ -306,9 +312,6 @@ datum M.take_oxygen_deprivation(-5 * mult) if (M.get_toxin_damage()) M.take_toxin_damage(-5 * mult) - M.delStatus("stunned") - M.delStatus("weakened") - M.delStatus("paralysis") M.delStatus("slowed") M.delStatus("disorient") if (M.misstep_chance) @@ -1087,7 +1090,7 @@ datum if (method == TOUCH) if (isrobot(M)) var/mob/living/silicon/robot/R = M - R.oil += volume * 2 + R.add_oil(volume * 2) boutput(R, "Your joints and servos begin to run more smoothly.") else boutput(M, "You feel greasy and gross.") @@ -2066,9 +2069,6 @@ datum M.make_jittery(2) M.drowsyness = max(M.drowsyness-6, 0) - M.changeStatus("paralysis", -10 * mult) - M.changeStatus("stunned", -10 * mult) - M.changeStatus("weakened", -10 * mult) if (M.sleeping) M.sleeping = 0 return @@ -2088,12 +2088,18 @@ datum on_add() if (istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"add_stam_mod_regen")) remove_buff = holder.my_atom:add_stam_mod_regen("consumable_good", 2) + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_fliptonium", 9) return on_remove() if (remove_buff) if (istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"remove_stam_mod_regen")) holder.my_atom:remove_stam_mod_regen("consumable_good") + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_fliptonium") if (istype(holder) && istype(holder.my_atom)) animate(holder.my_atom) @@ -2195,9 +2201,6 @@ datum M.make_jittery(4) M.drowsyness = max(M.drowsyness-12, 0) - M.changeStatus("paralysis", -30 * mult) - M.changeStatus("stunned", -30 * mult) - M.changeStatus("weakened", -30 * mult) if (M.sleeping) M.sleeping = 0 return @@ -2221,12 +2224,18 @@ datum on_add() if (istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"add_stam_mod_regen")) remove_buff = holder.my_atom:add_stam_mod_regen("consumable_good", 4) + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.add_stun_resist_mod("reagent_fliptonium", 60) return on_remove() if (remove_buff) if (istype(holder) && istype(holder.my_atom) && hascall(holder.my_atom,"remove_stam_mod_regen")) holder.my_atom:remove_stam_mod_regen("consumable_good") + if (ismob(holder.my_atom)) + var/mob/M = holder.my_atom + M.remove_stun_resist_mod("reagent_fliptonium") if (istype(holder) && istype(holder.my_atom)) animate(holder.my_atom) diff --git a/code/modules/chemistry/tools/dispensers.dm b/code/modules/chemistry/tools/dispensers.dm index b30a8c2..56598e2 100644 --- a/code/modules/chemistry/tools/dispensers.dm +++ b/code/modules/chemistry/tools/dispensers.dm @@ -178,6 +178,7 @@ desc = "It's called a fountain, but it's not very decorative or interesting. You can get a drink from it, though." icon_state = "water_fountain1" anchored = 1 + deconstruct_flags = DECON_SCREWDRIVER | DECON_CROWBAR var/cup_amount = 12 get_desc(dist, mob/user) // this shit refused to show the parent get_desc() info even if I added a ..() so I'M JUST COPYING THE CODE NOW LIKE SOME KIND OF GIGANTIC ASSHOLE diff --git a/code/modules/chemistry/tools/grenades.dm b/code/modules/chemistry/tools/grenades.dm index 303563c..8ca1f8a 100644 --- a/code/modules/chemistry/tools/grenades.dm +++ b/code/modules/chemistry/tools/grenades.dm @@ -331,8 +331,6 @@ var/list/U = R.get_unconvertables() if (!H.client || !H.mind) can_convert = 0 - else if (locate(/obj/item/implant/antirev) in H.implant) - can_convert = 0 else if (H.mind in U) can_convert = 0 else if (H.mind in R.head_revolutionaries) @@ -340,6 +338,14 @@ else can_convert = 1 + for (var/obj/item/implant/antirev/found_imp in H.implant) + found_imp.on_remove(H) + H.implant.Remove(found_imp) + qdel(found_imp) + + playsound(H.loc, 'sound/impact_sounds/Crystal_Shatter_1.ogg', 50, 0.1, 0, 0.9) + H.visible_message("The loyalty implant inside [H] shatters into one million pieces!") + if (can_convert && !(H.mind in R.revolutionaries)) R.add_revolutionary(H.mind) diff --git a/code/modules/chemistry/tools/patches.dm b/code/modules/chemistry/tools/patches.dm index c7f2e0b..4939108 100644 --- a/code/modules/chemistry/tools/patches.dm +++ b/code/modules/chemistry/tools/patches.dm @@ -37,18 +37,27 @@ New() ..() if (src.reagents) - src.reagents.temperature_cap = 440 + src.reagents.temperature_cap = 440 //you can remove/adjust these afterr you fix burns from reagnets being super strong + src.reagents.temperature_min = 270 //you can remove/adjust these afterr you fix burns from reagnets being super strong on_reagent_change() src.update_icon() if (src.reagents) src.reagents.temperature_cap = 440 + src.reagents.temperature_min = 270 if (src.reagents.total_temperature >= src.reagents.temperature_cap) if (ismob(src.loc)) var/mob/M = src.loc M.drop_item(src) qdel(src) + if (src.reagents.total_temperature <= src.reagents.temperature_min) + src.reagents.total_temperature = src.reagents.temperature_min + proc/clamp_reagents() + if (src.reagents.total_temperature > src.reagents.temperature_cap) + src.reagents.total_temperature = src.reagents.temperature_cap + if (src.reagents.total_temperature < src.reagents.temperature_min) + src.reagents.total_temperature = src.reagents.temperature_min proc/update_icon() src.underlays = null @@ -163,6 +172,9 @@ JOB_XP(user, "Medical Doctor", 1) logTheThing("combat", user, M, "applies a patch to %target% [log_reagents(src)] at [log_loc(user)].") + + src.clamp_reagents() + apply_to(M,user=user) return 1 diff --git a/code/modules/fluids/fluid_groups.dm b/code/modules/fluids/fluid_groups.dm index 9784ef5..3d6d986 100644 --- a/code/modules/fluids/fluid_groups.dm +++ b/code/modules/fluids/fluid_groups.dm @@ -533,8 +533,6 @@ //Same shit here with update_icon ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// - LAGCHECK(LAG_LOW) - F.name = src.master_reagent_name //maybe obscure later? F.finalalpha = targetalpha diff --git a/code/modules/fluids/fluid_objects.dm b/code/modules/fluids/fluid_objects.dm index 467959b..edb895f 100644 --- a/code/modules/fluids/fluid_objects.dm +++ b/code/modules/fluids/fluid_objects.dm @@ -24,6 +24,7 @@ var/drain_min = 2 var/drain_max = 7 mats = 8 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER big @@ -224,6 +225,7 @@ var/slurp = 10 //tiles of fluid to drain per tick var/piss = 500 //amt of reagents to piss out per tick mats = 20 + deconstruct_flags = DECON_CROWBAR | DECON_WELDER var/slurping = 0 var/pissing = 0 @@ -450,6 +452,7 @@ anchored = 0 mats = 16 + deconstruct_flags = DECON_WRENCH | DECON_WELDER | DECON_MULTITOOL flags = FPRINT var/active = 1 diff --git a/code/modules/fluids/fluid_turf.dm b/code/modules/fluids/fluid_turf.dm index 8684830..67ef6e5 100644 --- a/code/modules/fluids/fluid_turf.dm +++ b/code/modules/fluids/fluid_turf.dm @@ -33,7 +33,7 @@ special_volume_override = 0.62 - turf_flags = CAN_BE_SPACE_SAMPLE + turf_flags = CAN_BE_SPACE_SAMPLE | FLUID_MOVE var/datum/light/point/light = 0 var/light_r = 0.16 @@ -226,7 +226,7 @@ if (!prob(severity*20)) for (var/obj/O in src) - if (istype(O, /obj/lattice) || istype(O, /obj/cable/reinforced) || istype(O, /obj/item/heat_dowsing) || istype(O, /obj/machinery/conveyor) ) + if (istype(O, /obj/lattice) || istype(O, /obj/cable/reinforced) || istype(O, /obj/item/heat_dowsing) || istype(O, /obj/machinery/conveyor) || istype(O,/obj/item/cable_coil/reinforced) ) return blow_hole() @@ -258,7 +258,7 @@ L+=T Entered(var/atom/movable/AM) - if (istype(AM,/mob/dead) || istype(AM,/mob/wraith) || istype(AM,/mob/living/intangible) || istype(AM, /obj/lattice) || istype(AM, /obj/cable/reinforced)) + if (istype(AM,/mob/dead) || istype(AM,/mob/wraith) || istype(AM,/mob/living/intangible) || istype(AM, /obj/lattice) || istype(AM, /obj/cable/reinforced) || istype(AM,/obj/torpedo_targeter) || istype(AM,/obj/overlay) || istype (AM, /obj/arrival_missile)) return if (locate(/obj/lattice) in src) return @@ -266,8 +266,7 @@ try_build_turf_list() - if (L && L.len && !istype(AM,/obj/overlay) && !istype(AM,/obj/torpedo_targeter)) - + if (L && L.len) SPAWN_DBG(3)//you can 'jump' over a hole by running real fast or being thrown!! if (istype(AM.loc, /turf/space/fluid/warp_z5)) visible_message("[AM] falls down [src]!") @@ -293,15 +292,11 @@ try_build_turf_list() if (!L || L.len == 0) - for(var/turf/space/fluid/T in range(10,locate(src.x,src.y,5))) + for(var/turf/space/fluid/T in range(8,locate(src.x,src.y,5))) L += T break ..() - Entered(var/atom/movable/AM) - try_build_turf_list() - ..() - //trench floor /turf/space/fluid/trench diff --git a/code/modules/food_and_drink/pies.dm b/code/modules/food_and_drink/pies.dm index 8732fde..9d7aeb3 100644 --- a/code/modules/food_and_drink/pies.dm +++ b/code/modules/food_and_drink/pies.dm @@ -111,7 +111,7 @@ if (!usr) src.throw_impact(hit_atom) - var/atom/randomContent + var/atom/movable/randomContent if (contents.len >= 1) randomContent = pick(contents) else diff --git a/code/modules/forensics/atom_forensic.dm b/code/modules/forensics/atom_forensic.dm index ab0fc94..58e975f 100644 --- a/code/modules/forensics/atom_forensic.dm +++ b/code/modules/forensics/atom_forensic.dm @@ -317,7 +317,7 @@ if (Lstate) B.add_volume(blood_color_to_pass, 0.5, src.tracked_blood, Lstate, src.last_move, 0) if (Rstate) B.add_volume(blood_color_to_pass, 0.5, src.tracked_blood, Rstate, src.last_move, 0) else - B.add_volume(blood_color_to_pass, 1, src.tracked_blood, "smear2", src.last_move) + B.add_volume(blood_color_to_pass, 1, src.tracked_blood, "smear2", src.last_move, 0) if (src.tracked_blood && isnum(src.tracked_blood["count"])) // maybe this will fix the bad index runtime PART src.tracked_blood["count"] -- @@ -349,7 +349,7 @@ if (Lstate) B.add_volume(blood_color_to_pass, 0.5, src.tracked_blood, Lstate, src.last_move, 0) if (Rstate) B.add_volume(blood_color_to_pass, 0.5, src.tracked_blood, Rstate, src.last_move, 0) else - B.add_volume(blood_color_to_pass, 1, src.tracked_blood, "smear2", src.last_move) + B.add_volume(blood_color_to_pass, 1, src.tracked_blood, "smear2", src.last_move, 0) if (src.tracked_blood && isnum(src.tracked_blood["count"])) //mirror from above src.tracked_blood["count"] -- diff --git a/code/modules/holiday/halloween.dm b/code/modules/holiday/halloween.dm index 90f2960..1c83afe 100644 --- a/code/modules/holiday/halloween.dm +++ b/code/modules/holiday/halloween.dm @@ -211,6 +211,7 @@ desc = "For Emergency Use Only" configure_mode = 0 code = "54321" + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_WIRECUTTERS | DECON_MULTITOOL New() ..() diff --git a/code/modules/materials/Mat_Fabrication.dm b/code/modules/materials/Mat_Fabrication.dm index f8ad8b6..cc37cb6 100644 --- a/code/modules/materials/Mat_Fabrication.dm +++ b/code/modules/materials/Mat_Fabrication.dm @@ -62,6 +62,7 @@ density = 1 layer = FLOOR_EQUIP_LAYER1 flags = NOSPLASH + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_WIRECUTTERS | DECON_MULTITOOL var/outputInternal = 0 //Produced objects are fed back into the fabricator. diff --git a/code/modules/materials/Mat_RawMaterials.dm b/code/modules/materials/Mat_RawMaterials.dm index 07d4936..f74c008 100644 --- a/code/modules/materials/Mat_RawMaterials.dm +++ b/code/modules/materials/Mat_RawMaterials.dm @@ -140,6 +140,8 @@ var/in_use = 0 attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) + if (user.a_intent == INTENT_GRAB) + return ..() if (src.in_use) return ..() if (ishuman(M)) diff --git a/code/modules/medical/genetics/geneticsBooth.dm b/code/modules/medical/genetics/geneticsBooth.dm index 8e356e9..af06e5b 100644 --- a/code/modules/medical/genetics/geneticsBooth.dm +++ b/code/modules/medical/genetics/geneticsBooth.dm @@ -59,6 +59,7 @@ var/spam_time = 0 var/started = 0 mats = 40 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_WIRECUTTERS | DECON_MULTITOOL var/datum/light/light var/lr = 0.88 diff --git a/code/modules/medical/genetics/geneticsMachines.dm b/code/modules/medical/genetics/geneticsMachines.dm index 10b196c..89e073f 100644 --- a/code/modules/medical/genetics/geneticsMachines.dm +++ b/code/modules/medical/genetics/geneticsMachines.dm @@ -5,6 +5,7 @@ var/list/genetics_computers = list() icon = 'icons/obj/computer.dmi' icon_state = "scanner" req_access = list(access_heads) //Only used for record deletion right now. + object_flags = CAN_REPROGRAM_ACCESS var/obj/machinery/genetics_scanner/scanner = null //Linked scanner. For scanning. var/list/equipment = list(0,0,0,0) // Injector, Analyser, Emitter, Reclaimer diff --git a/code/modules/medical/genetics/geneticsScanner.dm b/code/modules/medical/genetics/geneticsScanner.dm index dcc2c62..a518d84 100644 --- a/code/modules/medical/genetics/geneticsScanner.dm +++ b/code/modules/medical/genetics/geneticsScanner.dm @@ -6,6 +6,7 @@ var/list/genescanner_addresses = list() icon_state = "scanner_0" density = 1 mats = 15 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_WIRECUTTERS | DECON_MULTITOOL var/mob/occupant = null var/locked = 0 anchored = 1.0 diff --git a/code/modules/medical/surgery_tools.dm b/code/modules/medical/surgery_tools.dm index 0d44f64..6dc9c58 100644 --- a/code/modules/medical/surgery_tools.dm +++ b/code/modules/medical/surgery_tools.dm @@ -364,6 +364,21 @@ CONTAINS: set_icon_state("[src.icon_base]-on") playsound(user.loc, "sound/weapons/flash.ogg", 75, 1) + proc/do_the_shocky_thing(mob/user as mob) + if (src.charged == 0) + user.show_text("[src] is still charging!", "red") + return 0 + playsound(src.loc, "sound/impact_sounds/Energy_Hit_3.ogg", 75, 1) + src.charged = 0 + set_icon_state("[src.icon_base]-shock") + SPAWN_DBG(10) + set_icon_state("[src.icon_base]-off") + SPAWN_DBG(src.charge_time) + src.charged = 1 + set_icon_state("[src.icon_base]-on") + playsound(src.loc, "sound/weapons/flash.ogg", 75, 1) + return 1 + disposing() ..() if (src.cell) @@ -383,14 +398,6 @@ CONTAINS: if (!src.user_can_suicide(user)) return 0 if (src.defibrillate(user, user, src.emagged, src.makeshift, src.cell, 1)) - src.charged = 0 - set_icon_state("[src.icon_base]-shock") - SPAWN_DBG(10) - set_icon_state("[src.icon_base]-off") - SPAWN_DBG(src.charge_time) - src.charged = 1 - set_icon_state("[src.icon_base]-on") - playsound(user.loc, "sound/weapons/flash.ogg", 75, 1) SPAWN_DBG(500) if (user && !isdead(user)) user.suiciding = 0 diff --git a/code/modules/networks/computer3/comm_dish.dm b/code/modules/networks/computer3/comm_dish.dm index d859f54..fe609e2 100644 --- a/code/modules/networks/computer3/comm_dish.dm +++ b/code/modules/networks/computer3/comm_dish.dm @@ -15,6 +15,7 @@ var/list/cargo_logs = list() mats = 25 + deconstruct_flags = DECON_NONE New() ..() diff --git a/code/modules/networks/computer3/mainframe2/misc_terms.dm b/code/modules/networks/computer3/mainframe2/misc_terms.dm index c3bb8a1..d9bc912 100644 --- a/code/modules/networks/computer3/mainframe2/misc_terms.dm +++ b/code/modules/networks/computer3/mainframe2/misc_terms.dm @@ -108,6 +108,7 @@ icon_state = "tapedrive0" device_tag = "PNET_DATA_BANK" mats = 12 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_WIRECUTTERS | DECON_MULTITOOL var/base_icon_state = "tapedrive" var/bank_id = null //Unique Identifier for this databank. var/locked = 1 @@ -1064,6 +1065,7 @@ #define DISARM_CUTOFF 10 //Can't disarm past this point! OH NO! mats = 80 //haha this is a bad idea + deconstruct_flags = DECON_NONE is_syndicate = 1 //^ Agreed New() @@ -1387,6 +1389,7 @@ device_tag = "PNET_PR6_RADIO" //var/freq = 1219 mats = 8 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_WIRECUTTERS | DECON_MULTITOOL var/list/frequencies = list() var/datum/radio_frequency/radio_connection var/transmission_range = 100 //How far does our signal reach? @@ -1714,6 +1717,7 @@ desc = "A networked printer. It's designed to print." anchored = 1 density = 1 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_WIRECUTTERS | DECON_MULTITOOL icon_state = "printer0" device_tag = "PNET_PRINTDEVC" mats = 6 diff --git a/code/modules/power/apc.dm b/code/modules/power/apc.dm index 29b5b0d..a26510e 100644 --- a/code/modules/power/apc.dm +++ b/code/modules/power/apc.dm @@ -22,6 +22,7 @@ var/zapLimiter = 0 icon_state = "apc0" anchored = 1 req_access = list(access_engineering_power) + object_flags = CAN_REPROGRAM_ACCESS netnum = -1 // set so that APCs aren't found as powernet nodes var/area/area var/areastring = null diff --git a/code/modules/power/furnace.dm b/code/modules/power/furnace.dm index 8cda0c4..9a0c670 100644 --- a/code/modules/power/furnace.dm +++ b/code/modules/power/furnace.dm @@ -12,6 +12,7 @@ var/genrate = 5000 var/stoked = 0 // engine ungrump mats = 20 + deconstruct_flags = DECON_WRENCH | DECON_CROWBAR | DECON_WELDER process() if(status & BROKEN) return diff --git a/code/modules/power/lgenerator.dm b/code/modules/power/lgenerator.dm index 116bea4..92b1c45 100644 --- a/code/modules/power/lgenerator.dm +++ b/code/modules/power/lgenerator.dm @@ -9,6 +9,7 @@ density = 1 //layer = FLOOR_EQUIP_LAYER1 //why was this set to this mats = 10 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_WELDER | DECON_MULTITOOL var/mode = 1 // 1 = charge APC, 2 = charge inserted power cell. var/active = 0 diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index 37d0581..537602f 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -314,6 +314,7 @@ allowed_type = /obj/item/light/bulb light_name = "light bulb" wallmounted = 0 + deconstruct_flags = DECON_SIMPLE var/switchon = 0 // independent switching for lamps - not controlled by area lightswitch diff --git a/code/modules/power/terminal.dm b/code/modules/power/terminal.dm index bd9bd52..66d4dda 100644 --- a/code/modules/power/terminal.dm +++ b/code/modules/power/terminal.dm @@ -82,6 +82,7 @@ directwired = 0 use_datanet = 1 mats = 5 + deconstruct_flags = DECON_SCREWDRIVER | DECON_CROWBAR | DECON_WELDER | DECON_WIRECUTTERS | DECON_MULTITOOL var/obj/master = null //It can be any obj that can use receive_signal ex_act() diff --git a/code/modules/projectiles/bullet.dm b/code/modules/projectiles/bullet.dm index f654224..945ba66 100644 --- a/code/modules/projectiles/bullet.dm +++ b/code/modules/projectiles/bullet.dm @@ -187,7 +187,7 @@ toxic - poisons if(proj.power > 80) var/turf/target = get_edge_target_turf(M, dirflag) SPAWN_DBG(0) - M.throw_at(target, 2, 2) + M.throw_at(target, 2, 2, throw_type = THROW_GUNIMPACT) if (src.hit_type) take_bleeding_damage(hit, null, round(src.power / 3), src.hit_type) impact_image_effect("K", hit) @@ -218,7 +218,7 @@ toxic - poisons if(power > 60) var/turf/target = get_edge_target_turf(M, dirflag) SPAWN_DBG(0) - M.throw_at(target, 3, 3) + M.throw_at(target, 3, 3, throw_type = THROW_GUNIMPACT) if (src.hit_type) take_bleeding_damage(hit, null, round(src.power / 3), src.hit_type) @@ -333,7 +333,7 @@ toxic - poisons var/turf/target = get_edge_target_turf(M, dirflag) SPAWN_DBG(0) if(!M.stat) M.emote("scream") - M.throw_at(target, 6, 2) + M.throw_at(target, 6, 2, throw_type = THROW_GUNIMPACT) if (src.hit_type) take_bleeding_damage(hit, null, round(src.power / 3), src.hit_type) @@ -363,7 +363,7 @@ toxic - poisons SPAWN_DBG(0) if(!M.stat) M.emote("scream") M.do_disorient(15, weakened = 10) - M.throw_at(target, 6, 3) + M.throw_at(target, 6, 3, throw_type = THROW_GUNIMPACT) /datum/projectile/bullet/airzooka/bad name = "plasmaburst" @@ -389,7 +389,7 @@ toxic - poisons if(!M.stat) M.emote("scream") fireflash(get_turf(M), 2) M.do_disorient(15, weakened = 25) - M.throw_at(target, 12, 3) + M.throw_at(target, 12, 3, throw_type = THROW_GUNIMPACT) /datum/projectile/bullet/aex @@ -435,10 +435,13 @@ toxic - poisons if (ishuman(hit)) var/mob/living/carbon/human/M = hit if(proj.power >= 16) + var/throw_range = (proj.power > 20) ? 5 : 3 + var/turf/target = get_edge_target_turf(M, dirflag) SPAWN_DBG(0) if(!M.stat) M.emote("scream") - M.throw_at(target, 3, 2) + M.throw_at(target, throw_range, 1, throw_type = THROW_GUNIMPACT) + M.update_canmove() //if (src.hit_type) // impact_image_effect("K", hit) //take_bleeding_damage(hit, null, round(src.power / 3), src.hit_type) @@ -1066,7 +1069,7 @@ toxic - poisons if(power > 80) var/turf/target = get_edge_target_turf(M, dirflag) SPAWN_DBG(0) - M.throw_at(target, 2, 2) + M.throw_at(target, 2, 2, throw_type = THROW_GUNIMPACT) if (src.hit_type) take_bleeding_damage(hit, null, round(src.power / 3), src.hit_type) @@ -1130,7 +1133,7 @@ toxic - poisons if (H.job == "Clown" || clown_tally >= 2) H.drop_from_slot(H.shoes) spawn(0) - H.throw_at(get_offset_target_turf(H, rand(5)-rand(5), rand(5)-rand(5)), rand(2,4), 2) + H.throw_at(get_offset_target_turf(H, rand(5)-rand(5), rand(5)-rand(5)), rand(2,4), 2, throw_type = THROW_GUNIMPACT) H.emote("twitch_v") return diff --git a/code/modules/projectiles/energy_bolt.dm b/code/modules/projectiles/energy_bolt.dm index a067e3c..69ef0b3 100644 --- a/code/modules/projectiles/energy_bolt.dm +++ b/code/modules/projectiles/energy_bolt.dm @@ -335,7 +335,7 @@ toxic - poisons on_pointblank(var/obj/projectile/P, var/mob/living/M) // var/dir = angle2dir(angle) - M.throw_at(get_edge_target_turf(M, get_dir(P, M)),7,1) + M.throw_at(get_edge_target_turf(M, get_dir(P, M)),7,1, throw_type = THROW_GUNIMPACT) //When it hits a mob or such should anything special happen on_hit(atom/hit, angle, var/obj/projectile/O) @@ -344,7 +344,7 @@ toxic - poisons if (ishuman(hit)) var/mob/living/carbon/human/H = hit H.do_disorient(stamina_damage = 60, weakened = 0, stunned = 0, disorient = 80, remove_stamina_below_zero = 0) - H.throw_at(get_edge_target_turf(hit, dir),7,1) + H.throw_at(get_edge_target_turf(hit, dir),7,1, throw_type = THROW_GUNIMPACT) H.emote("twitch_v") H.changeStatus("slowed", 3 SECONDS) return diff --git a/code/modules/projectiles/projectile_parent.dm b/code/modules/projectiles/projectile_parent.dm index e9b6fbe..2e841b3 100644 --- a/code/modules/projectiles/projectile_parent.dm +++ b/code/modules/projectiles/projectile_parent.dm @@ -116,7 +116,7 @@ // if we made it this far this is a valid bump, run the specific projectile's hit code if (proj_data) //Apparently proj_data can still be missing. HUH. - proj_data.on_hit(A, src.angle, src) + proj_data.on_hit(A, angle_to_dir(src.angle), src) //Trigger material on attack. if(proj_data && proj_data.material) //ZeWaka: Fix for null.material diff --git a/code/modules/projectiles/special.dm b/code/modules/projectiles/special.dm index 8c6a038..4868f9a 100644 --- a/code/modules/projectiles/special.dm +++ b/code/modules/projectiles/special.dm @@ -690,7 +690,7 @@ SPAWN_DBG(0) L.changeStatus("weakened", 2 SECONDS) L.force_laydown_standup() - L.throw_at(targetTurf, rand(5,7), rand(1,2)) + L.throw_at(targetTurf, rand(5,7), rand(1,2), throw_type = THROW_GUNIMPACT) on_canpass(var/obj/projectile/P, atom/movable/passing_thing) if (P != passing_thing) diff --git a/code/modules/robotics/bot/bot_parent.dm b/code/modules/robotics/bot/bot_parent.dm index 3863f4d..2ad5152 100644 --- a/code/modules/robotics/bot/bot_parent.dm +++ b/code/modules/robotics/bot/bot_parent.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/aibots.dmi' layer = MOB_LAYER event_handler_flags = USE_FLUID_ENTER | USE_CANPASS + object_flags = CAN_REPROGRAM_ACCESS var/obj/item/card/id/botcard // ID card that the bot "holds". var/access_lookup = "Captain" // For the get_access() proc. Defaults to all-access. var/locked = null diff --git a/code/modules/robotics/bot/cambot.dm b/code/modules/robotics/bot/cambot.dm index 919ae1c..013b1f0 100644 --- a/code/modules/robotics/bot/cambot.dm +++ b/code/modules/robotics/bot/cambot.dm @@ -31,13 +31,8 @@ var/photographing = 0 // Are we currently photographing something? var/list/photographed = null // what we've already photographed - var/datum/light/light - /obj/machinery/bot/cambot/New() ..() - light = new /datum/light/point - light.attach(src) - light.set_brightness(0.6) src.clear_invalid_targets = world.time SPAWN_DBG(5) if (src) @@ -73,7 +68,6 @@ playsound(get_turf(src), "sound/weapons/flash.ogg", 50, 1) flick("cambot-spark", src) src.emagged = 1 - src.light.set_brightness(0.8) return 1 return 0 @@ -83,7 +77,6 @@ if (user) user.show_text("You repair [src]'s flash control circuit.", "blue") src.emagged = 0 - src.light.set_brightness(0.6) return 1 /obj/machinery/bot/cambot/emp_act() @@ -156,9 +149,9 @@ src.clear_invalid_targets = world.time if (src.on) - light.enable() + add_simple_light("cambot", list(255,255,255,255 * (src.emagged ? 0.8 : 0.6))) else - light.disable() + remove_simple_light("cambot") return @@ -297,12 +290,10 @@ /obj/machinery/bot/cambot/proc/flash_blink(var/loops, var/delay) set waitfor = 0 - if (!src.light) // ??? - return for (var/i=loops, i>0, i--) - src.light.enable() + add_simple_light("cambot", list(255,255,255,255 * (src.emagged ? 0.8 : 0.6))) sleep(delay) - src.light.disable() + remove_simple_light("cambot") sleep(delay) /obj/machinery/bot/cambot/proc/photograph(var/atom/target) diff --git a/code/modules/robotics/bot/evilbot.dm b/code/modules/robotics/bot/evilbot.dm index a3b11ed..28c6864 100644 --- a/code/modules/robotics/bot/evilbot.dm +++ b/code/modules/robotics/bot/evilbot.dm @@ -19,6 +19,7 @@ setup_default_tool_path = /obj/item/device/guardbot_tool/taser no_camera = 1 req_access_txt = "8088" + object_flags = 0 speak(var/message) if((!src.on) || (src.idle) || (!message)) diff --git a/code/modules/robotics/bot/guardbot.dm b/code/modules/robotics/bot/guardbot.dm index 1140610..bb34bd6 100644 --- a/code/modules/robotics/bot/guardbot.dm +++ b/code/modules/robotics/bot/guardbot.dm @@ -137,7 +137,6 @@ var/flashlight_red = 0.1 var/flashlight_green = 0.4 var/flashlight_blue = 0.1 - var/datum/light/light var/datum/radio_frequency/radio_connection var/datum/radio_frequency/beacon_connection @@ -320,14 +319,11 @@ if(!setup_unique_name) src.name += "-[rand(100,999)]" - light = new /datum/light/point - light.attach(src) - light.set_color(src.flashlight_red, src.flashlight_green, src.flashlight_blue) - light.set_brightness(src.flashlight_lum / 7) + SPAWN_DBG(5) if (src.on) - light.enable() + add_simple_light("guardbot", list(src.flashlight_red*255, src.flashlight_green*255, src.flashlight_blue*255, (src.flashlight_lum / 7) * 255)) src.botcard = new /obj/item/card/id(src) src.botcard.access = get_access(src.botcard_access) @@ -780,7 +776,7 @@ src.moving = 0 src.emotion = null icon_needs_update = 1 - light.enable() + add_simple_light("guardbot", list(src.flashlight_red*255, src.flashlight_green*255, src.flashlight_blue*255, (src.flashlight_lum / 7) * 255)) if(src.bedsheet == 1) src.add_task(new /datum/computer/file/guardbot_task/bedsheet_handler, 1, 0) return @@ -792,7 +788,7 @@ if(src.idle) return //Already snoozing. src.idle = 1 set_emotion() - light.disable() + remove_simple_light("guardbot") src.wakeup_timer = timer //src.target = null src.moving = 0 diff --git a/code/modules/robotics/bot/medbot.dm b/code/modules/robotics/bot/medbot.dm index 4811a7c..ce81400 100644 --- a/code/modules/robotics/bot/medbot.dm +++ b/code/modules/robotics/bot/medbot.dm @@ -39,7 +39,6 @@ var/treatment_tox = "charcoal" var/treatment_virus = "spaceacillin" var/terrifying = 0 // for making the medbots all super fucked up - var/datum/light/light /obj/machinery/bot/medbot/no_camera no_camera = 1 @@ -135,10 +134,7 @@ /obj/machinery/bot/medbot/New() ..() - light = new /datum/light/point - light.attach(src) - light.set_brightness(0.5) - + add_simple_light("medbot", list(220, 220, 255, 0.5*255)) SPAWN_DBG(5) if (src) src.botcard = new /obj/item/card/id(src) @@ -430,9 +426,9 @@ /obj/machinery/bot/medbot/proc/toggle_power() src.on = !src.on if (src.on) - light.enable() + add_simple_light("medbot", list(220, 220, 255, 0.5*255)) else - light.disable() + remove_simple_light("medbot") src.patient = null src.oldpatient = null src.oldloc = null diff --git a/code/modules/robotics/bot/secbot.dm b/code/modules/robotics/bot/secbot.dm index 87b1fc9..83ab5ca 100644 --- a/code/modules/robotics/bot/secbot.dm +++ b/code/modules/robotics/bot/secbot.dm @@ -69,8 +69,6 @@ var/nearest_beacon // the nearest beacon's tag var/turf/nearest_beacon_loc // the nearest beacon's location - var/datum/light/light - disposing() radio_controller.remove_object(src, "1149") ..() @@ -147,10 +145,7 @@ if (!src.our_baton || !istype(src.our_baton)) src.our_baton = new our_baton_type(src) - light = new /datum/light/point - light.set_brightness(0.4) - light.attach(src) - light.enable() + add_simple_light("secbot", list(255, 255, 255, 0.4 * 255)) SPAWN_DBG(5) src.botcard = new /obj/item/card/id(src) @@ -205,9 +200,9 @@ Report Arrests: [report_arrests ? "On" if ((href_list["power"]) && (!src.locked || src.allowed(usr))) src.on = !src.on if (src.on) - light.enable() + add_simple_light("secbot", list(255, 255, 255, 0.4 * 255)) else - light.disable() + remove_simple_light("secbot") src.target = null src.oldtarget_name = null src.anchored = 0 @@ -825,6 +820,15 @@ Report Arrests: [report_arrests ? "On" var/weeoo = 10 playsound(src.loc, "sound/machines/siren_police.ogg", 50, 1) + while (weeoo) + add_simple_light("secbot", list(255 * 0.9, 255 * 0.1, 255 * 0.1, 0.8 * 255)) + sleep(3) + add_simple_light("secbot", list(255 * 0.1, 255 * 0.1, 255 * 0.9, 0.8 * 255)) + sleep(3) + weeoo-- + + //old one in case we still want that + /* light.set_brightness(0.8) while (weeoo) light.set_color(0.9, 0.1, 0.1) @@ -832,10 +836,11 @@ Report Arrests: [report_arrests ? "On" light.set_color(0.1, 0.1, 0.9) sleep(3) weeoo-- - light.set_brightness(0.4) light.set_color(1, 1, 1) + */ + add_simple_light("secbot", list(255, 255, 255, 0.4 * 255)) break else continue diff --git a/code/modules/sound/sound.dm b/code/modules/sound/sound.dm index baa5f83..1cfc521 100644 --- a/code/modules/sound/sound.dm +++ b/code/modules/sound/sound.dm @@ -1,6 +1,7 @@ #define TOO_QUIET 0.6 //experimentally found, I don't care if it's super quiet because there's already shitloads of other sounds playing #define EARLY_RETURN_IF_QUIET(v) if (v < TOO_QUIET) return #define EARLY_CONTINUE_IF_QUIET(v) if (v < TOO_QUIET) continue +#define MAX_SOUND_RANGE 31 // returns 0 to 1 /proc/attenuate_for_location(var/atom/loc) @@ -25,6 +26,8 @@ var/global/ECHO_AFAR = list(0,0,0,0,0,0,-10000,1.0,1.5,1.0,0,1.0,0,0,0,0,1.0,7) var/global/ECHO_CLOSE = list(0,0,0,0,0,0,0,0.25,1.5,1.0,0,1.0,0,0,0,0,1.0,7) +var/global/list/falloff_cache = list() + //volumous hair with l'orial paris /client/var/list/volumes = list(1, 1, 0.1, 0.5, 0.5) @@ -95,6 +98,11 @@ var/global/ECHO_CLOSE = list(0,0,0,0,0,0,0,0.25,1.5,1.0,0,1.0,0,0,0,0,1.0,7) var/mob/M = C.mob //LAGCHECK(LAG_LOW) + + var/dist = max(get_dist(C.mob, source), 1) + if (dist > MAX_SOUND_RANGE) + continue + Mloc = get_turf(M) if (Mloc && M.client && Mloc.z && Mloc.z == source.z) @@ -109,10 +117,25 @@ var/global/ECHO_CLOSE = list(0,0,0,0,0,0,0,0.25,1.5,1.0,0,1.0,0,0,0,0,1.0,7) //volume-related handling var/ourvolume = vol + + + if (dist > falloff_cache.len) + falloff_cache.len = dist + var/falloffmult = falloff_cache[dist] + if (falloffmult == null) + var/scaled_dist = clamp(dist/MAX_SOUND_RANGE,0,1) + falloffmult = (1 - ((1.2 * (0.5**-2.3)) / ((scaled_dist**-2.3) + (0.5**-2.3)))) + falloff_cache[dist] = falloffmult + + ourvolume *= falloffmult + + EARLY_CONTINUE_IF_QUIET(ourvolume) + //mbc : i'm making a call and removing this check's affect on volume bc it gets quite expensive and i dont care about the sound being quieter //if(M.ears_protected_from_sound()) //Bone conductivity, I guess? // ourvolume *= 0.2 ourvolume *= attenuate_for_location(Mloc) //SECRET GOON SOUND SAUCE + var/storedVolume = ourvolume ourvolume *= C.getVolume(channel) / 100 //boutput(world, "for client [C] updating volume [storedVolume] to [ourvolume] for channel [channel]") @@ -132,7 +155,7 @@ var/global/ECHO_CLOSE = list(0,0,0,0,0,0,0,0.25,1.5,1.0,0,1.0,0,0,0,0,1.0,7) else //boutput(M, "You hear a [source] at [source_location]!") S.echo = ECHO_CLOSE - //if(get_dist(M, source) >= 30) return // hard attentuation i guess + S.x = source.x - Mloc.x S.z = source.y - Mloc.y //Since sound coordinates are 3D, z for sound falls on y for the map. BYOND. S.y = 0 @@ -218,6 +241,9 @@ var/global/ECHO_CLOSE = list(0,0,0,0,0,0,0,0.25,1.5,1.0,0,1.0,0,0,0,0,1.0,7) if ("step_outdoors") soundin = pick(sounds_step_outdoors) if ("step_plating") soundin = pick(sounds_step_plating) if ("step_wood") soundin = pick(sounds_step_wood) + if ("step_rubberboot") soundin = pick(sounds_step_rubberboot) + if ("step_robo") soundin = pick(sounds_step_robo) + if ("step_flipflop") soundin = pick(sounds_step_flipflop) if(islist(soundin)) soundin = pick(soundin) @@ -229,7 +255,7 @@ var/global/ECHO_CLOSE = list(0,0,0,0,0,0,0,0.25,1.5,1.0,0,1.0,0,0,0,0,1.0,7) logTheThing("debug", null, null, "Sounds: Unable to find sound: [soundin]") return - S.falloff = (world.view + extrarange) / 3.5 + S.falloff = 9999//(world.view + extrarange) / 3.5 //world.log << "Playing sound; wv = [world.view] + er = [extrarange] / 3.5 = falloff [S.falloff]" S.wait = 0 //No queue S.channel = rand(1,900) //Any channel @@ -364,6 +390,12 @@ var/global/ECHO_CLOSE = list(0,0,0,0,0,0,0,0.25,1.5,1.0,0,1.0,0,0,0,0,1.0,7) /var/global/list/sounds_step_outdoors = list(sound('sound/misc/step/step_outdoors_1.ogg'),sound('sound/misc/step/step_outdoors_2.ogg'),sound('sound/misc/step/step_outdoors_3.ogg')) /var/global/list/sounds_step_plating = list(sound('sound/misc/step/step_plating_1.ogg'),sound('sound/misc/step/step_plating_2.ogg'),sound('sound/misc/step/step_plating_3.ogg'),sound('sound/misc/step/step_plating_4.ogg'),sound('sound/misc/step/step_plating_5.ogg')) /var/global/list/sounds_step_wood = list(sound('sound/misc/step/step_wood_1.ogg'),sound('sound/misc/step/step_wood_2.ogg'),sound('sound/misc/step/step_wood_3.ogg'),sound('sound/misc/step/step_wood_4.ogg'),sound('sound/misc/step/step_wood_5.ogg')) +/var/global/list/sounds_step_rubberboot = list(sound('sound/misc/step/step_rubberboot_1.ogg'),sound('sound/misc/step/step_rubberboot_2.ogg'),sound('sound/misc/step/step_rubberboot_3.ogg'),sound('sound/misc/step/step_rubberboot_4.ogg')) +/var/global/list/sounds_step_robo = list(sound('sound/misc/step/step_robo_1.ogg'),sound('sound/misc/step/step_robo_2.ogg'),sound('sound/misc/step/step_robo_3.ogg')) +/var/global/list/sounds_step_flipflop = list(sound('sound/misc/step/step_flipflop_1.ogg'),sound('sound/misc/step/step_flipflop_2.ogg'),sound('sound/misc/step/step_flipflop_3.ogg')) + + + //talksounds /var/global/list/sounds_speak = list( \ diff --git a/code/modules/sound/soundCache.dm b/code/modules/sound/soundCache.dm index 6e96c38..2b7697a 100644 --- a/code/modules/sound/soundCache.dm +++ b/code/modules/sound/soundCache.dm @@ -153,6 +153,7 @@ var/global/list/soundCache = list( "sound/effects/bubbles.ogg" = 'sound/effects/bubbles.ogg',\ "sound/effects/bubbles2.ogg" = 'sound/effects/bubbles2.ogg',\ "sound/effects/bubbles3.ogg" = 'sound/effects/bubbles3.ogg',\ + "sound/effects/chair_step.ogg" = 'sound/effects/chair_step.ogg',\ "sound/effects/chalk1.ogg" = 'sound/effects/chalk1.ogg',\ "sound/effects/chalk2.ogg" = 'sound/effects/chalk2.ogg',\ "sound/effects/chalk3.ogg" = 'sound/effects/chalk3.ogg',\ @@ -181,6 +182,7 @@ var/global/list/soundCache = list( "sound/effects/fireworks1.ogg" = 'sound/effects/fireworks1.ogg',\ "sound/effects/flame.ogg" = 'sound/effects/flame.ogg',\ "sound/effects/flameswoosh.ogg" = 'sound/effects/flameswoosh.ogg',\ + "sound/effects/flip.ogg" = 'sound/effects/flip.ogg',\ "sound/effects/ghost.ogg" = 'sound/effects/ghost.ogg',\ "sound/effects/ghost2.ogg" = 'sound/effects/ghost2.ogg',\ "sound/effects/ghostambi1.ogg" = 'sound/effects/ghostambi1.ogg',\ @@ -533,6 +535,7 @@ var/global/list/soundCache = list( "sound/machines/printer_dotmatrix.ogg" = 'sound/machines/printer_dotmatrix.ogg',\ "sound/machines/printer_thermal.ogg" = 'sound/machines/printer_thermal.ogg',\ "sound/machines/repairing.ogg" = 'sound/machines/repairing.ogg',\ + "sound/machines/reprog.ogg" = 'sound/machines/reprog.ogg',\ "sound/machines/rev_engine.ogg" = 'sound/machines/rev_engine.ogg',\ "sound/machines/romhack1.ogg" = 'sound/machines/romhack1.ogg',\ "sound/machines/romhack2.ogg" = 'sound/machines/romhack2.ogg',\ diff --git a/code/modules/status_system/statusFoodBuffs.dm b/code/modules/status_system/statusFoodBuffs.dm index d4d79c6..d63f864 100644 --- a/code/modules/status_system/statusFoodBuffs.dm +++ b/code/modules/status_system/statusFoodBuffs.dm @@ -141,9 +141,10 @@ var/times = (tickCount / tickSpacing) if(times >= 1 && ismob(owner)) tickCount -= (round(times) * tickSpacing) - for(var/i = 0, i < times, i++) - if (ishuman(owner)) - owner:bodytemperature -= 0.8 + var/mob/M = owner + if (M.bodytemperature > M.base_body_temp + 3) + for(var/i = 0, i < times, i++) + M.bodytemperature -= 2 return /datum/statusEffect/foodwarm @@ -163,9 +164,10 @@ var/times = (tickCount / tickSpacing) if(times >= 1 && ismob(owner)) tickCount -= (round(times) * tickSpacing) - for(var/i = 0, i < times, i++) - if (ishuman(owner)) - owner:bodytemperature += 6 + var/mob/M = owner + if (M.bodytemperature < M.base_body_temp + 8) + for(var/i = 0, i < times, i++) + M.bodytemperature += 6 return /datum/statusEffect/foodstaminaregen diff --git a/code/modules/status_system/statusSystem.dm b/code/modules/status_system/statusSystem.dm index 7df724c..3670cc5 100644 --- a/code/modules/status_system/statusSystem.dm +++ b/code/modules/status_system/statusSystem.dm @@ -185,6 +185,8 @@ var/list/statusGroupLimits = list("Food"=4) //Update it if(duration > 0 || isnull(duration)) var/datum/statusEffect/localInstance = hasStatus(statusId) + if (duration) + duration = localInstance.duration + localInstance.modify_change(duration - localInstance.duration) localInstance.duration = (isnull(localInstance.maxDuration) ? (duration):(min(duration, localInstance.maxDuration))) localInstance.onChange(optional) src.updateStatusUi() @@ -195,8 +197,10 @@ var/list/statusGroupLimits = list("Food"=4) if((duration > 0 || isnull(duration)) && !groupFull) //Add it var/datum/statusEffect/localInstance = new globalInstance.type() - localInstance.duration = (isnull(localInstance.maxDuration) ? (duration):(min(duration, localInstance.maxDuration))) localInstance.owner = src + if (duration) + duration = localInstance.duration + localInstance.modify_change(duration - localInstance.duration) + localInstance.duration = (isnull(localInstance.maxDuration) ? (duration):(min(duration, localInstance.maxDuration))) localInstance.archivedOwnerInfo = "OwnerName:[src.name] - OwnerType:[src.type] - ContLen:[src.contents.len] - StatusLen:[src.statusEffects.len]" localInstance.onAdd(optional) if(!statusEffects.Find(localInstance)) statusEffects.Add(localInstance) @@ -209,8 +213,10 @@ var/list/statusGroupLimits = list("Food"=4) //Add it if((duration > 0 || isnull(duration)) && !groupFull) var/datum/statusEffect/localInstance = new globalInstance.type() - localInstance.duration = (isnull(localInstance.maxDuration) ? (duration):(min(duration, localInstance.maxDuration))) localInstance.owner = src + if (duration) + duration = localInstance.duration + localInstance.modify_change(duration - localInstance.duration) + localInstance.duration = (isnull(localInstance.maxDuration) ? (duration):(min(duration, localInstance.maxDuration))) localInstance.archivedOwnerInfo = "OwnerName:[src.name] - OwnerType:[src.type] - ContLen:[src.contents.len] - StatusLen:[src.statusEffects.len]" localInstance.onAdd(optional) if(!statusEffects.Find(localInstance)) statusEffects.Add(localInstance) @@ -281,6 +287,9 @@ var/list/statusGroupLimits = list("Food"=4) proc/preCheck(var/atom/A) //Used to run a custom check before adding status to an object. For when you want something to be flat out immune or something. ret = 1 allow, 0 = do not allow return 1 + proc/modify_change(var/change) + .= change + proc/onAdd(var/optional=null) //Called when the status is added to an object. owner is already set at this point. Has the optional arg from setStatus passed in. return @@ -721,11 +730,18 @@ var/list/statusGroupLimits = list("Food"=4) return ..(timedPassed) stuns + modify_change(var/change) + . = change + if (owner && ismob(owner)) + var/mob/M = owner + var/percent_protection = M.get_stun_resist_mod() + percent_protection = 1 - (percent_protection/100) //scale from 0 to 1 + . *= percent_protection onRemove() ..() if(!owner) return - if (!owner.hasStatus("stunned") && !owner.hasStatus("weakened") && !owner.hasStatus("paralysis")) + if (!owner.hasStatus("stunned") && !owner.hasStatus("weakened") && !owner.hasStatus("paralysis") && !owner.hasStatus("pinned")) //consider later : a way to group effects to check a bunch in one proc call and save sonme cpu if (isliving(owner)) var/mob/living/L = owner L.force_laydown_standup() @@ -746,6 +762,35 @@ var/list/statusGroupLimits = list("Food"=4) unique = 1 maxDuration = 30 SECONDS + pinned + id = "pinned" + name = "Pinned" + desc = "You are pinned. Click this status effect to resist.
Unable to take any actions, prone." + icon_state = "pin" + unique = 1 + maxDuration = null + + + clicked(list/params) + if (ishuman(owner)) + var/mob/living/carbon/human/H = owner + H.resist() + + onUpdate() + if (ismob(owner)) + var/mob/M = owner + var/found = 0 + if (M.grabbed_by) + for (var/obj/item/grab/G in M.grabbed_by) + if (G.state == GRAB_PIN) + found = 1 + if (!found) + owner.delStatus("pinned") + + .=..() + + + paralysis id = "paralysis" name = "Unconscious" @@ -794,6 +839,7 @@ var/list/statusGroupLimits = list("Food"=4) desc = "You are disoriented.
Movement speed is reduced. You may stumble or drop items." icon_state = "disorient" unique = 1 + maxDuration = 15 SECONDS var/counter = 0 var/sound = "sound/effects/electric_shock_short.ogg" var/count = 7 @@ -1016,6 +1062,8 @@ var/list/statusGroupLimits = list("Food"=4) if(ismob(owner)) //var/mob/M = owner owner.delStatus("janktank_withdrawl") + var/mob/M = owner + M.add_stun_resist_mod("janktank", 40) else owner.delStatus("janktank") return @@ -1024,6 +1072,8 @@ var/list/statusGroupLimits = list("Food"=4) if(ismob(owner)) //var/mob/M = owner owner.setStatus("janktank_withdrawl", 25 MINUTES) + var/mob/M = owner + M.remove_stun_resist_mod("janktank") return onUpdate(var/timedPassed) @@ -1039,9 +1089,6 @@ var/list/statusGroupLimits = list("Food"=4) if (H.bleeding) repair_bleeding_damage(H, 10, 1) - H.changeStatus("stunned", -1 SECONDS) - H.changeStatus("weakened", -1 SECONDS) - H.changeStatus("disorient", -1 SECONDS) if (H.misstep_chance) H.change_misstep_chance(-5) diff --git a/code/modules/telescience/teleporter_old.dm b/code/modules/telescience/teleporter_old.dm index 3d1a545..06fb75f 100644 --- a/code/modules/telescience/teleporter_old.dm +++ b/code/modules/telescience/teleporter_old.dm @@ -4,6 +4,7 @@ density = 1 anchored = 1.0 mats = 10 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_WIRECUTTERS | DECON_MULTITOOL New() ..() diff --git a/code/modules/transport/pods/MainWeapon.dm b/code/modules/transport/pods/MainWeapon.dm index 67856b3..7202d9f 100644 --- a/code/modules/transport/pods/MainWeapon.dm +++ b/code/modules/transport/pods/MainWeapon.dm @@ -57,7 +57,7 @@ return -/obj/item/shipcomponent/mainweapon/proc/Fire(var/mob/user) +/obj/item/shipcomponent/mainweapon/proc/Fire(var/mob/user,var/shot_dir_override = -1) if(isfiring) return isfiring = 1 if(uses_ammunition) @@ -67,9 +67,11 @@ return var/rdir = ship.dir - if (!istype(ship,/obj/machinery/vehicle/tank)) //Tanks are allowed to shoot diagonally! - if ((rdir - 1) & rdir) - rdir &= 12 + if (shot_dir_override > 1) + rdir = shot_dir_override + //if (!istype(ship,/obj/machinery/vehicle/tank)) //Tanks are allowed to shoot diagonally! + // if ((rdir - 1) & rdir) + // rdir &= 12 logTheThing("combat", usr, null, "driving [ship.name] fires [src.name] (Dir: [dir2text(rdir)], Projectile: [src.current_projectile]) at [log_loc(ship)].") // Similar to handguns, but without target coordinates (Convair880). ship.ShootProjectiles(user, current_projectile, rdir) remaining_ammunition -= ship.AmmoPerShot() @@ -262,13 +264,16 @@ mode = !mode ..() - Fire(var/mob/user) + Fire(var/mob/user,var/shot_dir_override = -1) switch(mode) if(0) if(isfiring) return isfiring = 1 var/obj/decal/D = new/obj/decal(ship.loc) D.dir = ship.dir + if (shot_dir_override > 1) + D.dir = shot_dir_override + D.name = "metal foam spray" D.icon = 'icons/obj/chemical.dmi' D.icon_state = "chempuff" diff --git a/code/modules/transport/pods/ships.dm b/code/modules/transport/pods/ships.dm index e83a544..8ec2f3b 100644 --- a/code/modules/transport/pods/ships.dm +++ b/code/modules/transport/pods/ships.dm @@ -880,33 +880,72 @@ ShootProjectiles(var/mob/user, var/datum/projectile/PROJ, var/shoot_dir) var/H = (shoot_dir & 3) ? 1 : 0 var/V = (shoot_dir & 12) ? 1 : 0 - if (shoot_dir == SOUTH || shoot_dir == WEST) - var/obj/projectile/P = shoot_projectile_DIR(src, PROJ, shoot_dir) - if (P) - P.mob_shooter = user - P.pixel_x = H * -5 - P.pixel_y = V * -5 - if (shoot_dir == SOUTH || shoot_dir == EAST) - var/obj/projectile/P = shoot_projectile_DIR(get_step(get_turf(src), EAST), PROJ, shoot_dir) - if (P) - P.shooter = src - P.mob_shooter = user - P.pixel_x = H * 5 - P.pixel_y = V * -5 - if (shoot_dir == NORTH || shoot_dir == WEST) - var/obj/projectile/P = shoot_projectile_DIR(get_step(get_turf(src), NORTH), PROJ, shoot_dir) - if (P) - P.shooter = src - P.mob_shooter = user - P.pixel_x = H * -5 - P.pixel_y = V * 5 - if (shoot_dir == NORTH || shoot_dir == EAST) - var/obj/projectile/P = shoot_projectile_DIR(get_step(get_turf(src), NORTHEAST), PROJ, shoot_dir) - if (P) - P.shooter = src - P.mob_shooter = user - P.pixel_x = H * 5 - P.pixel_y = V * 5 + + //fucK ME + if (shoot_dir & (shoot_dir-1)) + if (shoot_dir == SOUTHEAST) + var/obj/projectile/P = shoot_projectile_DIR(get_step(get_turf(src), SOUTHEAST), PROJ, shoot_dir) + if (P) + P.mob_shooter = user + var/turf/E = get_step(get_turf(src), EAST) + P = shoot_projectile_DIR(get_step(E, EAST), PROJ, shoot_dir) + if (P) + P.mob_shooter = user + if (shoot_dir == SOUTHWEST) + var/obj/projectile/P = shoot_projectile_DIR(get_step(get_turf(src), WEST), PROJ, shoot_dir) + if (P) + P.mob_shooter = user + P = shoot_projectile_DIR(get_step(get_turf(src), SOUTH), PROJ, shoot_dir) + if (P) + P.mob_shooter = user + + if (shoot_dir == NORTHEAST) + var/turf/NE = get_step(get_turf(src), NORTHEAST) + + var/obj/projectile/P = shoot_projectile_DIR(get_step(NE, NORTH), PROJ, shoot_dir) + if (P) + P.mob_shooter = user + P = shoot_projectile_DIR(get_step(NE, EAST), PROJ, shoot_dir) + if (P) + P.mob_shooter = user + + if (shoot_dir == NORTHWEST) + var/turf/N = get_step(get_turf(src), NORTH) + var/obj/projectile/P = shoot_projectile_DIR(get_step(N, WEST), PROJ, shoot_dir) + if (P) + P.mob_shooter = user + P = shoot_projectile_DIR(get_step(N, NORTH), PROJ, shoot_dir) + if (P) + P.mob_shooter = user + else + if (shoot_dir == SOUTH || shoot_dir == WEST) + var/obj/projectile/P = shoot_projectile_DIR(src, PROJ, shoot_dir) + if (P) + P.mob_shooter = user + P.pixel_x = H * -5 + P.pixel_y = V * -5 + if (shoot_dir == SOUTH || shoot_dir == EAST) + var/obj/projectile/P = shoot_projectile_DIR(get_step(get_turf(src), EAST), PROJ, shoot_dir) + if (P) + P.shooter = src + P.mob_shooter = user + P.pixel_x = H * 5 + P.pixel_y = V * -5 + if (shoot_dir == NORTH || shoot_dir == WEST) + var/obj/projectile/P = shoot_projectile_DIR(get_step(get_turf(src), NORTH), PROJ, shoot_dir) + if (P) + P.shooter = src + P.mob_shooter = user + P.pixel_x = H * -5 + P.pixel_y = V * 5 + if (shoot_dir == NORTH || shoot_dir == EAST) + var/obj/projectile/P = shoot_projectile_DIR(get_step(get_turf(src), NORTHEAST), PROJ, shoot_dir) + if (P) + P.shooter = src + P.mob_shooter = user + P.pixel_x = H * 5 + P.pixel_y = V * 5 + /obj/machinery/vehicle/pod_smooth/light // standard civilian pods name = "Pod C-" diff --git a/code/modules/transport/pods/vehicle.dm b/code/modules/transport/pods/vehicle.dm index eac4ee8..12c1429 100644 --- a/code/modules/transport/pods/vehicle.dm +++ b/code/modules/transport/pods/vehicle.dm @@ -49,6 +49,10 @@ var/view_offset_y = 0 var/datum/movement_controller/movement_controller + var/req_smash_velocity = 9 //7 is the 'normal' cap right now + var/hitmob = 0 + var/ram_self_damage_multiplier = 0.09 + ////////////////////////////////////////////////////// ///////Life Support Stuff //////////////////////////// ///////////////////////////////////////////////////// @@ -442,7 +446,7 @@ var/damage = 0 damage = round((P.power*P.proj_data.ks_ratio), 1.0) - if (damage <= 0 && P.proj_data.ks_ratio <= 0) + if (damage <= 0 && P.proj_data.ks_ratio <= 0) //make stun weapons do some damage damage = round(P.power, 1.0) var/hitsound = null @@ -520,13 +524,21 @@ //if (P) // for (var/mob/M in src) // M.bullet_act_indirect(P) - var/chance = disruption * 2.5 + var/chance = disruption * 1 for(var/obj/item/shipcomponent/S in src.components) var/my_chance = chance if (istype(S, /obj/item/shipcomponent/engine)) - my_chance -= 25 + my_chance += 40 + if(prob(my_chance)) - S.deactivate() + if (istype(S, /obj/item/shipcomponent/engine)) //dont turn off engine thats annoying. instead ddisable the wormhole func!! + var/obj/item/shipcomponent/engine/E = S + if (E.ready) + E.ready = 0 + E.ready() + else + S.deactivate() + chance -= 25 if (chance <= 0) return @@ -556,12 +568,84 @@ src.health -= 25 checkhealth() - Bump(var/atom/A) - //boutput(world, "[src] bumped into [A]") + proc/get_move_velocity_magnitude() + .= movement_controller:velocity_magnitude + + Bump(var/atom/target) + if (get_move_velocity_magnitude() > 5) + var/power = get_move_velocity_magnitude() + + src.health -= min(power * ram_self_damage_multiplier,5) + checkhealth() + + if (istype(target, /obj/machinery/vehicle/)) + var/obj/machinery/vehicle/V = target + V.health -= min(power*1.5,30) + V.checkhealth() + + for (var/mob/C in src) + shake_camera(C, 6, 1) + //M << sound("sound/impact_sounds/Generic_Hit_Heavy_1.ogg",volume=35) + + if (ismob(target) && target != hitmob) + hitmob = target + SPAWN_DBG(5) + hitmob = 0 + var/mob/M = target + //M.changeStatus("stunned", 1 SECONDS) + //M.changeStatus("weakened", 1 SECONDS) + M.TakeDamage("chest", power * 1.3, 0, 0, DAMAGE_BLUNT) + M.remove_stamina(power) + var/turf/throw_at = get_edge_target_turf(src, src.dir) + SPAWN_DBG(0) + M.throw_at(throw_at, movement_controller:velocity, 2) + logTheThing("combat", src, target, "crashes into [target] [log_loc(src)].") + else if(isturf(target) && power > 20) + if(istype(target, /turf/simulated/wall/r_wall || istype(target, /turf/simulated/wall/auto/reinforced)) && prob(power / 2)) + return + if(istype(target, /turf/simulated/wall) && prob(power)) + var/turf/simulated/wall/T = target + T.dismantle_wall(1) + + logTheThing("combat", src, target, "crashes into [target] [log_loc(src)].") + else if (isobj(target) && power >= req_smash_velocity) + var/obj/O = target + + if (power > 20) + if (istype(O, /obj/machinery/door) && O.density) + var/obj/machinery/door/D = O + D.try_force_open(src) + if (istype(O, /obj/structure/girder) || istype(O, /obj/foamedmetal)) + qdel(O) + + if (istype(target, /obj/window)) + var/obj/window/W = target + W.health = 0 + W.smash() + + if (istype(O, /obj/grille)) + var/obj/grille/G = target + G.damage_slashing(15) + + if (istype(O, /obj/table)) + var/obj/table/table = target + table.deconstruct() + + if (istype(O,/obj/machinery/vending)) + var/obj/machinery/vending/V = O + V.fall(src) + if (istype(O,/obj/machinery/portable_atmospherics/canister)) + var/obj/machinery/portable_atmospherics/canister/C = O + C.health -= power + C.healthcheck() + logTheThing("combat", src, target, "crashes into [target] [log_loc(src)].") + + playsound(src.loc, "sound/impact_sounds/Generic_Hit_Heavy_1.ogg", 40, 1) + if (sec_system) if (sec_system.type == /obj/item/shipcomponent/secondary_system/crash) if (sec_system:crashable) - sec_system:crashtime2(A) + sec_system:crashtime2(target) SPAWN_DBG (0) ..() return @@ -575,7 +659,9 @@ // set return value to default .=..(NewLoc,Dir,step_x,step_y) - if (flying && facing != flying) + if (movement_controller) + movement_controller.update_owner_dir() + else if (flying && facing != flying) dir = facing disposing() @@ -642,7 +728,7 @@ M.update_burning(35) boutput(M, "The cabin bursts into flames!") playsound(M.loc, "sound/machines/engine_alert1.ogg", 35, 0) - if(26 to 50) + if(26 to health * 0.5) if(damage_overlays < 1) damage_overlays = 1 damage_overlay = image('icons/effects/64x64.dmi', "pod_damage") @@ -1466,14 +1552,14 @@ if(usr == ship.m_w_system.gunner) ship.stall += 1 ship.fire_delay += 1 - ship.m_w_system.Fire(usr) + ship.m_w_system.Fire(usr, src.facing) SPAWN_DBG(15) ship.fire_delay -= 1 // cogwerks: no more spamming lasers until the server dies if (ship.fire_delay > 0) ship.fire_delay = 0 else boutput(usr, "[ship.ship_message("You must be in the gunner seat!")]") else - ship.m_w_system.Fire() + ship.m_w_system.Fire(usr, src.facing) else boutput(usr, "[ship.ship_message("SYSTEM OFFLINE")]") else @@ -1645,11 +1731,9 @@ speed = 0 // speed literally does nothing? what?? stall = 0 // slow the ship down when firing weapon_class = 1 - var/req_smash_velocity = 9 //7 is the 'normal' cap right now var/prev_velocity = 0 - - var/hitmob = 0 + ram_self_damage_multiplier = 0.14 //var/datum/movement_controller/pod/movement_controller New() @@ -1668,6 +1752,9 @@ M.accel_sfx = 0 playsound(src, "sound/machines/rev_engine.ogg", 40, 1) + get_move_velocity_magnitude() + .= movement_controller:velocity + Install(obj/item/shipcomponent/S as obj) if(S.system == "Locomotion") if (istype(src,/obj/machinery/vehicle/tank)) @@ -1693,77 +1780,6 @@ locomotion.set_loc(src.loc) locomotion = null - Bump(var/atom/target) - if (movement_controller:velocity > 5) - var/power = movement_controller:velocity - - src.health -= min(power/6,5) - checkhealth() - - if (istype(target, /obj/machinery/vehicle/)) - var/obj/machinery/vehicle/V = target - V.health -= min(power*2,30) - V.checkhealth() - - for (var/mob/C in src) - shake_camera(C, 6, 1) - if (ismob(target) && target != hitmob) - hitmob = target - SPAWN_DBG(5) - hitmob = 0 - var/mob/M = target - //M.changeStatus("stunned", 1 SECONDS) - //M.changeStatus("weakened", 1 SECONDS) - M.TakeDamage("chest", power * 1.3, 0, 0, DAMAGE_BLUNT) - M.remove_stamina(power) - var/turf/throw_at = get_edge_target_turf(src, src.dir) - SPAWN_DBG(0) - M.throw_at(throw_at, movement_controller:velocity, 2) - logTheThing("combat", src, target, "crashes into [target] [log_loc(src)].") - else if(isturf(target) && power > 20) - if(istype(target, /turf/simulated/wall/r_wall || istype(target, /turf/simulated/wall/auto/reinforced)) && prob(power / 2)) - return - if(istype(target, /turf/simulated/wall) && prob(power)) - var/turf/simulated/wall/T = target - T.dismantle_wall(1) - - logTheThing("combat", src, target, "crashes into [target] [log_loc(src)].") - else if (isobj(target) && power >= req_smash_velocity) - var/obj/O = target - - if (power > 20) - if (istype(O, /obj/machinery/door) && O.density) - var/obj/machinery/door/D = O - D.try_force_open(src) - if (istype(O, /obj/structure/girder) || istype(O, /obj/foamedmetal)) - qdel(O) - - if (istype(target, /obj/window)) - var/obj/window/W = target - W.health = 0 - W.smash() - - if (istype(O, /obj/grille)) - var/obj/grille/G = target - G.damage_slashing(15) - - if (istype(O, /obj/table)) - var/obj/table/table = target - table.deconstruct() - - if (istype(O,/obj/machinery/vending)) - var/obj/machinery/vending/V = O - V.fall(src) - if (istype(O,/obj/machinery/portable_atmospherics/canister)) - var/obj/machinery/portable_atmospherics/canister/C = O - C.health -= power - C.healthcheck() - logTheThing("combat", src, target, "crashes into [target] [log_loc(src)].") - - playsound(src.loc, "sound/impact_sounds/Generic_Hit_Heavy_1.ogg", 40, 1) - ..() - - /obj/machinery/vehicle/tank/minisub body_type = "minisub" event_handler_flags = USE_FLUID_ENTER | IMMUNE_MANTA_PUSH diff --git a/code/modules/transport/shuttle/shuttle_turfobjs.dm b/code/modules/transport/shuttle/shuttle_turfobjs.dm index 3c4a749..0253ffb 100644 --- a/code/modules/transport/shuttle/shuttle_turfobjs.dm +++ b/code/modules/transport/shuttle/shuttle_turfobjs.dm @@ -38,6 +38,7 @@ icon = 'icons/turf/shuttle.dmi' thermal_conductivity = 0.05 heat_capacity = 0 + turf_flags = MOB_STEP attackby() attack_hand() @@ -57,6 +58,7 @@ name = "shuttle floor" icon_state = "floor" icon = 'icons/turf/shuttle.dmi' + turf_flags = MOB_STEP attackby() attack_hand() diff --git a/code/modules/vending/vending.dm b/code/modules/vending/vending.dm index 69b579a..387c399 100644 --- a/code/modules/vending/vending.dm +++ b/code/modules/vending/vending.dm @@ -38,6 +38,8 @@ anchored = 1 density = 1 mats = 20 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_MULTITOOL + object_flags = CAN_REPROGRAM_ACCESS var/freestuff = 0 var/obj/item/card/id/scan = null diff --git a/code/obj.dm b/code/obj.dm index 1b84448..2d1af0c 100644 --- a/code/obj.dm +++ b/code/obj.dm @@ -10,6 +10,8 @@ var/is_syndicate = 0 var/list/mats = 0 + var/deconstruct_flags = DECON_NONE + var/mechanics_type_override = null //Fix for children of scannable items being reproduced in mechanics var/artifact = null var/move_triggered = 0 diff --git a/code/obj/ToSplit/barber_shop.dm b/code/obj/ToSplit/barber_shop.dm index 8ccfb23..18d0258 100644 --- a/code/obj/ToSplit/barber_shop.dm +++ b/code/obj/ToSplit/barber_shop.dm @@ -384,6 +384,7 @@ density = 1 anchored = 1.0 mats = 15 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_MULTITOOL var/obj/item/dye_bottle/bottle = null diff --git a/code/obj/artifacts/artifactprocs.dm b/code/obj/artifacts/artifactprocs.dm index 3ce7152..dfb2675 100644 --- a/code/obj/artifacts/artifactprocs.dm +++ b/code/obj/artifacts/artifactprocs.dm @@ -243,6 +243,13 @@ src.visible_message("[user.name] burns the artifact with [ZIP]!") return 0 + if (istype(W, /obj/item/robodefibrillator)) + var/obj/item/robodefibrillator/R = W + if (R.do_the_shocky_thing(user)) + src.ArtifactStimulus("elec", 2500) + src.visible_message("[user.name] shocks \the [src] with \the [R]!") + return 0 + if(istype(W,/obj/item/baton)) var/obj/item/baton/BAT = W if (BAT.can_stun(1, 1, user) == 1) @@ -255,10 +262,36 @@ if (istype(W,/obj/item/parts/robot_parts)) var/obj/item/parts/robot_parts/THISPART = W - src.visible_message("[user.name] activates the [THISPART] and it reaches out to the artifact.") + src.visible_message("[user.name] presses \the [THISPART] against \the [src].") src.ArtifactStimulus("silitouch", 1) return 0 + if (istype(W, /obj/item/parts/human_parts)) + var/obj/item/parts/human_parts/THISPART = W + src.visible_message("[user.name] smooshes \the [THISPART] against \the [src].") + src.ArtifactStimulus("carbtouch", 1) + return 0 + + if (istype(W, /obj/item/grab)) + var/obj/item/grab/GRAB = W + if (ismob(GRAB.affecting)) + if (GRAB.state < 1) + // Not a strong grip so just smoosh em into it + // generally speaking only humans and the like can be grabbed so whatev + if (istype(GRAB.affecting, /mob/living/carbon)) + src.visible_message("[user] gently presses [GRAB.affecting] against \the [src].") + src.ArtifactStimulus("carbtouch", 1) + return 0 + + var/mob/M = GRAB.affecting + var/mob/A = GRAB.assailant + if (get_dist(src.loc, M.loc) > 1) + return + src.visible_message("[A] shoves [M] against \the [src]!") + logTheThing("combat", A, M, "forces %target% to touch \an ([A.type]) artifact at [log_loc(src)].") + src.ArtifactTouched(M) + return 0 + if (istype(W,/obj/item/circuitboard)) var/obj/item/circuitboard/CIRCUITBOARD = W src.visible_message("[user.name]offers the [CIRCUITBOARD] to the artifact.") diff --git a/code/obj/critter/gunbot.dm b/code/obj/critter/gunbot.dm index eac5e3d..202dbfc 100644 --- a/code/obj/critter/gunbot.dm +++ b/code/obj/critter/gunbot.dm @@ -16,6 +16,7 @@ brutevuln = 1 is_syndicate = 1 mats = 8 + deconstruct_flags = DECON_CROWBAR | DECON_WELDER | DECON_WIRECUTTERS | DECON_MULTITOOL seek_target() src.anchored = 0 diff --git a/code/obj/decal.dm b/code/obj/decal.dm index 223028e..eb4678c 100644 --- a/code/obj/decal.dm +++ b/code/obj/decal.dm @@ -401,6 +401,53 @@ obj/decal/fakeobjects/teleport_pad event_handler_flags = USE_FLUID_ENTER | USE_CHECKEXIT | USE_CANPASS CanPass(atom/movable/mover, turf/target, height=0, air_group=0) // stolen from window.dm + if (mover && mover.throwing & THROW_CHAIRFLIP) + return 1 + if (src.dir == SOUTHWEST || src.dir == SOUTHEAST || src.dir == NORTHWEST || src.dir == NORTHEAST || src.dir == SOUTH || src.dir == NORTH) + return 0 + if(get_dir(loc, target) == dir) + + return !density + else + return 1 + + CheckExit(atom/movable/O as mob|obj, target as turf) + if (!src.density) + return 1 + if (get_dir(O.loc, target) == src.dir) + return 0 + return 1 + +/obj/stool/chair/boxingrope_corner + name = "Boxing Ropes" + desc = "Do not exit the ring." + density = 1 + anchored = 1 + icon = 'icons/obj/decoration.dmi' + icon_state = "ringrope" + layer = OBJ_LAYER + event_handler_flags = USE_FLUID_ENTER | USE_CHECKEXIT | USE_CANPASS + + rotatable = 0 + foldable = 0 + climbable = 2 + buckle_move_delay = 6 // this should have been a var somepotato WHY WASN'T IT A VAR + securable = 0 + + MouseDrop_T(mob/M as mob, mob/user as mob) + if (M != user) + return + + if ((!( iscarbon(M) ) || get_dist(src, user) > 1 || user.restrained() || usr.stat || !user.canmove)) + return + + M.set_loc(src.loc) + user.visible_message("[M] climbs up on [src]!", "You climb up on [src].") + buckle_in(M, 1) + + CanPass(atom/movable/mover, turf/target, height=0, air_group=0) // stolen from window.dm + if (mover && mover.throwing & THROW_CHAIRFLIP) + return 1 if (src.dir == SOUTHWEST || src.dir == SOUTHEAST || src.dir == NORTHWEST || src.dir == NORTHEAST || src.dir == SOUTH || src.dir == NORTH) return 0 if(get_dir(loc, target) == dir) diff --git a/code/obj/item.dm b/code/obj/item.dm index ae55260..eba1e85 100644 --- a/code/obj/item.dm +++ b/code/obj/item.dm @@ -84,6 +84,11 @@ var/block_hearing_when_worn = HEARING_NORMAL //fuck me mbc why you do this | | ok i did it to reduce type checking in a proc that gets called A LOT and idk what else to do ok help + + var/obj/item/grab/chokehold = null + var/obj/item/grab/special_grab = null + + proc/setTwoHanded(var/twohanded = 1) //This is the safe way of changing 2-handed-ness at runtime. Use this please. if(ismob(src.loc)) var/mob/L = src.loc @@ -502,8 +507,8 @@ after_stack(O, user, added) +#define src_exists_inside_user_or_user_storage (src.loc == user || (istype(src.loc, /obj/item/storage) && src.loc.loc == user)) -#define src_exists_inside_usr_or_usr_storage (src.loc == usr || (istype(src.loc, /obj/item/storage) && src.loc.loc == usr)) /obj/item/MouseDrop(atom/over_object, src_location, over_location, params) ..() @@ -513,21 +518,45 @@ var/on_turf = isturf(src.loc) + var/mob/user = usr - if (isturf(over_object) && in_range(over_object,src)) - if (on_turf) //drag from floor to floor == slide - if (istype(over_object,/turf/simulated/floor) || istype(over_object,/turf/unsimulated/floor)) + params = params2list(params) + + if (isliving(over_object) && isliving(usr) && !istype(src,/obj/item/storage)) //pickup action + if (user == over_object) + actions.start(new /datum/action/bar/private/icon/pickup(src), user) + //else // use laterr, after we improve the 'give' dialog to work with multicontext + // if (get_dist(user,over_object) <= 1 && src_exists_inside_usr_or_usr_storage) + // user.give_to(over_object) + else + + if (isturf(over_object)) + if (on_turf && in_range(over_object,src)) //drag from floor to floor == slide + if (istype(over_object,/turf/simulated/floor) || istype(over_object,/turf/unsimulated/floor)) + step_to(src,over_object) + //this would be cool ha ha h + //if (islist(params) && params["icon-y"] && params["icon-x"]) + //src.pixel_x = text2num(params["icon-x"]) - 16 + //src.pixel_y = text2num(params["icon-y"]) - 16 + //animate(src, pixel_x = text2num(params["icon-x"]) - 16, pixel_y = text2num(params["icon-y"]) - 16, time = 30, flags = ANIMATION_END_NOW) + return + else if (src_exists_inside_user_or_user_storage && !istype(src,/obj/item/storage)) //sorry for the storage check, i dont wanna override their mousedrop and to do it Correcly would be a whole big rewrite + usr.drop_from_slot(src) //drag from inventory to floor == drop step_to(src,over_object) - //this would be cool ha ha h - //if (islist(params) && params["icon-y"] && params["icon-x"]) - //src.pixel_x = text2num(params["icon-x"]) - 16 - //src.pixel_y = text2num(params["icon-y"]) - 16 - //animate(src, pixel_x = text2num(params["icon-x"]) - 16, pixel_y = text2num(params["icon-y"]) - 16, time = 30, flags = ANIMATION_END_NOW) - return - else if (src_exists_inside_usr_or_usr_storage && !istype(src,/obj/item/storage)) //sorry for the storage check, i dont wanna override their mousedrop and to do it Correcly would be a whole big rewrite - usr.drop_from_slot(src) //drag from inventory to floor == drop - step_to(src,over_object) + + var/is_storage = istype(over_object,/obj/item/storage) + if (is_storage || istype(over_object, /obj/screen/hud)) + if (on_turf && isturf(over_object.loc) && is_storage) + try_equip_to_inventory_object(usr, over_object, params) + else if (on_turf) + actions.start(new /datum/action/bar/private/icon/pickup/then_hud_click(src, over_object, params), usr) + else + try_equip_to_inventory_object(usr, over_object, params) + + +//equip an item, given an inventory hud object or storage item UI thing +/obj/item/proc/try_equip_to_inventory_object(var/mob/user, var/atom/over_object, var/params) var/obj/screen/hud/S = over_object if (istype(S)) if (S.master && istype(S.master,/datum/hud/storage)) @@ -537,32 +566,27 @@ if (istype(over_object,/obj/item/storage) && over_object != src) var/obj/item/storage/storage = over_object if (istype(storage.loc, /turf)) - if (!(in_range(src,usr) && in_range(storage,usr))) + if (!(in_range(src,user) && in_range(storage,user))) return - else if (!(get_turf(src) == get_turf(storage))) - return - var/succ = src.try_put_hand_mousedrop(usr, storage) + var/succ = src.try_put_hand_mousedrop(user, storage) if (succ) SPAWN_DBG(1) - if (usr.is_in_hands(src)) - storage.attackby(src, usr) - + if (user.is_in_hands(src)) + storage.attackby(src, user) + return if (istype(S)) - if (on_turf) - usr.show_text("You need to pick up this item first.", "blue") if (src.cant_self_remove) return - if ( !usr.restrained() && !usr.stat && src_exists_inside_usr_or_usr_storage ) - var/succ = src.try_put_hand_mousedrop(usr) + if ( !user.restrained() && !user.stat ) + var/succ = src.try_put_hand_mousedrop(user) if (succ) SPAWN_DBG(1) - if (usr.is_in_hands(src)) - S.clicked(params) - -#undef src_exists_inside_usr_or_usr_storage + if (user.is_in_hands(src)) + S.sendclick(params, user) +#undef src_exists_inside_user_or_user_storage /obj/item/proc/try_put_hand_mousedrop(mob/user) var/oldloc = src.loc @@ -687,7 +711,7 @@ burning_last_process = src.burning return null -/obj/item/proc/attack_self() +/obj/item/proc/attack_self(mob/user) if (src.temp_flags & IS_LIMB_ITEM) if (istype(src.loc,/obj/item/parts/human_parts/arm/left/item)) var/obj/item/parts/human_parts/arm/left/item/I = src.loc @@ -697,6 +721,11 @@ var/obj/item/parts/human_parts/arm/right/item/I = src.loc I.remove_from_mob() I.set_item(src) + + if (special_grab) + if(chokehold) + chokehold.attack_self(user) + return /obj/item/proc/talk_into(mob/M as mob, text, secure, real_name, lang_id) @@ -791,40 +820,43 @@ set src in oview(1) set category = "Local" - if (world.time < usr.next_click) + src.pick_up_by(usr) + +/obj/item/proc/pick_up_by(var/mob/M) + if (world.time < M.next_click) return //fuck youuuuu - if (isdead(usr) || (!iscarbon(usr) && !iscritter(usr))) + if (isdead(M) || (!iscarbon(M) && !iscritter(M))) return - if (!istype(src.loc, /turf) || !isalive(usr) || usr.getStatusDuration("paralysis") || usr.getStatusDuration("stunned") || usr.getStatusDuration("weakened") || usr.restrained()) + if (!istype(src.loc, /turf) || !isalive(M) || M.getStatusDuration("paralysis") || M.getStatusDuration("stunned") || M.getStatusDuration("weakened") || M.restrained()) return - if (!can_reach(usr, src)) + if (!can_reach(M, src)) return - if (issmallanimal(usr)) - var/mob/living/critter/small_animal = usr + if (issmallanimal(M)) + var/mob/living/critter/small_animal = M for (var/datum/handHolder/HH in small_animal.hands) if (istype(HH.limb,/datum/limb/small_critter)) - if (usr.equipped()) - usr.drop_item() + if (M.equipped()) + M.drop_item() SPAWN_DBG(1) - HH.limb.attack_hand(src,usr,1) + HH.limb.attack_hand(src,M,1) else - HH.limb.attack_hand(src,usr,1) - usr.next_click = world.time + src.click_delay + HH.limb.attack_hand(src,M,1) + M.next_click = world.time + src.click_delay return //the verb is PICK-UP, not 'smack this object with that object' - if (usr.equipped()) - usr.drop_item() + if (M.equipped()) + M.drop_item() SPAWN_DBG(1) - src.attack_hand(usr) + src.attack_hand(M) else - src.attack_hand(usr) - usr.next_click = world.time + src.click_delay + src.attack_hand(M) + M.next_click = world.time + src.click_delay /obj/item/get_desc() var/t @@ -922,6 +954,15 @@ logTheThing("combat", user, M, "tries to attack %target% with [src] ([type], object name: [initial(name)]) but is out of stamina") return + if (special_grab) + if (chokehold) + chokehold.attack(M, user, def_zone, is_special) + return + else + if (user.a_intent == INTENT_GRAB) + src.try_grab(M, user) + return + var/obj/item/affecting = M.get_affecting(user, def_zone) var/hit_area var/d_zone @@ -1191,6 +1232,9 @@ if (M.trinket == src) M.trinket = null + if (special_grab) + drop_grab() + ..() /obj/item/proc/on_spin_emote(var/mob/living/carbon/human/user as mob) @@ -1224,4 +1268,22 @@ else possible_mob_holder.hand = !possible_mob_holder.hand possible_mob_holder.drop_item() - possible_mob_holder.hand = !possible_mob_holder.hand \ No newline at end of file + possible_mob_holder.hand = !possible_mob_holder.hand + +/obj/item/proc/dropped(mob/user as mob) + if(src.material) src.material.triggerDrop(user, src) + if (islist(src.ability_buttons)) + for(var/obj/ability_button/B in ability_buttons) + B.OnDrop() + hide_buttons() + clear_mob() + + if (special_grab) + drop_grab() + return + +/obj/item/proc/pickup(mob/user) + if(src.material) src.material.triggerPickup(user, src) + set_mob(user) + show_buttons() + return diff --git a/code/obj/item/cable_coil.dm b/code/obj/item/cable_coil.dm index 3856475..e26d8c7 100644 --- a/code/obj/item/cable_coil.dm +++ b/code/obj/item/cable_coil.dm @@ -24,10 +24,14 @@ stamina_cost = 5 stamina_crit_chance = 10 rand_pos = 1 + event_handler_flags = USE_GRAB_CHOKE | USE_FLUID_ENTER + special_grab = /obj/item/grab var/datum/material/insulator = null var/datum/material/conductor = null + var/cable_obj_type = /obj/cable + // will use getMaterial() to apply these at spawn var/spawn_insulator_name = "synthrubber" var/spawn_conductor_name = "copper" @@ -146,6 +150,8 @@ spawn_insulator_name = "synthblubber" spawn_conductor_name = "pharosium" + cable_obj_type = /obj/cable/reinforced + New(loc, length = MAXCOIL) ..(loc, length) @@ -282,7 +288,7 @@ for (var/obj/cable/C in A) if (C.d1 == dirn || C.d2 == dirn) return - var/obj/cable/NC = new(A, src) + var/obj/cable/NC = new cable_obj_type(A, src) applyCableMaterials(NC, src.insulator, src.conductor) NC.d1 = 0 @@ -327,7 +333,7 @@ if ((LC.d1 == nd1 && LC.d2 == nd2) || (LC.d1 == nd2 && LC.d2 == nd1) ) // make sure no cable matches either direction return qdel(C) - var/obj/cable/NC = new(T, src) + var/obj/cable/NC = new cable_obj_type(T, src) applyCableMaterials(NC, src.insulator, src.conductor) NC.d1 = nd1 NC.d2 = nd2 @@ -365,7 +371,7 @@ boutput(user, "There's already a cable at that position.") return - var/obj/cable/C = new(F, src) + var/obj/cable/C = new cable_obj_type(F, src) C.d1 = 0 C.d2 = dirn C.add_fingerprint(user) @@ -411,7 +417,7 @@ boutput(user, "There's already a cable at that position.") return - var/obj/cable/NC = new(U, src) + var/obj/cable/NC = new cable_obj_type(U, src) applyCableMaterials(NC, src.insulator, src.conductor) NC.d1 = 0 NC.d2 = fdirn @@ -442,7 +448,7 @@ return C.shock(user, 25) qdel(C) - var/obj/cable/NC = new(T, src) + var/obj/cable/NC = new cable_obj_type(T, src) applyCableMaterials(NC, src.insulator, src.conductor) NC.d1 = nd1 NC.d2 = nd2 diff --git a/code/obj/item/clothing/armor.dm b/code/obj/item/clothing/armor.dm index ae69fec..b80ab1c 100644 --- a/code/obj/item/clothing/armor.dm +++ b/code/obj/item/clothing/armor.dm @@ -315,6 +315,7 @@ ..() setProperty("meleeprot", 12) setProperty("rangedprot", 3) + setProperty("disorient_resist", 25) /obj/item/clothing/suit/armor/death_commando name = "death commando armor" @@ -389,6 +390,7 @@ ..() setProperty("meleeprot", 9) setProperty("rangedprot", 2) + setProperty("disorient_resist", 10) /obj/item/clothing/suit/armor/hoscape name = "head of securitys cape" diff --git a/code/obj/item/clothing/ears.dm b/code/obj/item/clothing/ears.dm index a200fb9..2e5276f 100644 --- a/code/obj/item/clothing/ears.dm +++ b/code/obj/item/clothing/ears.dm @@ -19,6 +19,7 @@ setupProperties() ..() setProperty("coldprot", 20) + setProperty("disorient_resist_ear", 100) /obj/item/clothing/ears/earmuffs/earplugs name = "ear plugs" @@ -30,6 +31,7 @@ setupProperties() ..() setProperty("coldprot", 0) + setProperty("disorient_resist_ear", 100) /obj/item/clothing/ears/earmuffs/yeti name = "yeti-fur earmuffs" @@ -40,4 +42,5 @@ setupProperties() ..() - setProperty("coldprot", 80) \ No newline at end of file + setProperty("coldprot", 80) + setProperty("disorient_resist_ear", 80) diff --git a/code/obj/item/clothing/glasses.dm b/code/obj/item/clothing/glasses.dm index 60dffb5..6bf9c12 100644 --- a/code/obj/item/clothing/glasses.dm +++ b/code/obj/item/clothing/glasses.dm @@ -27,6 +27,8 @@ block_vision = 1 alpha = 255 + setProperty("disorient_resist_eye", src.getProperty("density") * 0.6) + /obj/item/clothing/glasses/blindfold name = "blindfold" icon_state = "blindfold" @@ -41,11 +43,16 @@ item_state = "glasses" mats = 6 desc = "Goggles that allow you to see the structure of the station through walls." - color_r = 0.9 + color_r = 0.92 color_g = 1 - color_b = 0.9 + color_b = 0.92 var/on = 1 + setupProperties() + ..() + setProperty("disorient_resist_eye", 15) + + attack_self(mob/user) src.toggle(user) @@ -86,10 +93,14 @@ name = "peculiar spectacles" desc = "Admittedly, they are rather strange." icon_state = "ectoglasses" - color_r = 0.85 + color_r = 0.89 color_g = 1 color_b = 0.85 + setupProperties() + ..() + setProperty("disorient_resist_eye", 15) + /obj/item/clothing/glasses/regular/ecto/goggles name = "ectoplasmoleic imager" desc = "A pair of goggles with a dumb name." @@ -106,6 +117,10 @@ color_g = 0.9 color_b = 0.95 // kinda blue + setupProperties() + ..() + setProperty("disorient_resist_eye", 100) + /obj/item/clothing/glasses/sunglasses/equipped(var/mob/user, var/slot) var/mob/living/carbon/human/H = user if(istype(H) && slot == "eyes") @@ -120,7 +135,11 @@ /obj/item/clothing/glasses/sunglasses/tanning desc = "Strangely ancient technology used to help provide rudimentary eye cover. This pair has a label that says: \"For tanning use only.\"" mats = 4 - color_b = 1 + color_b = 95 + + setupProperties() + ..() + setProperty("disorient_resist_eye", 30) /obj/item/clothing/glasses/sunglasses/sechud name = "\improper Security HUD" @@ -215,6 +234,13 @@ mats = 4 desc = "VIS-tech Optical Rejuvinator goggles allow the blind to see while worn." allow_blind_sight = 1 + color_r = 0.92 + color_g = 0.92 + color_b = 1 + + setupProperties() + ..() + setProperty("disorient_resist_eye", 15) equipped(var/mob/user, var/slot) if (slot == "eyes") @@ -234,6 +260,11 @@ block_eye = "R" var/pinhole = 0 var/mob/living/carbon/human/equipper + + setupProperties() + ..() + setProperty("disorient_resist_eye", 7) + equipped(var/mob/user, var/slot) var/mob/living/carbon/human/H = user if(istype(H) && slot == "eyes") @@ -289,6 +320,10 @@ item_state = "sunglasses" var/network = "det_net" + setupProperties() + ..() + setProperty("disorient_resist_eye", 28) + New() SPAWN_DBG(20) if (src) @@ -338,7 +373,11 @@ mats = 8 color_r = 0.85 color_g = 1 - color_b = 0.85 + color_b = 0.87 + + setupProperties() + ..() + setProperty("disorient_resist_eye", 15) //proc/updateIcons() //I wouldve liked to avoid this but i dont want to put this inside the mobs life proc as that would be more code. process() @@ -424,6 +463,10 @@ color_g = 0.8 color_b = 0.9 + setupProperties() + ..() + setProperty("disorient_resist_eye", 5) + // testing thing for static overlays /obj/item/clothing/glasses/staticgoggles name = "goggles" diff --git a/code/obj/item/clothing/hats.dm b/code/obj/item/clothing/hats.dm index 7c950c3..d080088 100644 --- a/code/obj/item/clothing/hats.dm +++ b/code/obj/item/clothing/hats.dm @@ -75,6 +75,8 @@ setProperty("heatprot", 10) setProperty("viralprot", 50) setProperty("meleeprot", 1) + setProperty("disorient_resist_eye", 5) + setProperty("disorient_resist_ear", 2) /obj/item/clothing/head/bio_hood/janitor // adhara stuff name = "bio hood" @@ -101,6 +103,11 @@ c_flags = SPACEWEAR | COVERSEYES | COVERSMOUTH desc = "Helps protect from vacuum for a short period of time." + setupProperties() + ..() + setProperty("disorient_resist_eye", 9) + setProperty("disorient_resist_ear", 5) + /obj/item/clothing/head/rad_hood name = "Class II Radiation Hood" icon_state = "radiation" @@ -114,6 +121,8 @@ setProperty("radprot", 50) setProperty("heatprot", 10) setProperty("meleeprot", 1) + setProperty("disorient_resist_eye", 12) + setProperty("disorient_resist_ear", 8) /obj/item/clothing/head/cakehat name = "cakehat" @@ -581,6 +590,11 @@ item_state = "wizard" magical = 1 + setupProperties() + ..() + setProperty("disorient_resist_eye", 15) + setProperty("disorient_resist_ear", 15) + handle_other_remove(var/mob/source, var/mob/living/carbon/human/target) . = ..() if (prob(75)) @@ -956,6 +970,11 @@ desc = "Won't you run, live to fly, fly to live, Aces high." icon_state = "aviator" + setupProperties() + ..() + setProperty("disorient_resist_eye", 25) + setProperty("disorient_resist_ear", 5) + attack_self(mob/user as mob) user.show_text("You change the hat's style.") if (src.icon_state == "aviator") @@ -1001,6 +1020,11 @@ c_flags = SPACEWEAR | COVERSEYES | COVERSMOUTH seal_hair = 1 + setupProperties() + ..() + setProperty("disorient_resist_eye", 6) + setProperty("disorient_resist_ear", 5) + /obj/item/clothing/head/jester name = "jester's hat" desc = "The hat of not-so-funny-clown." diff --git a/code/obj/item/clothing/helmets.dm b/code/obj/item/clothing/helmets.dm index 2b70899..e7f4e5c 100644 --- a/code/obj/item/clothing/helmets.dm +++ b/code/obj/item/clothing/helmets.dm @@ -50,6 +50,8 @@ setProperty("coldprot", 20) setProperty("heatprot", 5) setProperty("viralprot", 50) + setProperty("disorient_resist_eye", 8) + setProperty("disorient_resist_ear", 8) oldish icon_state = "space-OLD" @@ -435,11 +437,23 @@ m_amt = 3000 g_amt = 1000 var/up = 0 - color_r = 0.3 // darken - color_g = 0.3 - color_b = 0.3 + color_r = 0.5 // darken + color_g = 0.5 + color_b = 0.5 var/nodarken = 0 + setupProperties() + ..() + setProperty("meleeprot", 2) + + proc/flip_down() + setProperty("meleeprot", 2) + setProperty("disorient_resist_eye", 100) + + proc/flip_up() + setProperty("meleeprot", 4) + setProperty("disorient_resist_eye", 0) + /obj/item/clothing/head/helmet/welding/abilities = list(/obj/ability_button/mask_toggle) /obj/item/clothing/head/helmet/EOD @@ -451,6 +465,7 @@ setupProperties() ..() setProperty("meleeprot", 9) + setProperty("disorient_resist_eye", 25) /obj/item/clothing/head/helmet/HoS name = "HoS Hat" @@ -547,12 +562,14 @@ desc = "Good Lord, this thing is heavy. How the hell is anyone supposed to see out of this?" icon_state = "riot"//Awww yeah, sprites item_state = "riot"//go buttes, go - color_r = 0.5 // darken a medium amount, that thick visor glass really dims things! - color_g = 0.5 - color_b = 0.6 + color_r = 0.7 + color_g = 0.7 + color_b = 0.8 setupProperties() ..() setProperty("meleeprot", 10) + setProperty("disorient_resist_eye", 50) + setProperty("disorient_resist_ear", 30) /obj/item/clothing/head/helmet/NT name = "\improper Nanotrasen helmet" @@ -564,6 +581,7 @@ setupProperties() ..() setProperty("meleeprot", 8) + setProperty("disorient_resist_eye", 15) /obj/item/clothing/head/helmet/space/industrial mats = 7 @@ -604,6 +622,8 @@ ..() setProperty("radprot", 25) setProperty("meleeprot", 2) + setProperty("disorient_resist_eye", 25) + setProperty("disorient_resist_ear", 10) /obj/item/clothing/head/helmet/bucket name = "bucket helmet" diff --git a/code/obj/item/clothing/masks.dm b/code/obj/item/clothing/masks.dm index 473f826..f4b59de 100644 --- a/code/obj/item/clothing/masks.dm +++ b/code/obj/item/clothing/masks.dm @@ -11,6 +11,13 @@ var/is_muzzle = 0 var/use_bloodoverlay = 1 + New() + ..() + if (c_flags & COVERSMOUTH | MASKINTERNALS) + special_grab = /obj/item/grab/force_mask + event_handler_flags |= USE_GRAB_CHOKE + + setupProperties() ..() setProperty("coldprot", 5) @@ -67,6 +74,7 @@ ..() setProperty("coldprot", 7) setProperty("heatprot", 7) + setProperty("disorient_resist_eye", 10) /obj/item/clothing/mask/moustache name = "fake moustache" @@ -216,6 +224,11 @@ c_flags = COVERSMOUTH | COVERSEYES permeability_coefficient = 0.50 + setupProperties() + ..() + setProperty("meleeprot", 1) + setProperty("disorient_resist_eye", 10) + /obj/item/paper_mask name = "unfinished paper mask" icon = 'icons/obj/items.dmi' diff --git a/code/obj/item/clothing/shoes.dm b/code/obj/item/clothing/shoes.dm index 6460e22..8021d64 100644 --- a/code/obj/item/clothing/shoes.dm +++ b/code/obj/item/clothing/shoes.dm @@ -199,6 +199,8 @@ burn_possible = 0 module_research = list("efficiency" = 5, "engineering" = 5) laces = LACES_NONE + step_sound = "step_flipflop" + step_priority = STEP_PRIORITY_LOW setupProperties() ..() @@ -233,6 +235,8 @@ desc = "Rubber boots that prevent slipping on wet surfaces." icon_state = "galoshes" c_flags = NOSLIP + step_sound = "step_rubberboot" + step_priority = STEP_PRIORITY_LOW permeability_coefficient = 0.05 /obj/item/clothing/shoes/clown_shoes @@ -252,7 +256,8 @@ icon_state = "flippers" permeability_coefficient = 0.05 laces = LACES_NONE - //step_sound = "clownstep" to-do : flip flopping sfx + step_sound = "step_flipflop" + step_priority = STEP_PRIORITY_LOW New() ..() @@ -304,6 +309,8 @@ c_flags = NOSLIP magical = 1 laces = LACES_NONE + step_sound = "step_flipflop" + step_priority = STEP_PRIORITY_LOW handle_other_remove(var/mob/source, var/mob/living/carbon/human/target) . = ..() @@ -317,6 +324,8 @@ icon_state = "tourist" protective_temperature = 0 permeability_coefficient = 1 + step_sound = "step_flipflop" + step_priority = STEP_PRIORITY_LOW setupProperties() ..() @@ -359,6 +368,8 @@ name = "fuzzy slippers" desc = "A pair of cute little pink rabbit slippers." icon_state = "fuzzy" + step_sound = "step_carpet" + step_priority = STEP_PRIORITY_LOW setupProperties() ..() @@ -368,6 +379,8 @@ name = "go-go boots" desc = "These boots complete your Space Age look." icon_state = "gogo" + step_sound = "step_rubberboot" + step_priority = STEP_PRIORITY_LOW setupProperties() ..() diff --git a/code/obj/item/clothing/suits.dm b/code/obj/item/clothing/suits.dm index f45d303..e369efe 100644 --- a/code/obj/item/clothing/suits.dm +++ b/code/obj/item/clothing/suits.dm @@ -269,6 +269,7 @@ setProperty("radprot", 50) setProperty("meleeprot", 4) setProperty("rangedprot", 2) + setProperty("movespeed", 1) /obj/item/clothing/suit/rad // re-added for Russian Station as there is a permarads area there! name = "\improper Class II radiation suit" @@ -482,6 +483,7 @@ ..() setProperty("coldprot", 20) setProperty("heatprot", 20) + setProperty("movespeed", 15) /obj/item/clothing/suit/wcoat name = "waistcoat" @@ -814,6 +816,7 @@ setProperty("heatprot", 50) setProperty("meleeprot", 3) setProperty("rangedprot", 0.5) + setProperty("movespeed", 1) /obj/item/clothing/suit/fire/armored name = "armored firesuit" @@ -850,6 +853,7 @@ setProperty("heatprot", 65) setProperty("meleeprot", 4) setProperty("rangedprot", 0.8) + setProperty("movespeed", 2) /obj/item/clothing/suit/fire/old name = "old firesuit" @@ -971,6 +975,8 @@ setProperty("meleeprot", 3) setProperty("rangedprot", 0.5) + setProperty("space_movespeed", 0.8) + /obj/item/clothing/suit/space/emerg name = "emergency suit" desc = "A suit that protects against low pressure environments for a short time." @@ -980,6 +986,10 @@ body_parts_covered = TORSO|LEGS|ARMS var/rip = 0 + setupProperties() + ..() + setProperty("space_movespeed", 2) + snow // bleh whatever!!! name = "snow suit" desc = "A thick padded suit that protects against extreme cold temperatures." @@ -1004,6 +1014,10 @@ icon_state = "spacecap" item_state = "spacecap" + setupProperties() + ..() + setProperty("space_movespeed", 0.4) + blue icon_state = "spacecap-blue" item_state = "spacecap-blue" @@ -1138,6 +1152,7 @@ body_parts_covered = TORSO|LEGS|ARMS mats = 45 //should not be cheap to make at mechanics, increased from 15. + #ifdef UNDERWATER_MAP name = "industrial diving suit" icon_state = "diving_suit-industrial" @@ -1156,6 +1171,7 @@ setProperty("exploprot", 3) setProperty("meleeprot", 2) setProperty("rangedprot", 0.5) + setProperty("space_movespeed", 0) syndicate name = "\improper Syndicate command armor" diff --git a/code/obj/item/clothing/uniforms.dm b/code/obj/item/clothing/uniforms.dm index 349bbf3..12ffd5a 100644 --- a/code/obj/item/clothing/uniforms.dm +++ b/code/obj/item/clothing/uniforms.dm @@ -20,6 +20,8 @@ burn_possible = 1 health = 50 + duration_remove = 6.5 SECONDS + setupProperties() ..() setProperty("coldprot", 5) diff --git a/code/obj/item/device/accessgun.dm b/code/obj/item/device/accessgun.dm new file mode 100644 index 0000000..c98756d --- /dev/null +++ b/code/obj/item/device/accessgun.dm @@ -0,0 +1,153 @@ +/obj/item/device/accessgun + name = "access-pro" + desc = "This device can reprogram electronic access requirements. It will copy the permissions of any inserted ID." + icon = 'icons/obj/device.dmi' + icon_state = "accessgun" + item_state = "accessgun" + w_class = 2.0 + rand_pos = 0 + flags = FPRINT | TABLEPASS | ONBELT + var/obj/item/card/id/ID_card = null + req_access = list(list(access_change_ids,access_engineering_chief)) + + proc/eject_id_card(var/mob/user as mob) + if (src.ID_card) + if (istype(user)) + user.put_in_hand_or_drop(src.ID_card) + else + var/turf/T = get_turf(src) + src.ID_card.set_loc(T) + src.ID_card = null + src.icon_state = "accessgun" + + proc/insert_id_card(var/obj/item/card/id/ID as obj, var/mob/user as mob) + if (!istype(ID)) + return + if (src.ID_card) + src.eject_id_card(istype(user) ? user : null) + src.ID_card = ID + if (user) + user.u_equip(ID) + ID.set_loc(src) + + switch(ID.icon_state) + if ("id" || "id_civ") + icon_state = "accessgun-civ" + if ("id_sec") + icon_state = "accessgun-sec" + if ("id_com") + icon_state = "accessgun-com" + if ("id_res") + icon_state = "accessgun-res" + if ("id_eng") + icon_state = "accessgun-eng" + if ("id_clown") + icon_state = "accessgun-clown" + else + icon_state = "accessgun-?" + + if (!ID.access) + icon_state = "accessgun-null" + else + for (var/acc in ID.access) + icon_state = "accessgun-null" + break + + attack_self(mob/user as mob) + ..() + if (src.ID_card) + boutput(user, "You eject [ID_card] from [src].") + src.eject_id_card(user) + + attackby(obj/item/C as obj, mob/user as mob) + if (istype(C, /obj/item/card/id)) + var/obj/item/card/id/ID = C + if (src.ID_card) + boutput(user, "You swap [ID] and [src.ID_card].") + src.eject_id_card(user) + src.insert_id_card(ID, user) + return + else if (!src.ID_card) + src.insert_id_card(ID, user) + boutput(user, "You insert [ID] into [src].") + else + ..() + + afterattack(atom/target, mob/user, reach, params) + ..() + if (!src.ID_card) + playsound(get_turf(src), 'sound/machines/airlock_deny.ogg', 35, 1, 0, 2) + boutput(user, "[src] refuses to turn on without an ID inserted.") + return + if (!isobj(target)) + playsound(get_turf(src), 'sound/machines/airlock_deny.ogg', 35, 1, 0, 2) + boutput(user, "[src] can't reprogram this.") + return + + if (!allowed(user)) + playsound(get_turf(src), 'sound/machines/airlock_deny.ogg', 35, 1, 0, 2) + boutput(user, "Your worn ID fails [src]'s check!") + return + + var/obj/O = target + if (O.object_flags & CAN_REPROGRAM_ACCESS) + if (istype(target,/obj/machinery/door)) + var/obj/machinery/door/D = target + if (D.cant_emag || isrestrictedz(D.z)) + playsound(get_turf(src), 'sound/machines/airlock_deny.ogg', 35, 1, 0, 2) + boutput(user, "[src] can't reprogram this.") + return + + actions.start(new/datum/action/bar/icon/access_reprog(O,src), user) + else + playsound(get_turf(src), 'sound/machines/airlock_deny.ogg', 35, 1, 0, 2) + boutput(user, "[src] can't reprogram this.") + + + + proc/reprogram(var/obj/O,var/mob/user) + O.set_access_list(ID_card.access) + playsound(get_turf(src), "sound/machines/reprog.ogg", 50, 1) + + +/datum/action/bar/icon/access_reprog + duration = 90 + interrupt_flags = INTERRUPT_MOVE | INTERRUPT_ACT | INTERRUPT_STUNNED | INTERRUPT_ACTION + id = "access_reprog" + icon = 'icons/ui/actions.dmi' + icon_state = "reprog" + var/obj/O + var/obj/item/device/accessgun/A + New(Obj,AccessGun) + O = Obj + A = AccessGun + ..() + + onUpdate() + ..() + if(get_dist(owner, O) > 1 || O == null || owner == null || A == null) + interrupt(INTERRUPT_ALWAYS) + return + + onStart() + ..() + if(get_dist(owner, O) > 1 || O == null || owner == null || A == null) + interrupt(INTERRUPT_ALWAYS) + return + + onEnd() + ..() + if(get_dist(owner, O) > 1 || O == null || owner == null || A == null) + interrupt(INTERRUPT_ALWAYS) + return + if (ismob(owner)) + var/mob/M = owner + if (!A in M.equipped_list()) + interrupt(INTERRUPT_ALWAYS) + return + A.reprogram(O,owner) + + onInterrupt() + if (O && owner) + boutput(owner, "Access change of [O] interrupted!") + ..() \ No newline at end of file diff --git a/code/obj/item/device/energy_shield_device.dm b/code/obj/item/device/energy_shield_device.dm index d36dfac..ccc11eb 100644 --- a/code/obj/item/device/energy_shield_device.dm +++ b/code/obj/item/device/energy_shield_device.dm @@ -80,8 +80,4 @@ SPAWN_DBG(10) work() can_use() - if(!user || !ismob(loc)) return 0 - if(src in user.get_equipped_items()) - return 1 - else - return 0 \ No newline at end of file + if(!user || !ismob(loc) || user != loc) return 0 \ No newline at end of file diff --git a/code/obj/item/device/pda2/modules.dm b/code/obj/item/device/pda2/modules.dm index 4b3789b..91d274c 100644 --- a/code/obj/item/device/pda2/modules.dm +++ b/code/obj/item/device/pda2/modules.dm @@ -98,23 +98,35 @@ var/lumlevel = 0.5 //How bright are we? var/datum/light/light abilities = list(/obj/ability_button/pda_flashlight_toggle) + var/use_simple_light = 1 New() ..() - light = new /datum/light/point - light.set_brightness(lumlevel) - light.set_color(1, 1, 1) + if (!use_simple_light) + light = new /datum/light/point + light.set_brightness(lumlevel) + light.set_color(1, 1, 1) relay_pickup(mob/user) ..() - light.attach(user) + if (!use_simple_light) + light.attach(user) + else if (on) + if (src.host) + src.host.remove_simple_light("pda\ref[src]") + user.add_simple_light("pda\ref[src]", list(255,255,255,lumlevel * 255)) relay_drop(mob/user) ..() SPAWN_DBG(0) if (src.host) if (src.host.loc != user) - light.attach(src.host.loc) + if (!use_simple_light) + light.attach(src.host.loc) + else if (on) + user.remove_simple_light("pda\ref[src]") + src.host.add_simple_light("pda\ref[src]", list(255,255,255,lumlevel * 255)) + return_menu_badge() var/text = "
[src.on ? "Disable" : "Enable"] Flashlight" @@ -122,10 +134,16 @@ install(var/obj/item/device/pda2/pda) ..() - light.attach(pda) + if (!use_simple_light) + light.attach(pda) + else if (on) + pda.add_simple_light("pda\ref[src]", list(255,255,255,lumlevel * 255)) uninstall() - light.disable() + if (!use_simple_light) + light.disable() + else if (on) + src.host.remove_simple_light("pda\ref[src]") src.on = 0 ..() @@ -138,12 +156,30 @@ proc/toggle_light() src.on = !src.on - if (ismob(src.host.loc)) - light.attach(src.host.loc) + if (!use_simple_light) + if (ismob(src.host.loc)) + light.attach(src.host.loc) + if (src.on) - light.enable() + if (!use_simple_light) + light.enable() + else + if (!isturf(src.host.loc)) + var/atom/A = src.host.loc + A.add_simple_light("pda\ref[src]", list(255,255,255,lumlevel * 255)) + else + src.host.add_simple_light("pda\ref[src]", list(255,255,255,lumlevel * 255)) + else - light.disable() + if (!use_simple_light) + light.disable() + else + if (!isturf(src.host.loc)) + var/atom/A = src.host.loc + A.remove_simple_light("pda\ref[src]") + else + src.host.remove_simple_light("pda\ref[src]") + if (islist(src.ability_buttons)) for (var/obj/ability_button/pda_flashlight_toggle/B in src.ability_buttons) B.icon_state = "pda[src.on]" @@ -163,6 +199,7 @@ /obj/item/device/pda_module/flashlight/high_power name = "high-power flashlight module" lumlevel = 1 + use_simple_light = 0 /obj/ability_button/pda_flashlight_toggle name = "Toggle PDA Flashlight" diff --git a/code/obj/item/device/pda2/scanners.dm b/code/obj/item/device/pda2/scanners.dm index 67d559f..635a6d0 100644 --- a/code/obj/item/device/pda2/scanners.dm +++ b/code/obj/item/device/pda2/scanners.dm @@ -84,7 +84,7 @@ if(istype(O,/obj/machinery/rkit)) return - if(O.mats == 0 || O.mats == "Built" || O.is_syndicate != 0) + if(O.mats == 0 || O.is_syndicate != 0) return "Unable to scan." if (!istype(master.host_program, /datum/computer/file/pda_program/os/main_os) || !master.host_program:message_on) @@ -93,7 +93,7 @@ var/datum/computer/file/electronics_scan/theScan = new theScan.scannedName = initial(O.name) theScan.scannedPath = O.mechanics_type_override ? O.mechanics_type_override : O.type - theScan.scannedMats = O.mats + theScan.scannedMats = initial(O.mats) var/datum/signal/signal = get_free_signal() signal.source = src.master diff --git a/code/obj/item/fitness.dm b/code/obj/item/fitness.dm index 3dbc884..97a97ff 100644 --- a/code/obj/item/fitness.dm +++ b/code/obj/item/fitness.dm @@ -4,6 +4,7 @@ icon = 'icons/obj/stationobjs.dmi' icon_state = "punchingbag" anchored = 1 + deconstruct_flags = DECON_SIMPLE layer = MOB_LAYER_BASE+1 // TODO LAYER var/list/hit_sounds = list('sound/impact_sounds/Generic_Hit_1.ogg', 'sound/impact_sounds/Generic_Hit_2.ogg', 'sound/impact_sounds/Generic_Hit_3.ogg',\ 'sound/impact_sounds/Generic_Punch_2.ogg', 'sound/impact_sounds/Generic_Punch_3.ogg', 'sound/impact_sounds/Generic_Punch_4.ogg', 'sound/impact_sounds/Generic_Punch_5.ogg') @@ -53,6 +54,7 @@ icon_state = "fitnesslifter" density = 1 anchored = 1 + deconstruct_flags = DECON_WRENCH var/in_use = 0 attack_hand(mob/user as mob) @@ -98,6 +100,7 @@ icon_state = "fitnessweight" density = 1 anchored = 1 + deconstruct_flags = DECON_WRENCH var/in_use = 0 attack_hand(mob/user as mob) diff --git a/code/obj/item/grab.dm b/code/obj/item/grab.dm index 2ed91dd..f0a318d 100644 --- a/code/obj/item/grab.dm +++ b/code/obj/item/grab.dm @@ -3,7 +3,7 @@ flags = SUPPRESSATTACK var/mob/living/assailant var/mob/living/affecting - var/state = 0 // 0 = passive, 1 aggressive, 2 neck, 3 kill + var/state = 0 // 0 = passive, 1 aggressive, 2 neck, 3 kill, 4 pin (setup.dm. any state above KILL is considered an alt state that is also an 'end point' in the tree of options. ok var/choke_count = 0 icon = 'icons/mob/hud_human_new.dmi' icon_state = "reinforce" @@ -13,15 +13,33 @@ var/break_prob = 45 var/assailant_stam_drain = 30 var/affecting_stam_drain = 20 + var/resist_count = 0 - New() + New(atom/loc) + ..() + + var/icon/hud_style = hud_style_selection[get_hud_style(src.assailant)] + if (isicon(hud_style)) + src.icon = hud_style + + if (isitem(src.loc)) + var/obj/item/I = src.loc + + var/image/ima = SafeGetOverlayImage("grab", src.icon, "grab_small") + ima.layer = src.loc.layer + 1 + ima.appearance_flags = RESET_COLOR | KEEP_APART | RESET_TRANSFORM + + I.UpdateOverlays(ima, "grab", 0, 1) + + proc/post_item_setup()//after grab is done being made with item ..() - SPAWN_DBG(0) - var/icon/hud_style = hud_style_selection[get_hud_style(src.assailant)] - if (isicon(hud_style)) - src.icon = hud_style disposing() + if (isitem(src.loc)) + var/obj/item/I = src.loc + I.ClearSpecificOverlays("grab") + I.chokehold = null + if(assailant) //drop that grab to avoid the sticky behavior if (src in assailant.equipped_list()) if (assailant.equipped() == src) @@ -41,8 +59,17 @@ affecting.pixel_y = initial(affecting.pixel_y) affecting.set_density(1) + + if (state == GRAB_PIN) + assailant.changeStatus("weakened",2 SECONDS) + affecting.changeStatus("weakened",1 SECONDS) + assailant.force_laydown_standup() + affecting.force_laydown_standup() + if (state == GRAB_KILL) logTheThing("combat", src.assailant, src.affecting, "releases their choke on %target% after [choke_count] cycles") + else if (state == GRAB_PIN) + logTheThing("combat", src.assailant, src.affecting, "drops their pin on %target%") else logTheThing("combat", src.assailant, src.affecting, "drops their grab on %target%") if (affecting.grabbed_by) affecting.grabbed_by -= src @@ -66,12 +93,21 @@ if(H) H.remove_stamina(STAMINA_REGEN * 0.5 * mult) src.affecting.set_density(0) + if (src.state == GRAB_PIN) + if (ishuman(src.assailant)) + var/mob/living/carbon/human/HH = src.assailant + HH.remove_stamina(STAMINA_REGEN * 0.5 * mult) + if (src.state == GRAB_KILL) //src.affecting.losebreath++ //if (src.affecting.paralysis < 2) // src.affecting.paralysis = 2 process_kill(H, mult) + if (isitem(src.loc)) + var/obj/item/I = src.loc + I.process_grab(mult) + update_icon() attack(atom/target, mob/user) @@ -88,14 +124,16 @@ proc/process_kill(var/mob/living/carbon/human/H, mult = 1) if(H) choke_count += 1 * mult - H.remove_stamina(STAMINA_REGEN+7 * mult) + H.remove_stamina((STAMINA_REGEN+8.5) * mult) H.stamina_stun() if(H.stamina <= -75) - H.losebreath += (2 * mult) + H.losebreath += (3 * mult) else if(H.stamina <= -50) - H.losebreath += (1 * mult) + H.losebreath += (1.5 * mult) else if(H.stamina <= -33) if(prob(33)) H.losebreath += (1 * mult) + else + if(prob(33)) H.losebreath += (0.2 * mult) proc/set_affected_loc() if (!isturf(src.assailant.loc)) @@ -137,7 +175,14 @@ return switch (src.state) if (GRAB_PASSIVE) - if (user.is_hulk() || prob(75)) + if (src.affecting.buckled) + src.affecting.buckled.attack_hand(src.assailant) + src.affecting.force_laydown_standup() //safety because buckle code is a mess + if (src.affecting.targeting_spell == src.affecting.chair_flip_ability) //fuCKKK + src.affecting.end_chair_flip_targeting() + src.affecting.buckled = null + + else if (user.is_hulk() || prob(75)) logTheThing("combat", src.assailant, src.affecting, "'s grip upped to aggressive on %target%") for(var/mob/O in AIviewers(src.assailant, null)) O.show_message("[src.assailant] has grabbed [src.affecting] aggressively (now hands)!", 1) @@ -190,12 +235,19 @@ user.next_click = world.time + user.combat_click_delay update_icon() - proc/upgrade_to_kill() + proc/upgrade_to_kill(var/msg_overridden = 0) icon_state = "disarm/kill" logTheThing("combat", src.assailant, src.affecting, "chokes %target%") choke_count = 0 - for (var/mob/O in AIviewers(src.assailant, null)) - O.show_message("[src.assailant] has tightened [his_or_her(assailant)] grip on [src.affecting]'s neck!", 1) + + if (!msg_overridden) + if (isitem(src.loc)) + var/obj/item/I = src.loc + for (var/mob/O in AIviewers(src.assailant, null)) + O.show_message("[src.assailant] has tightened [I] on [src.affecting]'s neck!", 1) + else + for (var/mob/O in AIviewers(src.assailant, null)) + O.show_message("[src.assailant] has tightened [his_or_her(assailant)] grip on [src.affecting]'s neck!", 1) src.state = GRAB_KILL src.assailant.lastattacked = src.affecting src.affecting.lastattacker = src.assailant @@ -212,14 +264,54 @@ var/mob/living/carbon/human/H = src.affecting H.set_stamina(min(0, H.stamina)) + if (ishuman(src.affecting)) + src.affecting:was_harmed(src.assailant) + + proc/upgrade_to_pin(var/turf/T) + icon_state = "pin" + logTheThing("combat", src.assailant, src.affecting, "pins %target%") + + for (var/mob/O in AIviewers(src.assailant, null)) + O.show_message("[src.assailant] has pinned [src.affecting] to [T]!", 1) + + src.state = GRAB_PIN + + src.assailant.lastattacked = src.affecting + src.affecting.lastattacker = src.assailant + src.affecting.lastattackertime = world.time + + step_to(src.assailant,T) + + src.affecting.setStatus("pinned", duration = null) + src.affecting.force_laydown_standup() + if (!src.affecting.buckled) + set_affected_loc() + if (src.assailant.bioHolder.HasEffect("fat")) + src.affecting.unlock_medal("Bear Hug", 1) + + if (ishuman(src.assailant)) + var/mob/living/carbon/human/H = src.assailant + H.update_canmove() + + if (ishuman(src.affecting)) + src.affecting:was_harmed(src.assailant) + + proc/stunned_targets_can_break() + .= (src.state == GRAB_PIN) + proc/check() if(!assailant || !affecting) qdel(src) return 1 - if(!assailant.is_in_hands(src)) - qdel(src) - return 1 + if (isitem(src.loc)) + if(!assailant.is_in_hands(src.loc)) + qdel(src) + return 1 + else + if(!assailant.is_in_hands(src)) + qdel(src) + return 1 if(!isturf(assailant.loc) || (!isturf(affecting.loc) || assailant.loc != affecting.loc && get_dist(assailant, affecting) > 1) ) qdel(src) @@ -237,12 +329,41 @@ icon_state = "disarm/kill" if (GRAB_KILL) icon_state = "disarm/kill1" + if (GRAB_PIN) + icon_state = "pin" proc/do_resist() + hit_twitch(src.assailant) + src.affecting.dir = pick(alldirs) + resist_count += 1 + if (src.state == GRAB_PASSIVE) for (var/mob/O in AIviewers(src.affecting, null)) O.show_message(text("[] has broken free of []'s grip!", src.affecting, src.assailant), 1, group = "resist") qdel(src) + else if (src.state == GRAB_PIN) + var/succ = 0 + + if (resist_count >= 8 && prob(7)) //after 8 resists, start rolling for breakage. this is to make sure people with stamina buffs cant infinite-pin someone + succ = 1 + else if (ishuman(src.assailant)) + src.assailant.remove_stamina(29) + src.affecting.remove_stamina(10) + var/mob/living/carbon/human/H = src.assailant + if (H.stamina <= 0) + succ = 1 + else if (prob(13)) //the grabber must be a critter or some shit + succ = 1 + + + if (succ) + for (var/mob/O in AIviewers(src.affecting, null)) + O.show_message(text("[] has broken free of []'s pin!", src.affecting, src.assailant), 1, group = "resist") + qdel(src) + else + for (var/mob/O in AIviewers(src.affecting, null)) + O.show_message(text("[] attempts to break free of []'s pin!", src.affecting, src.assailant), 1, group = "resist") + else if (prob(break_prob)) for (var/mob/O in AIviewers(src.affecting, null)) @@ -256,6 +377,10 @@ O.show_message(text("[] attempts to break free of []'s grip!", src.affecting, src.assailant), 1, group = "resist") +////////////////////// +//PROGRESS BAR STUFF// +////////////////////// + /datum/action/bar/icon/strangle_target duration = 30 interrupt_flags = INTERRUPT_MOVE | INTERRUPT_ACT | INTERRUPT_STUNNED @@ -300,3 +425,278 @@ boutput(owner, "You have been interrupted!") G = null target = null + +/datum/action/bar/icon/pin_target + duration = 30 + interrupt_flags = INTERRUPT_ACT | INTERRUPT_STUNNED + id = "pin_target" + icon = 'icons/ui/actions.dmi' + icon_state = "pin" + var/mob/living/target + var/obj/item/grab/G + var/turf/T + + New(Target, Grab, Turf) + target = Target + G = Grab + T = Turf + + if (ishuman(target) && target:stamina < target:stamina_max/2) + duration -= 15 * (1-(target:stamina/(target:stamina_max/2))) + + if (G.state < GRAB_NECK) + duration += 25 //takes longer if you dont have a good gripp + + ..() + + onUpdate() + ..() + + if(get_dist(owner, target) > 1 || target == null || owner == null || get_dist(owner,T) > 1) + interrupt(INTERRUPT_ALWAYS) + return + + if (!G || !istype(G) || G.affecting != target) + interrupt(INTERRUPT_ALWAYS) + return + + onStart() + ..() + if(get_dist(owner, target) > 1 || target == null || owner == null || get_dist(owner,T) > 1) + interrupt(INTERRUPT_ALWAYS) + return + + onEnd() + ..() + var/mob/ownerMob = owner + if(owner && ownerMob && target && G && get_dist(owner, target) <= 1 || get_dist(owner,T) > 1) + G.upgrade_to_pin(T) + else + interrupt(INTERRUPT_ALWAYS) + + onInterrupt() + ..() + boutput(owner, "You have been interrupted!") + G = null + target = null + + +///////////// +//GRABSMASH// +///////////// + +/atom/proc/grab_smash(obj/item/grab/G as obj, mob/user as mob) + var/mob/M = G.affecting + + if (!(ismob(G.affecting))) + return 0 + + if (get_dist(src, M) > 1) + return 0 + + user.visible_message("[M] has been smashed against [src] by [user]!") + logTheThing("combat", user, M, "smashes %target% against [src]") + + random_brute_damage(G.affecting, rand(2,3)) + G.affecting.TakeDamage("chest", 0, rand(4,5)) + playsound(G.affecting.loc, "punch", 25, 1, -1) + + user.u_equip(G) + G.dispose() + return 1 + + +/turf/simulated/floor/grab_smash(obj/item/grab/G as obj, mob/user as mob) + var/mob/M = G.affecting + + if (!(ismob(G.affecting))) + return 0 + + if (get_dist(src, M) > 1) + return 0 + + if (ishuman(G.affecting)) + G.affecting:was_harmed(G.assailant) + + actions.start(new/datum/action/bar/icon/pin_target(G.affecting, G, src), G.assailant) + attack_particle(user,src) + +/turf/unsimulated/floor/grab_smash(obj/item/grab/G as obj, mob/user as mob) + var/mob/M = G.affecting + + if (!(ismob(G.affecting))) + return 0 + + if (get_dist(src, M) > 1) + return 0 + + actions.start(new/datum/action/bar/icon/pin_target(G.affecting, G, src), G.assailant) + attack_particle(user,src) + + +/////////////////////// +//SPECIAL GRABS BELOW// +/////////////////////// + +/obj/item/proc/process_grab(var/mult = 1) //items override for unique behaviorse + .= 0 + if (src.chokehold && src.chokehold.state == GRAB_KILL) + if (tool_flags & TOOL_CUTTING && hit_type == DAMAGE_CUT) //bleed em a bit + take_bleeding_damage(src.chokehold.affecting, src.chokehold.assailant, 0.5 * mult, bloodsplatter = 0) + +/obj/item/proc/try_grab(var/mob/living/target, var/mob/living/user) + .= 0 + if(!chokehold && istype(target) && istype(user)) + src.chokehold = user.grab_other(target, hide_attack, src) + chokehold.post_item_setup() + .= 1 + +/obj/item/proc/drop_grab() + if(src.chokehold) + qdel(chokehold) + chokehold = null + + +/obj/item/grab/rag_muffle + check() + if(!assailant || !affecting) + qdel(src) + return 1 + + if(!isturf(assailant.loc) || (!isturf(affecting.loc) || assailant.loc != affecting.loc && get_dist(assailant, affecting) > 1) ) + qdel(src) + return 1 + + return 0 + +/obj/item/grab/force_mask + + proc/get_breath(volume_needed) + .= null + if (src.state == GRAB_KILL) + for (var/obj/item/tank/use_internal in src.assailant.equipped_list(check_for_magtractor = 0)) + return use_internal.remove_air_volume(volume_needed) + + upgrade_to_kill() + if (src.assailant.wear_mask && src.assailant.wear_mask.c_flags & COVERSMOUTH | MASKINTERNALS) + for (var/mob/O in AIviewers(src.assailant, null)) + O.show_message("[src.assailant] fails to choke [src.affecting] with [src.loc] because they are already wearing [src.assailant.wear_mask]!", 1) + return 0 + else + ..(msg_overridden = 1) + + var/obj/item/tank/use_internal = null + for (var/obj/item/tank/T in src.assailant.equipped_list(check_for_magtractor = 0)) + use_internal = T + break + + if (use_internal) + for (var/mob/O in AIviewers(src.assailant, null)) + O.show_message("[src.assailant] has tightened [his_or_her(assailant)] grip on [src.affecting]'s neck, forcing them to inhale from [use_internal]!", 1) + else + for (var/mob/O in AIviewers(src.assailant, null)) + O.show_message("[src.assailant] has tightened [his_or_her(assailant)] grip on [src.affecting]'s neck with no internals tank attached!", 1) + + + + check() + if(!assailant || !affecting) + qdel(src) + return 1 + + if(!isturf(assailant.loc) || (!isturf(affecting.loc) || assailant.loc != affecting.loc && get_dist(assailant, affecting) > 1) ) + qdel(src) + return 1 + + if (!ishuman(affecting)) + qdel(src) + return 1 + + return 0 + + + +/obj/item/gun/try_grab(var/mob/living/target, var/mob/living/user) + src.hide_attack = 1 + + if (..()) + for (var/mob/O in AIviewers(user, null)) + if (O.client) + O.show_message("[user] presses the barrel of [src] right against [target]!") + target.show_text("[user] is ready to fire if you try to move or make any sudden movements!") + + src.hide_attack = initial(src.hide_attack) + +/obj/item/grab/gunpoint + var/shot = 0 + + New() + ..() + + post_item_setup() + ..() + if (!(src.affecting.mob_flags & AT_GUNPOINT)) + src.affecting.mob_flags |= AT_GUNPOINT + + disposing() + if (!shot && src.assailant && isitem(src.loc)) + for (var/mob/O in AIviewers(src.assailant, null)) + if (O.client) + O.show_message("[src.assailant] lowers [src.loc].") + + if (src.affecting) + var/found = 0 + for (var/obj/item/grab/gunpoint/G in src.affecting.grabbed_by) + if (G != src) + found = 1 + break + if (!found) + src.affecting.mob_flags &= ~AT_GUNPOINT + ..() + + proc/shoot() + shot = 1 + + if (affecting && assailant && isitem(src.loc)) + if (get_dist(src.affecting,src.assailant) <= 1) + var/obj/item/gun/G = src.loc + G.shoot_point_blank(src.affecting,src.assailant) + + qdel(src) + +//////////////////////////// +//SPECIAL GRAB ITEMS STUFF// +//////////////////////////// + +/obj/item/material_piece/cloth + event_handler_flags = USE_GRAB_CHOKE | USE_FLUID_ENTER + special_grab = /obj/item/grab/rag_muffle + + New() + ..() + var/datum/reagents/R = new/datum/reagents(10) + reagents = R + R.my_atom = src + + disposing() + ..() + if(reagents) + reagents.clear_reagents() + + process_grab(var/mult = 1) + ..() + if (src.chokehold && src.reagents && src.reagents.total_volume > 0 && chokehold.state == GRAB_KILL && iscarbon(src.chokehold.affecting)) + src.reagents.reaction(chokehold.affecting, INGEST, 0.5 * mult) + src.reagents.trans_to(chokehold.affecting, 0.5 * mult) + + is_open_container() + .= 1 + + + +/obj/item/cable_coil/process_grab(var/mult = 1) + ..() + if (src.chokehold && chokehold.state == GRAB_KILL) + if (ishuman(src.chokehold.affecting)) + var/mob/living/carbon/human/H = src.chokehold.affecting + H.losebreath += (0.5 * mult) diff --git a/code/obj/item/gun/gun_parent.dm b/code/obj/item/gun/gun_parent.dm index a6e3e81..8637e8f 100644 --- a/code/obj/item/gun/gun_parent.dm +++ b/code/obj/item/gun/gun_parent.dm @@ -5,6 +5,9 @@ var/list/forensic_IDs = new/list() //Global list of all guns, based on bioholder icon = 'icons/obj/gun.dmi' inhand_image_icon = 'icons/mob/inhand/hand_weapons.dmi' flags = FPRINT | TABLEPASS | CONDUCT | ONBELT | USEDELAY | EXTRADELAY + event_handler_flags = USE_GRAB_CHOKE | USE_FLUID_ENTER + special_grab = /obj/item/grab/gunpoint + item_state = "gun" m_amt = 2000 force = 10.0 @@ -32,7 +35,6 @@ var/list/forensic_IDs = new/list() //Global list of all guns, based on bioholder var/list/projectiles = null var/current_projectile_num = 1 var/silenced = 0 - var/mob/holding_at_gunpoint = 0 var/can_dual_wield = 1 var/slowdown = 0 //Movement delay attack after attack @@ -210,9 +212,10 @@ var/list/forensic_IDs = new/list() //Global list of all guns, based on bioholder M.lastattacker = user M.lastattackertime = world.time - if(user.a_intent != "help" && isliving(M)) - if (user.a_intent == "grab") - src.hold_at_gunpoint(M, user) + if(user.a_intent != INTENT_HELP && isliving(M)) + if (user.a_intent == INTENT_GRAB) + attack_particle(user,M) + return ..() else src.shoot_point_blank(M, user) else @@ -224,49 +227,6 @@ var/list/forensic_IDs = new/list() //Global list of all guns, based on bioholder #endif return -/obj/item/gun/proc/hold_at_gunpoint(var/mob/M as mob, var/mob/user as mob) - if (!M || !user) - return - if (M == user) - return - if (src.holding_at_gunpoint == user && M.at_gunpoint == src) - return - - for (var/mob/O in AIviewers(M, null)) - if (O.client) - O.show_message("[user] presses the barrel of [src] right against [M]!") - M.show_text("[user] is ready to fire if you try to move or make any sudden movements!") - M.at_gunpoint = src - user.at_gunpoint = src - src.holding_at_gunpoint = user - -/obj/item/gun/proc/lower_gunpoint(var/mob/M as mob, var/silent = 0) - if (!src.holding_at_gunpoint || !M) - return - - if (!silent) - for (var/mob/O in AIviewers(M, null)) - if (O.client) - O.show_message("[src.holding_at_gunpoint] lowers [src].") - M.at_gunpoint = null - src.holding_at_gunpoint.at_gunpoint = null - src.holding_at_gunpoint = 0 - - -/obj/item/gun/proc/shoot_at_gunpoint(var/mob/M as mob) - if (!src.holding_at_gunpoint || !M) - src.lower_gunpoint(M,1) - return - if (M == src.holding_at_gunpoint) - src.lower_gunpoint(M) - return - if (get_dist(src.holding_at_gunpoint,M)>1) - src.lower_gunpoint(M,1) - return - - src.shoot_point_blank(M,src.holding_at_gunpoint) - src.lower_gunpoint(M,1) - /obj/item/gun/proc/shoot_point_blank(var/mob/M as mob, var/mob/user as mob, var/second_shot = 0) if (!M || !user) return @@ -284,14 +244,14 @@ var/list/forensic_IDs = new/list() //Global list of all guns, based on bioholder var/target_turf = get_turf(M) SPAWN_DBG(2) if (get_dist(user,M)<=1) - user.r_hand:shoot_point_blank(M,user,1) + user.r_hand:shoot_point_blank(M,user,second_shot = 1) else user.r_hand:shoot(target_turf,get_turf(user), user, rand(-5,5), rand(-5,5)) else if(!user.hand && istype(user.l_hand, /obj/item/gun) && user.l_hand:can_dual_wield) var/target_turf = get_turf(M) SPAWN_DBG(2) if (get_dist(user,M)<=1) - user.l_hand:shoot_point_blank(M,user,1) + user.l_hand:shoot_point_blank(M,user,second_shot = 11) else user.l_hand:shoot(target_turf,get_turf(user), user, rand(-5,5), rand(-5,5)) @@ -364,8 +324,9 @@ var/list/forensic_IDs = new/list() //Global list of all guns, based on bioholder if (ismob(user)) var/mob/M = user - if (M.at_gunpoint) - M.at_gunpoint.shoot_at_gunpoint(M) + if (M.mob_flags & AT_GUNPOINT) + for(var/obj/item/grab/gunpoint/G in M.grabbed_by) + G.shoot() if(slowdown) SPAWN_DBG(-1) M.movement_delay_modifier += slowdown diff --git a/code/obj/item/gun/kinetic.dm b/code/obj/item/gun/kinetic.dm index a4d4ac5..b5457f7 100644 --- a/code/obj/item/gun/kinetic.dm +++ b/code/obj/item/gun/kinetic.dm @@ -318,7 +318,7 @@ afterattack(obj/O as obj, mob/user as mob) if (O.loc == user && O != src && istype(O, /obj/item/clothing)) - boutput(user, "You hide the derringer inside \the [O]. (Use the wink emote to retrieve it.)") + boutput(user, "You hide the derringer inside \the [O]. (Use the wink emote while wearing the clothing item to retrieve it.)") user.u_equip(src) src.set_loc(O) src.dropped(user) diff --git a/code/obj/item/implant.dm b/code/obj/item/implant.dm index ccdd5e4..5d22c29 100644 --- a/code/obj/item/implant.dm +++ b/code/obj/item/implant.dm @@ -426,7 +426,7 @@ var/global/list/tracking_implants = list() // things were looping through world if (ticker && ticker.mode && istype(ticker.mode, /datum/game_mode/revolution)) if (H.mind in ticker.mode:head_revolutionaries) H.visible_message("[H] resists the loyalty implant!") - H.changeStatus("weakened", 2 SECONDS) + H.changeStatus("weakened", 1 SECONDS) H.force_laydown_standup() playsound(H.loc, "sound/effects/electric_shock.ogg", 60, 0,0,pitch = 2.4) //src.on_remove(H) @@ -434,7 +434,7 @@ var/global/list/tracking_implants = list() // things were looping through world //src.set_loc(get_turf(H)) else if (H.mind in ticker.mode:revolutionaries) H.TakeDamage("chest", 1, 1, 0) - H.changeStatus("weakened", 2 SECONDS) + H.changeStatus("weakened", 1 SECONDS) H.force_laydown_standup() H.emote("scream") playsound(H.loc, "sound/effects/electric_shock.ogg", 60, 0,0,pitch = 1.6) @@ -445,7 +445,7 @@ var/global/list/tracking_implants = list() // things were looping through world return var/mob/living/carbon/human/H = src.owner if (H.mind in ticker.mode:revolutionaries) - H.TakeDamage("chest", 2*mult, 2*mult, 0) + H.TakeDamage("chest", 1.5*mult, 1.5*mult, 0) if (H.health < 0) H.changeStatus("paralysis", 5 SECONDS) H.force_laydown_standup() diff --git a/code/obj/item/kitchen.dm b/code/obj/item/kitchen.dm index 39f4fd4..dbe0b6b 100644 --- a/code/obj/item/kitchen.dm +++ b/code/obj/item/kitchen.dm @@ -126,6 +126,8 @@ TRAYS icon_state = "knife" flags = FPRINT | TABLEPASS | CONDUCT | ONBELT tool_flags = TOOL_CUTTING + event_handler_flags = USE_GRAB_CHOKE | USE_FLUID_ENTER + special_grab = /obj/item/grab hit_type = DAMAGE_CUT hitsound = 'sound/impact_sounds/Flesh_Cut_1.ogg' force = 7.0 diff --git a/code/obj/item/mob_parts/robot_parts.dm b/code/obj/item/mob_parts/robot_parts.dm index eb8fa18..e526480 100644 --- a/code/obj/item/mob_parts/robot_parts.dm +++ b/code/obj/item/mob_parts/robot_parts.dm @@ -291,7 +291,7 @@ desc = "A reinforced head unit capable of taking more abuse than usual." appearanceString = "sturdy" max_health = 225 - weight = 0.5 + weight = 0.2 attackby(obj/item/W as obj, mob/user as mob) if (istype(W,/obj/item/sheet) && (src.type == /obj/item/parts/robot_parts/head/sturdy)) @@ -344,7 +344,7 @@ desc = "A heavily reinforced head unit intended for use on cyborgs that perform tough and dangerous work." appearanceString = "heavy" max_health = 350 - weight = 1 + weight = 0.4 attackby(obj/item/W as obj, mob/user as mob) if (istype(W, /obj/item/weldingtool) && W:welding) @@ -549,7 +549,7 @@ name = "sturdy cyborg left arm" appearanceString = "sturdy" max_health = 100 - weight = 0.5 + weight = 0.2 attackby(obj/item/W as obj, mob/user as mob) if(istype(W,/obj/item/sheet) && (src.type == /obj/item/parts/robot_parts/arm/left/sturdy)) @@ -576,7 +576,7 @@ name = "heavy cyborg left arm" appearanceString = "heavy" max_health = 175 - weight = 1 + weight = 0.4 /obj/item/parts/robot_parts/arm/left/light name = "light cyborg left arm" @@ -614,7 +614,7 @@ name = "sturdy cyborg right arm" appearanceString = "sturdy" max_health = 100 - weight = 0.5 + weight = 0.2 attackby(obj/item/W as obj, mob/user as mob) if(istype(W,/obj/item/sheet) && (src.type == /obj/item/parts/robot_parts/arm/right/sturdy)) @@ -641,7 +641,7 @@ name = "heavy cyborg right arm" appearanceString = "heavy" max_health = 175 - weight = 1 + weight = 0.4 /obj/item/parts/robot_parts/arm/right/light name = "light cyborg right arm" @@ -655,6 +655,8 @@ desc = "A metal leg for a cyborg. It won't be able to move very well without this!" max_health = 60 effect_modifier = 0.2 + var/step_sound = "step_robo" + var/step_priority = STEP_PRIORITY_LOW attack(mob/living/carbon/M as mob, mob/living/carbon/user as mob) if(!ismob(M)) diff --git a/code/obj/item/organs/eye.dm b/code/obj/item/organs/eye.dm index e9e6a36..6856ac4 100644 --- a/code/obj/item/organs/eye.dm +++ b/code/obj/item/organs/eye.dm @@ -135,6 +135,10 @@ color_b = 0.975 // kinda blue change_iris = 0 + setupProperties() + ..() + setProperty("disorient_resist_eye", 100) + /obj/item/organ/eye/cyber/sechud name = "\improper Security HUD cybereye" organ_name = "\improper Security HUD cybereye" diff --git a/code/obj/item/organs/heart.dm b/code/obj/item/organs/heart.dm index 437194b..cb700ea 100644 --- a/code/obj/item/organs/heart.dm +++ b/code/obj/item/organs/heart.dm @@ -26,9 +26,11 @@ if (src.emagged) src.donor.add_stam_mod_regen("heart", 15) src.donor.add_stam_mod_max("heart", 90) + src.donor.add_stun_resist_mod("heart", 30) else src.donor.add_stam_mod_regen("heart", 5) src.donor.add_stam_mod_max("heart", 40) + src.donor.add_stun_resist_mod("heart", 15) if (src.donor) for (var/datum/ailment_data/disease in src.donor.ailments) @@ -44,6 +46,11 @@ on_removal() ..() if (donor) + if (src.robotic) + src.donor.remove_stam_mod_regen("heart") + src.donor.remove_stam_mod_max("heart") + src.donor.remove_stun_resist_mod("heart") + var/datum/ailment_data/malady/HD = donor.find_ailment_by_type(/datum/ailment/malady/heartdisease) if (HD) if (!islist(src.diseases)) @@ -133,7 +140,7 @@ if (ishuman(M)) M:blood_color = "#4d736d" // there is no undo for this. wear the stain of your weird alien blood, pal - //was do_process + //was do_process on_life() var/mob/living/M = src.holder.donor if(!M || !ishuman(M)) // flockdrones shouldn't have these problems diff --git a/code/obj/item/storage/backpack_belt_etc.dm b/code/obj/item/storage/backpack_belt_etc.dm index 95094bf..49b86f8 100644 --- a/code/obj/item/storage/backpack_belt_etc.dm +++ b/code/obj/item/storage/backpack_belt_etc.dm @@ -103,13 +103,9 @@ stamina_crit_chance = 5 proc/can_use() + .= 1 if (!ismob(loc)) return 0 - var/mob/M = loc - if (src in M.get_equipped_items()) - return 1 - else - return 0 MouseDrop(obj/over_object as obj, src_location, over_location) var/mob/M = usr diff --git a/code/obj/item/stun_baton.dm b/code/obj/item/stun_baton.dm index 5b282e3..dba6890 100644 --- a/code/obj/item/stun_baton.dm +++ b/code/obj/item/stun_baton.dm @@ -558,6 +558,7 @@ item_state = "barrier0" uses_multiple_icon_states = 1 flags = FPRINT | ONBELT | TABLEPASS + c_flags = EQUIPPED_WHILE_HELD force = 2 throwforce = 6 w_class = 2 @@ -591,6 +592,9 @@ setProperty("meleeprot", 9) setProperty("rangedprot", 1.5) setProperty("movespeed", 0.3) + setProperty("disorient_resist", 65) + setProperty("disorient_resist_eye", 65) + setProperty("disorient_resist_ear", 50) //idk how lol ok flick("barrier_a",src) @@ -601,6 +605,7 @@ setProperty("meleeprot", 0) setProperty("rangedprot", 0) setProperty("movespeed", 0) + setProperty("disorient_resist", 0) src.setItemSpecial(/datum/item_special/simple) diff --git a/code/obj/item/toilets.dm b/code/obj/item/toilets.dm index 18cc8ae..3fd4119 100644 --- a/code/obj/item/toilets.dm +++ b/code/obj/item/toilets.dm @@ -10,6 +10,7 @@ var/list/all_toilets = null anchored = 1.0 density = 0.0 mats = 5 + deconstruct_flags = DECON_WRENCH | DECON_WELDER var/status = 0.0 var/clogged = 0.0 anchored = 1.0 diff --git a/code/obj/item/toys.dm b/code/obj/item/toys.dm index 1cf1780..6bc7637 100644 --- a/code/obj/item/toys.dm +++ b/code/obj/item/toys.dm @@ -5,6 +5,7 @@ icon_state = "claw" anchored = 1 density = 1 + deconstruct_flags = DECON_MULTITOOL | DECON_WRENCH | DECON_CROWBAR var/busy = 0 var/list/prizes = list(/obj/item/toy/plush/small/bee,\ /obj/item/toy/plush/small/buddy,\ @@ -300,6 +301,29 @@ user.lastattacked = src return 0 + attack_self(mob/user as mob) + var/message = input("What should [src] say?") + message = trim(copytext(sanitize(html_encode(message)), 1, MAX_MESSAGE_LEN)) + if (!message) + return + logTheThing("say", user, null, "makes [src] say, \"[message]\"") + user.audible_message("[src] says, \"[message]\"") + if (ishuman(user)) + var/mob/living/carbon/human/H = user + if (H.sims) + H.sims.affectMotive("fun", 1) + + afterattack(atom/target, mob/user, reach, params) + ..() + if (src.icon_state == "fig-beebo") + if (istype(target,/obj/stool/bed)) + user.visible_message("[user] tucks the [src.name] into [target].") + src.icon_state = "fig-sleebee" + SPAWN_DBG(1 MINUTES) + src.icon_state = "fig-beebo" + + + UpdateName() if (istype(src.info)) src.name = "[name_prefix(null, 1)][src.info.name] figure[name_suffix(null, 1)]" @@ -387,7 +411,9 @@ var/list/figure_patreon_rarity = list(\ /datum/figure_info/shelterfrog, /datum/figure_info/floorpills, /datum/figure_info/stephaniemir, -/datum/figure_info/fletcherhenderson) +/datum/figure_info/fletcherhenderson, +/datum/figure_info/adaohara, +/datum/figure_info/oranges) /datum/figure_info var/name = "staff assistant" @@ -710,7 +736,7 @@ var/list/figure_patreon_rarity = list(\ floorpills name = "\improper Dr. Floorpills" - icon_state = "floorpillls" + icon_state = "floorpills" stephaniemir name = "\improper Stephanie Mir" @@ -720,7 +746,14 @@ var/list/figure_patreon_rarity = list(\ name = "\improper Fletcher Henderson" icon_state = "fletcherhenderson" + adaohara + name = "\improper Ada O'Hara" + icon_state = "adaohara" + oranges + name = "\improper The Tangerine" + icon_state = "oranges" + #ifdef XMAS santa name = "\improper Santa Claus" diff --git a/code/obj/machinery/air_sensor.dm b/code/obj/machinery/air_sensor.dm index 3c55963..3f1eeac 100644 --- a/code/obj/machinery/air_sensor.dm +++ b/code/obj/machinery/air_sensor.dm @@ -11,6 +11,9 @@ obj/machinery/air_sensor var/on = 1 var/output = 3 + + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_MULTITOOL + //Flags: // 1 for pressure // 2 for temperature diff --git a/code/obj/machinery/air_vendor.dm b/code/obj/machinery/air_vendor.dm index 8d33981..15611e4 100644 --- a/code/obj/machinery/air_vendor.dm +++ b/code/obj/machinery/air_vendor.dm @@ -7,6 +7,8 @@ obj/machinery/air_vendor anchored = 1 density = 1 + deconstruct_flags = DECON_CROWBAR | DECON_WRENCH | DECON_MULTITOOL + // Credits inserted var/credits = 0 diff --git a/code/obj/machinery/camera.dm b/code/obj/machinery/camera.dm index b122188..9c600fe 100644 --- a/code/obj/machinery/camera.dm +++ b/code/obj/machinery/camera.dm @@ -3,6 +3,8 @@ desc = "A small, high quality camera with thermal, light-amplification, and diffused laser imaging to see through walls. It is tied into a computer system, allowing those with access to watch what occurs around it." icon = 'icons/obj/monitors.dmi' icon_state = "camera" + deconstruct_flags = DECON_SCREWDRIVER | DECON_WELDER | DECON_WIRECUTTERS | DECON_MULTITOOL + var/network = "SS13" layer = EFFECTS_LAYER_UNDER_1 var/c_tag = null diff --git a/code/obj/machinery/cashreg.dm b/code/obj/machinery/cashreg.dm index e178e58..913b00c 100644 --- a/code/obj/machinery/cashreg.dm +++ b/code/obj/machinery/cashreg.dm @@ -5,6 +5,7 @@ icon_state = "scanner" anchored = 1 mats = 6 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_MULTITOOL var/datum/data/record/mainaccount = null diff --git a/code/obj/machinery/cell_charger.dm b/code/obj/machinery/cell_charger.dm index 10b5242..cecc1bf 100644 --- a/code/obj/machinery/cell_charger.dm +++ b/code/obj/machinery/cell_charger.dm @@ -8,6 +8,7 @@ var/chargelevel = -1 anchored = 1 mats = 8 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WIRECUTTERS | DECON_MULTITOOL power_usage = 50 /obj/machinery/cell_charger/attackby(obj/item/W, mob/user) diff --git a/code/obj/machinery/clonepod.dm b/code/obj/machinery/clonepod.dm index 6a3e4cd..a3fdd68 100644 --- a/code/obj/machinery/clonepod.dm +++ b/code/obj/machinery/clonepod.dm @@ -15,6 +15,7 @@ icon = 'icons/obj/cloning.dmi' icon_state = "pod_0_lowmeat" req_access = list(access_medlab) //For premature unlocking. + object_flags = CAN_REPROGRAM_ACCESS mats = 15 var/meat_used_per_tick = DEFAULT_MEAT_USED_PER_TICK var/mob/living/occupant diff --git a/code/obj/machinery/computer/QM_supply.dm b/code/obj/machinery/computer/QM_supply.dm index a36d232..4b2d272 100644 --- a/code/obj/machinery/computer/QM_supply.dm +++ b/code/obj/machinery/computer/QM_supply.dm @@ -58,6 +58,8 @@ var/global/datum/cdc_contact_controller/QM_CDC = new() icon = 'icons/obj/computer.dmi' icon_state = "QMcom" req_access = list(access_cargo) + object_flags = CAN_REPROGRAM_ACCESS + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_WELDER | DECON_MULTITOOL var/temp = null var/last_cdc_message = null var/hacked = 0 diff --git a/code/obj/machinery/computer/announcement.dm b/code/obj/machinery/computer/announcement.dm index a9a7d73..2a894cc 100644 --- a/code/obj/machinery/computer/announcement.dm +++ b/code/obj/machinery/computer/announcement.dm @@ -18,6 +18,7 @@ var/voice_message = "broadcasts" var/voice_name = "Announcement Computer" req_access = list(access_heads) + object_flags = CAN_REPROGRAM_ACCESS lr = 0.6 lg = 1 diff --git a/code/obj/machinery/computer/arcade.dm b/code/obj/machinery/computer/arcade.dm index e59e7f7..19563d4 100644 --- a/code/obj/machinery/computer/arcade.dm +++ b/code/obj/machinery/computer/arcade.dm @@ -6,6 +6,8 @@ name = "arcade machine" icon = 'icons/obj/computer.dmi' icon_state = "arcade" + mats = 10 + deconstruct_flags = DECON_MULTITOOL var/enemy_name = "Space Villian" var/temp = "Winners Don't Use Spacedrugs" //Temporary message, for attack messages, etc var/player_hp = 30 //Player health/attack points diff --git a/code/obj/machinery/computer/card.dm b/code/obj/machinery/computer/card.dm index 22f361f..210cb23 100644 --- a/code/obj/machinery/computer/card.dm +++ b/code/obj/machinery/computer/card.dm @@ -11,6 +11,7 @@ req_access = list(access_change_ids) desc = "A computer that allows an authorized user to change the identification of other ID cards." + deconstruct_flags = DECON_MULTITOOL lr = 0.7 lg = 1 lb = 0.1 diff --git a/code/obj/machinery/computer/cloning.dm b/code/obj/machinery/computer/cloning.dm index b3c85d6..a9ba361 100644 --- a/code/obj/machinery/computer/cloning.dm +++ b/code/obj/machinery/computer/cloning.dm @@ -7,6 +7,7 @@ icon = 'icons/obj/computer.dmi' icon_state = "dna" req_access = list(access_heads) //Only used for record deletion right now. + object_flags = CAN_REPROGRAM_ACCESS var/obj/machinery/clone_scanner/scanner = null //Linked scanner. For scanning. var/obj/machinery/clonepod/pod1 = null //Linked cloning pod. var/temp = "Initializing System..." diff --git a/code/obj/machinery/computer/communications.dm b/code/obj/machinery/computer/communications.dm index 31d60fb..8b10ab2 100644 --- a/code/obj/machinery/computer/communications.dm +++ b/code/obj/machinery/computer/communications.dm @@ -4,6 +4,7 @@ name = "Communications Console" icon_state = "comm" req_access = list(access_heads) + object_flags = CAN_REPROGRAM_ACCESS var/prints_intercept = 1 var/authenticated = 0 var/list/messagetitle = list() diff --git a/code/obj/machinery/computer/general_air_control.dm b/code/obj/machinery/computer/general_air_control.dm index cd85620..81fcd84 100644 --- a/code/obj/machinery/computer/general_air_control.dm +++ b/code/obj/machinery/computer/general_air_control.dm @@ -130,6 +130,7 @@ obj/machinery/computer/general_air_control icon = 'icons/obj/computer.dmi' icon_state = "tank" req_access = list(access_engineering_atmos) + object_flags = CAN_REPROGRAM_ACCESS var/input_tag var/output_tag @@ -558,6 +559,7 @@ Rate: -- wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. icon = 'icons/obj/doors/doorint.dmi' icon_state = "door_closed" + deconstruct_flags = DECON_ACCESS | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_SCREWDRIVER | DECON_MULTITOOL + object_flags = BOTS_DIRBLOCK | CAN_REPROGRAM_ACCESS + var/image/panel_image = null var/panel_icon_state = "panel_open" @@ -146,6 +149,7 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. cant_emag = 1 hardened = 1 aiControlDisabled = 1 + object_flags = BOTS_DIRBLOCK meteorhit() return @@ -159,6 +163,7 @@ Airlock index -> wire color are { 9, 4, 6, 7, 5, 8, 1, 2, 3 }. cant_emag = 1 hardened = 1 aiControlDisabled = 1 + object_flags = BOTS_DIRBLOCK meteorhit() return diff --git a/code/obj/machinery/door/door_parent.dm b/code/obj/machinery/door/door_parent.dm index 8a9a2a7..5a2d020 100644 --- a/code/obj/machinery/door/door_parent.dm +++ b/code/obj/machinery/door/door_parent.dm @@ -318,18 +318,6 @@ if (src.sound_deny) playsound(src.loc, src.sound_deny, 25, 0) - //grabsmash - if (istype(I, /obj/item/grab/)) - var/obj/item/grab/G = I - - if (ismob(G.affecting) && src.allowed(G.affecting) && src.density) - src.last_used = world.time - src.open() - - if (!grab_smash(G, user)) - return ..(I, user) - else return - if (src.density && !src.operating && I) user.lastattacked = src attack_particle(user,src) @@ -350,7 +338,7 @@ src.take_damage(resolvedForce, user) - return + return ..(I,user) /obj/machinery/door/proc/bumpopen(mob/user as mob) if (src.operating) diff --git a/code/obj/machinery/door/poddoor.dm b/code/obj/machinery/door/poddoor.dm index 08d417f..f2ced9b 100644 --- a/code/obj/machinery/door/poddoor.dm +++ b/code/obj/machinery/door/poddoor.dm @@ -5,6 +5,7 @@ icon_base = "pdoor" cant_emag = 1 layer = 2.8 + object_flags = 0 health = 1800 health_max = 1800 diff --git a/code/obj/machinery/door/window.dm b/code/obj/machinery/door/window.dm index d67d08c..e20cde0 100644 --- a/code/obj/machinery/door/window.dm +++ b/code/obj/machinery/door/window.dm @@ -17,6 +17,7 @@ brainloss_stumble = 1 autoclose = 1 event_handler_flags = USE_FLUID_ENTER | USE_CHECKEXIT | USE_CANPASS + object_flags = CAN_REPROGRAM_ACCESS New() ..() diff --git a/code/obj/machinery/espresso.dm b/code/obj/machinery/espresso.dm index c4735e4..86d1f2a 100644 --- a/code/obj/machinery/espresso.dm +++ b/code/obj/machinery/espresso.dm @@ -10,6 +10,7 @@ anchored = 1 flags = FPRINT | NOSPLASH mats = 30 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_WELDER | DECON_WIRECUTTERS var/cupinside = 0 //true or false var/top_on = 1 //screwed on or screwed off var/water_level = 100 //water level, used to press the coffee @@ -248,6 +249,7 @@ anchored = 1 flags = FPRINT | NOSPLASH mats = 30 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_WELDER | DECON_WIRECUTTERS var/top_on = 1 //screwed on or screwed off var/water_level = 100 //water level, used to press the coffee var/water_level_max = 100 diff --git a/code/obj/machinery/firealarm.dm b/code/obj/machinery/firealarm.dm index 8d9017e..205cc77 100644 --- a/code/obj/machinery/firealarm.dm +++ b/code/obj/machinery/firealarm.dm @@ -6,6 +6,8 @@ name = "Fire Alarm" icon = 'icons/obj/monitors.dmi' icon_state = "fire0" + deconstruct_flags = DECON_WIRECUTTERS | DECON_MULTITOOL + var/alarm_frequency = "1437" var/detecting = 1.0 var/working = 1.0 @@ -40,6 +42,13 @@ radio_controller.remove_object(src, alarm_frequency) ..() +/obj/machinery/firealarm/set_loc(var/newloc) + ..() + var/area/A = get_area(loc) + if (A) + alarm_zone = A.name + net_id = generate_net_id(src) + /obj/machinery/firealarm/proc/toggleinput(var/datum/mechanicsMessage/inp) if(src.icon_state == "fire0") alarm() diff --git a/code/obj/machinery/gibber.dm b/code/obj/machinery/gibber.dm index dd22f90..7c66595 100644 --- a/code/obj/machinery/gibber.dm +++ b/code/obj/machinery/gibber.dm @@ -11,6 +11,7 @@ var/mob/occupant // Mob who has been put inside var/output_direction = "W" // Spray gibs and meat in that direction. mats = 15 + deconstruct_flags = DECON_WRENCH | DECON_WELDER output_north output_direction = "N" diff --git a/code/obj/machinery/glass_recycler.dm b/code/obj/machinery/glass_recycler.dm index d0180da..22b9a08 100644 --- a/code/obj/machinery/glass_recycler.dm +++ b/code/obj/machinery/glass_recycler.dm @@ -7,6 +7,7 @@ density = 0 var/glass_amt = 0 mats = 10 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_WELDER | DECON_WIRECUTTERS New() ..() diff --git a/code/obj/machinery/launcherloader.dm b/code/obj/machinery/launcherloader.dm index a80616f..3870262 100644 --- a/code/obj/machinery/launcherloader.dm +++ b/code/obj/machinery/launcherloader.dm @@ -298,6 +298,8 @@ icon = 'icons/obj/delivery.dmi' icon_state = "barcode_comp" + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_WIRECUTTERS | DECON_MULTITOOL + var/printing = 0 // log account information for QM sales diff --git a/code/obj/machinery/manufacturer.dm b/code/obj/machinery/manufacturer.dm index 3e91192..06d2676 100644 --- a/code/obj/machinery/manufacturer.dm +++ b/code/obj/machinery/manufacturer.dm @@ -9,6 +9,7 @@ density = 1 anchored = 1 mats = 20 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_WELDER | DECON_WIRECUTTERS | DECON_MULTITOOL flags = NOSPLASH var/health = 100 var/mode = "ready" @@ -1555,7 +1556,7 @@ src.build_icon() proc/claim_free_resources() - if (mats == "Built") + if (src.deconstruct_flags & DECON_BUILT) free_resource_amt = 0 if (free_resources.len && free_resource_amt > 0) var/looper = src.free_resource_amt diff --git a/code/obj/machinery/microwave.dm b/code/obj/machinery/microwave.dm index 58b9566..5d264d4 100644 --- a/code/obj/machinery/microwave.dm +++ b/code/obj/machinery/microwave.dm @@ -21,6 +21,7 @@ var/obj/item/reagent_containers/food/snacks/being_cooked = null // The item being cooked var/obj/item/extra_item // One non food item that can be added mats = 12 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH var/emagged = 0 emag_act(var/mob/user, var/obj/item/card/emag/E) diff --git a/code/obj/machinery/navbeacon.dm b/code/obj/machinery/navbeacon.dm index 62d45b8..c58a201 100644 --- a/code/obj/machinery/navbeacon.dm +++ b/code/obj/machinery/navbeacon.dm @@ -20,6 +20,7 @@ var/net_id = "" req_access = list(access_engineering) + object_flags = CAN_REPROGRAM_ACCESS New() ..() diff --git a/code/obj/machinery/phone.dm b/code/obj/machinery/phone.dm index 484016f..950c881 100644 --- a/code/obj/machinery/phone.dm +++ b/code/obj/machinery/phone.dm @@ -9,6 +9,7 @@ anchored = 1 density = 0 mats = 25 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WIRECUTTERS | DECON_MULTITOOL _health = 50 var/can_talk_across_z_levels = 0 var/phone_id = null diff --git a/code/obj/machinery/photocopier.dm b/code/obj/machinery/photocopier.dm index 4969455..6eb3e72 100644 --- a/code/obj/machinery/photocopier.dm +++ b/code/obj/machinery/photocopier.dm @@ -7,6 +7,7 @@ icon_state = "close_sesame" pixel_x = 2 //its just a bit limited by sprite width, needs a small offset mats = 16 //just to make photocopiers mech copyable, how could this possibly go wrong? + deconstruct_flags = DECON_SCREWDRIVER | DECON_CROWBAR | DECON_WELDER | DECON_MULTITOOL var/use_state = 0 //0 is closed, 1 is open, 2 is busy, closed by default var/paper_amount = 0.0 //starts at 0.0, increments by one for every paper added, max of... 30 sheets var/make_amount = 0 //from 0 to 30, amount of copies the photocopier will copy, copy? @@ -156,7 +157,7 @@ if ("Print Copies") src.visible_message("\The [src] starts printing copies!") make_amount = max(make_amount, 30) - if (paper_amount <= 0) + if (paper_amount <= 0) src.visible_message("No more paper in tray!") return for (var/i = 1, i <= src.make_amount, i++) @@ -215,7 +216,7 @@ P.info = "{butt butt butt butt butt butt
butt butt
butt
}" //6 butts then 2 butts then 1 butt haha P.icon = 'icons/obj/surgery.dmi' P.icon_state = "butt" - + return proc/reset_all() @@ -236,4 +237,4 @@ src.use_state = 0 else src.icon_state = "open_sesame" - src.use_state = 1 + src.use_state = 1 diff --git a/code/obj/machinery/pipe/pipe_dispenser.dm b/code/obj/machinery/pipe/pipe_dispenser.dm index 8a0b4e5..6285df1 100644 --- a/code/obj/machinery/pipe/pipe_dispenser.dm +++ b/code/obj/machinery/pipe/pipe_dispenser.dm @@ -55,6 +55,7 @@ density = 1 anchored = 1.0 mats = 16 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_WIRECUTTERS /obj/machinery/disposal_pipedispenser/mobile name = "Disposal Pipe Dispenser Cart" diff --git a/code/obj/machinery/porters.dm b/code/obj/machinery/porters.dm index 081d61e..8fd4e1c 100644 --- a/code/obj/machinery/porters.dm +++ b/code/obj/machinery/porters.dm @@ -278,6 +278,7 @@ var/global/list/portable_machinery = list() // stop looping through world for th anchored = 0 p_class = 1.8 req_access = list(access_security) + object_flags = CAN_REPROGRAM_ACCESS mats = 30 var/mob/occupant = null var/locked = 0 diff --git a/code/obj/machinery/recharge_station.dm b/code/obj/machinery/recharge_station.dm index 7e063bc..cbde9f4 100644 --- a/code/obj/machinery/recharge_station.dm +++ b/code/obj/machinery/recharge_station.dm @@ -6,6 +6,7 @@ density = 1 anchored = 1.0 mats = 10 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_MULTITOOL allow_stunned_dragndrop = 1 var/chargerate = 400 var/cabling = 250 diff --git a/code/obj/machinery/recharger.dm b/code/obj/machinery/recharger.dm index 5afd8a2..aa4761c 100644 --- a/code/obj/machinery/recharger.dm +++ b/code/obj/machinery/recharger.dm @@ -27,6 +27,7 @@ obj/machinery/recharger icon_state = "recharger0" name = "recharger" mats = 16 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_MULTITOOL desc = "An anchored minature recharging device, used to recharge small, hand-held objects that don't require much electrical charge." power_usage = 50 diff --git a/code/obj/machinery/secscanner.dm b/code/obj/machinery/secscanner.dm index b1c88ed..ea36a65 100644 --- a/code/obj/machinery/secscanner.dm +++ b/code/obj/machinery/secscanner.dm @@ -8,6 +8,7 @@ anchored = 1 layer = 2 mats = 18 + deconstruct_flags = DECON_WRENCH | DECON_WELDER | DECON_WIRECUTTERS | DECON_MULTITOOL appearance_flags = TILE_BOUND var/timeBetweenUses = 20//I can see this being fun var/success_sound = "sound/machines/chime.ogg" diff --git a/code/obj/machinery/singularity.dm b/code/obj/machinery/singularity.dm index eec35d7..66a0ccb 100644 --- a/code/obj/machinery/singularity.dm +++ b/code/obj/machinery/singularity.dm @@ -74,6 +74,7 @@ Contains: anchored = 1 density = 1 event_handler_flags = IMMUNE_SINGULARITY + deconstruct_flags = DECON_WELDER | DECON_MULTITOOL bound_width = 96 bound_height = 96 @@ -372,6 +373,7 @@ for some reason I brought it back and tried to clean it up a bit and I regret ev anchored = 0 density = 1 req_access = list(access_engineering_engine) + object_flags = CAN_REPROGRAM_ACCESS var/Varedit_start = 0 var/Varpower = 0 var/active = 0 @@ -837,6 +839,7 @@ for some reason I brought it back and tried to clean it up a bit and I regret ev anchored = 0 density = 1 req_access = list(access_engineering_engine) + object_flags = CAN_REPROGRAM_ACCESS var/active = 0 var/power = 20 var/fire_delay = 100 diff --git a/code/obj/machinery/sleeper.dm b/code/obj/machinery/sleeper.dm index 6877b68..15ce40e 100644 --- a/code/obj/machinery/sleeper.dm +++ b/code/obj/machinery/sleeper.dm @@ -20,6 +20,7 @@ anchored = 1 density = 1 mats = 8 + deconstruct_flags = DECON_CROWBAR | DECON_MULTITOOL var/timing = 0 // Timer running? var/time = null // In 1/10th seconds. var/time_started = 0 // world.timeofday when the timer was started @@ -281,6 +282,7 @@ density = 1 anchored = 1 mats = 25 + deconstruct_flags = DECON_CROWBAR | DECON_WIRECUTTERS | DECON_MULTITOOL event_handler_flags = USE_FLUID_ENTER | USE_CANPASS var/mob/occupant = null var/image/image_lid = null diff --git a/code/obj/machinery/spaceheater.dm b/code/obj/machinery/spaceheater.dm index 180f895..628dee9 100644 --- a/code/obj/machinery/spaceheater.dm +++ b/code/obj/machinery/spaceheater.dm @@ -14,6 +14,7 @@ var/heating_power = 40000 var/cooling_power = -30000 mats = 8 + deconstruct_flags = DECON_WRENCH | DECON_WELDER flags = FPRINT @@ -270,6 +271,7 @@ var/heating_power = 40000 var/cooling_power = -30000 mats = 8 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER flags = FPRINT diff --git a/code/obj/machinery/status_display.dm b/code/obj/machinery/status_display.dm index 68ca11b..5b984e4 100644 --- a/code/obj/machinery/status_display.dm +++ b/code/obj/machinery/status_display.dm @@ -14,6 +14,7 @@ var/list/status_display_text_images = list() anchored = 1 density = 0 mats = 14 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_MULTITOOL // var/mode = 1 // 0 = Blank // 1 = Shuttle timer @@ -374,6 +375,7 @@ var/list/status_display_text_images = list() anchored = 1 density = 0 mats = 14 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_MULTITOOL var/mode = 0 // 0 = Blank // 1 = AI emoticon diff --git a/code/obj/machinery/turret.dm b/code/obj/machinery/turret.dm index 3f62584..c42cb48 100644 --- a/code/obj/machinery/turret.dm +++ b/code/obj/machinery/turret.dm @@ -342,6 +342,7 @@ var/turretsExist = 1 req_access = list(access_ai_upload) + object_flags = CAN_REPROGRAM_ACCESS /obj/machinery/turretid/attackby(obj/item/W, mob/user) if(status & BROKEN) return diff --git a/code/obj/machinery/tv_vis.dm b/code/obj/machinery/tv_vis.dm index a773381..1f1130e 100644 --- a/code/obj/machinery/tv_vis.dm +++ b/code/obj/machinery/tv_vis.dm @@ -1,8 +1,12 @@ /obj/landmark/boxing_ring name = "boxing ring" -/turf - appearance_flags = KEEP_TOGETHER - vis_flags = VIS_INHERIT_PLANE|VIS_INHERIT_PLANE|VIS_INHERIT_ID + + + //disabling this for now bcause somepotato says its costly on client fps stuff +///turf + //appearance_flags = KEEP_TOGETHER + //vis_flags = VIS_INHERIT_PLANE|VIS_INHERIT_PLANE|VIS_INHERIT_ID + /obj/machinery/security_monitor name = "Security Monitor" icon = 'icons/obj/sec_tv.dmi' @@ -10,7 +14,7 @@ anchored = 1.0 pixel_y = 30 layer = OBJ_LAYER+1 - appearance_flags = KEEP_TOGETHER + appearance_flags = KEEP_TOGETHER var/list/cameras = list() //all camera's detected by this device which it can link to var/obj/current_camera = null var/obj/video_screen/video_screen @@ -89,7 +93,7 @@ plane = PLANE_LIGHTING + 1 var/fov = 2 var/obj/machinery/security_monitor/owner - var/image/blank + var/image/blank New(var/obj/machinery/security_monitor/owner) ..() diff --git a/code/obj/machinery/weapon_racks.dm b/code/obj/machinery/weapon_racks.dm index c625436..a31d34a 100644 --- a/code/obj/machinery/weapon_racks.dm +++ b/code/obj/machinery/weapon_racks.dm @@ -21,6 +21,7 @@ var/amount = 1 anchored = 1 density = 1 + object_flags = CAN_REPROGRAM_ACCESS var/stand_type = "katanastand" var/contained_weapon = /obj/item/katana_sheath var/contained_weapon_name = "katana" diff --git a/code/obj/mining.dm b/code/obj/mining.dm index 0f797a4..9050d85 100644 --- a/code/obj/mining.dm +++ b/code/obj/mining.dm @@ -795,6 +795,7 @@ var/list/linked_magnets = list() var/obj/machinery/mining_magnet/linked_magnet = null req_access = list(access_engineering_chief) + object_flags = CAN_REPROGRAM_ACCESS New() ..() @@ -1349,6 +1350,7 @@ var/stone_color = null var/image/coloration_overlay = null var/list/space_overlays = list() + turf_flags = MOB_SLIP | MOB_STEP | IS_TYPE_SIMULATED | FLUID_MOVE #ifdef UNDERWATER_MAP fullbright = 0 @@ -2188,6 +2190,7 @@ var/global/list/cargopads = list() anchored = 1 plane = PLANE_FLOOR mats = 10 //I don't see the harm in re-adding this. -ZeWaka + deconstruct_flags = DECON_SCREWDRIVER | DECON_CROWBAR | DECON_WELDER | DECON_MULTITOOL var/active = 1 podbay @@ -2226,6 +2229,18 @@ var/global/list/cargopads = list() cargopads.Remove(src) ..() + + was_deconstructed_to_frame(mob/user) + if (cargopads.Find(src)) + cargopads.Remove(src) + ..() + + was_built_from_frame(mob/user) + if (!cargopads.Find(src)) + cargopads.Add(src) + ..() + + attack_hand(var/mob/user as mob) if (src.active == 1) boutput(user, "You switch the receiver off.") diff --git a/code/obj/misc_junk.dm b/code/obj/misc_junk.dm index 5d10ac1..cf0ab71 100644 --- a/code/obj/misc_junk.dm +++ b/code/obj/misc_junk.dm @@ -736,6 +736,7 @@ density = 1 icon = 'icons/obj/wrestlingbell.dmi' icon_state = "wrestlingbell" + deconstruct_flags = DECON_WRENCH var/last_ring = 0 attack_hand(mob/user as mob) diff --git a/code/obj/morgue.dm b/code/obj/morgue.dm index 519937b..ecb77ac 100644 --- a/code/obj/morgue.dm +++ b/code/obj/morgue.dm @@ -376,6 +376,7 @@ icon_state = "crema_switch" anchored = 1.0 req_access = list(access_crematorium) + object_flags = CAN_REPROGRAM_ACCESS var/on = 0 var/area/area = null var/otherarea = null diff --git a/code/obj/posters.dm b/code/obj/posters.dm index c7031d8..594d556 100644 --- a/code/obj/posters.dm +++ b/code/obj/posters.dm @@ -390,6 +390,7 @@ var/global/icon/wanted_poster_unknown = icon('icons/obj/decals.dmi', "wanted-unk density = 1 anchored = 1 mats = 6 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_WIRECUTTERS | DECON_MULTITOOL icon = 'icons/obj/objects.dmi' icon_state = "poster_printer" var/pdata = null diff --git a/code/obj/screen.dm b/code/obj/screen.dm index f0efb56..47ad576 100644 --- a/code/obj/screen.dm +++ b/code/obj/screen.dm @@ -6,7 +6,7 @@ mat_changename = 0 mat_changedesc = 0 -/obj/screen/proc/clicked(list/params) +/obj/screen/proc/clicked(list/params, mob/user = null) /obj/screen/proc/add_to_client(var/client/C) if (clients) diff --git a/code/obj/sealab_objects.dm b/code/obj/sealab_objects.dm index af595bf..c6afb31 100644 --- a/code/obj/sealab_objects.dm +++ b/code/obj/sealab_objects.dm @@ -65,7 +65,25 @@ //mbc : added dumb layer code to keep perspective intact *most of the time* /obj/sea_plant/CanPass(atom/A, turf/T) if (ismob(A)) - A.changeStatus("slowed", 5) + + var/mob/M = A + + var/has_fluid_move_gear = 0 + for(var/atom in M.get_equipped_items()) + var/obj/item/I = atom + if (I.getProperty("negate_fluid_speed_penalty")) + has_fluid_move_gear = 1 + break + + if (!has_fluid_move_gear) + if (ishuman(A)) + var/mob/living/carbon/human/H = A + if (H.mutantrace && H.mutantrace.aquatic) + has_fluid_move_gear = 1 + + if (!has_fluid_move_gear) + A.setStatus("slowed", 5, optional = 4) + if (get_dir(src,A) & SOUTH || pixel_y > 0) //If we approach from underneath, fudge the layer so the drawing order doesn't break perspective src.layer = 3.9 else diff --git a/code/obj/stool.dm b/code/obj/stool.dm index 11c3184..cff6ad4 100644 --- a/code/obj/stool.dm +++ b/code/obj/stool.dm @@ -78,12 +78,6 @@ else if (isscrewingtool(W) && src.securable) src.toggle_secure(user) return - //grabsmash - else if (istype(W, /obj/item/grab)) - var/obj/item/grab/G = W - if (!grab_smash(G, user)) - return ..(W, user) - else return else return ..() @@ -92,7 +86,8 @@ return proc/unbuckle() //Ditto but for unbuckling - return + if (src.buckled_guy) + src.buckled_guy.end_chair_flip_targeting() proc/toggle_secure(mob/user as mob) if (user) @@ -342,9 +337,11 @@ to_buckle.setStatus("buckled", duration = null) unbuckle() + ..() if(src.buckled_guy) buckled_guy.anchored = 0 buckled_guy.buckled = null + buckled_guy.force_laydown_standup() src.buckled_guy = null playsound(get_turf(src), "sound/misc/belt_click.ogg", 50, 1) @@ -634,7 +631,9 @@ H.on_chair = src to_buckle.buckled = src src.buckled_guy = to_buckle + src.buckledIn = 1 to_buckle.setStatus("buckled", duration = null) + H.start_chair_flip_targeting() else if (src.anchored) to_buckle.anchored = 1 @@ -647,15 +646,19 @@ unbuckle() + ..() if(!src.buckled_guy) return var/mob/living/M = src.buckled_guy var/mob/living/carbon/human/H = src.buckled_guy + M.end_chair_flip_targeting() + if (istype(H) && H.on_chair)// == 1) M.pixel_y = 0 M.anchored = 0 M.buckled = null + buckled_guy.force_laydown_standup() src.buckled_guy = null SPAWN_DBG (5) H.on_chair = 0 @@ -663,6 +666,7 @@ else if ((M.buckled)) M.anchored = 0 M.buckled = null + buckled_guy.force_laydown_standup() src.buckled_guy = null SPAWN_DBG (5) src.buckledIn = 0 diff --git a/code/obj/storage/secure_closets.dm b/code/obj/storage/secure_closets.dm index 012fbb2..4f685c7 100644 --- a/code/obj/storage/secure_closets.dm +++ b/code/obj/storage/secure_closets.dm @@ -80,7 +80,8 @@ /obj/item/clothing/shoes/brown, /obj/item/clothing/suit/armor/vest, /obj/item/stamp/hop, - /obj/item/device/radio/headset/command/hop) + /obj/item/device/radio/headset/command/hop, + /obj/item/device/accessgun) /obj/storage/secure/closet/command/research_director name = "\improper Research Director's locker" @@ -149,7 +150,8 @@ /obj/item/device/multitool, /obj/item/device/flash, /obj/item/stamp/ce, - /obj/item/device/radio/headset/command/ce) + /obj/item/device/radio/headset/command/ce, + /obj/item/deconstructor) /* ==================== */ /* ----- Security ----- */ @@ -526,7 +528,8 @@ /obj/item/clothing/glasses/meson, /obj/item/pen/infrared, /obj/item/clothing/head/helmet/welding, - /obj/item/storage/belt/utility) + /obj/item/storage/belt/utility, + /obj/item/deconstructor) /obj/storage/secure/closet/engineering/mining name = "\improper Miner's locker" diff --git a/code/obj/storage/wall_cabinet.dm b/code/obj/storage/wall_cabinet.dm index e2aef88..3c3fcf7 100644 --- a/code/obj/storage/wall_cabinet.dm +++ b/code/obj/storage/wall_cabinet.dm @@ -11,6 +11,7 @@ anchored = 1.0 density = 0 mats = 8 + deconstruct_flags = DECON_SIMPLE max_wclass = 4 slots = 13 // these can't move so I guess we may as well let them store more stuff? mechanics_type_override = /obj/item/storage/wall diff --git a/code/obj/submachine/cooking.dm b/code/obj/submachine/cooking.dm index 0aae9d9..5285022 100644 --- a/code/obj/submachine/cooking.dm +++ b/code/obj/submachine/cooking.dm @@ -6,6 +6,7 @@ anchored = 1 density = 1 mats = 12 + deconstruct_flags = DECON_WRENCH | DECON_WELDER flags = NOSPLASH attackby(obj/item/W as obj, mob/user as mob) @@ -74,6 +75,7 @@ anchored = 1 density = 1 mats = 18 + deconstruct_flags = DECON_WRENCH | DECON_CROWBAR | DECON_WELDER flags = NOSPLASH var/list/flavors = list("chocolate","vanilla","coffee") var/obj/item/reagent_containers/glass/beaker = null @@ -224,6 +226,7 @@ var/list/oven_recipes = list() anchored = 1 density = 1 mats = 18 + deconstruct_flags = DECON_WRENCH | DECON_CROWBAR | DECON_WELDER flags = NOSPLASH var/emagged = 0 var/working = 0 @@ -755,6 +758,7 @@ table#cooktime a#start { anchored = 1 density = 1 mats = 18 + deconstruct_flags = DECON_WRENCH | DECON_CROWBAR | DECON_WELDER var/working = 0 var/allowed = list(/obj/item/reagent_containers/food/, /obj/item/plant/, /obj/item/organ/brain, /obj/item/clothing/head/butt) @@ -985,6 +989,7 @@ var/list/mixer_recipes = list() density = 1 anchored = 1 mats = 15 + deconstruct_flags = DECON_WRENCH | DECON_CROWBAR | DECON_WELDER var/list/recipes = null var/list/to_remove = list() var/allowed = list(/obj/item/reagent_containers/food/, /obj/item/parts/robot_parts/head, /obj/item/clothing/head/butt, /obj/item/organ/brain) diff --git a/code/obj/submachine/robotics.dm b/code/obj/submachine/robotics.dm index fece7f1..0580110 100644 --- a/code/obj/submachine/robotics.dm +++ b/code/obj/submachine/robotics.dm @@ -8,6 +8,7 @@ anchored = 1 density = 1 mats = 15 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_WIRECUTTERS | DECON_MULTITOOL var/working = 0 var/modules = 0 diff --git a/code/obj/submachine/seed.dm b/code/obj/submachine/seed.dm index 6253dd9..7b4f562 100644 --- a/code/obj/submachine/seed.dm +++ b/code/obj/submachine/seed.dm @@ -4,6 +4,7 @@ density = 1 anchored = 1 mats = 10 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_WIRECUTTERS | DECON_MULTITOOL icon = 'icons/obj/objects.dmi' icon_state = "geneman-on" flags = NOSPLASH @@ -721,6 +722,7 @@ density = 1 anchored = 1 mats = 6 + deconstruct_flags = DECON_SCREWDRIVER | DECON_CROWBAR | DECON_WELDER | DECON_WIRECUTTERS | DECON_MULTITOOL icon = 'icons/obj/objects.dmi' icon_state = "reex-off" flags = NOSPLASH @@ -1083,6 +1085,7 @@ density = 1 anchored = 1 mats = 6 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WIRECUTTERS | DECON_MULTITOOL var/vendamt = 1 var/hacked = 0 var/panelopen = 0 diff --git a/code/obj/submachine/slots.dm b/code/obj/submachine/slots.dm index 326da82..278395e 100644 --- a/code/obj/submachine/slots.dm +++ b/code/obj/submachine/slots.dm @@ -6,6 +6,7 @@ anchored = 1 density = 1 mats = 8 + deconstruct_flags = DECON_SIMPLE //var/money = 1000000 var/plays = 0 var/working = 0 @@ -164,6 +165,7 @@ anchored = 1 density = 1 mats = 8 + deconstruct_flags = DECON_SCREWDRIVER | DECON_WRENCH | DECON_CROWBAR | DECON_WELDER | DECON_MULTITOOL //var/money = 1000000 var/plays = 0 var/working = 0 diff --git a/code/obj/table.dm b/code/obj/table.dm index e551a89..0c387ce 100644 --- a/code/obj/table.dm +++ b/code/obj/table.dm @@ -668,7 +668,7 @@ if (src.reinforced) smashprob = round(smashprob / 2, 1) - if (src.place_on(W, user)) + if (src.place_on(W, user, params)) playsound(get_turf(src), "sound/impact_sounds/Crystal_Hit_1.ogg", 100, 1) else if (W && user.a_intent != "help") DEBUG_MESSAGE("[src] smashprob = ([smashprob] * 1.5) (result [(smashprob * 1.5)])") diff --git a/code/obj/window.dm b/code/obj/window.dm index 4b8c08a..5b040b1 100644 --- a/code/obj/window.dm +++ b/code/obj/window.dm @@ -8,7 +8,6 @@ dir = 5 //full tile flags = FPRINT | USEDELAY | ON_BORDER | ALWAYS_SOLID_FLUID event_handler_flags = USE_FLUID_ENTER | USE_CHECKEXIT | USE_CANPASS - object_flags = BOTS_DIRBLOCK var/health = 30 var/health_max = 30 var/health_multiplier = 1 diff --git a/code/procs/accents.dm b/code/procs/accents.dm index aed8fb0..bc490c8 100644 --- a/code/procs/accents.dm +++ b/code/procs/accents.dm @@ -1671,7 +1671,7 @@ var/list/zalgo_mid = list( else if (R.prev_char == " " && R.next_char != " ") new_string = "ho" used = 1 - else if(R.next_char == " " && R.prev_char == " ") + else if(R.next_char == " " && R.prev_char == " ") new_string = "crisse" used = 1 if("O") @@ -1681,7 +1681,7 @@ var/list/zalgo_mid = list( else if (R.prev_char == " " && R.next_char != " ") new_string = "HO" used = 1 - else if(R.next_char == " " && R.prev_char == " ") + else if(R.next_char == " " && R.prev_char == " ") new_string = "ZUT!" used = 1 @@ -1698,14 +1698,14 @@ var/list/zalgo_mid = list( if (R.next_char != " " && R.prev_char == " ") new_string = "he" used = 2 - else if(R.next_char == " " && R.prev_char == " ") + else if(R.next_char == " " && R.prev_char == " ") new_string = "oeuf" used = 1 if("E") if (R.next_char != " " && R.prev_char == " ") new_string = "HE" used = 2 - else if(R.next_char == " " && R.prev_char == " ") + else if(R.next_char == " " && R.prev_char == " ") new_string = "OEUF" used = 1 @@ -1756,3 +1756,59 @@ var/list/zalgo_mid = list( P.string = new_string P.chars_used = used return P + +/proc/mufflespeech(var/string) + var/modded = "" + var/datum/text_roamer/T = new/datum/text_roamer(string) + + for(var/i = 0, i < length(string), i=i) + var/datum/parse_result/P = mufflespeech_parse(T) + modded += P.string + i += P.chars_used + T.curr_char_pos = T.curr_char_pos + P.chars_used + T.update() + + return modded + + +/proc/mufflespeech_parse(var/datum/text_roamer/R) + var/new_string = "" + var/used = 0 + + switch(R.curr_char) + if("q", "t", "k") + new_string = "p" + used = 1 + if("w","s","z","c") + new_string = "h" + used = 1 + + if("e", "y", "i") + new_string = "f" + used = 1 + if("u", "o","a","d","g","j","l","x","v","b") + new_string = "m" + used = 1 + + if("Q", "T", "K") + new_string = "P" + used = 1 + if("W","S","Z","C") + new_string = "H" + used = 1 + + if("E", "Y", "I") + new_string = "F" + used = 1 + if("U", "O","A","D","G","J","L","X","V","B") + new_string = "M" + used = 1 + + if(new_string == "") + new_string = R.curr_char + used = 1 + + var/datum/parse_result/P = new/datum/parse_result + P.string = new_string + P.chars_used = used + return P \ No newline at end of file diff --git a/code/procs/access.dm b/code/procs/access.dm index c6fd846..2e93c6a 100644 --- a/code/procs/access.dm +++ b/code/procs/access.dm @@ -612,4 +612,7 @@ proc/fetchAirlock(access,variant) else return "/obj/machinery/door/airlock" +/obj/proc/set_access_list(var/list/L) + src.req_access = L.Copy() + src.req_access_txt = null diff --git a/code/procs/gamehelpers.dm b/code/procs/gamehelpers.dm index cf6da5b..32d52ed 100644 --- a/code/procs/gamehelpers.dm +++ b/code/procs/gamehelpers.dm @@ -281,6 +281,12 @@ var/obj/item/dummy/click_dummy = new if (istype(S,/datum/bioEffect/speech/)) message = S.OnSpeak(message) + if (H.grabbed_by && H.grabbed_by.len) + for (var/obj/item/grab/rag_muffle/RM in H.grabbed_by) + if (RM.state > 0) + message = mufflespeech(message) + break + if (iscluwne(H)) message = honk(message) if (world.time >= (H.last_cluwne_noise + CLUWNE_NOISE_DELAY)) @@ -361,12 +367,13 @@ var/obj/item/dummy/click_dummy = new /mob/proc/get_equipped_items() . = list() - if(src.back) . += src.back if(src.ears) . += src.ears if(src.wear_mask) . += src.wear_mask - if(src.l_hand) . += src.l_hand - if(src.r_hand) . += src.r_hand + + if(src.l_hand && src.l_hand.c_flags & EQUIPPED_WHILE_HELD) . += src.l_hand + if(src.r_hand && src.r_hand.c_flags & EQUIPPED_WHILE_HELD) . += src.r_hand + /proc/get_step_towards2(var/atom/ref , var/atom/trg) var/base_dir = get_dir(ref, get_step_towards(ref,trg)) diff --git a/code/procs/helpers.dm b/code/procs/helpers.dm index c1ea70f..d3fd542 100644 --- a/code/procs/helpers.dm +++ b/code/procs/helpers.dm @@ -2480,3 +2480,10 @@ proc/check_whitelist(var/atom/TA, var/list/whitelist, var/mob/user as mob) return (seer.dir == dir) + + +/proc/lerp(var/a, var/b, var/t) + return a * (1 - t) + b * t + +proc/get_manhattan_dist(atom/A,atom/B) + .= abs(A.x - B.x) + abs(A.y - B.y) \ No newline at end of file diff --git a/code/procs/mob_procs.dm b/code/procs/mob_procs.dm index 4531eca..bda3095 100644 --- a/code/procs/mob_procs.dm +++ b/code/procs/mob_procs.dm @@ -165,14 +165,10 @@ /mob/living/carbon/human/eyes_protected_from_light() if (!src.sight_check(1)) // Blindness etc (Convair880). return 1 - if (src.glasses && (istype(src.glasses, /obj/item/clothing/glasses/sunglasses) && !istype(src.glasses, /obj/item/clothing/glasses/sunglasses/tanning))) + if (src.get_disorient_protection_eye() >= 100) return 1 if (src.eye_istype(/obj/item/organ/eye/cyber/thermal)) return 0 - if (src.eye_istype(/obj/item/organ/eye/cyber/sunglass)) - return 1 - if (src.head && istype(src.head, /obj/item/clothing/head/helmet/welding) && !src.head:up) - return 1 return 0 /mob/proc/apply_flash() @@ -243,7 +239,7 @@ if (safety == 0) src.flash(animation_duration) #ifdef USE_STAMINA_DISORIENT - src.do_disorient(stamina_damage, weakened = weak*20, stunned = stun*20, disorient = disorient_time, remove_stamina_below_zero = 0) + src.do_disorient(stamina_damage, weakened = weak*20, stunned = stun*20, disorient = disorient_time, remove_stamina_below_zero = 0, target_type = DISORIENT_EYE) #else changeStatus("weakened", weak*20) changeStatus("stunned", stun*20) @@ -291,6 +287,7 @@ .= 0 else .= 1 + //dont do disorient_ear check here cause its slower. just use the flags HEARING_BLOCKED pls if (src.ears) if (src.ears.block_hearing_when_worn >= HEARING_BLOCKED) return 0 @@ -366,7 +363,7 @@ #ifdef USE_STAMINA_DISORIENT - src.do_disorient(stamina_damage, weakened = weak*20, stunned = stun*20, disorient = 60, remove_stamina_below_zero = 0) + src.do_disorient(stamina_damage, weakened = weak*20, stunned = stun*20, disorient = 60, remove_stamina_below_zero = 0, target_type = DISORIENT_EAR) #else changeStatus("weakened", stun*10) diff --git a/code/procs/mobprocs/attacks.dm b/code/procs/mobprocs/attacks.dm index 72f73ff..900f8ed 100644 --- a/code/procs/mobprocs/attacks.dm +++ b/code/procs/mobprocs/attacks.dm @@ -13,8 +13,9 @@ user.lastattacked = src - if (ismob(user) && user.at_gunpoint && user.at_gunpoint.holding_at_gunpoint != user) // Haine fix for Cannot read 0.at_gunpoint - user.at_gunpoint.shoot_at_gunpoint(user) + if (user.mob_flags & AT_GUNPOINT) + for(var/obj/item/grab/gunpoint/G in user.grabbed_by) + G.shoot() var/shielded = 0 if (src.spellshield) diff --git a/code/turf/floors_unsimulated.dm b/code/turf/floors_unsimulated.dm index d9017ca..ec3dc14 100644 --- a/code/turf/floors_unsimulated.dm +++ b/code/turf/floors_unsimulated.dm @@ -11,6 +11,25 @@ thermal_conductivity = 0.040 heat_capacity = 225000 + +/turf/unsimulated/floor/attackby(obj/item/C as obj, mob/user as mob, params) + + if (!C || !user) + return 0 + + if (istype(C, /obj/item/pen)) + var/obj/item/pen/P = C + P.write_on_turf(src, user, params) + return + + else if (istype(C, /obj/item/grab/)) + var/obj/item/grab/G = C + if (!grab_smash(G, user)) + return ..(C, user) + else + return + ..() + ///////////////////////////////////////// /turf/unsimulated/floor/scorched diff --git a/code/z_adventurezones/biodome.dm b/code/z_adventurezones/biodome.dm index 858e748..49e8241 100644 --- a/code/z_adventurezones/biodome.dm +++ b/code/z_adventurezones/biodome.dm @@ -618,6 +618,7 @@ SYNDICATE DRONE FACTORY AREAS ..() setProperty("coldprot", 80) setProperty("heatprot", 80) + setProperty("movespeed", 2) // scare the everliving fuck out of the player when they equip it // what else should this thing do? idk yet. maybe some crazy hallucinations with an ancient blood reagent or something? something like the obsidian crown? diff --git a/goonstation.dme b/goonstation.dme index 62ee8b6..820861f 100644 --- a/goonstation.dme +++ b/goonstation.dme @@ -57,6 +57,7 @@ var/datum/preMapLoad/preMapLoad = new #include "code\player.dm" #include "code\pooling.dm" #include "code\RobustLight2.dm" +#include "code\SimpleLight.dm" #include "code\world.dm" #include "code\style.dms" #include "code\atom\throwing.dm" @@ -137,6 +138,7 @@ var/datum/preMapLoad/preMapLoad = new #include "code\datums\abilities\critter.dm" #include "code\datums\abilities\cruiser.dm" #include "code\datums\abilities\diabolical.dm" +#include "code\datums\abilities\generic.dm" #include "code\datums\abilities\ghost_observer.dm" #include "code\datums\abilities\hunter.dm" #include "code\datums\abilities\kudzumen.dm" @@ -268,6 +270,7 @@ var/datum/preMapLoad/preMapLoad = new #include "code\datums\controllers\process\lighting.dm" #include "code\datums\controllers\process\machines.dm" #include "code\datums\controllers\process\mob_ai.dm" +#include "code\datums\controllers\process\mob_ui.dm" #include "code\datums\controllers\process\mobs.dm" #include "code\datums\controllers\process\particles.dm" #include "code\datums\controllers\process\process.dm" @@ -1131,6 +1134,7 @@ var/datum/preMapLoad/preMapLoad = new #include "code\obj\item\clothing\uniforms.dm" #include "code\obj\item\clothing\uniforms_autocolor.dm" #include "code\obj\item\clothing\under\gimmick\hakama.dm" +#include "code\obj\item\device\accessgun.dm" #include "code\obj\item\device\audio_log.dm" #include "code\obj\item\device\brainjar.dm" #include "code\obj\item\device\camera_viewer.dm" diff --git a/icons/effects/overlays/simplelight.dmi b/icons/effects/overlays/simplelight.dmi new file mode 100644 index 0000000..678375d Binary files /dev/null and b/icons/effects/overlays/simplelight.dmi differ diff --git a/icons/mob/hud_human.dmi b/icons/mob/hud_human.dmi index fc9e273..dec0487 100644 Binary files a/icons/mob/hud_human.dmi and b/icons/mob/hud_human.dmi differ diff --git a/icons/mob/hud_human_classic.dmi b/icons/mob/hud_human_classic.dmi index ae6024e..4d54e05 100644 Binary files a/icons/mob/hud_human_classic.dmi and b/icons/mob/hud_human_classic.dmi differ diff --git a/icons/mob/hud_human_new.dmi b/icons/mob/hud_human_new.dmi index dd50a0c..09b401d 100644 Binary files a/icons/mob/hud_human_new.dmi and b/icons/mob/hud_human_new.dmi differ diff --git a/icons/mob/hud_human_quilty.dmi b/icons/mob/hud_human_quilty.dmi index 14fc078..e21b928 100644 Binary files a/icons/mob/hud_human_quilty.dmi and b/icons/mob/hud_human_quilty.dmi differ diff --git a/icons/obj/device.dmi b/icons/obj/device.dmi index 543e151..55d69d9 100644 Binary files a/icons/obj/device.dmi and b/icons/obj/device.dmi differ diff --git a/icons/ui/actions.dmi b/icons/ui/actions.dmi index e25e008..b204baf 100644 Binary files a/icons/ui/actions.dmi and b/icons/ui/actions.dmi differ diff --git a/interface/skin.dmf b/interface/skin.dmf index ee25ee0..9562661 100644 --- a/interface/skin.dmf +++ b/interface/skin.dmf @@ -266,30 +266,28 @@ menu "menu" command = "" category = "&Display" saved-params = "is-checked" + elem "fps_creamy" + name = "&Creamy (67fps, high end PCs)" + command = "set-fps" + category = "&Framerate" + can-check = true + group = "fps" + saved-params = "is-checked" elem "fps_smooth" - name = "&Smooth" + name = "&Smooth (40fps, default)" command = "set-fps" category = "&Framerate" can-check = true group = "fps" saved-params = "is-checked" + is-checked = true elem "fps_chunky" - name = "&Chunky" + name = "&Chunky (25fps, low end PCs)" command = "set-fps" category = "&Framerate" can-check = true group = "fps" saved-params = "is-checked" - elem - name = "" - command = "" - category = "&Framerate" - saved-params = "is-checked" - elem - name = "&There's only two settings, yep. Try Chunky if your PC is slow. I'm sorry. Blame BYOND." - command = "" - category = "&Framerate" - saved-params = "is-checked" elem name = "&Effects" command = "" diff --git a/sound/effects/chair_step.ogg b/sound/effects/chair_step.ogg new file mode 100644 index 0000000..33d24e4 Binary files /dev/null and b/sound/effects/chair_step.ogg differ diff --git a/sound/effects/flip.ogg b/sound/effects/flip.ogg new file mode 100644 index 0000000..32e8292 Binary files /dev/null and b/sound/effects/flip.ogg differ diff --git a/sound/machines/reprog.ogg b/sound/machines/reprog.ogg new file mode 100644 index 0000000..c893cd3 Binary files /dev/null and b/sound/machines/reprog.ogg differ diff --git a/sound/misc/step/step_flipflop_1.ogg b/sound/misc/step/step_flipflop_1.ogg new file mode 100644 index 0000000..1794726 Binary files /dev/null and b/sound/misc/step/step_flipflop_1.ogg differ diff --git a/sound/misc/step/step_flipflop_2.ogg b/sound/misc/step/step_flipflop_2.ogg new file mode 100644 index 0000000..166a209 Binary files /dev/null and b/sound/misc/step/step_flipflop_2.ogg differ diff --git a/sound/misc/step/step_flipflop_3.ogg b/sound/misc/step/step_flipflop_3.ogg new file mode 100644 index 0000000..6728cc8 Binary files /dev/null and b/sound/misc/step/step_flipflop_3.ogg differ diff --git a/sound/misc/step/step_robo_1.ogg b/sound/misc/step/step_robo_1.ogg new file mode 100644 index 0000000..fcd2301 Binary files /dev/null and b/sound/misc/step/step_robo_1.ogg differ diff --git a/sound/misc/step/step_robo_2.ogg b/sound/misc/step/step_robo_2.ogg new file mode 100644 index 0000000..1f0d07e Binary files /dev/null and b/sound/misc/step/step_robo_2.ogg differ diff --git a/sound/misc/step/step_robo_3.ogg b/sound/misc/step/step_robo_3.ogg new file mode 100644 index 0000000..fb0e85e Binary files /dev/null and b/sound/misc/step/step_robo_3.ogg differ diff --git a/sound/misc/step/step_rubberboot_1.ogg b/sound/misc/step/step_rubberboot_1.ogg new file mode 100644 index 0000000..319c10e Binary files /dev/null and b/sound/misc/step/step_rubberboot_1.ogg differ diff --git a/sound/misc/step/step_rubberboot_2.ogg b/sound/misc/step/step_rubberboot_2.ogg new file mode 100644 index 0000000..7ec02dd Binary files /dev/null and b/sound/misc/step/step_rubberboot_2.ogg differ diff --git a/sound/misc/step/step_rubberboot_3.ogg b/sound/misc/step/step_rubberboot_3.ogg new file mode 100644 index 0000000..2619959 Binary files /dev/null and b/sound/misc/step/step_rubberboot_3.ogg differ diff --git a/sound/misc/step/step_rubberboot_4.ogg b/sound/misc/step/step_rubberboot_4.ogg new file mode 100644 index 0000000..421109c Binary files /dev/null and b/sound/misc/step/step_rubberboot_4.ogg differ diff --git a/sound/voice/screams/Psychic_Scream_1.ogg b/sound/voice/screams/Psychic_Scream_1.ogg index 44c72ca..52396e2 100644 Binary files a/sound/voice/screams/Psychic_Scream_1.ogg and b/sound/voice/screams/Psychic_Scream_1.ogg differ diff --git a/sound/voice/screams/Robot_Scream_2.ogg b/sound/voice/screams/Robot_Scream_2.ogg index 03a071b..a2dad36 100644 Binary files a/sound/voice/screams/Robot_Scream_2.ogg and b/sound/voice/screams/Robot_Scream_2.ogg differ diff --git a/sound/voice/screams/female_scream.ogg b/sound/voice/screams/female_scream.ogg index 8e8b5b0..b35363b 100644 Binary files a/sound/voice/screams/female_scream.ogg and b/sound/voice/screams/female_scream.ogg differ diff --git a/sound/voice/screams/fescream1.ogg b/sound/voice/screams/fescream1.ogg index 49b3517..659a64f 100644 Binary files a/sound/voice/screams/fescream1.ogg and b/sound/voice/screams/fescream1.ogg differ diff --git a/sound/voice/screams/fescream2.ogg b/sound/voice/screams/fescream2.ogg index 8abfe42..e58b9c0 100644 Binary files a/sound/voice/screams/fescream2.ogg and b/sound/voice/screams/fescream2.ogg differ diff --git a/sound/voice/screams/fescream3.ogg b/sound/voice/screams/fescream3.ogg index 8ddf04e..add9ef4 100644 Binary files a/sound/voice/screams/fescream3.ogg and b/sound/voice/screams/fescream3.ogg differ diff --git a/sound/voice/screams/fescream4.ogg b/sound/voice/screams/fescream4.ogg index baf1b37..821fb5e 100644 Binary files a/sound/voice/screams/fescream4.ogg and b/sound/voice/screams/fescream4.ogg differ diff --git a/sound/voice/screams/fescream5.ogg b/sound/voice/screams/fescream5.ogg index b6b2c16..1e8c445 100644 Binary files a/sound/voice/screams/fescream5.ogg and b/sound/voice/screams/fescream5.ogg differ diff --git a/sound/voice/screams/frogscream1.ogg b/sound/voice/screams/frogscream1.ogg index da2547f..30a072f 100644 Binary files a/sound/voice/screams/frogscream1.ogg and b/sound/voice/screams/frogscream1.ogg differ diff --git a/sound/voice/screams/frogscream3.ogg b/sound/voice/screams/frogscream3.ogg index a81aafa..29aa902 100644 Binary files a/sound/voice/screams/frogscream3.ogg and b/sound/voice/screams/frogscream3.ogg differ diff --git a/sound/voice/screams/frogscream4.ogg b/sound/voice/screams/frogscream4.ogg index 464de90..442b389 100644 Binary files a/sound/voice/screams/frogscream4.ogg and b/sound/voice/screams/frogscream4.ogg differ diff --git a/sound/voice/screams/male_scream.ogg b/sound/voice/screams/male_scream.ogg index ab510b1..11ba574 100644 Binary files a/sound/voice/screams/male_scream.ogg and b/sound/voice/screams/male_scream.ogg differ diff --git a/sound/voice/screams/martian_growl.ogg b/sound/voice/screams/martian_growl.ogg index d33a353..c2cfc75 100644 Binary files a/sound/voice/screams/martian_growl.ogg and b/sound/voice/screams/martian_growl.ogg differ diff --git a/sound/voice/screams/martian_screech.ogg b/sound/voice/screams/martian_screech.ogg index 084b46f..81c5eaf 100644 Binary files a/sound/voice/screams/martian_screech.ogg and b/sound/voice/screams/martian_screech.ogg differ diff --git a/sound/voice/screams/mascream1.ogg b/sound/voice/screams/mascream1.ogg index 6a8f261..fc735b0 100644 Binary files a/sound/voice/screams/mascream1.ogg and b/sound/voice/screams/mascream1.ogg differ diff --git a/sound/voice/screams/mascream2.ogg b/sound/voice/screams/mascream2.ogg index 7bab359..5ecf12c 100644 Binary files a/sound/voice/screams/mascream2.ogg and b/sound/voice/screams/mascream2.ogg differ diff --git a/sound/voice/screams/mascream3.ogg b/sound/voice/screams/mascream3.ogg index a528398..c4811d0 100644 Binary files a/sound/voice/screams/mascream3.ogg and b/sound/voice/screams/mascream3.ogg differ diff --git a/sound/voice/screams/mascream4.ogg b/sound/voice/screams/mascream4.ogg index d7f12f7..6163d47 100644 Binary files a/sound/voice/screams/mascream4.ogg and b/sound/voice/screams/mascream4.ogg differ diff --git a/sound/voice/screams/mascream5.ogg b/sound/voice/screams/mascream5.ogg index 66862ca..d0e30f4 100644 Binary files a/sound/voice/screams/mascream5.ogg and b/sound/voice/screams/mascream5.ogg differ diff --git a/sound/voice/screams/mascream6.ogg b/sound/voice/screams/mascream6.ogg index 39665b0..91cb949 100644 Binary files a/sound/voice/screams/mascream6.ogg and b/sound/voice/screams/mascream6.ogg differ diff --git a/sound/voice/screams/mascream7.ogg b/sound/voice/screams/mascream7.ogg index 4ae8aec..4dafc71 100644 Binary files a/sound/voice/screams/mascream7.ogg and b/sound/voice/screams/mascream7.ogg differ diff --git a/sound/voice/screams/monkey_scream.ogg b/sound/voice/screams/monkey_scream.ogg index af38be0..cd20c72 100644 Binary files a/sound/voice/screams/monkey_scream.ogg and b/sound/voice/screams/monkey_scream.ogg differ diff --git a/sound/voice/screams/robot_scream.ogg b/sound/voice/screams/robot_scream.ogg index 5db056a..51f284d 100644 Binary files a/sound/voice/screams/robot_scream.ogg and b/sound/voice/screams/robot_scream.ogg differ diff --git a/sound/voice/screams/sillyscream1.ogg b/sound/voice/screams/sillyscream1.ogg index b67b561..6561074 100644 Binary files a/sound/voice/screams/sillyscream1.ogg and b/sound/voice/screams/sillyscream1.ogg differ diff --git a/sound/voice/screams/sillyscream2.ogg b/sound/voice/screams/sillyscream2.ogg index a389532..4190386 100644 Binary files a/sound/voice/screams/sillyscream2.ogg and b/sound/voice/screams/sillyscream2.ogg differ diff --git a/strings/changelog.txt b/strings/changelog.txt index 4d9ee85..d432750 100644 --- a/strings/changelog.txt +++ b/strings/changelog.txt @@ -1,4 +1,90 @@  +(t)sun feb 09 20 +(u)mbc +(*)Added a new way to handle tiny light sources that move around a lot (using a static image attached to an object instead of updating nearby tiles each step). They'll look a bit different, but also take some load off of our lighting system. Affects PDA lights, station bots, and human burning status right now. +(t)sat feb 08 20 +(u)mbc +(*)Balanced scream sounds to be a bit quieter and more equivalent to each other. Also quieted burps and farts a little. +(*)Add new step sounds for galoshes, sandals, and robots. +(t)wed feb 05 20 +(u)mbc +(*)New device - the access-pro. Use it to change access requirements of many different kinds of machines. It will copy the access requirements from any ID that you insert into the access-pro. The user must be wearing an ID with id-change priveliges to do this. Find it in the HoP locker. +(*)Added an AND/OR toggle to the access-pro if you use it in-hand when its empty. This lets you specify if you want a door to require a list of accesses for entry, or allow anyone who meets any one value in the list. +(*)If a door has 0 access requirements, it can be deconstructed with the deconstruction device now. +(*)There will probably be some items I forgot to flag as access-changable or some bugs. Please report as usual +(t)tue feb 04 20 +(u)mbc +(*)Welding helmet now provides a bit less head armor when it's flipped down. Full protection is only given when flipped up. +(*)Weakened the intensity of scanlines and other vision-impairing wearables +(t)sun feb 02 20 +(u)mbc +(*)Deconstruction Device will appear in engineer lockers as well as mechanic lockers. +(*)The Deconstruction Device can now be used to deconstruct more kinds of objects, and not just things mechanics have created (either click in-hand or use mousedrag). When you deconstruct an object, it turns into a mechanics frame that can later be soldered up at a different location. Most things will require some tool use to deconstruct as well, depending on complexity of the object. +(*)There will probably be some bugs or objects I've forgotten to whitelist as 'deconstructable'. Please report if you encounter those! +(t)sat feb 01 20 +(u)mbc +(*)Stamina bar updates more frequently. +(*)The time it takes to pin someone with an aggressive grab will be reduced proportionally depending on their remaining stamina (as opposed to the previous implementation where they had to be at 0 for a fast pin) +(*)Replaced the existing (byond built-in) sound falloff rate with our own custom one. Also reduced the max ranges of sounds a bit. +(t)wed jan 29 20 +(u)mbc +(*)Fixed bot pathfinding to not get stuck on unopenable doors. +(t)tue jan 28 20 +(u)mbc +(*)Moved hold-at-gunpoint functions to the new item grabs framework. Hold any gun and click someone on Grab intent to hold them hostage. This behaves similar to the old gunpoint mode, but now it's more flexible and you can get a tight hold + pull the target around. +(*)Fixed bullets that throw the impacted player, like shotgun rounds - they were throwing in basically random directions instead of the direction the bullet was moving and weren't throwing at all on pointblank shots. Also, players who are thrown through the air by bullets will no longer be able to counteract the throw by running (this behavior is unchanged for normal throws) +(t)mon jan 27 20 +(u)mbc +(*)Fixed reinforced cables not being immune to explosions. +(*)Fluid movement gear (flippers etc) will prevent sea plants from slowing you down. It also won't slow you on mined rock tiles anymore. +(*)Increased time it takes to remove a jumpsuit from someone else. +(t)sun jan 26 20 +(u)mbc +(*)Revolution leaders can now buy daggers and standard flashes through their uplink. +(*)Pins can be executed a little faster on targets who have 0 stamina. +(*)You can chair flip off of boxing rope corners now (same input - mousedrag) +(*)Knives can be used to strangle and inflict minor bleed damage. +(*)Cable coil can be used to strangle and inflict a bit extra oxygen deprivation. +(*)Added overlay for inhand item grabs. +(*)You can now pin someone by grabbing them and clicking the floor. The action will happen faster if you have a tight grip before starting. Neither party will be able to move during the pin (but the target can resist), and the pin will break when the attacker's stamina runs out. +(*)Fixed bot and mulebot pathfinding, for real this time. Probably. +(t)sat jan 25 20 +(u)mbc +(*)Split the disorient resist armor property into 3 types - Body, Eye, and Ear. Body protects from mostly anything, Eye for flashes, and Ear for sonic stuns. Also added some different amounts of Eye/Ear protection to existing headwear where it would fit. +(*)You can now dose a material cloth with a small amount of reagents to force targets you strangle to inhale from it. +(*)You can now strangle someone with a breath mask. If you're holding an internals tank in your off-hand, they will be forced to inhale from the tank. +(t)thu jan 23 20 +(u)mbc +(*)Revolutionary flashbangs will shatter loyalty implants in affected targets. +(t)tue jan 21 20 +(u)mbc +(*)Adjusted triplemeth stun reduction from 100% to 98%. +(u)mbc +(*)Use Grab intent with a cloth (material piece) to hold someone aggressively with an additional effect of muffled speech. Not a 'quiet' effect, it's normal volume and more unintelligible. +(*)Adjusted hot/cold food buffs to only apply their effect appropriately when you are too hot / too cold. +(*)You can now suplex two people at once. +(*)Slightly changed suplex stun times. +(t)mon jan 20 +(u)mbc +(*)You can now dive off the pool springboard with a technique identical to the chair flip. Also, people can now be thrown into/out of the pool instead of always needing to enter through the ladder. +(t)sun jan 19 +(u)mbc +(*)Reworked the way stun reductions work. (They used to reduce all stuns by some amount per life tick. Now, stuns are reduced on the instant of application by some percentage value). This affects lots of drugs, but also fixes some stuff like the changeling abomination form. +(*)Disorient reductions have been introduced as properties of armor. Currently the only things that grant a disorient reduction are the security barrier, heavy riot suit, and EOD armor. Probably make some craftable civilian version at some point. +(*)You can view these protection values by using the STAT tooltip on the ingame HUD. +(*)Fixed a longstanding bug where you could get the benefits of armor simply by holding it in your hand (no more spacewalking by holding a space suit, sorry) +(t)sun jan 12 20 +(u)mbc +(*)In the 'Display' menu on the top left you now have the option to toggle framerate up to 60. This won't look good for everyone and may look worse, depending on your PC. +(*)Chair flip is now a targeted ability where you can click on a tile to throw yourself in that direction. Flipping will launch you in whatever direction your character is facing. +(*)Chair flip range extended to 3 tiles instead of 2. You will deal more damage to targets who are farther away. Missing your target (slamming into walls etc) can hurt a little. +(*)Added little pull/unpull icon effects. +(t)sun jan 05 20 +(u)mbc +(*)Pods can now aim and shoot diagonally. +(*)Pods can brake (hold your SPRINT button) +(*)Pods bump into things and take/deal damage just like subs do. +(*)When impacted by a taser, there is a chance that the pod's wormhole recharge will be put on cooldown. (t)wed jan 01 20 (u)Firebarrage (*) You can now transfer spacebux between online players and check your balance mid round. Check an ATM for details