diff --git a/code/__DEFINES/dcs/signals/atom/mob/living/signals_xeno.dm b/code/__DEFINES/dcs/signals/atom/mob/living/signals_xeno.dm index ab233e9cf82c..e76768a82b46 100644 --- a/code/__DEFINES/dcs/signals/atom/mob/living/signals_xeno.dm +++ b/code/__DEFINES/dcs/signals/atom/mob/living/signals_xeno.dm @@ -50,6 +50,10 @@ /// From /datum/action/xeno_action/proc/use_ability_wrapper(): (mob/owner) #define COMSIG_XENO_ACTION_USED "xeno_action_used" +/// From /datum/action/xeno_action/proc/use_ability_wrapper(): (mob/owner) +#define COMSIG_XENO_PRE_ACTION_USED "xeno_pre_action_used" +/// From /datum/action/xeno_action/proc/use_ability_wrapper(): (mob/owner) +#define COMSIG_XENO_FAILED_ACTION_USED "xeno_failed_action_used" /// From /mob/living/carbon/xenomorph/proc/check_blood_splash() #define COMSIG_XENO_DEAL_ACID_DAMAGE "xeno_deal_acid_damage" /// From /mob/living/carbon/xenomorph/proc/recalculate_speed() diff --git a/code/__DEFINES/dcs/signals/atom/signals_item.dm b/code/__DEFINES/dcs/signals/atom/signals_item.dm index 5ba79960657b..88f99bbff578 100644 --- a/code/__DEFINES/dcs/signals/atom/signals_item.dm +++ b/code/__DEFINES/dcs/signals/atom/signals_item.dm @@ -83,3 +83,5 @@ #define COMSIG_CAMERA_SET_AREA "camera_manager_set_area" #define COMSIG_CAMERA_CLEAR "camera_manager_clear_target" #define COMSIG_CAMERA_REFRESH "camera_manager_refresh" + +#define COMSIG_PRED_BRACER_DECLOAKED "pred_bracer_decloaked" diff --git a/code/__DEFINES/dcs/signals/atom/signals_movable.dm b/code/__DEFINES/dcs/signals/atom/signals_movable.dm index ba889d0b5212..ad4be2b1dc9f 100644 --- a/code/__DEFINES/dcs/signals/atom/signals_movable.dm +++ b/code/__DEFINES/dcs/signals/atom/signals_movable.dm @@ -11,6 +11,9 @@ #define COMPONENT_CANCEL_MOVE (1<<0) /// From /turf/open/gm/river/Entered(): (turf/open/gm/river/river, covered) #define COMSIG_MOVABLE_ENTERED_RIVER "movable_entered_river" +/// From /atom/movable/proc/doMove: I think it only works with forceMove so watch out +#define COMSIG_MOVABLE_FORCEMOVE_PRE_CROSSED "movable_forcemove_pre_crossed" + #define COMPONENT_IGNORE_CROSS (1<<0) ///from /mob/living/carbon/xenomorph/start_pulling(): (mob/living/carbon/xenomorph/X) #define COMSIG_MOVABLE_XENO_START_PULLING "movable_xeno_start_pulling" diff --git a/code/__DEFINES/dcs/signals/signals_datum.dm b/code/__DEFINES/dcs/signals/signals_datum.dm index b798d510763e..c35038fcf3e9 100644 --- a/code/__DEFINES/dcs/signals/signals_datum.dm +++ b/code/__DEFINES/dcs/signals/signals_datum.dm @@ -34,6 +34,8 @@ #define COMSIG_ACTION_HIDDEN "action_hidden" /// From base of /datum/action/proc/unhide_from(): (mob/owner) #define COMSIG_ACTION_UNHIDDEN "action_unhidden" +/// From base of /datum/action/proc/action_activate() : () +#define COMSIG_ACTION_ACTIVATED "action_activated" ///from /datum/component/bonus_damage_stack #define COMSIG_BONUS_DAMAGE "bonus_damage" diff --git a/code/__DEFINES/traits.dm b/code/__DEFINES/traits.dm index 964e77402655..e6b9c4c4b9ee 100644 --- a/code/__DEFINES/traits.dm +++ b/code/__DEFINES/traits.dm @@ -161,6 +161,8 @@ #define TRAIT_MERGED_WITH_WEEDS "merged_with_weeds" /// Apply this to identify a mob as temporarily muted #define TRAIT_TEMPORARILY_MUTED "temporarily_muted" +/// Mob wont get hit by stray projectiles +#define TRAIT_NO_STRAY "trait_no_stray" // SPECIES TRAITS /// Knowledge of Yautja technology diff --git a/code/__HELPERS/game.dm b/code/__HELPERS/game.dm index 5bf36f785746..094f8205c80e 100644 --- a/code/__HELPERS/game.dm +++ b/code/__HELPERS/game.dm @@ -235,7 +235,7 @@ * * hive - The hive we're filling a slot for to check if the player is banished * * sorted - Whether to sort by larva_queue_time (default TRUE) or leave unsorted */ -/proc/get_alien_candidates(datum/hive_status/hive = null, sorted = TRUE) +/proc/get_alien_candidates(datum/hive_status/hive = null, sorted = TRUE, abomination = FALSE) var/list/candidates = list() for(var/mob/dead/observer/cur_obs as anything in GLOB.observer_list) @@ -275,6 +275,11 @@ if(banished) continue + if(abomination) + if(!(/datum/tutorial/xenomorph/abomination::tutorial_id in cur_obs.client.prefs.completed_tutorials)) + to_chat(cur_obs, SPAN_BOLDNOTICE("You were passed over for playing as an Abomination because you have not completed its tutorial.")) + continue + candidates += cur_obs // Optionally sort by larva_queue_time diff --git a/code/_macros.dm b/code/_macros.dm index abfa83df7d36..9b92dc8730c3 100644 --- a/code/_macros.dm +++ b/code/_macros.dm @@ -95,6 +95,9 @@ #define GENERATE_DEBUG_ID "[rand(0, 9)][rand(0, 9)][rand(0, 9)][rand(0, 9)][pick(alphabet_lowercase)][pick(alphabet_lowercase)][pick(alphabet_lowercase)][pick(alphabet_lowercase)]" #define RECT new /datum/shape/rectangle +#define SQUARE new /datum/shape/rectangle/square +#define ELLIPSE new /datum/shape/ellipse +#define CIRCLE new /datum/shape/ellipse/circle #define QTREE new /datum/quadtree #define SEARCH_QTREE(qtree, shape_range, flags) qtree.query_range(shape_range, null, flags) diff --git a/code/_onclick/xeno.dm b/code/_onclick/xeno.dm index 3bb69fe05419..15dc1c39f495 100644 --- a/code/_onclick/xeno.dm +++ b/code/_onclick/xeno.dm @@ -3,7 +3,7 @@ */ /mob/living/carbon/xenomorph/UnarmedAttack(atom/target, proximity, click_parameters, tile_attack = FALSE, ignores_resin = FALSE) - if(body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_ABILITY_BURROWED)) //No attacks while laying down + if(body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_ABILITY_BURROWED) || cannot_slash) //No attacks while laying down return FALSE var/mob/alt diff --git a/code/controllers/subsystem/sound.dm b/code/controllers/subsystem/sound.dm index 024df7cc45ad..3cc3f0ef8090 100644 --- a/code/controllers/subsystem/sound.dm +++ b/code/controllers/subsystem/sound.dm @@ -19,8 +19,7 @@ SUBSYSTEM_DEF(sound) if(!run_hearers) // Initialize for handling next template run_hearers = run_queue[run_template] // get base hearers if(run_template.range) // ranging - var/datum/shape/rectangle/zone = RECT(run_template.x, run_template.y, run_template.range * 2, run_template.range * 2) - run_hearers |= SSquadtree.players_in_range(zone, run_template.z) + run_hearers |= SSquadtree.players_in_range(SQUARE(run_template.x, run_template.y, run_template.range * 2), run_template.z) if(MC_TICK_CHECK) return while(length(run_hearers)) // Output sound to hearers diff --git a/code/controllers/subsystem/vote.dm b/code/controllers/subsystem/vote.dm index 85e2a57cc6d6..25f522753543 100644 --- a/code/controllers/subsystem/vote.dm +++ b/code/controllers/subsystem/vote.dm @@ -414,6 +414,7 @@ SUBSYSTEM_DEF(vote) qdel(src) /datum/action/innate/vote/action_activate() + . = ..() owner.vote() /datum/action/innate/vote/proc/remove_from_client() diff --git a/code/datums/action.dm b/code/datums/action.dm index d1768655a2da..8dbf6c9df5a5 100644 --- a/code/datums/action.dm +++ b/code/datums/action.dm @@ -43,7 +43,9 @@ return /datum/action/proc/action_activate() - return + SHOULD_CALL_PARENT(TRUE) + + SEND_SIGNAL(src, COMSIG_ACTION_ACTIVATED) /// handler for when a keybind signal is received by the action, calls the action_activate proc asynchronous /datum/action/proc/keybind_activation() @@ -158,6 +160,10 @@ hidden = FALSE L.update_action_buttons() +/proc/get_action(mob/action_mob, action_path) + for(var/datum/action/action in action_mob.actions) + if(istype(action, action_path)) + return action /datum/action/item_action name = "Use item" @@ -182,6 +188,7 @@ return ..() /datum/action/item_action/action_activate() + . = ..() if(target) var/obj/item/I = target I.ui_action_click(owner, holder_item) diff --git a/code/datums/ammo/bullet/lever_action.dm b/code/datums/ammo/bullet/lever_action.dm index 2770231b6811..e1475146b21f 100644 --- a/code/datums/ammo/bullet/lever_action.dm +++ b/code/datums/ammo/bullet/lever_action.dm @@ -52,7 +52,7 @@ /datum/ammo/bullet/lever_action/xm88 name = ".458 SOCOM round" - damage = 80 + damage = 104 penetration = ARMOR_PENETRATION_TIER_2 accuracy = HIT_ACCURACY_TIER_1 shell_speed = AMMO_SPEED_TIER_6 diff --git a/code/datums/ammo/misc.dm b/code/datums/ammo/misc.dm index 9a9ed2fb505b..28610f283df2 100644 --- a/code/datums/ammo/misc.dm +++ b/code/datums/ammo/misc.dm @@ -49,10 +49,21 @@ drop_flame(get_turf(P), P.weapon_cause_data) /datum/ammo/flamethrower/tank_flamer - flamer_reagent_id = "napalmx" - + flamer_reagent_id = "highdamagenapalm" max_range = 8 +/datum/ammo/flamethrower/tank_flamer/drop_flame(turf/turf, datum/cause_data/cause_data) + if(!istype(turf)) + return + + var/datum/reagent/napalm/high_damage/reagent = new() + new /obj/flamer_fire(turf, cause_data, reagent, 1) + + var/datum/effect_system/smoke_spread/landingsmoke = new /datum/effect_system/smoke_spread + landingsmoke.set_up(1, 0, turf, null, 4, cause_data) + landingsmoke.start() + landingsmoke = null + /datum/ammo/flamethrower/sentry_flamer flags_ammo_behavior = AMMO_IGNORE_ARMOR|AMMO_IGNORE_COVER|AMMO_FLAME flamer_reagent_id = "napalmx" diff --git a/code/datums/components/bad_leg.dm b/code/datums/components/bad_leg.dm index 4a8678c4da76..8793271803dc 100644 --- a/code/datums/components/bad_leg.dm +++ b/code/datums/components/bad_leg.dm @@ -149,6 +149,7 @@ CRASH("No bound wound to link action") /datum/action/human_action/rest_legs/action_activate() + . = ..() var/mob/living/carbon/human/homan = owner if(in_use) to_chat(homan, SPAN_WARNING("You're already doing that!")) diff --git a/code/datums/components/bonus_damage_stack.dm b/code/datums/components/bonus_damage_stack.dm index 78da5e036ce4..7a9bf5aa9560 100644 --- a/code/datums/components/bonus_damage_stack.dm +++ b/code/datums/components/bonus_damage_stack.dm @@ -60,7 +60,7 @@ var/color = COLOR_BONUS_DAMAGE var/intensity = bonus_damage_stacks / (initial(bonus_damage_cap) * 2) // if intensity is too high of a value, the hex code will become invalid - color += num2text(BONUS_DAMAGE_MAX_ALPHA * clamp(intensity, 0, 0.5), 1, 16) + color += num2text(BONUS_DAMAGE_MAX_ALPHA * clamp(intensity, 0, 0.5), 2, 16) if(parent) var/atom/A = parent A.add_filter("bonus_damage_stacks", 2, list("type" = "outline", "color" = color, "size" = 1 + clamp(intensity, 0, 1))) diff --git a/code/datums/quadtree.dm b/code/datums/quadtree.dm index 5e5b27d57330..200a51b358a0 100644 --- a/code/datums/quadtree.dm +++ b/code/datums/quadtree.dm @@ -49,43 +49,124 @@ ..() return QDEL_HINT_IWILLGC -/datum/shape //Leaving rectangles as a subtype if anyone decides to add circles later +/// A simple geometric shape for testing collisions and intersections. This one is a single point. +/datum/shape + /// Horizontal position of the shape's center point. var/center_x = 0 + /// Vertical position of the shape's center point. var/center_y = 0 + /// Distance from the shape's leftmost to rightmost extent. + var/bounds_x = 0 + /// Distance from the shape's topmost to bottommost extent. + var/bounds_y = 0 -/datum/shape/proc/intersects() - return -/datum/shape/proc/contains() - return +/datum/shape/New(center_x, center_y) + set_shape(center_x, center_y) +/// Assign shape variables. +/datum/shape/proc/set_shape(center_x, center_y) + src.center_x = center_x + src.center_y = center_y + +/// Returns TRUE if the coordinates x, y are in or on the shape, otherwise FALSE. +/datum/shape/proc/contains_xy(x, y) + return center_x == x && center_y == y + +/// Returns TRUE if the coord datum is in or on the shape, otherwise FALSE. +/datum/shape/proc/contains_coords(datum/coords/coords) + return contains_xy(coords.x_pos, coords.y_pos) + +/// Returns TRUE if the atom is in or on the shape, otherwise FALSE. +/datum/shape/proc/contains_atom(atom/atom) + return contains_xy(atom.x, atom.y) + +/// Returns TRUE if this shape's bounding box intersects the provided shape's bounding box, otherwise FALSE. Generally faster than a full intersection test. +/datum/shape/proc/intersects_aabb(datum/shape/aabb) + return (abs(src.center_x - aabb.center_x) <= (src.bounds_x + aabb.bounds_x) * 0.5) && (abs(src.center_y - aabb.center_y) <= (src.bounds_x + aabb.bounds_x) * 0.5) + +/// Returns TRUE if this shape intersects the provided rectangle shape, otherwise FALSE. +/datum/shape/proc/intersects_rect(datum/shape/rectangle/rect) + return rect.contains_xy(src.center_x, src.center_y) + +/// A simple geometric shape for testing collisions and intersections. This one is an axis-aligned rectangle. /datum/shape/rectangle + /// Distance from the shape's leftmost to rightmost extent. + var/width = 0 + /// Distance from the shape's topmost to bottommost extent. + var/height = 0 + +/datum/shape/rectangle/New(center_x, center_y, width, height) + set_shape(center_x, center_y, width, height) + +/datum/shape/rectangle/set_shape(center_x, center_y, width, height) + ..() + src.bounds_x = width + src.bounds_y = height + src.width = width + src.height = height + +/datum/shape/rectangle/contains_xy(x, y) + return (abs(center_x - x) <= width * 0.5) && (abs(center_y - y) <= height * 0.5) + +/datum/shape/rectangle/intersects_rect(datum/shape/rectangle/rect) + return intersects_aabb(rect) + +/// A simple geometric shape for testing collisions and intersections. This one is an axis-aligned square. +/datum/shape/rectangle/square + /// Distance between the shape's opposing extents. + var/length = 0 + +/datum/shape/rectangle/square/New(center_x, center_y, length) + set_shape(center_x, center_y, length) + +/datum/shape/rectangle/square/set_shape(center_x, center_y, length) + ..(center_x, center_y, length, length) + src.length = length + +/// A simple geometric shape for testing collisions and intersections. This one is an axis-aligned ellipse. +/datum/shape/ellipse + /// Distance from the shape's leftmost to rightmost extent. var/width = 0 + /// Distance from the shape's topmost to bottommost extent. var/height = 0 + VAR_PROTECTED/_axis_x_sq = 0 + VAR_PROTECTED/_axis_y_sq = 0 + +/datum/shape/ellipse/New(center_x, center_y, width, height) + set_shape(center_x, center_y, width, height) -/datum/shape/rectangle/New(x, y, w, h) +/datum/shape/ellipse/set_shape(center_x, center_y, width, height) ..() - center_x = x - center_y = y - width = w - height = h - -/datum/shape/rectangle/intersects(datum/shape/rectangle/range) - return !(range.center_x + range.width/2 < center_x - width / 2|| \ - range.center_x - range.width/2 > center_x + width / 2|| \ - range.center_y + range.height/2 < center_y - height / 2|| \ - range.center_y - range.height/2 > center_y + height / 2) - -/datum/shape/rectangle/contains(datum/coords/coords) - return (coords.x_pos >= center_x - width / 2 \ - && coords.x_pos <= center_x + width / 2 \ - && coords.y_pos >= center_y - height /2 \ - && coords.y_pos <= center_y + height / 2) - -/datum/shape/rectangle/proc/contains_atom(atom/A) - return (A.x >= center_x - width / 2 \ - && A.x <= center_x + width / 2 \ - && A.y >= center_y - height /2 \ - && A.y <= center_y + height / 2) + src.bounds_x = width + src.bounds_y = height + src.width = width + src.height = height + src._axis_x_sq = (width * 0.5)**2 + src._axis_y_sq = (height * 0.5)**2 + +/datum/shape/ellipse/contains_xy(x, y) + return ((center_x - x)**2 / _axis_x_sq + (center_y - y)**2 / _axis_y_sq <= 1) + +/datum/shape/ellipse/intersects_rect(datum/shape/rectangle/rect) + if(..()) + return TRUE + + var/nearest_x = clamp(src.center_x, rect.center_x - rect.width * 0.5, rect.center_x + rect.width * 0.5) + var/nearest_y = clamp(src.center_y, rect.center_y - rect.height * 0.5, rect.center_y + rect.height * 0.5) + + return src.contains_xy(nearest_x, nearest_y) + +/// A simple geometric shape for testing collisions and intersections. This one is a circle. +/datum/shape/ellipse/circle + /// Distance from the shape's center to edge. + var/radius = 0 + +/datum/shape/ellipse/circle/New(center_x, center_y, radius) + set_shape(center_x, center_y, radius) + +/datum/shape/ellipse/circle/set_shape(center_x, center_y, radius) + ..(center_x, center_y, radius * 2, radius * 2) + src.radius = radius /datum/quadtree/proc/subdivide() //Warning: this might give you eye cancer @@ -96,7 +177,7 @@ is_divided = TRUE /datum/quadtree/proc/insert_player(datum/coords/qtplayer/p_coords) - if(!boundary.contains(p_coords)) + if(!boundary.contains_coords(p_coords)) return FALSE if(!player_coords) @@ -118,11 +199,11 @@ player_coords.Add(p_coords) return TRUE -/datum/quadtree/proc/query_range(datum/shape/rectangle/range, list/found_players, flags = 0) +/datum/quadtree/proc/query_range(datum/shape/range, list/found_players, flags = 0) if(!found_players) found_players = list() . = found_players - if(!range?.intersects(boundary)) + if(!range?.intersects_rect(boundary)) return if(is_divided) nw_branch.query_range(range, found_players, flags) @@ -136,7 +217,7 @@ continue if((flags & QTREE_EXCLUDE_OBSERVER) && P.is_observer) continue - if(range.contains(P)) + if(range.contains_coords(P)) if(flags & QTREE_SCAN_MOBS) found_players.Add(P.player.mob) else diff --git a/code/datums/statistics/entities/round_stats.dm b/code/datums/statistics/entities/round_stats.dm index 10ec04c6da0e..79493ca87ef0 100644 --- a/code/datums/statistics/entities/round_stats.dm +++ b/code/datums/statistics/entities/round_stats.dm @@ -393,6 +393,7 @@ return TRUE /datum/action/show_round_statistics/action_activate() + . = ..() if(!can_use_action()) return diff --git a/code/datums/supply_packs/explosives.dm b/code/datums/supply_packs/explosives.dm index 032ef047c78a..78f0f3e9251a 100644 --- a/code/datums/supply_packs/explosives.dm +++ b/code/datums/supply_packs/explosives.dm @@ -89,6 +89,18 @@ containername = "\improper explosive M40 HEDP grenades crate (WARNING)" group = "Explosives" +/datum/supply_packs/explosives_sebb + name = "G2 electroshock grenades crate (x6)" + contains = list( + /obj/item/storage/box/packet/sebb, + /obj/item/storage/box/packet/sebb, + ) + cost = 30 + containertype = /obj/structure/closet/crate/explosives + containername = "\improper G2 electroshock grenades crate (WARNING)" + group = "Explosives" + + /datum/supply_packs/explosives_hedp name = "M40 HEDP blast grenade box crate (x25)" contains = list( diff --git a/code/datums/tutorial/_tutorial.dm b/code/datums/tutorial/_tutorial.dm index ddeddddd0407..b7403da3c0a9 100644 --- a/code/datums/tutorial/_tutorial.dm +++ b/code/datums/tutorial/_tutorial.dm @@ -4,7 +4,7 @@ GLOBAL_LIST_EMPTY_TYPED(ongoing_tutorials, /datum/tutorial) /datum/tutorial /// What the tutorial is called, is player facing var/name = "Base" - /// Internal ID of the tutorial, kept for save files + /// Internal ID of the tutorial, kept for save files. Format is "tutorialtype_specifictutorial_number". So, the first basic xeno tutorial would be "xeno_basic_1", and the 2nd marine medical tutorial would be "marine_medical_2" var/tutorial_id = "base" /// A short 1-2 sentence description of the tutorial itself var/desc = "" @@ -144,6 +144,8 @@ GLOBAL_LIST_EMPTY_TYPED(ongoing_tutorials, /datum/tutorial) /// Ends the tutorial after a certain amount of time. /datum/tutorial/proc/tutorial_end_in(time = 5 SECONDS, completed = TRUE) + if(completed) + mark_completed() // This is done because if you're calling this proc with completed == TRUE, then the tutorial's a done deal. We shouldn't penalize the player if they exit a few seconds before it actually completes. tutorial_ending = TRUE addtimer(CALLBACK(src, PROC_REF(end_tutorial), completed), time) @@ -221,6 +223,7 @@ GLOBAL_LIST_EMPTY_TYPED(ongoing_tutorials, /datum/tutorial) tutorial = WEAKREF(selected_tutorial) /datum/action/tutorial_end/action_activate() + . = ..() if(!tutorial) return diff --git a/code/datums/tutorial/xenomorph/abomination.dm b/code/datums/tutorial/xenomorph/abomination.dm new file mode 100644 index 000000000000..db9b77cf2e75 --- /dev/null +++ b/code/datums/tutorial/xenomorph/abomination.dm @@ -0,0 +1,247 @@ +/datum/tutorial/xenomorph/abomination + name = "Xenomorph - Predalien" + desc = "A tutorial to teach you how to play the \"Predalien\", also known as Abomination, xenomorph caste. Completing this is required to be able to play an Abomination." + icon_state = "predalien" + tutorial_id = "xeno_abom_1" + tutorial_template = /datum/map_template/tutorial/s7x7 + starting_xenomorph_type = /mob/living/carbon/xenomorph/predalien/tutorial + /// How many marines in the kill_marines stage have been killed + var/ending_marines_killed = 0 + +// START OF SCRITPING + +/datum/tutorial/xenomorph/abomination/start_tutorial(mob/starting_mob) + . = ..() + if(!.) + return + + init_mob() + xeno.lock_evolve = TRUE + + message_to_player("Welcome to the tutorial for the Abomination xenomorph. As an Abomination, you are a frontline powerhouse whose damage scales with your kill count.") + message_to_player("Your kill count scales when you kill humans with your slash attack, up to 10 kills. Ability kills do not count towards this.") + + addtimer(CALLBACK(src, PROC_REF(how_to_be_abom)), 12 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/how_to_be_abom() + message_to_player("Be aware that you are kill-on-sight to all Predators forever, and will very likely need to defend yourself against multiple.") + message_to_player("Be sure to stick close to other xenomorphs or over-extend. While you may be stronger than many, you don't have enough health or armor to go out on your own.") + addtimer(CALLBACK(src, PROC_REF(feral_rush_tutorial)), 10.5 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/feral_rush_tutorial() + var/datum/action/rush = give_action(xeno, /datum/action/xeno_action/onclick/feralrush) + message_to_player("Your first unique ability is Feral Rush, an ability that temporarily increases your speed and your armor. Use Feral Rush to continue.") + update_objective("Use your Feral Rush ability.") + add_highlight(rush.button) + RegisterSignal(rush, COMSIG_XENO_ACTION_USED, PROC_REF(on_rush_used)) + +/datum/tutorial/xenomorph/abomination/proc/on_rush_used(datum/action/source, mob/owner) + SIGNAL_HANDLER + + UnregisterSignal(source, COMSIG_XENO_ACTION_USED) + remove_highlight(source.button) + addtimer(CALLBACK(src, PROC_REF(predalien_roar_tutorial_1)), 5 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/predalien_roar_tutorial_1() + hide_action(xeno, /datum/action/xeno_action/onclick/feralrush) + xeno.cannot_slash = TRUE + message_to_player("Your next ability is Roar, a versatile ability that disables any motion detectors or cloaks in a medium radius around you.") + message_to_player("Additionally, it gives a slash and speed bonus to any friendly xenomorphs in range.") + addtimer(CALLBACK(src, PROC_REF(predalien_roar_tutorial_2)), 8 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/predalien_roar_tutorial_2() + var/datum/action/roar = give_action(xeno, /datum/action/xeno_action/onclick/predalien_roar) + message_to_player("One of Roar's most useful abilities is uncloaking nearby Predators. Use Roar to uncloak the newly spawned Predator.") + update_objective("Use your Roar ability to uncloak the nearby predator.") + add_highlight(roar.button) + var/mob/living/carbon/human/pred = new(loc_from_corner(3, 3)) + add_to_tracking_atoms(pred) + pred.create_hud() + arm_equipment(pred, /datum/equipment_preset/yautja/blooded) + var/obj/item/clothing/gloves/yautja/hunter/bracers = locate() in pred + if(!bracers) + message_to_player("Something has gone wrong. Please make a bug report.") + CRASH("predator spawned without bracers in tutorial") + + bracers.cloaker_internal(pred, TRUE, TRUE, TRUE) + RegisterSignal(bracers, COMSIG_PRED_BRACER_DECLOAKED, PROC_REF(smash_tutorial_1)) + +/datum/tutorial/xenomorph/abomination/proc/smash_tutorial_1(datum/source) + SIGNAL_HANDLER + + var/datum/action/roar = get_action(xeno, /datum/action/xeno_action/onclick/predalien_roar) + remove_highlight(roar.button) + update_objective("") + + UnregisterSignal(source, COMSIG_PRED_BRACER_DECLOAKED) + addtimer(CALLBACK(src, PROC_REF(smash_tutorial_2)), 2.5 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/smash_tutorial_2() + hide_action(xeno, /datum/action/xeno_action/onclick/predalien_roar) + message_to_player("Good. Roar will be one of your primary tools for defending against Predators. Your next ability is Feral Smash.") + xeno.cannot_slash = FALSE + + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, pred) + remove_from_tracking_atoms(pred) + qdel(pred) + + addtimer(CALLBACK(src, PROC_REF(smash_tutorial_3)), 5 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/smash_tutorial_3() + var/datum/action/smash = give_action(xeno, /datum/action/xeno_action/activable/feral_smash) + RegisterSignal(smash, COMSIG_XENO_PRE_ACTION_USED, PROC_REF(frenzy_tutorial_1)) + add_highlight(smash.button) + + message_to_player("Feral Smash is a strong lunge with a range of five tiles. It deals decent damage that scales with your kill count.") + message_to_player("Use Feral Smash on the marine to continue.") + update_objective("Use your Feral Smash ability on the marine.") + + xeno.forceMove(loc_from_corner(0, 2)) + xeno.anchored = TRUE + ADD_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_TUTORIAL) + + var/mob/living/carbon/human/marine = new(loc_from_corner(4, 2)) + add_to_tracking_atoms(marine) + arm_equipment(marine, /datum/equipment_preset/uscm/private_equipped) + +/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_1(datum/action/source, mob/owner) + SIGNAL_HANDLER + + xeno.anchored = FALSE + REMOVE_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_TUTORIAL) + RegisterSignal(source, COMSIG_XENO_ACTION_USED, PROC_REF(frenzy_tutorial_2)) + RegisterSignal(source, COMSIG_XENO_FAILED_ACTION_USED, PROC_REF(frenzy_tutorial_1_fail)) + +/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_1_fail(datum/action/source, mob/owner) + SIGNAL_HANDLER + + xeno.anchored = TRUE + ADD_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_TUTORIAL) + UnregisterSignal(source, list(COMSIG_XENO_FAILED_ACTION_USED, COMSIG_XENO_ACTION_USED)) + +/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_2(datum/action/source, mob/owner) + SIGNAL_HANDLER + + if(get_turf(xeno) == loc_from_corner(0, 2)) // xeno didn't lunge at the mob + xeno.anchored = TRUE + UnregisterSignal(source, COMSIG_XENO_ACTION_USED) + ADD_TRAIT(xeno, TRAIT_IMMOBILIZED, TRAIT_SOURCE_TUTORIAL) + return + + update_objective("") + var/datum/action/smash = get_action(xeno, /datum/action/xeno_action/activable/feral_smash) + remove_highlight(smash.button) + UnregisterSignal(source, list(COMSIG_XENO_ACTION_USED, COMSIG_XENO_PRE_ACTION_USED)) + addtimer(CALLBACK(src, PROC_REF(frenzy_tutorial_3)), 2 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_3() + remove_action(xeno, /datum/action/xeno_action/activable/feral_smash) + message_to_player("Good. Your final ability is Feral Frenzy, a strong ability that can alternate between hitting a single target or all within a large radius. However, it locks you in place while it winds up.") + + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine) + remove_from_tracking_atoms(marine) + qdel(marine) + + addtimer(CALLBACK(src, PROC_REF(frenzy_tutorial_4)), 6 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_4() + var/mob/living/carbon/human/marine = new(loc_from_corner(4, 2)) + add_to_tracking_atoms(marine) + arm_equipment(marine, /datum/equipment_preset/uscm/private_equipped) + + var/datum/action/frenzy = give_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) + add_highlight(frenzy.button) + message_to_player("By default, Feral Frenzy is on single-target mode. Use Feral Frenzy on the newly spawned marine.") + update_objective("Use Feral Frenzy on the marine.") + + RegisterSignal(frenzy, COMSIG_XENO_ACTION_USED, PROC_REF(frenzy_tutorial_5)) + +/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_5(datum/action/xeno_action/source, mob/owner) + SIGNAL_HANDLER + + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine) + if(get_dist(marine, xeno) > 1) + return + + UnregisterSignal(source, COMSIG_XENO_ACTION_USED) + var/datum/action/frenzy = get_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) + remove_highlight(frenzy.button) + var/datum/action/frenzy_toggle = give_action(xeno, /datum/action/xeno_action/onclick/toggle_gut_targeting) + add_highlight(frenzy_toggle.button) + message_to_player("Good, now toggle Feral Frenzy's AOE mode with the newly available Toggle Gutting Type ability.") + update_objective("Use the Toggle Gutting Type ability to change your frenzy mode.") + + RegisterSignal(frenzy_toggle, COMSIG_XENO_ACTION_USED, PROC_REF(frenzy_tutorial_6)) + +/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_6(datum/action/xeno_action/source, mob/owner) + SIGNAL_HANDLER + + UnregisterSignal(source, COMSIG_XENO_ACTION_USED) + remove_highlight(source.button) + source.plasma_cost = INFINITY // slightly scuffed way of disabling the switch button + source.update_button_icon() + + message_to_player("Feral Frenzy has now been changed into AOE mode. Use Feral Frenzy again anywhere within 2 tiles of the marine.") + update_objective("Use Feral Frenzy within 2 tiles of the marine.") + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine) + marine.rejuvenate() + var/datum/action/xeno_action/activable/feralfrenzy/frenzy = get_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) + frenzy.targeting = AOETARGETGUT + frenzy.reduce_cooldown(frenzy.xeno_cooldown) + add_highlight(frenzy.button) + + RegisterSignal(frenzy, COMSIG_XENO_ACTION_USED, PROC_REF(frenzy_tutorial_7)) + +/datum/tutorial/xenomorph/abomination/proc/frenzy_tutorial_7(datum/action/source) + SIGNAL_HANDLER + + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine) + var/datum/action/xeno_action/activable/feralfrenzy/frenzy = get_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) + if(get_dist(xeno, marine) > frenzy.range) + // Not close enough to actually hit the marine + return + + UnregisterSignal(frenzy, COMSIG_XENO_ACTION_USED) + remove_highlight(frenzy.button) + message_to_player("Good. As you may have noticed, the AOE version of Feral Frenzy takes longer to wind up, in addition to doing less overall damage.") + addtimer(CALLBACK(src, PROC_REF(kill_marines)), 6 SECONDS) + +/datum/tutorial/xenomorph/abomination/proc/kill_marines() + message_to_player("To finish the tutorial, kill the three newly-spawned marines using any of your attacks or abilities.") + + // Spawn/rejuv the dummies + TUTORIAL_ATOM_FROM_TRACKING(/mob/living/carbon/human, marine) // we can reuse this one though + marine.rejuvenate() + marine.forceMove(loc_from_corner(4, 2)) + RegisterSignal(marine, COMSIG_MOB_DEATH, PROC_REF(kill_marines_2)) + + var/mob/living/carbon/human/marine_2 = new(loc_from_corner(2, 2)) + arm_equipment(marine_2, /datum/equipment_preset/uscm/private_equipped) + RegisterSignal(marine_2, COMSIG_MOB_DEATH, PROC_REF(kill_marines_2)) + + var/mob/living/carbon/human/marine_3 = new(loc_from_corner(0, 2)) + arm_equipment(marine_3, /datum/equipment_preset/uscm/private_equipped) + RegisterSignal(marine_3, COMSIG_MOB_DEATH, PROC_REF(kill_marines_2)) + + // Arrange the actions about how they'd be in an actual game + remove_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) + remove_action(xeno, /datum/action/xeno_action/onclick/toggle_gut_targeting) + + give_action(xeno, /datum/action/xeno_action/activable/tail_stab) + give_action(xeno, /datum/action/xeno_action/onclick/feralrush) + give_action(xeno, /datum/action/xeno_action/onclick/predalien_roar) + give_action(xeno, /datum/action/xeno_action/activable/feral_smash) + give_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) + give_action(xeno, /datum/action/xeno_action/onclick/toggle_gut_targeting) + +/datum/tutorial/xenomorph/abomination/proc/kill_marines_2(datum/source) + SIGNAL_HANDLER + + if(ending_marines_killed < 2) + ending_marines_killed++ + return + + message_to_player("Good work. The tutorial will end shortly.") + tutorial_end_in(7 SECONDS, TRUE) + +// END OF SCRIPTING diff --git a/code/datums/xeno_shields/shield_types/vanguard_shield.dm b/code/datums/xeno_shields/shield_types/vanguard_shield.dm index 21d9fb12cfd7..cd9e4534e778 100644 --- a/code/datums/xeno_shields/shield_types/vanguard_shield.dm +++ b/code/datums/xeno_shields/shield_types/vanguard_shield.dm @@ -42,7 +42,7 @@ return linked_xeno.overlay_shields() - var/datum/action/xeno_action/activable/cleave/cAction = get_xeno_action_by_type(linked_xeno, /datum/action/xeno_action/activable/cleave) + var/datum/action/xeno_action/activable/cleave/cAction = get_action(linked_xeno, /datum/action/xeno_action/activable/cleave) if (istype(cAction)) addtimer(CALLBACK(cAction, TYPE_PROC_REF(/datum/action/xeno_action/activable/cleave, remove_buff)), 7, TIMER_UNIQUE) diff --git a/code/game/camera_manager/camera_manager.dm b/code/game/camera_manager/camera_manager.dm index 9f111b0f8ec6..90e80ec7037e 100644 --- a/code/game/camera_manager/camera_manager.dm +++ b/code/game/camera_manager/camera_manager.dm @@ -6,7 +6,7 @@ /datum/component/camera_manager var/map_name var/obj/structure/machinery/camera/current - var/datum/shape/rectangle/current_area + var/datum/shape/current_area var/atom/movable/screen/map_view/cam_screen var/atom/movable/screen/background/cam_background var/list/range_turfs = list() @@ -86,7 +86,7 @@ RegisterSignal(parent, COMSIG_CAMERA_UNREGISTER_UI, PROC_REF(unregister)) RegisterSignal(parent, COMSIG_CAMERA_SET_NVG, PROC_REF(enable_nvg)) RegisterSignal(parent, COMSIG_CAMERA_CLEAR_NVG, PROC_REF(disable_nvg)) - RegisterSignal(parent, COMSIG_CAMERA_SET_AREA, PROC_REF(set_camera_rect)) + RegisterSignal(parent, COMSIG_CAMERA_SET_AREA, PROC_REF(set_camera_area)) RegisterSignal(parent, COMSIG_CAMERA_SET_TARGET, PROC_REF(set_camera)) RegisterSignal(parent, COMSIG_CAMERA_CLEAR, PROC_REF(clear_camera)) RegisterSignal(parent, COMSIG_CAMERA_REFRESH, PROC_REF(refresh_camera)) @@ -133,18 +133,18 @@ RegisterSignal(current, COMSIG_PARENT_QDELETING, PROC_REF(show_camera_static)) update_target_camera() -/datum/component/camera_manager/proc/set_camera_rect(source, x, y, z, w, h) +/datum/component/camera_manager/proc/set_camera_area(source, datum/shape/new_area, z) SIGNAL_HANDLER render_mode = RENDER_MODE_AREA if(current) UnregisterSignal(current, COMSIG_PARENT_QDELETING) current = null - current_area = RECT(x, y, w, h) - target_x = x - target_y = y + current_area = new_area + target_x = current_area.center_x + target_y = current_area.center_y target_z = z - target_width = w - target_height = h + target_width = current_area.bounds_x + target_height = current_area.bounds_y update_area_camera() /datum/component/camera_manager/proc/enable_nvg(source, power, matrixcol) @@ -221,8 +221,8 @@ // Cameras that get here are moving, and are likely attached to some moving atom such as cyborgs. last_camera_turf = new_location - var/x_size = current_area.width - var/y_size = current_area.height + var/x_size = current_area.bounds_x + var/y_size = current_area.bounds_y var/turf/target = locate(current_area.center_x, current_area.center_y, target_z) var/list/visible_things = isXRay ? range("[x_size]x[y_size]", target) : view("[x_size]x[y_size]", target) diff --git a/code/game/machinery/autolathe_datums.dm b/code/game/machinery/autolathe_datums.dm index 78a8e46b64aa..9c8ee271845d 100644 --- a/code/game/machinery/autolathe_datums.dm +++ b/code/game/machinery/autolathe_datums.dm @@ -136,11 +136,6 @@ path = /obj/item/circuitboard/apc category = AUTOLATHE_CATEGORY_ENGINEERING -/datum/autolathe/recipe/rcd_ammo - name = "matter cartridge" - path = /obj/item/ammo_rcd - category = AUTOLATHE_CATEGORY_ENGINEERING - /datum/autolathe/recipe/table_parts name = "table parts" path = /obj/item/frame/table diff --git a/code/game/machinery/computer/dropship_weapons.dm b/code/game/machinery/computer/dropship_weapons.dm index e07b415ed233..7f8f4f2b3850 100644 --- a/code/game/machinery/computer/dropship_weapons.dm +++ b/code/game/machinery/computer/dropship_weapons.dm @@ -313,9 +313,8 @@ var/obj/structure/machinery/defenses/sentry/defense = sentry.deployed_turret if(defense.has_camera) defense.set_range() - var/datum/shape/rectangle/current_bb = defense.range_bounds camera_area_equipment = sentry - SEND_SIGNAL(src, COMSIG_CAMERA_SET_AREA, current_bb.center_x, current_bb.center_y, defense.loc.z, current_bb.width, current_bb.height) + SEND_SIGNAL(src, COMSIG_CAMERA_SET_AREA, defense.range_bounds, defense.loc.z) return TRUE if("clear-camera") diff --git a/code/game/machinery/vending/vendor_types/crew/combat_correspondent.dm b/code/game/machinery/vending/vendor_types/crew/combat_correspondent.dm index b0894ca2a5a2..81bee126dbc8 100644 --- a/code/game/machinery/vending/vendor_types/crew/combat_correspondent.dm +++ b/code/game/machinery/vending/vendor_types/crew/combat_correspondent.dm @@ -3,9 +3,11 @@ GLOBAL_LIST_INIT(cm_vending_clothing_combat_correspondent, list( list("STANDARD EQUIPMENT (TAKE ALL)", 0, null, null, null), list("Essential Reporter's Set", 0, /obj/effect/essentials_set/cc, MARINE_CAN_BUY_ESSENTIALS, VENDOR_ITEM_MANDATORY), + list("Leather Satchel", 0, /obj/item/storage/backpack/satchel, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_REGULAR), + + list("CIVILIAN EQUIPMENT (TAKE ALL)", 0, null, null, null), list("Portable Press Fax Machine", 0, /obj/item/device/fax_backpack, CIVILIAN_CAN_BUY_BACKPACK, VENDOR_ITEM_RECOMMENDED), list("Press Broadcasting Camera", 0, /obj/item/device/camera/broadcasting, CIVILIAN_CAN_BUY_UTILITY, VENDOR_ITEM_RECOMMENDED), - list("Leather Satchel", 0, /obj/item/storage/backpack/satchel, MARINE_CAN_BUY_BACKPACK, VENDOR_ITEM_REGULAR), list("UNIFORM (CHOOSE 1)", 0, null, null, null), list("Black Uniform", 0, /obj/item/clothing/under/marine/reporter/black, MARINE_CAN_BUY_UNIFORM, VENDOR_ITEM_REGULAR), diff --git a/code/game/machinery/vending/vendor_types/crew/commanding_officer.dm b/code/game/machinery/vending/vendor_types/crew/commanding_officer.dm index d7d49a8ae044..dd2fc9c4a5b7 100644 --- a/code/game/machinery/vending/vendor_types/crew/commanding_officer.dm +++ b/code/game/machinery/vending/vendor_types/crew/commanding_officer.dm @@ -32,6 +32,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_commanding_officer, list( list("HEDP Grenade Pack", 15, /obj/item/storage/box/packet/high_explosive, null, VENDOR_ITEM_REGULAR), list("HEFA Grenade Pack", 15, /obj/item/storage/box/packet/hefa, null, VENDOR_ITEM_REGULAR), list("WP Grenade Pack", 15, /obj/item/storage/box/packet/phosphorus, null, VENDOR_ITEM_REGULAR), + list("G2 Electroshock Grenade Packet (x3 grenades)", 15, /obj/item/storage/box/packet/sebb, null, VENDOR_ITEM_REGULAR), list("RAIL ATTACHMENTS", 0, null, null, null), list("Red-Dot Sight", 15, /obj/item/attachable/reddot, null, VENDOR_ITEM_REGULAR), diff --git a/code/game/machinery/vending/vendor_types/crew/synthetic.dm b/code/game/machinery/vending/vendor_types/crew/synthetic.dm index 7fbe39480999..9ce15535e2da 100644 --- a/code/game/machinery/vending/vendor_types/crew/synthetic.dm +++ b/code/game/machinery/vending/vendor_types/crew/synthetic.dm @@ -188,7 +188,7 @@ GLOBAL_LIST_INIT(cm_vending_clothing_synth, list( GLOBAL_LIST_INIT(cm_vending_clothing_synth_snowflake, list( list("USCM UNIFORMS", 0, null, null, null), list("Medical Scrubs, Blue", 12, /obj/item/clothing/under/rank/medical/blue, null, VENDOR_ITEM_REGULAR), - list("Medical Scrubs, Light Blue", 0, /obj/item/clothing/under/rank/medical/lightblue, null, VENDOR_ITEM_REGULAR), + list("Medical Scrubs, Light Blue", 12, /obj/item/clothing/under/rank/medical/lightblue, null, VENDOR_ITEM_REGULAR), list("Medical Scrubs, Green", 12, /obj/item/clothing/under/rank/medical/green, null, VENDOR_ITEM_REGULAR), list("Medical Scrubs, Purple", 12, /obj/item/clothing/under/rank/medical/purple, null, VENDOR_ITEM_REGULAR), list("Medical Scrubs, Olive", 12, /obj/item/clothing/under/rank/medical/olive, null, VENDOR_ITEM_REGULAR), @@ -349,6 +349,13 @@ GLOBAL_LIST_INIT(cm_vending_clothing_synth_snowflake, list( list("Purple Armband", 6, /obj/item/clothing/accessory/armband/science, null, VENDOR_ITEM_REGULAR), list("Yellow Armband", 6, /obj/item/clothing/accessory/armband/engine, null, VENDOR_ITEM_REGULAR), list("Green Armband", 6, /obj/item/clothing/accessory/armband/medgreen, null, VENDOR_ITEM_REGULAR), + list("Blue Tie", 6, /obj/item/clothing/accessory/blue, null, VENDOR_ITEM_REGULAR), + list("Green Tie", 6, /obj/item/clothing/accessory/green, null, VENDOR_ITEM_REGULAR), + list("Black Tie", 6, /obj/item/clothing/accessory/black, null, VENDOR_ITEM_REGULAR), + list("Gold Tie", 6, /obj/item/clothing/accessory/gold, null, VENDOR_ITEM_REGULAR), + list("Red Tie", 6, /obj/item/clothing/accessory/red, null, VENDOR_ITEM_REGULAR), + list("Purple Tie", 6, /obj/item/clothing/accessory/purple, null, VENDOR_ITEM_REGULAR), + list("Stethoscope", 6, /obj/item/clothing/accessory/stethoscope, null, VENDOR_ITEM_REGULAR), list("Dress Gloves", 6, /obj/item/clothing/gloves/marine/dress, null, VENDOR_ITEM_REGULAR), )) diff --git a/code/game/machinery/vending/vendor_types/requisitions.dm b/code/game/machinery/vending/vendor_types/requisitions.dm index a8d44a8b5012..5c5362257da2 100644 --- a/code/game/machinery/vending/vendor_types/requisitions.dm +++ b/code/game/machinery/vending/vendor_types/requisitions.dm @@ -55,6 +55,7 @@ list("M74 AGM-Smoke Airburst Grenade", floor(scale * 4), /obj/item/explosive/grenade/smokebomb/airburst, VENDOR_ITEM_REGULAR), list("M74 AGM-Star Shell", floor(scale * 2), /obj/item/explosive/grenade/high_explosive/airburst/starshell, VENDOR_ITEM_REGULAR), list("M74 AGM-Hornet Shell", floor(scale * 4), /obj/item/explosive/grenade/high_explosive/airburst/hornet_shell, VENDOR_ITEM_REGULAR), + list("G2 Electroshock Grenade", round(scale * 5), /obj/item/explosive/grenade/sebb, VENDOR_ITEM_REGULAR), list("M40 HIRR Baton Slug", floor(scale * 8), /obj/item/explosive/grenade/slug/baton, VENDOR_ITEM_REGULAR), list("M40 MFHS Metal Foam Grenade", floor(scale * 6), /obj/item/explosive/grenade/metal_foam, VENDOR_ITEM_REGULAR), list("Plastic Explosives", floor(scale * 3), /obj/item/explosive/plastic, VENDOR_ITEM_REGULAR), @@ -154,6 +155,7 @@ list("M74 AGM-Airburst Smoke Grenade Packet", 0, /obj/item/storage/box/packet/airburst_smoke, VENDOR_ITEM_REGULAR), list("M74 AGM-S Star Shell Packet", 0, /obj/item/storage/box/packet/flare, VENDOR_ITEM_REGULAR), list("M74 AGM-H Hornet Shell Packet", 0, /obj/item/storage/box/packet/hornet, VENDOR_ITEM_REGULAR), + list("G2 Electroshock grenade packet", 0, /obj/item/storage/box/packet/sebb, VENDOR_ITEM_REGULAR), list("M20 mine box", 0, /obj/item/storage/box/explosive_mines, VENDOR_ITEM_REGULAR), list("OTHER BOXES", -1, null, null), diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm index aaf134c4a459..9c19a5b172c6 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_engineer.dm @@ -35,6 +35,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_engi, list( list("M74 AGM-Hornet Airburst Packet (x3 airburst grenades", 20, /obj/item/storage/box/packet/hornet, null, VENDOR_ITEM_REGULAR), list("M20 Mine Box (x4 mines)", 18, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR), list("M40 MFHS Metal Foam Grenade", 5, /obj/item/explosive/grenade/metal_foam, null, VENDOR_ITEM_REGULAR), + list("G2 Electroshock Grenade Packet (x3 grenades)", 16, /obj/item/storage/box/packet/sebb, null, VENDOR_ITEM_REGULAR), list("PRIMARY AMMUNITION", 0, null, null, null), list("M4RA AP Magazine (10x24mm)", 6, /obj/item/ammo_magazine/rifle/m4ra/ap, null, VENDOR_ITEM_REGULAR), diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm index 17d3419ac2f8..7f8d70db4328 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_leader.dm @@ -61,6 +61,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_leader, list( list("M74 AGM-Hornet Airburst Packet (x3 airburst grenades", 20, /obj/item/storage/box/packet/hornet, null, VENDOR_ITEM_REGULAR), list("M20 Mine Box (x4 mines)", 20, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR), list("M40 MFHS Metal Foam Grenade", 5, /obj/item/explosive/grenade/metal_foam, null, VENDOR_ITEM_REGULAR), + list("G2 Electroshock Grenade Packet (x3 grenades)", 16, /obj/item/storage/box/packet/sebb, null, VENDOR_ITEM_REGULAR), list("MEDICAL SUPPLIES", 0, null, null, null), list("Burn Kit", 2, /obj/item/stack/medical/advanced/ointment, null, VENDOR_ITEM_REGULAR), diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm index a73df202d4ef..e9d69ad396de 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_medic.dm @@ -57,6 +57,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_medic, list( list("M74 AGM-Smoke Airburst Packet (x3 airburst grenades)", 10, /obj/item/storage/box/packet/airburst_smoke, null, VENDOR_ITEM_REGULAR), list("M74 AGM-Hornet Airburst Packet (x3 airburst grenades", 20, /obj/item/storage/box/packet/hornet, null, VENDOR_ITEM_REGULAR), list("M20 Mine Box (x4 mines)", 20, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR), + list("G2 Electroshock Grenade Packet (x3 grenades)", 16, /obj/item/storage/box/packet/sebb, null, VENDOR_ITEM_REGULAR), list("PRIMARY AMMUNITION", 0, null, null, null), list("M4RA AP Magazine (10x24mm)", 6, /obj/item/ammo_magazine/rifle/m4ra/ap, null, VENDOR_ITEM_REGULAR), diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_specialist.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_specialist.dm index 4d14b7b89ccd..8fbf574d36d7 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_specialist.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_specialist.dm @@ -32,6 +32,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_spec, list( list("M74 AGM-F Fragmentation Grenades x6", 40, /obj/effect/essentials_set/agmf_6_pack, null, VENDOR_ITEM_REGULAR), list("M74 AGM-I Incendiary Grenades x6", 40, /obj/effect/essentials_set/agmi_6_pack, null, VENDOR_ITEM_REGULAR), list("M74 AGM-S Smoke Grenades x6", 20, /obj/effect/essentials_set/agms_6_pack, null, VENDOR_ITEM_REGULAR), + list("G2 Electroshock Grenade Pack x6", 40, /obj/effect/essentials_set/sebb_6_pack, null, VENDOR_ITEM_REGULAR), list("EXTRA FLAMETHROWER TANKS", 0, null, null, null), list("Large Incinerator Tank", 40, /obj/item/ammo_magazine/flamer_tank/large, null, VENDOR_ITEM_REGULAR), @@ -249,3 +250,13 @@ GLOBAL_LIST_INIT(cm_vending_clothing_specialist, list( /obj/item/explosive/grenade/smokebomb/airburst, /obj/item/explosive/grenade/smokebomb/airburst, ) + +/obj/effect/essentials_set/sebb_6_pack + spawned_gear_list = list( + /obj/item/explosive/grenade/sebb, + /obj/item/explosive/grenade/sebb, + /obj/item/explosive/grenade/sebb, + /obj/item/explosive/grenade/sebb, + /obj/item/explosive/grenade/sebb, + /obj/item/explosive/grenade/sebb, + ) diff --git a/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm b/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm index c37dd98ed263..73efbe1148e5 100644 --- a/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm +++ b/code/game/machinery/vending/vendor_types/squad_prep/squad_tl.dm @@ -12,6 +12,7 @@ GLOBAL_LIST_INIT(cm_vending_gear_tl, list( list("M74 AGM-Hornet Airburst Packet (x3 airburst grenades", 20, /obj/item/storage/box/packet/hornet, null, VENDOR_ITEM_REGULAR), list("M20 Mine Box (x4 mines)", 20, /obj/item/storage/box/explosive_mines, null, VENDOR_ITEM_REGULAR), list("M40 MFHS Metal Foam Grenade", 5, /obj/item/explosive/grenade/metal_foam, null, VENDOR_ITEM_REGULAR), + list("G2 Electroshock Grenade Packet (x3 grenades)", 16, /obj/item/storage/box/packet/sebb, null, VENDOR_ITEM_REGULAR), list("PRIMARY AMMUNITION", 0, null, null, null), list("M4RA AP Magazine (10x24mm)", 10, /obj/item/ammo_magazine/rifle/m4ra/ap, null, VENDOR_ITEM_REGULAR), diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index 10d4e8d098fb..34da5e3d2623 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -597,7 +597,7 @@ total_hits++ - var/datum/action/xeno_action/activable/boiler_trap/trap = get_xeno_action_by_type(linked_xeno, /datum/action/xeno_action/activable/boiler_trap) + var/datum/action/xeno_action/activable/boiler_trap/trap = get_action(linked_xeno, /datum/action/xeno_action/activable/boiler_trap) trap.reduce_cooldown(total_hits*4 SECONDS) diff --git a/code/game/objects/effects/effect_system/smoke.dm b/code/game/objects/effects/effect_system/smoke.dm index d4152bdee37e..d0ea5d2ed5ef 100644 --- a/code/game/objects/effects/effect_system/smoke.dm +++ b/code/game/objects/effects/effect_system/smoke.dm @@ -731,7 +731,7 @@ location = get_turf(loca) if(direct) direction = direct - if(lifetime) + if(smoke_time) lifetime = smoke_time radius = min(radius, 10) amount = radius diff --git a/code/game/objects/effects/overlays.dm b/code/game/objects/effects/overlays.dm index ce0fd5506cd7..d559137f79b1 100644 --- a/code/game/objects/effects/overlays.dm +++ b/code/game/objects/effects/overlays.dm @@ -223,6 +223,7 @@ icon_state = "empdisable" name = "emp sparks" effect_duration = 10 + mouse_opacity = MOUSE_OPACITY_TRANSPARENT /obj/effect/overlay/temp/emp_sparks/New(loc) setDir(pick(GLOB.cardinals)) @@ -234,8 +235,12 @@ icon_state = "emppulse" effect_duration = 20 - - +/obj/effect/overlay/temp/elec_arc + icon = 'icons/effects/effects.dmi' + icon_state = "electricity" + name = "electric arc" + effect_duration = 3 SECONDS + mouse_opacity = MOUSE_OPACITY_TRANSPARENT //gib animation diff --git a/code/game/objects/items/devices/RCD.dm b/code/game/objects/items/devices/RCD.dm deleted file mode 100644 index 00e569800314..000000000000 --- a/code/game/objects/items/devices/RCD.dm +++ /dev/null @@ -1,194 +0,0 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 - -/* -CONTAINS: -RCD -*/ -/obj/item/device/rcd - name = "rapid-construction-device (RCD)" - desc = "A device used to rapidly build walls/floor." - icon = 'icons/obj/items/devices.dmi' - icon_state = "rcd" - opacity = FALSE - density = FALSE - anchored = FALSE - flags_atom = FPRINT|CONDUCT - force = 10 - throwforce = 10 - throw_speed = SPEED_FAST - throw_range = 5 - w_class = SIZE_MEDIUM - matter = list("metal" = 50000) - - var/datum/effect_system/spark_spread/spark_system - var/stored_matter = 0 - var/working = 0 - var/mode = 1 - var/canRwall = 0 - var/disabled = 0 - - -/obj/item/device/rcd/New() - desc = "A RCD. It currently holds [stored_matter]/30 matter-units." - src.spark_system = new /datum/effect_system/spark_spread - spark_system.set_up(5, 0, src) - spark_system.attach(src) - return - -/obj/item/device/rcd/Destroy() - QDEL_NULL(spark_system) - return ..() - - -/obj/item/device/rcd/attackby(obj/item/W, mob/user) - ..() - if(istype(W, /obj/item/ammo_rcd)) - if((stored_matter + 10) > 30) - to_chat(user, SPAN_NOTICE("The RCD cant hold any more matter-units.")) - return - user.drop_held_item() - qdel(W) - stored_matter += 10 - playsound(src.loc, 'sound/machines/click.ogg', 15, 1) - to_chat(user, SPAN_NOTICE("The RCD now holds [stored_matter]/30 matter-units.")) - desc = "A RCD. It currently holds [stored_matter]/30 matter-units." - return - - -/obj/item/device/rcd/attack_self(mob/user) - ..() - - //Change the mode - playsound(src.loc, 'sound/effects/pop.ogg', 15, 0) - switch(mode) - if(1) - mode = 2 - to_chat(user, SPAN_NOTICE("Changed mode to 'Airlock'")) - if(prob(20)) - src.spark_system.start() - return - if(2) - mode = 3 - to_chat(user, SPAN_NOTICE("Changed mode to 'Deconstruct'")) - if(prob(20)) - src.spark_system.start() - return - if(3) - mode = 1 - to_chat(user, SPAN_NOTICE("Changed mode to 'Floor & Walls'")) - if(prob(20)) - src.spark_system.start() - return - -/obj/item/device/rcd/proc/activate() - playsound(src.loc, 'sound/items/Deconstruct.ogg', 25, 1) - - -/obj/item/device/rcd/afterattack(atom/A, mob/user, proximity) - if(!proximity) return - if(disabled) - return 0 - if(istype(A,/area/shuttle) || istype(A,/turf/open/space/transit)) - return 0 - if(!(istype(A, /turf) || istype(A, /obj/structure/machinery/door/airlock))) - return 0 - - switch(mode) - if(1) - if(istype(A, /turf/open/space)) - if(useResource(1, user)) - to_chat(user, "Building Floor...") - activate() - A:ChangeTurf(/turf/open/floor/plating/airless) - return 1 - return 0 - - if(istype(A, /turf/open/floor)) - if(checkResource(3, user)) - to_chat(user, "Building Wall ...") - playsound(src.loc, 'sound/machines/click.ogg', 15, 1) - if(do_after(user, 20, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) - if(!useResource(3, user)) return 0 - activate() - A:ChangeTurf(/turf/closed/wall) - return 1 - return 0 - - if(2) - if(istype(A, /turf/open/floor)) - if(checkResource(10, user)) - to_chat(user, "Building Airlock...") - playsound(src.loc, 'sound/machines/click.ogg', 15, 1) - if(do_after(user, 50, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) - if(!useResource(10, user)) return 0 - activate() - var/obj/structure/machinery/door/airlock/T = new /obj/structure/machinery/door/airlock( A ) - T.autoclose = 1 - return 1 - return 0 - return 0 - - if(3) - if(istype(A, /turf/closed/wall)) - var/turf/closed/wall/WL = A - if(WL.hull) - return 0 - if(istype(A, /turf/closed/wall/r_wall) && !canRwall) - return 0 - if(checkResource(5, user)) - to_chat(user, "Deconstructing Wall...") - playsound(src.loc, 'sound/machines/click.ogg', 15, 1) - if(do_after(user, 40, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) - if(!useResource(5, user)) return 0 - activate() - A:ChangeTurf(/turf/open/floor/plating/airless) - return 1 - return 0 - - if(istype(A, /turf/open/floor) && !istype(A, /turf/open/floor/plating)) - if(checkResource(5, user)) - to_chat(user, "Deconstructing Floor...") - playsound(src.loc, 'sound/machines/click.ogg', 15, 1) - if(do_after(user, 50, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) - if(!useResource(5, user)) return 0 - activate() - A:ChangeTurf(/turf/open/floor/plating/airless) - return 1 - return 0 - - if(istype(A, /obj/structure/machinery/door/airlock)) - if(checkResource(10, user)) - to_chat(user, "Deconstructing Airlock...") - playsound(src.loc, 'sound/machines/click.ogg', 15, 1) - if(do_after(user, 50, INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) - if(!useResource(10, user)) return 0 - activate() - qdel(A) - return 1 - return 0 - return 0 - else - to_chat(user, "ERROR: RCD in MODE: [mode] attempted use by [user]. Send this text #coderbus or an admin.") - return 0 - -/obj/item/device/rcd/proc/useResource(amount, mob/user) - if(stored_matter < amount) - return 0 - stored_matter -= amount - desc = "A RCD. It currently holds [stored_matter]/30 matter-units." - return 1 - -/obj/item/device/rcd/proc/checkResource(amount, mob/user) - return stored_matter >= amount - -/obj/item/ammo_rcd - name = "compressed matter cartridge" - desc = "Highly compressed matter for the RCD." - icon = 'icons/obj/items/weapons/guns/legacy/old_bayguns.dmi' - icon_state = "rcd" - item_state = "rcdammo" - opacity = FALSE - density = FALSE - anchored = FALSE - - matter = list("metal" = 30000,"glass" = 15000) diff --git a/code/game/objects/items/devices/RSF.dm b/code/game/objects/items/devices/RSF.dm deleted file mode 100644 index 29f84c7c6d0c..000000000000 --- a/code/game/objects/items/devices/RSF.dm +++ /dev/null @@ -1,98 +0,0 @@ -/* -CONTAINS: -RSF - -*/ - -/obj/item/device/rsf - name = "\improper Rapid-Service-Fabricator" - desc = "A device used to rapidly deploy service items." - icon = 'icons/obj/items/devices.dmi' - icon_state = "rcd" - opacity = FALSE - density = FALSE - anchored = FALSE - var/stored_matter = 30 - var/mode = 1 - w_class = SIZE_MEDIUM - -/obj/item/device/rsf/get_examine_text(mob/user) - . = ..() - . += "It currently holds [stored_matter]/30 fabrication-units." - -/obj/item/device/rsf/attackby(obj/item/W, mob/user) - ..() - if (istype(W, /obj/item/ammo_rcd)) - - if ((stored_matter + 10) > 30) - to_chat(user, "The RSF can't hold any more matter.") - return - - qdel(W) - - stored_matter += 10 - playsound(src.loc, 'sound/machines/click.ogg', 15, 1) - to_chat(user, "The RSF now holds [stored_matter]/30 fabrication-units.") - return - -/obj/item/device/rsf/attack_self(mob/user) - ..() - playsound(src.loc, 'sound/effects/pop.ogg', 15, 0) - if (mode == 1) - mode = 2 - to_chat(user, "Changed dispensing mode to 'Drinking Glass'") - return - if (mode == 2) - mode = 3 - to_chat(user, "Changed dispensing mode to 'Paper'") - return - if (mode == 3) - mode = 4 - to_chat(user, "Changed dispensing mode to 'Pen'") - return - if (mode == 4) - mode = 5 - to_chat(user, "Changed dispensing mode to 'Dice Pack'") - return - if (mode == 5) - mode = 6 - to_chat(user, "Changed dispensing mode to 'Cigarette'") - return - if (mode == 6) - mode = 1 - to_chat(user, "Changed dispensing mode to 'Dosh'") - return - // Change mode - -/obj/item/device/rsf/afterattack(atom/A, mob/user, proximity) - - if(!proximity) return - - if(stored_matter <= 0) - return - - if(!istype(A, /obj/structure/surface/table) && !istype(A, /turf/open/floor)) - return - - playsound(src.loc, 'sound/machines/click.ogg', 25, 1) - var/obj/product - - switch(mode) - if(1) - product = new /obj/item/spacecash/c10() - if(2) - product = new /obj/item/reagent_container/food/drinks/drinkingglass() - if(3) - product = new /obj/item/paper() - if(4) - product = new /obj/item/tool/pen() - if(5) - product = new /obj/item/storage/pill_bottle/dice() - if(6) - product = new /obj/item/clothing/mask/cigarette() - - to_chat(user, "Dispensing [product ? product : "product"]...") - product.forceMove(get_turf(A)) - - stored_matter-- - to_chat(user, "The RSF now holds [stored_matter]/30 fabrication-units.") diff --git a/code/game/objects/items/devices/RSP.dm b/code/game/objects/items/devices/RSP.dm deleted file mode 100644 index cb61de1a77cc..000000000000 --- a/code/game/objects/items/devices/RSP.dm +++ /dev/null @@ -1,11 +0,0 @@ -/obj/item/device/rsp - name = "\improper Rapid-Seed-Producer (RSP)" - desc = "A device used to rapidly deploy seeds." - icon = 'icons/obj/items/devices.dmi' - icon_state = "rsp" - opacity = FALSE - density = FALSE - anchored = FALSE - var/stored_matter = 0 - var/mode = 1 - w_class = SIZE_MEDIUM diff --git a/code/game/objects/items/devices/binoculars.dm b/code/game/objects/items/devices/binoculars.dm index 5da4704e0e78..3248115adfa8 100644 --- a/code/game/objects/items/devices/binoculars.dm +++ b/code/game/objects/items/devices/binoculars.dm @@ -403,6 +403,7 @@ COOLDOWN_START(designator, spotting_cooldown, 0) /datum/action/item_action/specialist/spotter_target/action_activate() + . = ..() if(!ishuman(owner)) return var/mob/living/carbon/human/human = owner diff --git a/code/game/objects/items/devices/helmet_visors.dm b/code/game/objects/items/devices/helmet_visors.dm index 8f921a62f3f5..e2005a841bc3 100644 --- a/code/game/objects/items/devices/helmet_visors.dm +++ b/code/game/objects/items/devices/helmet_visors.dm @@ -146,6 +146,7 @@ return /datum/action/item_action/view_publications/helmet_visor/action_activate() + . = ..() var/obj/item/device/helmet_visor/medical/advanced/medical_visor = locate() in holder_item if(!medical_visor) diff --git a/code/game/objects/items/devices/motion_detector.dm b/code/game/objects/items/devices/motion_detector.dm index 3551e3a02bef..dcbcc0dd8bc7 100644 --- a/code/game/objects/items/devices/motion_detector.dm +++ b/code/game/objects/items/devices/motion_detector.dm @@ -35,7 +35,7 @@ var/iff_signal = FACTION_MARINE actions_types = list(/datum/action/item_action) var/scanning = FALSE // controls if MD is in process of scan - var/datum/shape/rectangle/range_bounds + var/datum/shape/rectangle/square/range_bounds var/long_range_locked = FALSE //only long-range MD var/ping_overlay @@ -48,7 +48,7 @@ /obj/item/device/motiondetector/Initialize() . = ..() - range_bounds = new //Just creating a rectangle datum + range_bounds = new //Just creating a square datum update_icon() /obj/item/device/motiondetector/Destroy() @@ -215,12 +215,7 @@ if(!istype(cur_turf)) return - if(!range_bounds) - range_bounds = new/datum/shape/rectangle - range_bounds.center_x = cur_turf.x - range_bounds.center_y = cur_turf.y - range_bounds.width = detector_range * 2 - range_bounds.height = detector_range * 2 + range_bounds.set_shape(cur_turf.x, cur_turf.y, detector_range * 2) var/list/ping_candidates = SSquadtree.players_in_range(range_bounds, cur_turf.z, QTREE_EXCLUDE_OBSERVER | QTREE_SCAN_MOBS) diff --git a/code/game/objects/items/devices/walkman.dm b/code/game/objects/items/devices/walkman.dm index 42c03d757dbd..bef8e8f5ff79 100644 --- a/code/game/objects/items/devices/walkman.dm +++ b/code/game/objects/items/devices/walkman.dm @@ -269,6 +269,7 @@ button.name = name /datum/action/item_action/walkman/play_pause/action_activate() + . = ..() if(target) var/obj/item/device/walkman/WM = target WM.attack_self(owner) @@ -282,6 +283,7 @@ button.name = name /datum/action/item_action/walkman/next_song/action_activate() + . = ..() if(target) var/obj/item/device/walkman/WM = target WM.next_song(owner) @@ -295,6 +297,7 @@ button.name = name /datum/action/item_action/walkman/restart_song/action_activate() + . = ..() if(target) var/obj/item/device/walkman/WM = target WM.restart_song(owner) diff --git a/code/game/objects/items/explosives/grenades/marines.dm b/code/game/objects/items/explosives/grenades/marines.dm index 1cd3e1577c57..09c0197cda7f 100644 --- a/code/game/objects/items/explosives/grenades/marines.dm +++ b/code/game/objects/items/explosives/grenades/marines.dm @@ -465,6 +465,187 @@ icon_state = "grenade_phos_clf" item_state = "grenade_phos_clf" +/obj/item/explosive/grenade/sebb + name = "\improper G2 Electroshock grenade" + desc = "This is a G2 Electroshock Grenade. Produced by Armat Battlefield Systems, it's sometimes referred to as the Sonic Electric Ball Breaker, \ + after a rash of incidents where the intense 1.2 gV sonic payload caused... rupturing. \ + A bounding landmine mode is available for this weapon which activates a small drill to self-bury itself when planted. Simply plant it at your feet and walk away." + icon_state = "grenade_sebb" + item_state = "grenade_sebb" + det_time = 3 SECONDS + underslug_launchable = TRUE + /// Maximum range of effect + var/range = 5 + /// Maximum possible damage before falloff. + var/damage = 110 + /// Factor to mutiply the effect range has on damage. + var/falloff_dam_reduction_mult = 20 + /// Post falloff calc damage is divided by this to get xeno slowdown + var/xeno_slowdown_numerator = 12 + /// Post falloff calc damage is multipled by this to get human stamina damage + var/human_stam_dam_factor = 0.9 + +/obj/item/explosive/grenade/sebb/get_examine_text(mob/user) + . = ..() + . += SPAN_NOTICE("To put into mine mode, plant at feet.") + +/obj/item/explosive/grenade/sebb/afterattack(atom/target, mob/user, proximity) + var/turf/user_turf = get_turf(user) + if(active) + return + + if(!isturf(target)) + return + + if(user.action_busy) + return + + if(target != get_turf(user)) + return + + if(locate(/obj/item/explosive/mine) in get_turf(src)) + to_chat(user, SPAN_WARNING("There already is a mine at this position!")) + return + + if(antigrief_protection && user.faction == FACTION_MARINE && explosive_antigrief_check(src, user)) + to_chat(user, SPAN_WARNING("\The [name]'s safe-area accident inhibitor prevents you from planting!")) + msg_admin_niche("[key_name(user)] attempted to plant \a [name] in [get_area(src)] [ADMIN_JMP(src.loc)]") + return + + if(ishuman(user)) + var/mob/living/carbon/human/human = user + if(!human.allow_gun_usage) + to_chat(user, SPAN_WARNING("Your programming prevents you from using this!")) + return + + if(user_turf && (user_turf.density || locate(/obj/structure/fence) in user_turf)) + to_chat(user, SPAN_WARNING("You can't plant a mine here.")) + return + + if(Adjacent(/obj/item/explosive/mine)) // bit more strict on this than normal mines + to_chat(user, SPAN_WARNING("Too close to another mine! Plant it somewhere less obvious.")) + return + + user.visible_message(SPAN_NOTICE("[user] starts deploying [src]."), + SPAN_NOTICE("You switch [src] into landmine mode and start placing it...")) + playsound(user.loc, 'sound/effects/thud.ogg', 40) + if(!do_after(user, 5 SECONDS * user.get_skill_duration_multiplier(SKILL_CONSTRUCTION), INTERRUPT_ALL|BEHAVIOR_IMMOBILE, BUSY_ICON_BUILD)) + to_chat(user, SPAN_NOTICE("You stop planting.")) + return + + user.visible_message(SPAN_NOTICE("[user] finishes deploying [src]."), + SPAN_NOTICE("You finish deploying [src].")) + var/obj/item/explosive/mine/sebb/planted = new /obj/item/explosive/mine/sebb(get_turf(user)) + planted.activate_sensors() + planted.iff_signal = user.faction // assuring IFF is set + planted.pixel_x += rand(-5, 5) + planted.pixel_y += rand(-5, 5) + qdel(src) + +/obj/item/explosive/grenade/sebb/activate() + ..() + var/beeplen = 6 // Actual length of the sound rounded up to nearest decisecond + var/soundtime = det_time - beeplen + if(det_time < beeplen) // just play sound if detonation shorter than the sound + playsound(loc, 'sound/effects/sebb_explode.ogg', 90, 0, 10) + else + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(playsound), loc, 'sound/effects/sebb_beep.ogg', 60, 0, 10), soundtime) + + + +/obj/item/explosive/grenade/sebb/prime() + var/datum/effect_system/spark_spread/sparka = new + var/turf/sebb_turf = get_turf(src) + var/list/full_range = oview(range, src) // Fill a list of stuff in the range so we won't have to spam oview + new /obj/effect/overlay/temp/sebb(sebb_turf) + + playsound(src.loc, 'sound/effects/sebb_explode.ogg', 90, 0, 10) + + for(var/obj/structure/machinery/defenses/sentry/sentry_stun in full_range) + sentry_stun.sentry_range = 0 // Temporarily "disable" the sentry by killing its range then setting it back. + new /obj/effect/overlay/temp/elec_arc(get_turf(sentry_stun)) // sprites are meh but we need visual indication that the sentry was messed up + addtimer(VARSET_CALLBACK(sentry_stun, sentry_range, initial(sentry_stun.sentry_range)), 5 SECONDS) // assure to set it back + sentry_stun.visible_message(SPAN_DANGER("[src]'s screen flickes violently as it's shocked!")) + sentry_stun.visible_message(SPAN_DANGER("[src] says \"ERROR: Fire control system resetting due to critical voltage flucuation!\"")) + sparka.set_up(1, 1, sentry_stun) + sparka.start() + + for(var/turf/turf in full_range) + if(prob(8)) + var/datum/effect_system/spark_spread/sparkTurf = new //using a different spike system because the spark system doesn't like when you reuse it for differant things + sparkTurf.set_up(1, 1, turf) + sparkTurf.start() + if(prob(10)) + new /obj/effect/overlay/temp/emp_sparks(turf) + + for(var/mob/living/carbon/mob in full_range) // no legacy mob support + + var/mob_dist = get_dist(src, mob) // Distance from mob + + /** + * Damage equation: damage - (mob distance * falloff_dam_reduction_mult) + * Example: A marine is 3 tiles out, the distance (3) is multiplied by falloff_dam_reduction_mult to get falloff. + * The raw damage is minused by falloff to get actual damage + */ + + var/falloff = mob_dist * falloff_dam_reduction_mult + var/damage_applied = damage - falloff // Final damage applied after falloff calc + sparka.set_up(1, 1, mob) + sparka.start() + shake_camera(mob, 1, 1) + if(ishuman(mob)) + var/mob/living/carbon/human/shocked_human = mob + if(isspeciessynth(shocked_human)) // Massive overvoltage to ungrounded robots is pretty bad + shocked_human.Stun(1 + (damage_applied/40)) + damage_applied *= 1.5 + new /obj/effect/overlay/temp/elec_arc(get_turf(shocked_human)) + to_chat(mob, SPAN_HIGHDANGER("All of your systems jam up as your main bus is overvolted by [damage_applied*2] volts.")) + mob.visible_message(SPAN_WARNING("[mob] seizes up from the elctric shock")) + shocked_human.take_overall_armored_damage(damage_applied, ARMOR_ENERGY, BURN, 90) // 90% chance to be on additional limbs + shocked_human.make_dizzy(damage_applied) + mob.apply_stamina_damage(damage_applied*human_stam_dam_factor) // Stamina damage + shocked_human.emote("pain") + else //nonhuman damage + slow + mob.apply_damage(damage_applied, BURN) + if((mob_dist < (range-3))) // 2 tiles around small superslow + mob.Superslow(2) + mob.Slow(damage_applied/11) + + if(mob_dist < 1) // Range based stuff, standing ontop of the equivalent of a canned lighting bolt should mess you up. + mob.Superslow(3) // Note that humans will likely be in stamcrit so it's always worse for them when ontop of it and we can just balancing it on xenos. + mob.eye_blurry = damage_applied/4 + mob.Daze(1) + else if((mob_dist < (range-1)) && (mob.mob_size < MOB_SIZE_XENO_VERY_SMALL)) // Flicker stun humans that are closer to the grenade and larvas too. + mob.apply_effect(1 + (damage_applied/100),WEAKEN) // 1 + damage/40 + mob.eye_blurry = damage_applied/8 + + else + to_chat(mob, SPAN_HIGHDANGER("Your entire body seizes up as a powerful shock courses through it!")) + + + new /obj/effect/overlay/temp/emp_sparks(mob) + mob.make_jittery(damage_applied*2) + empulse(src, 1, 2) // mini EMP + qdel(src) + + +/obj/item/explosive/grenade/sebb/primed + desc = "A G2 Electroshock Grenade, looks like it's quite angry! Oh shit!" + det_time = 7 // 0.7 seconds to blow up. We want them to get caught if they go through. + +/obj/item/explosive/grenade/sebb/primed/Initialize() + . = ..() + src.visible_message(SPAN_HIGHDANGER("[src] pops out of the ground!")) + activate() + +/obj/effect/overlay/temp/sebb + icon = 'icons/effects/sebb.dmi' + icon_state = "sebb_explode" + layer = ABOVE_LIGHTING_PLANE + pixel_x = -175 // We need these offsets to force center the sprite because BYOND is dumb + pixel_y = -175 + appearance_flags = RESET_COLOR + /* //================================================ Nerve Gas Grenades diff --git a/code/game/objects/items/explosives/mine.dm b/code/game/objects/items/explosives/mine.dm index 45065a2de1de..6e7aa2bdccc3 100644 --- a/code/game/objects/items/explosives/mine.dm +++ b/code/game/objects/items/explosives/mine.dm @@ -14,6 +14,7 @@ throw_speed = SPEED_VERY_FAST unacidable = TRUE flags_atom = FPRINT|CONDUCT + antigrief_protection = TRUE allowed_sensors = list(/obj/item/device/assembly/prox_sensor) max_container_volume = 120 reaction_limits = list( "max_ex_power" = 105, "base_ex_falloff" = 60, "max_ex_shards" = 32, @@ -71,7 +72,12 @@ if(active || user.action_busy) return - user.visible_message(SPAN_NOTICE("[user] starts deploying [src]."), \ + if(antigrief_protection && user.faction == FACTION_MARINE && explosive_antigrief_check(src, user)) + to_chat(user, SPAN_WARNING("\The [name]'s safe-area accident inhibitor prevents you from planting!")) + msg_admin_niche("[key_name(user)] attempted to plant \a [name] in [get_area(src)] [ADMIN_JMP(src.loc)]") + return + + user.visible_message(SPAN_NOTICE("[user] starts deploying [src]."), SPAN_NOTICE("You start deploying [src].")) if(!do_after(user, 40, INTERRUPT_NO_NEEDHAND, BUSY_ICON_HOSTILE)) user.visible_message(SPAN_NOTICE("[user] stops deploying [src]."), \ @@ -317,3 +323,19 @@ customizable = TRUE matter = list("metal" = 3750) has_blast_wave_dampener = TRUE + +/obj/item/explosive/mine/sebb + name = "\improper G2 Electroshock grenade" + icon_state = "grenade_sebb_planted" + desc = "A G2 electroshock grenade planted as a landmine." + pixel_y = -5 + anchored = TRUE // this is supposed to be planeted already when spawned + +/obj/item/explosive/mine/sebb/disarm() + . = ..() + new /obj/item/explosive/grenade/sebb(get_turf(src)) + qdel(src) + +/obj/item/explosive/mine/sebb/prime() + new /obj/item/explosive/grenade/sebb/primed(get_turf(src)) + qdel(src) diff --git a/code/game/objects/items/hoverpack.dm b/code/game/objects/items/hoverpack.dm index 02a2d4be779a..65406eb15dc6 100644 --- a/code/game/objects/items/hoverpack.dm +++ b/code/game/objects/items/hoverpack.dm @@ -208,6 +208,7 @@ return TRUE /datum/action/item_action/hover/action_activate() + . = ..() var/mob/living/carbon/human/H = owner if(H.selected_ability == src) to_chat(H, "You will no longer use [name] with \ diff --git a/code/game/objects/items/reagent_containers/reagent_container.dm b/code/game/objects/items/reagent_containers/reagent_container.dm index 5207df4ca7bb..37029ff247d6 100644 --- a/code/game/objects/items/reagent_containers/reagent_container.dm +++ b/code/game/objects/items/reagent_containers/reagent_container.dm @@ -109,5 +109,6 @@ button.overlays += IMG /datum/action/item_action/reagent_container/set_transfer_amount/action_activate() + . = ..() var/obj/item/reagent_container/cont = holder_item cont.set_APTFT() diff --git a/code/game/objects/items/stacks/flags.dm b/code/game/objects/items/stacks/flags.dm index 484d2779f5f8..14833812b06c 100644 --- a/code/game/objects/items/stacks/flags.dm +++ b/code/game/objects/items/stacks/flags.dm @@ -76,3 +76,208 @@ newflag.icon_state = "[newflag.base_state]_open" newflag.visible_message("[user] plants [newflag] firmly in the ground.") src.use(1) + + +/// PLANTABLE FLAG + +/obj/structure/flag/plantable + name = "flag" + desc = "A flag of something. This one looks like you could dismantle it." + icon = 'icons/obj/structures/plantable_flag.dmi' + pixel_x = 9 // All flags need to be offset to the right by 9 to be centered. + layer = ABOVE_XENO_LAYER + health = 150 + unacidable = TRUE + + /// The typepath for the flag item that gets spawned when the flag is taken down. + var/flag_type = /obj/item/flag/plantable + /// Used to limit the spam of the warcry_extra_sound + COOLDOWN_DECLARE(warcry_cooldown_struc) + +/obj/structure/flag/plantable/attack_hand(mob/user) + ..() + disassemble(user, flag_type) + +/// Proc for dismantling the flag into an item that can be picked up. +/obj/structure/flag/plantable/proc/disassemble(mob/user, flag_type) + if(user.action_busy) + return + + user.visible_message(SPAN_NOTICE("[user] starts taking [src] down..."), SPAN_NOTICE("You start taking [src] down...")) + + playsound(loc, 'sound/effects/flag_raising.ogg', 30) + if(!do_after(user, 6 SECONDS, INTERRUPT_ALL, BUSY_ICON_GENERIC) || QDELETED(src)) + return + + playsound(loc, 'sound/effects/flag_raised.ogg', 30) + user.visible_message(SPAN_NOTICE("[user] starts takes [src] down!"), SPAN_NOTICE("You take [src] down!")) + var/obj/item/flag/plantable/flag_item = new flag_type(loc) + user.put_in_hands(flag_item) + COOLDOWN_START(flag_item, warcry_cooldown_item, COOLDOWN_TIMELEFT(src, warcry_cooldown_struc)) + qdel(src) + +/// Proc for when the flag gets forcefully dismantled (due to general damage, explosions, etc.) +/obj/structure/flag/plantable/proc/demolish(flag_type) + playsound(loc, 'sound/effects/flag_raised.ogg', 30) + visible_message(SPAN_WARNING("[src] crumples to the ground!")) + var/obj/item/flag/plantable/flag_item = new flag_type(loc) + COOLDOWN_START(flag_item, warcry_cooldown_item, COOLDOWN_TIMELEFT(src, warcry_cooldown_struc)) + qdel(src) + +// Procs for handling damage. +/obj/structure/flag/plantable/update_health(damage) + if(damage) + health -= damage + if(health <= 0) + demolish(flag_type) + +/obj/structure/flag/plantable/ex_act(severity) + if(health <= 0) + return + update_health(severity) + +/obj/structure/flag/plantable/attack_alien(mob/living/carbon/xenomorph/xeno) + if(xeno.a_intent == INTENT_HARM) + if(unslashable) + return + xeno.animation_attack_on(src) + playsound(loc, 'sound/effects/metalhit.ogg', 25, 1) + xeno.visible_message(SPAN_DANGER("[xeno] slashes [src]!"), SPAN_DANGER("We slash [src]!"), null, 5, CHAT_TYPE_XENO_COMBAT) + update_health(rand(xeno.melee_damage_lower, xeno.melee_damage_upper)) + return XENO_ATTACK_ACTION + else + to_chat(xeno, SPAN_WARNING("We stare at [src] cluelessly.")) + return XENO_NONCOMBAT_ACTION + +/obj/structure/flag/plantable/bullet_act(obj/projectile/bullet) + bullet_ping(bullet) + visible_message(SPAN_DANGER("[src] is hit by [bullet]!"), null, 4, CHAT_TYPE_TAKING_HIT) + update_health(bullet.damage) + return TRUE + +/obj/structure/flag/plantable/attackby(obj/item/weapon, mob/living/user) + if(!indestructible) + visible_message(SPAN_DANGER("[src] has been hit by [user] with [weapon]!"), null, 5, CHAT_TYPE_MELEE_HIT) + user.animation_attack_on(src) + playsound(loc, 'sound/effects/metalhit.ogg', 25, 1) + update_health(weapon.force * weapon.demolition_mod) + +/obj/item/flag/plantable + name = "plantable flag" + desc = "A flag of something. This one looks ready to be planted into the ground." + w_class = SIZE_LARGE + throw_range = 2 + icon = 'icons/obj/structures/plantable_flag.dmi' + inhand_x_dimension = 64 + inhand_y_dimension = 64 + force = 15 + throwforce = 5 + hitsound = "swing_hit" + unacidable = TRUE + indestructible = TRUE + item_icons = list( + WEAR_L_HAND = 'icons/mob/humans/onmob/items_lefthand_64.dmi', + WEAR_R_HAND = 'icons/mob/humans/onmob/items_righthand_64.dmi' + ) + + /// The typepath of the flag structure that gets spawned when the flag is planted. + var/flag_type = /obj/structure/flag/plantable + /// Used to check if nearby mobs belong to a faction when calculating for the stronger warcry. + var/faction + /// Does the flag play a unique warcry when planted? (Only while on harm intent.) + var/play_warcry = FALSE + /// The warcry's sound path. + var/warcry_sound + /// When there are more than 14 allies nearby, play this stronger warcry. + var/warcry_extra_sound + /// How many nearby allies do we need for the stronger warcry to be played? + var/allies_required = 14 + /// Used to limit the spam of the warcry_extra_sound + COOLDOWN_DECLARE(warcry_cooldown_item) + +/obj/item/flag/plantable/get_examine_text(mob/user) + . = ..() + if(play_warcry && user.faction == faction) + . += SPAN_NOTICE("Planting the flag while in HARM intent will cause you to bellow out a rallying warcry!") + +/// Proc for turning the flag item into a structure. +/obj/item/flag/plantable/proc/plant_flag(mob/living/user, play_warcry = FALSE, warcry_sound, warcry_extra_sound, faction) + if(user.action_busy) + return + + if(SSinterior.in_interior(user)) + to_chat(usr, SPAN_WARNING("There's no way to plant [src] in here!")) + return + + var/turf/turf_to_plant = get_step(user, user.dir) + if(istype(turf_to_plant, /turf/open)) + var/turf/open/floor = turf_to_plant + if(!floor.allow_construction || istype(floor, /turf/open/space)) + to_chat(user, SPAN_WARNING("You cannot deploy [src] here, find a more secure surface!")) + return + else + to_chat(user, SPAN_WARNING("[turf_to_plant] is blocking you from deploying [src]!")) + return + + for(var/obj/object in turf_to_plant) + if(object.density) + to_chat(usr, SPAN_WARNING("You need a clear, open area to plant [src], something is blocking the way in front of you!")) + return + + user.visible_message(SPAN_NOTICE("[user] starts planting [src] into the ground..."), SPAN_NOTICE("You start planting [src] into the ground...")) + playsound(user, 'sound/effects/flag_raising.ogg', 30) + if(!do_after(user, 6 SECONDS, INTERRUPT_ALL, BUSY_ICON_GENERIC)) + return + + user.visible_message(SPAN_NOTICE("[user] plants [src] into the ground!"), SPAN_NOTICE("You plant [src] into the ground!")) + var/obj/structure/flag/plantable/planted_flag = new flag_type(turf_to_plant) + + // If there are more than 14 allies nearby, play a stronger rallying cry. + // Otherwise, play the default warcry sound if there is one. If not, play a generic flag raising sfx. + if(play_warcry && user.faction == faction && user.a_intent == INTENT_HARM) + var/allies_nearby = 0 + if(COOLDOWN_FINISHED(src, warcry_cooldown_item)) + for(var/mob/living/carbon/human in orange(planted_flag, 7)) + if(human.is_dead() || human.faction != faction) + continue + allies_nearby++ + + user.show_speech_bubble("warcry") + if(allies_nearby >= allies_required) + playsound(user, warcry_extra_sound, 40) + // Start a cooldown on the flag structure. This way we can keep track of the cooldown when the flag is hoisted and taken down. + COOLDOWN_START(planted_flag, warcry_cooldown_struc, 90 SECONDS) + user.manual_emote("shouts an invigorating rallying cry!") + else + playsound(user, warcry_sound, 30) + user.manual_emote("shouts an inspiring cry!") + // Ditto. If the cooldown isn't finished we have to transfer the leftover time to the structure. + COOLDOWN_START(planted_flag, warcry_cooldown_struc, COOLDOWN_TIMELEFT(src, warcry_cooldown_item)) + else + playsound(loc, 'sound/effects/flag_raised.ogg', 30) + + qdel(src) + +/obj/item/flag/plantable/attack_self(mob/user) + ..() + plant_flag(user, play_warcry, warcry_sound, warcry_extra_sound, faction) + +// UNITED AMERICAS FLAG // +////////////////////////// + +/obj/item/flag/plantable/ua + name = "\improper United Americas flag" + desc = "The flag of the United Americas. This one looks ready to be planted into the ground." + icon = 'icons/obj/structures/plantable_flag.dmi' + icon_state = "flag_ua" + flag_type = /obj/structure/flag/plantable/ua + faction = FACTION_MARINE + play_warcry = TRUE + warcry_sound = 'sound/effects/flag_warcry_ua.ogg' + warcry_extra_sound = 'sound/effects/flag_warcry_ua_extra.ogg' + +/obj/structure/flag/plantable/ua + name = "\improper United Americas flag" + desc = "The flag of the United Americas. Semper fi." + icon_state = "flag_ua_planted" + flag_type = /obj/item/flag/plantable/ua diff --git a/code/game/objects/items/storage/backpack.dm b/code/game/objects/items/storage/backpack.dm index baa91db19396..06636d2c3f76 100644 --- a/code/game/objects/items/storage/backpack.dm +++ b/code/game/objects/items/storage/backpack.dm @@ -268,6 +268,7 @@ return TRUE /datum/action/item_action/specialist/santabag/action_activate() + . = ..() var/obj/item/storage/backpack/santabag/santa_bag = holder_item santa_bag.refill_santa_bag(owner) update_button_icon() @@ -537,6 +538,7 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r button.overlays += IMG /datum/action/item_action/rto_pack/use_phone/action_activate() + . = ..() for(var/obj/item/storage/backpack/marine/satchel/rto/radio_backpack in owner) radio_backpack.use_phone(owner) return @@ -870,6 +872,7 @@ GLOBAL_LIST_EMPTY_TYPED(radio_packs, /obj/item/storage/backpack/marine/satchel/r return TRUE /datum/action/item_action/specialist/toggle_cloak/action_activate() + . = ..() var/obj/item/storage/backpack/marine/satchel/scout_cloak/SC = holder_item SC.camouflage() diff --git a/code/game/objects/items/storage/large_holster.dm b/code/game/objects/items/storage/large_holster.dm index 02983e1552ed..d8e1ee51d0d8 100644 --- a/code/game/objects/items/storage/large_holster.dm +++ b/code/game/objects/items/storage/large_holster.dm @@ -375,6 +375,7 @@ return TRUE /datum/action/item_action/specialist/toggle_fuel/action_activate() + . = ..() var/obj/item/storage/large_holster/fuelpack/FP = holder_item if (!istype(FP)) return diff --git a/code/game/objects/items/tanks/jetpack.dm b/code/game/objects/items/tanks/jetpack.dm deleted file mode 100644 index 3a5afef6cf1e..000000000000 --- a/code/game/objects/items/tanks/jetpack.dm +++ /dev/null @@ -1,85 +0,0 @@ -//This file was auto-corrected by findeclaration.exe on 25.5.2012 20:42:32 - -/obj/item/tank/jetpack - name = "Jetpack (Empty)" - desc = "A tank of compressed gas for use as propulsion in zero-gravity areas. Use with caution." - icon_state = "jetpack" - w_class = SIZE_LARGE - item_state = "jetpack" - distribute_pressure = ONE_ATMOSPHERE*O2STANDARD - var/datum/effect_system/ion_trail_follow/ion_trail - var/on = 0 - var/stabilization_on = 0 - var/volume_rate = 500 //Needed for borg jetpack transfer - actions_types = list(/datum/action/item_action) - -/obj/item/tank/jetpack/Initialize() - . = ..() - src.ion_trail = new /datum/effect_system/ion_trail_follow() - src.ion_trail.set_up(src) - -/obj/item/tank/jetpack/Destroy() - QDEL_NULL(ion_trail) - return ..() - - -/obj/item/tank/jetpack/verb/toggle_rockets() - set name = "Toggle Jetpack Stabilization" - set category = "Object" - set src in usr - src.stabilization_on = !( src.stabilization_on ) - to_chat(usr, "You toggle the stabilization [stabilization_on? "on":"off"].") - -/obj/item/tank/jetpack/verb/toggle() - set name = "Toggle Jetpack" - set category = "Object" - set src in usr - on = !on - if(on) - icon_state = "[icon_state]-on" - ion_trail.start() - else - icon_state = initial(icon_state) - ion_trail.stop() - - if (ismob(usr)) - var/mob/M = usr - M.update_inv_back() - - for(var/X in actions) - var/datum/action/A = X - A.update_button_icon() - -/obj/item/tank/jetpack/proc/allow_thrust(num, mob/living/user) - if(!(src.on)) - return 0 - - if(pressure > 5) - return 1 - else - ion_trail.stop() - return 0 - - -/obj/item/tank/jetpack/ui_action_click() - toggle() - - -/obj/item/tank/jetpack/void - name = "Void Jetpack (Oxygen)" - desc = "It works well in a void." - icon_state = "jetpack-void" - item_state = "jetpack-void" - -/obj/item/tank/jetpack/oxygen - name = "Jetpack (Oxygen)" - desc = "A tank of compressed oxygen for use as propulsion in zero-gravity areas. Use with caution." - icon_state = "jetpack" - item_state = "jetpack" - -/obj/item/tank/jetpack/carbondioxide - name = "Jetpack (Carbon Dioxide)" - desc = "A tank of compressed carbon dioxide for use as propulsion in zero-gravity areas. Painted black to indicate that it should not be used as a source for internals." - distribute_pressure = 0 - icon_state = "jetpack-black" - item_state = "jetpack-black" diff --git a/code/game/objects/items/tools/kitchen_tools.dm b/code/game/objects/items/tools/kitchen_tools.dm index d6473b156a67..a4c4925fba2c 100644 --- a/code/game/objects/items/tools/kitchen_tools.dm +++ b/code/game/objects/items/tools/kitchen_tools.dm @@ -48,7 +48,7 @@ var/fullness = M.nutrition + (M.reagents.get_reagent_amount("nutriment") * 25) if(fullness > NUTRITION_HIGH) to_chat(user, SPAN_WARNING("[user == M ? "You" : "They"] don't feel like eating more right now.")) - return ..() + return reagents.set_source_mob(user) reagents.trans_to_ingest(M, reagents.total_volume) if(M == user) diff --git a/code/game/objects/objs.dm b/code/game/objects/objs.dm index f93f2dab0984..2dc064aa86d4 100644 --- a/code/game/objects/objs.dm +++ b/code/game/objects/objs.dm @@ -416,7 +416,7 @@ var/offset_x = worn_x_dimension var/offset_y = worn_y_dimension - if(inhands) + if(inhands == 1 || inhands == 0) offset_x = inhand_x_dimension offset_y = inhand_y_dimension diff --git a/code/game/objects/structures/crates_lockers/closets/malfunction.dm b/code/game/objects/structures/crates_lockers/closets/malfunction.dm deleted file mode 100644 index 704e2c79157a..000000000000 --- a/code/game/objects/structures/crates_lockers/closets/malfunction.dm +++ /dev/null @@ -1,16 +0,0 @@ - -/obj/structure/closet/malf/suits - desc = "It's a storage unit for operational gear." - icon_state = "syndicate" - icon_closed = "syndicate" - icon_opened = "syndicate_open" - -/obj/structure/closet/malf/suits/Initialize() - . = ..() - new /obj/item/tank/jetpack/void(src) - new /obj/item/clothing/mask/breath(src) - new /obj/item/clothing/head/helmet/space/uscm(src) - new /obj/item/clothing/suit/space/uscm(src) - new /obj/item/tool/crowbar(src) - new /obj/item/cell(src) - new /obj/item/device/multitool(src) diff --git a/code/game/objects/structures/crates_lockers/crates.dm b/code/game/objects/structures/crates_lockers/crates.dm index d891119a8404..8a10cd4d93ea 100644 --- a/code/game/objects/structures/crates_lockers/crates.dm +++ b/code/game/objects/structures/crates_lockers/crates.dm @@ -277,13 +277,6 @@ name = "RCD crate" desc = "A crate for the storage of the RCD." -/obj/structure/closet/crate/rcd/Initialize() - . = ..() - new /obj/item/ammo_rcd(src) - new /obj/item/ammo_rcd(src) - new /obj/item/ammo_rcd(src) - new /obj/item/device/rcd(src) - /obj/structure/closet/crate/freezer/rations //Fpr use in the escape shuttle desc = "A crate of emergency rations." name = "Emergency Rations" diff --git a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm index 986ae99739aa..f71882374518 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/wheelchair.dm @@ -36,12 +36,12 @@ move_delay += 4 //harder to move a wheelchair with a single hand working_hands-- else if((left_hand.status & LIMB_BROKEN) && !(left_hand.status & LIMB_SPLINTED)) - move_delay++ + move_delay ++ if(!right_hand || (right_hand.status & LIMB_DESTROYED)) move_delay += 4 working_hands-- else if((right_hand.status & LIMB_BROKEN) && !(right_hand.status & LIMB_SPLINTED)) - move_delay += 2 + move_delay++ if(!working_hands) return // No hands to drive your chair? Tough luck! if(driver.pulling && driver.pulling.drag_delay && driver.get_pull_miltiplier()) //Dragging stuff can slow you down a bit. diff --git a/code/game/objects/structures/stool_bed_chair_nest/xeno_nest.dm b/code/game/objects/structures/stool_bed_chair_nest/xeno_nest.dm index c3f0b97e509a..68b899f78f15 100644 --- a/code/game/objects/structures/stool_bed_chair_nest/xeno_nest.dm +++ b/code/game/objects/structures/stool_bed_chair_nest/xeno_nest.dm @@ -245,6 +245,7 @@ do_buckle(mob, user) ADD_TRAIT(mob, TRAIT_NESTED, TRAIT_SOURCE_BUCKLE) + ADD_TRAIT(mob, TRAIT_NO_STRAY, TRAIT_SOURCE_BUCKLE) SEND_SIGNAL(mob, COMSIG_MOB_NESTED, user) if(!human) @@ -275,6 +276,7 @@ buckled_mob.pixel_y = 0 buckled_mob.old_y = 0 REMOVE_TRAIT(buckled_mob, TRAIT_NESTED, TRAIT_SOURCE_BUCKLE) + REMOVE_TRAIT(buckled_mob, TRAIT_NO_STRAY, TRAIT_SOURCE_BUCKLE) var/mob/living/carbon/human/buckled_human = buckled_mob var/mob/dead/observer/G = ghost_of_buckled_mob diff --git a/code/game/objects/structures/vulture_spotter.dm b/code/game/objects/structures/vulture_spotter.dm index dc341edf0446..dcbfd88c9c08 100644 --- a/code/game/objects/structures/vulture_spotter.dm +++ b/code/game/objects/structures/vulture_spotter.dm @@ -313,6 +313,7 @@ tripod = WEAKREF(spotting_tripod) /datum/action/vulture_tripod_unscope/action_activate() + . = ..() if(!tripod) return diff --git a/code/game/turfs/transit.dm b/code/game/turfs/transit.dm index 00175ac5e365..5b4645805d3b 100644 --- a/code/game/turfs/transit.dm +++ b/code/game/turfs/transit.dm @@ -138,6 +138,12 @@ clear_active_explosives() ADD_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_SOURCE_DROPSHIP_INTERACTION) ADD_TRAIT(src, TRAIT_UNDENSE, TRAIT_SOURCE_DROPSHIP_INTERACTION) + ADD_TRAIT(src, TRAIT_NO_STRAY, TRAIT_SOURCE_DROPSHIP_INTERACTION) + RegisterSignal(src, COMSIG_MOVABLE_FORCEMOVE_PRE_CROSSED, PROC_REF(cancel_cross)) + RegisterSignal(src, list( + COMSIG_LIVING_FLAMER_FLAMED, + COMSIG_LIVING_PREIGNITION + ), PROC_REF(cancel_fire)) var/image/cables = image('icons/obj/structures/droppod_32x64.dmi', src, "chute_cables_static") overlays += cables var/image/chute = image('icons/obj/structures/droppod_64x64.dmi', src, "chute_static") @@ -163,8 +169,18 @@ return REMOVE_TRAIT(src, TRAIT_IMMOBILIZED, TRAIT_SOURCE_DROPSHIP_INTERACTION) REMOVE_TRAIT(src, TRAIT_UNDENSE, TRAIT_SOURCE_DROPSHIP_INTERACTION) + REMOVE_TRAIT(src, TRAIT_NO_STRAY, TRAIT_SOURCE_DROPSHIP_INTERACTION) + UnregisterSignal(src, list( + COMSIG_MOVABLE_FORCEMOVE_PRE_CROSSED, + COMSIG_LIVING_FLAMER_FLAMED, + COMSIG_LIVING_PREIGNITION + )) overlays -= cables overlays -= chute + for(var/atom/movable/atom in loc) + if(atom == src) + continue + atom.Cross(src) /atom/movable/proc/clear_active_explosives() for(var/obj/item/explosive/explosive in contents) @@ -232,6 +248,13 @@ death(last_damage_data) status_flags |= PERMANENTLY_DEAD +/atom/movable/proc/cancel_cross() + SIGNAL_HANDLER + return COMPONENT_IGNORE_CROSS + +/atom/movable/proc/cancel_fire() + SIGNAL_HANDLER + return COMPONENT_NO_BURN /turf/open/space/transit/dropship/alamo shuttle_tag = DROPSHIP_ALAMO diff --git a/code/modules/asset_cache/asset_list_items.dm b/code/modules/asset_cache/asset_list_items.dm index 0b27cf268a12..e826b0b64767 100644 --- a/code/modules/asset_cache/asset_list_items.dm +++ b/code/modules/asset_cache/asset_list_items.dm @@ -367,6 +367,10 @@ retrieved_icon.Scale(128, 128) Insert("intents", retrieved_icon) + retrieved_icon = icon('icons/mob/xenos/predalien.dmi', "Normal Predalien Walking") + retrieved_icon.Scale(128, 128) + Insert("predalien", retrieved_icon) + return ..() diff --git a/code/modules/clothing/glasses/hud.dm b/code/modules/clothing/glasses/hud.dm index 7406e6baa754..6e086e651a10 100644 --- a/code/modules/clothing/glasses/hud.dm +++ b/code/modules/clothing/glasses/hud.dm @@ -40,6 +40,7 @@ return TRUE /datum/action/item_action/view_publications/action_activate() + . = ..() var/obj/item/clothing/glasses/hud/health/hud = holder_item hud.tgui_interact(owner) diff --git a/code/modules/clothing/glasses/night.dm b/code/modules/clothing/glasses/night.dm index b2b6f8406dcc..984a906eabed 100644 --- a/code/modules/clothing/glasses/night.dm +++ b/code/modules/clothing/glasses/night.dm @@ -184,6 +184,7 @@ button.overlays += image('icons/mob/hud/actions.dmi', button, action_icon_state) /datum/action/item_action/m56_goggles/far_sight/action_activate() + . = ..() if(target) var/obj/item/clothing/glasses/night/m56_goggles/G = target G.set_far_sight(owner, !G.far_sight) diff --git a/code/modules/clothing/head/helmet.dm b/code/modules/clothing/head/helmet.dm index e52032d0cba6..463a4b16f7ec 100644 --- a/code/modules/clothing/head/helmet.dm +++ b/code/modules/clothing/head/helmet.dm @@ -354,7 +354,7 @@ GLOBAL_LIST_INIT(allowed_helmet_items, list( armor_melee = CLOTHING_ARMOR_MEDIUM armor_bullet = CLOTHING_ARMOR_MEDIUM armor_laser = CLOTHING_ARMOR_MEDIUMLOW - armor_energy = CLOTHING_ARMOR_NONE + armor_energy = CLOTHING_ARMOR_LOW armor_bomb = CLOTHING_ARMOR_LOW armor_bio = CLOTHING_ARMOR_MEDIUM armor_rad = CLOTHING_ARMOR_LOW diff --git a/code/modules/clothing/suits/marine_armor/_marine_armor.dm b/code/modules/clothing/suits/marine_armor/_marine_armor.dm index e6cf78611a7f..8a8d5934b506 100644 --- a/code/modules/clothing/suits/marine_armor/_marine_armor.dm +++ b/code/modules/clothing/suits/marine_armor/_marine_armor.dm @@ -50,7 +50,7 @@ armor_melee = CLOTHING_ARMOR_MEDIUM armor_bullet = CLOTHING_ARMOR_MEDIUM armor_laser = CLOTHING_ARMOR_MEDIUMLOW - armor_energy = CLOTHING_ARMOR_NONE + armor_energy = CLOTHING_ARMOR_LOW armor_bomb = CLOTHING_ARMOR_MEDIUMLOW armor_bio = CLOTHING_ARMOR_MEDIUM armor_rad = CLOTHING_ARMOR_MEDIUMLOW @@ -361,6 +361,7 @@ armor_bomb = CLOTHING_ARMOR_MEDIUM armor_bio = CLOTHING_ARMOR_MEDIUMHIGH armor_internaldamage = CLOTHING_ARMOR_MEDIUMHIGH + armor_energy = CLOTHING_ARMOR_MEDIUM specialty = "B12 pattern marine" light_range = 5 @@ -547,6 +548,7 @@ armor_bomb = CLOTHING_ARMOR_HIGHPLUS armor_bio = CLOTHING_ARMOR_MEDIUMHIGH armor_rad = CLOTHING_ARMOR_MEDIUM + armor_energy = CLOTHING_ARMOR_MEDIUMLOW armor_internaldamage = CLOTHING_ARMOR_MEDIUMHIGH storage_slots = 2 slowdown = SLOWDOWN_ARMOR_LOWHEAVY @@ -591,6 +593,7 @@ armor_bio = CLOTHING_ARMOR_MEDIUMLOW armor_rad = CLOTHING_ARMOR_MEDIUMHIGH armor_internaldamage = CLOTHING_ARMOR_MEDIUMHIGH + armor_energy = CLOTHING_ARMOR_MEDIUM storage_slots = 2 flags_inventory = BLOCKSHARPOBJ|BLOCK_KNOCKDOWN flags_armor_protection = BODY_FLAG_CHEST|BODY_FLAG_GROIN|BODY_FLAG_ARMS|BODY_FLAG_LEGS|BODY_FLAG_FEET @@ -632,6 +635,7 @@ armor_bullet = CLOTHING_ARMOR_MEDIUMHIGH armor_bomb = CLOTHING_ARMOR_VERYHIGH armor_bio = CLOTHING_ARMOR_MEDIUMLOW + armor_energy = CLOTHING_ARMOR_MEDIUM armor_internaldamage = CLOTHING_ARMOR_MEDIUMHIGH flags_inventory = BLOCKSHARPOBJ|BLOCK_KNOCKDOWN flags_item = MOB_LOCK_ON_EQUIP|NO_CRYO_STORE diff --git a/code/modules/clothing/suits/marine_armor/ghillie.dm b/code/modules/clothing/suits/marine_armor/ghillie.dm index 1f1b71227655..44729ac16b2f 100644 --- a/code/modules/clothing/suits/marine_armor/ghillie.dm +++ b/code/modules/clothing/suits/marine_armor/ghillie.dm @@ -150,6 +150,7 @@ return TRUE /datum/action/item_action/specialist/prepare_position/action_activate() + . = ..() var/obj/item/clothing/suit/storage/marine/ghillie/GS = holder_item GS.camouflage() diff --git a/code/modules/clothing/suits/marine_armor/intel.dm b/code/modules/clothing/suits/marine_armor/intel.dm index b3f0f93e004d..12aa824648d1 100644 --- a/code/modules/clothing/suits/marine_armor/intel.dm +++ b/code/modules/clothing/suits/marine_armor/intel.dm @@ -18,6 +18,7 @@ update_icon() /datum/action/item_action/intel/action_activate() + . = ..() if(!ishuman(owner)) return diff --git a/code/modules/clothing/suits/marine_armor/spec_fire.dm b/code/modules/clothing/suits/marine_armor/spec_fire.dm index 52343a204f68..c3f2863b3545 100644 --- a/code/modules/clothing/suits/marine_armor/spec_fire.dm +++ b/code/modules/clothing/suits/marine_armor/spec_fire.dm @@ -145,6 +145,7 @@ return TRUE /datum/action/item_action/specialist/fire_shield/action_activate() + . = ..() var/obj/item/clothing/suit/storage/marine/M35/armor = holder_item if (!istype(armor)) return diff --git a/code/modules/clothing/under/marine_uniform.dm b/code/modules/clothing/under/marine_uniform.dm index c7353840d439..74cb5ea552ee 100644 --- a/code/modules/clothing/under/marine_uniform.dm +++ b/code/modules/clothing/under/marine_uniform.dm @@ -1210,6 +1210,7 @@ button.overlays += button_overlay /datum/action/item_action/specialist/toggle_cbrn_hood/action_activate() + . = ..() var/obj/item/clothing/under/marine/cbrn/armor = holder_item if(!istype(armor)) return diff --git a/code/modules/cm_aliens/structures/fruit.dm b/code/modules/cm_aliens/structures/fruit.dm index f555cac64b8c..b2a0fd27d65b 100644 --- a/code/modules/cm_aliens/structures/fruit.dm +++ b/code/modules/cm_aliens/structures/fruit.dm @@ -185,7 +185,7 @@ bound_xeno.current_fruits.Remove(src) var/number_of_fruit = length(bound_xeno.current_fruits) - var/datum/action/xeno_action/onclick/plant_resin_fruit/plant_action = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/plant_resin_fruit) + var/datum/action/xeno_action/onclick/plant_resin_fruit/plant_action = get_action(bound_xeno, /datum/action/xeno_action/onclick/plant_resin_fruit) plant_action.button.set_maptext(SMALL_FONTS_COLOR(7, number_of_fruit, "#e69d00"), 19, 2) plant_action.update_button_icon() @@ -377,7 +377,7 @@ /obj/item/reagent_container/food/snacks/resin_fruit/proc/delete_fruit() if(bound_xeno) bound_xeno.current_fruits.Remove(src) - var/datum/action/xeno_action/onclick/plant_resin_fruit/prf = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/plant_resin_fruit) + var/datum/action/xeno_action/onclick/plant_resin_fruit/prf = get_action(bound_xeno, /datum/action/xeno_action/onclick/plant_resin_fruit) var/number_of_fruit = length(bound_xeno.current_fruits) prf.button.set_maptext(SMALL_FONTS_COLOR(7, number_of_fruit, "#e69d00"), 19, 2) prf.update_button_icon() diff --git a/code/modules/cm_aliens/structures/special/egg_morpher.dm b/code/modules/cm_aliens/structures/special/egg_morpher.dm index c4fb5c0a900c..ac501bb5c970 100644 --- a/code/modules/cm_aliens/structures/special/egg_morpher.dm +++ b/code/modules/cm_aliens/structures/special/egg_morpher.dm @@ -14,14 +14,14 @@ var/huggers_to_grow_max = 12 var/huggers_reserved = 0 var/mob/captured_mob - var/datum/shape/rectangle/range_bounds + var/datum/shape/range_bounds appearance_flags = KEEP_TOGETHER layer = FACEHUGGER_LAYER /obj/effect/alien/resin/special/eggmorph/Initialize(mapload, hive_ref) . = ..() - range_bounds = RECT(x, y, EGGMORPG_RANGE, EGGMORPG_RANGE) + range_bounds = SQUARE(x, y, EGGMORPG_RANGE) /obj/effect/alien/resin/special/eggmorph/Destroy() if (stored_huggers && linked_hive) @@ -158,7 +158,7 @@ /obj/effect/alien/resin/special/eggmorph/proc/check_facehugger_target() if(!range_bounds) - range_bounds = RECT(x, y, EGGMORPG_RANGE, EGGMORPG_RANGE) + range_bounds = SQUARE(x, y, EGGMORPG_RANGE) var/list/targets = SSquadtree.players_in_range(range_bounds, z, QTREE_SCAN_MOBS | QTREE_EXCLUDE_OBSERVER) if(isnull(targets) || !length(targets)) diff --git a/code/modules/cm_marines/equipment/kit_boxes.dm b/code/modules/cm_marines/equipment/kit_boxes.dm index 5ba670d89bc1..951cd30f84ff 100644 --- a/code/modules/cm_marines/equipment/kit_boxes.dm +++ b/code/modules/cm_marines/equipment/kit_boxes.dm @@ -248,12 +248,9 @@ return TRUE /obj/item/spec_kit/proc/select_and_spawn(mob/living/carbon/human/user) - var/selection = tgui_input_list(user, "Pick your specialist equipment type.", "Specialist Kit Selection", GLOB.available_specialist_kit_boxes) + var/selection = tgui_input_list(user, "Pick your specialist equipment type.", "Specialist Kit Selection", GLOB.available_specialist_kit_boxes, 10 SECONDS) if(!selection || QDELETED(src)) return FALSE - if(!skillcheckexplicit(user, SKILL_SPEC_WEAPONS, SKILL_SPEC_TRAINED) && !skillcheckexplicit(user, SKILL_SPEC_WEAPONS, SKILL_SPEC_ALL)) - to_chat(user, SPAN_WARNING("You already unwrapped your [name], give this one to someone else!")) - return if(!GLOB.available_specialist_kit_boxes[selection] || GLOB.available_specialist_kit_boxes[selection] <= 0) to_chat(user, SPAN_WARNING("No more kits of this type may be chosen!")) return FALSE @@ -299,6 +296,7 @@ user.put_in_hands(spec_box) card.set_assignment((user.assigned_squad && squad_assignment_update ? (user.assigned_squad.name + " ") : "") + card.assignment + " ([specialist_assignment])") GLOB.data_core.manifest_modify(user.real_name, WEAKREF(user), card.assignment) + GLOB.available_specialist_kit_boxes[selection]-- return TRUE return FALSE diff --git a/code/modules/cm_marines/equipment/mortar/mortar_shells.dm b/code/modules/cm_marines/equipment/mortar/mortar_shells.dm index dae0910cc9b4..1cb93c6a809e 100644 --- a/code/modules/cm_marines/equipment/mortar/mortar_shells.dm +++ b/code/modules/cm_marines/equipment/mortar/mortar_shells.dm @@ -167,23 +167,43 @@ return ..() /obj/item/mortar_shell/flamer_fire_act(dam, datum/cause_data/flame_cause_data) + addtimer(VARSET_CALLBACK(src, burning, FALSE), 5 SECONDS, TIMER_UNIQUE|TIMER_OVERRIDE|TIMER_DELETE_ME) + if(burning) return burning = TRUE cause_data = create_cause_data("Burning Mortar Shell", flame_cause_data.resolve_mob(), src) - handle_fire() + handle_fire(cause_data) -/obj/item/mortar_shell/proc/handle_fire() - visible_message(SPAN_WARNING("[src] catches on fire and starts cooking off! It's gonna blow!")) - anchored = TRUE // don't want other explosions launching it elsewhere +/obj/item/mortar_shell/proc/can_explode() + return TRUE - var/datum/effect_system/spark_spread/sparks = new() - sparks.set_up(n = 10, loca = loc) - sparks.start() - new /obj/effect/warning/explosive(loc, 5 SECONDS) +/obj/item/mortar_shell/custom/can_explode() + for(var/obj/item/reagent_container/glass/container in warhead?.containers) + for(var/datum/reagent/reagent in container?.reagents?.reagent_list) + if(reagent.explosive) + return TRUE - addtimer(CALLBACK(src, PROC_REF(detonate), loc), 5 SECONDS) - addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), (src)), 5.5 SECONDS) + return FALSE + +/obj/item/mortar_shell/flare/can_explode() + return FALSE + +/obj/item/mortar_shell/proc/handle_fire(cause_data) + if(can_explode()) + visible_message(SPAN_WARNING("[src] catches on fire and starts cooking off! It's gonna blow!")) + anchored = TRUE // don't want other explosions launching it elsewhere + var/datum/effect_system/spark_spread/sparks = new() + sparks.set_up(n = 10, loca = loc) + sparks.start() + new /obj/effect/warning/explosive(loc, 5 SECONDS) + + addtimer(CALLBACK(src, PROC_REF(explode), cause_data), 5 SECONDS) + addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(qdel), (src)), 5.5 SECONDS) + + +/obj/item/mortar_shell/proc/explode(flame_cause_data) + cell_explosion(src, 100, 25, EXPLOSION_FALLOFF_SHAPE_LINEAR, null, flame_cause_data) /obj/structure/closet/crate/secure/mortar_ammo name = "\improper M402 mortar ammo crate" diff --git a/code/modules/cm_preds/yaut_actions.dm b/code/modules/cm_preds/yaut_actions.dm index f55f58e0a557..0d260363ab15 100644 --- a/code/modules/cm_preds/yaut_actions.dm +++ b/code/modules/cm_preds/yaut_actions.dm @@ -49,6 +49,7 @@ return TRUE /datum/action/predator_action/action_activate() + . = ..() if(!can_use_action()) return FALSE @@ -248,6 +249,7 @@ action_icon_state = "looc_toggle" /datum/action/yautja_emote_panel/action_activate() + . = ..() var/mob/living/carbon/human/human_owner = owner var/datum/species/yautja/yautja_species = human_owner.species yautja_species.open_emote_panel() diff --git a/code/modules/cm_preds/yaut_bracers.dm b/code/modules/cm_preds/yaut_bracers.dm index 5577691d64c2..77efbb7ad4ef 100644 --- a/code/modules/cm_preds/yaut_bracers.dm +++ b/code/modules/cm_preds/yaut_bracers.dm @@ -556,7 +556,7 @@ set src in usr . = cloaker_internal(usr, FALSE) -/obj/item/clothing/gloves/yautja/hunter/proc/cloaker_internal(mob/caller, forced = FALSE) +/obj/item/clothing/gloves/yautja/hunter/proc/cloaker_internal(mob/caller, forced = FALSE, silent = FALSE, instant = FALSE) . = check_random_function(caller, forced) if(.) return @@ -600,15 +600,21 @@ M.see_invisible = SEE_INVISIBLE_LEVEL_ONE log_game("[key_name_admin(usr)] has enabled their cloaking device.") - M.visible_message(SPAN_WARNING("[M] vanishes into thin air!"), SPAN_NOTICE("You are now invisible to normal detection.")) - playsound(M.loc,'sound/effects/pred_cloakon.ogg', 15, 1) - animate(M, alpha = new_alpha, time = 1.5 SECONDS, easing = SINE_EASING|EASE_OUT) + if(!silent) + M.visible_message(SPAN_WARNING("[M] vanishes into thin air!"), SPAN_NOTICE("You are now invisible to normal detection.")) + playsound(M.loc,'sound/effects/pred_cloakon.ogg', 15, 1) + + if(!instant) + animate(M, alpha = new_alpha, time = 1.5 SECONDS, easing = SINE_EASING|EASE_OUT) + else + M.alpha = new_alpha var/datum/mob_hud/security/advanced/SA = GLOB.huds[MOB_HUD_SECURITY_ADVANCED] SA.remove_from_hud(M) var/datum/mob_hud/xeno_infection/XI = GLOB.huds[MOB_HUD_XENO_INFECTION] XI.remove_from_hud(M) - anim(M.loc,M,'icons/mob/mob.dmi',,"cloak",,M.dir) + if(!instant) + anim(M.loc,M,'icons/mob/mob.dmi',,"cloak",,M.dir) var/datum/action/predator_action/bracer/cloak/cloak_action for(cloak_action as anything in M.actions) @@ -634,6 +640,8 @@ if(!user) return + SEND_SIGNAL(src, COMSIG_PRED_BRACER_DECLOAKED) + UnregisterSignal(user, COMSIG_HUMAN_EXTINGUISH) UnregisterSignal(user, COMSIG_HUMAN_PRE_BULLET_ACT) UnregisterSignal(user, COMSIG_MOB_EFFECT_CLOAK_CANCEL) diff --git a/code/modules/cm_tech/hologram.dm b/code/modules/cm_tech/hologram.dm index 1fcba71a4560..1d85df9e49ad 100644 --- a/code/modules/cm_tech/hologram.dm +++ b/code/modules/cm_tech/hologram.dm @@ -102,6 +102,7 @@ GLOBAL_LIST_EMPTY_TYPED(hologram_list, /mob/hologram) var/mob/hologram/linked_hologram /datum/action/leave_hologram/action_activate() + . = ..() qdel(src) /datum/action/leave_hologram/Destroy() diff --git a/code/modules/cm_tech/implements/adv_weapon.dm b/code/modules/cm_tech/implements/adv_weapon.dm index 3cc8f1ceb4d6..f7b1008e0882 100644 --- a/code/modules/cm_tech/implements/adv_weapon.dm +++ b/code/modules/cm_tech/implements/adv_weapon.dm @@ -130,6 +130,7 @@ name = "Start Charging" /datum/action/item_action/techweb_railgun_start_charge/action_activate() + . = ..() if (target) var/obj/item/weapon/gun/rifle/techweb_railgun/TR = target TR.start_charging(owner) @@ -138,6 +139,7 @@ name = "Abort Charge" /datum/action/item_action/techweb_railgun_abort_charge/action_activate() + . = ..() if (target) var/obj/item/weapon/gun/rifle/techweb_railgun/TR = target TR.abort_charge(owner) diff --git a/code/modules/defenses/bell_tower.dm b/code/modules/defenses/bell_tower.dm index 68d58f02b481..7ce252b3f4d7 100644 --- a/code/modules/defenses/bell_tower.dm +++ b/code/modules/defenses/bell_tower.dm @@ -257,7 +257,7 @@ STOP_PROCESSING(SSobj, src) return - var/list/targets = SSquadtree.players_in_range(RECT(M.x, M.y, area_range, area_range), M.z, QTREE_SCAN_MOBS | QTREE_EXCLUDE_OBSERVER) + var/list/targets = SSquadtree.players_in_range(SQUARE(M.x, M.y, area_range), M.z, QTREE_SCAN_MOBS | QTREE_EXCLUDE_OBSERVER) if(!targets) return diff --git a/code/modules/defenses/planted_flag.dm b/code/modules/defenses/planted_flag.dm index d2b9b23e8f3b..d44f22f38b68 100644 --- a/code/modules/defenses/planted_flag.dm +++ b/code/modules/defenses/planted_flag.dm @@ -7,7 +7,7 @@ desc = "A planted flag with the iconic USCM flag plastered all over it, you feel a burst of energy by its mere sight." handheld_type = /obj/item/defenses/handheld/planted_flag disassemble_time = 10 - var/datum/shape/rectangle/range_bounds + var/datum/shape/range_bounds var/area_range = PLANTED_FLAG_RANGE var/buff_intensity = PLANTED_FLAG_BUFF health = 200 @@ -33,7 +33,7 @@ apply_area_effect() start_processing() - range_bounds = RECT(x, y, PLANTED_FLAG_RANGE, PLANTED_FLAG_RANGE) + range_bounds = SQUARE(x, y, PLANTED_FLAG_RANGE) update_icon() /obj/structure/machinery/defenses/planted_flag/Destroy() @@ -70,9 +70,9 @@ /obj/structure/machinery/defenses/planted_flag/proc/apply_area_effect() if(!range_bounds) - range_bounds = RECT(x, y, area_range, area_range) + range_bounds = SQUARE(x, y, area_range) - var/list/targets = SSquadtree.players_in_range(RECT(x, y, area_range, area_range), z, QTREE_SCAN_MOBS | QTREE_EXCLUDE_OBSERVER) + var/list/targets = SSquadtree.players_in_range(SQUARE(x, y, area_range), z, QTREE_SCAN_MOBS | QTREE_EXCLUDE_OBSERVER) if(!targets) return @@ -180,7 +180,7 @@ if(!M.x && !M.y && !M.z) return - var/list/targets = SSquadtree.players_in_range(RECT(M.x, M.y, area_range, area_range), M.z, QTREE_SCAN_MOBS | QTREE_EXCLUDE_OBSERVER) + var/list/targets = SSquadtree.players_in_range(SQUARE(M.x, M.y, area_range), M.z, QTREE_SCAN_MOBS | QTREE_EXCLUDE_OBSERVER) targets |= M for(var/mob/living/carbon/human/H in targets) diff --git a/code/modules/defenses/sentry.dm b/code/modules/defenses/sentry.dm index 695b3387d909..8ad4cd407e75 100644 --- a/code/modules/defenses/sentry.dm +++ b/code/modules/defenses/sentry.dm @@ -12,7 +12,7 @@ var/list/targets = list() // Lists of current potential targets var/list/other_targets = list() //List of special target types to shoot at, if needed. var/atom/movable/target = null - var/datum/shape/rectangle/range_bounds + var/datum/shape/range_bounds var/datum/effect_system/spark_spread/spark_system //The spark system, used for generating... sparks? var/last_fired = 0 var/fire_delay = 4 @@ -93,17 +93,17 @@ /obj/structure/machinery/defenses/sentry/proc/set_range() if(omni_directional) - range_bounds = RECT(x, y, 8, 8) + range_bounds = SQUARE(x, y, 8) return switch(dir) if(EAST) - range_bounds = RECT(x + 4, y, 7, 7) + range_bounds = SQUARE(x + 4, y, 7) if(WEST) - range_bounds = RECT(x - 4, y, 7, 7) + range_bounds = SQUARE(x - 4, y, 7) if(NORTH) - range_bounds = RECT(x, y + 4, 7, 7) + range_bounds = SQUARE(x, y + 4, 7) if(SOUTH) - range_bounds = RECT(x, y - 4, 7, 7) + range_bounds = SQUARE(x, y - 4, 7) /obj/structure/machinery/defenses/sentry/proc/unset_range() SIGNAL_HANDLER @@ -614,17 +614,17 @@ var/dbl_range = range * 2 if(omni_directional) - range_bounds = RECT(x, y, dbl_range, dbl_range) + range_bounds = SQUARE(x, y, dbl_range) return switch(dir) if(EAST) - range_bounds = RECT(x+range, y, dbl_range, dbl_range) + range_bounds = SQUARE(x+range, y, dbl_range) if(WEST) - range_bounds = RECT(x-range, y, dbl_range, dbl_range) + range_bounds = SQUARE(x-range, y, dbl_range) if(NORTH) - range_bounds = RECT(x, y+range, dbl_range, dbl_range) + range_bounds = SQUARE(x, y+range, dbl_range) if(SOUTH) - range_bounds = RECT(x, y-range, dbl_range, dbl_range) + range_bounds = SQUARE(x, y-range, dbl_range) //the turret inside the shuttle sentry deployment system /obj/structure/machinery/defenses/sentry/premade/dropship @@ -672,13 +672,13 @@ /obj/structure/machinery/defenses/sentry/dmr/set_range() switch(dir) if(EAST) - range_bounds = RECT(x + (SENTRY_SNIPER_RANGE/2), y, SENTRY_SNIPER_RANGE, SENTRY_SNIPER_RANGE) + range_bounds = SQUARE(x + (SENTRY_SNIPER_RANGE/2), y, SENTRY_SNIPER_RANGE) if(WEST) - range_bounds = RECT(x - (SENTRY_SNIPER_RANGE/2), y, SENTRY_SNIPER_RANGE, SENTRY_SNIPER_RANGE) + range_bounds = SQUARE(x - (SENTRY_SNIPER_RANGE/2), y, SENTRY_SNIPER_RANGE) if(NORTH) - range_bounds = RECT(x, y + (SENTRY_SNIPER_RANGE/2), SENTRY_SNIPER_RANGE, SENTRY_SNIPER_RANGE) + range_bounds = SQUARE(x, y + (SENTRY_SNIPER_RANGE/2), SENTRY_SNIPER_RANGE) if(SOUTH) - range_bounds = RECT(x, y - (SENTRY_SNIPER_RANGE/2), SENTRY_SNIPER_RANGE, SENTRY_SNIPER_RANGE) + range_bounds = SQUARE(x, y - (SENTRY_SNIPER_RANGE/2), SENTRY_SNIPER_RANGE) #undef SENTRY_SNIPER_RANGE /obj/structure/machinery/defenses/sentry/shotgun diff --git a/code/modules/defenses/sentry_computer.dm b/code/modules/defenses/sentry_computer.dm index 59c6409d552c..639a74e6ba30 100644 --- a/code/modules/defenses/sentry_computer.dm +++ b/code/modules/defenses/sentry_computer.dm @@ -402,8 +402,7 @@ var/obj/structure/machinery/defenses/sentry/defense = sentry if (defense.has_camera) defense.set_range() - var/datum/shape/rectangle/current_bb = defense.range_bounds - SEND_SIGNAL(src, COMSIG_CAMERA_SET_AREA, current_bb.center_x, current_bb.center_y, defense.loc.z, current_bb.width, current_bb.height) + SEND_SIGNAL(src, COMSIG_CAMERA_SET_AREA, defense.range_bounds, defense.loc.z) return TRUE if("ping") diff --git a/code/modules/defenses/sentry_flamer.dm b/code/modules/defenses/sentry_flamer.dm index 979d18eb41d1..2c5e9ae62677 100644 --- a/code/modules/defenses/sentry_flamer.dm +++ b/code/modules/defenses/sentry_flamer.dm @@ -90,13 +90,13 @@ /obj/structure/machinery/defenses/sentry/flamer/plasma/set_range() switch(dir) if(EAST) - range_bounds = RECT(x + (FLAMER_SENTRY_SNIPER_RANGE/2), y, FLAMER_SENTRY_SNIPER_RANGE, FLAMER_SENTRY_SNIPER_RANGE) + range_bounds = SQUARE(x + (FLAMER_SENTRY_SNIPER_RANGE/2), y, FLAMER_SENTRY_SNIPER_RANGE) if(WEST) - range_bounds = RECT(x - (FLAMER_SENTRY_SNIPER_RANGE/2), y, FLAMER_SENTRY_SNIPER_RANGE, FLAMER_SENTRY_SNIPER_RANGE) + range_bounds = SQUARE(x - (FLAMER_SENTRY_SNIPER_RANGE/2), y, FLAMER_SENTRY_SNIPER_RANGE) if(NORTH) - range_bounds = RECT(x, y + (FLAMER_SENTRY_SNIPER_RANGE/2), FLAMER_SENTRY_SNIPER_RANGE, FLAMER_SENTRY_SNIPER_RANGE) + range_bounds = SQUARE(x, y + (FLAMER_SENTRY_SNIPER_RANGE/2), FLAMER_SENTRY_SNIPER_RANGE) if(SOUTH) - range_bounds = RECT(x, y - (FLAMER_SENTRY_SNIPER_RANGE/2), FLAMER_SENTRY_SNIPER_RANGE, FLAMER_SENTRY_SNIPER_RANGE) + range_bounds = SQUARE(x, y - (FLAMER_SENTRY_SNIPER_RANGE/2), FLAMER_SENTRY_SNIPER_RANGE) #undef FLAMER_SENTRY_SNIPER_RANGE diff --git a/code/modules/gear_presets/_select_equipment.dm b/code/modules/gear_presets/_select_equipment.dm index 5311a7a79a3b..138e091ad5a4 100644 --- a/code/modules/gear_presets/_select_equipment.dm +++ b/code/modules/gear_presets/_select_equipment.dm @@ -138,6 +138,9 @@ new_human.set_languages(languages) /datum/equipment_preset/proc/load_preset(mob/living/carbon/human/new_human, randomise = FALSE, count_participant = FALSE, client/mob_client, show_job_gear = TRUE) + if(!new_human.hud_used) + new_human.create_hud() + load_race(new_human, mob_client) if(randomise || uses_special_name) load_name(new_human, randomise, mob_client) diff --git a/code/modules/gear_presets/other.dm b/code/modules/gear_presets/other.dm index 9ea05749fe0d..4d7ef9bda559 100644 --- a/code/modules/gear_presets/other.dm +++ b/code/modules/gear_presets/other.dm @@ -504,29 +504,6 @@ new_human.equip_if_possible(new /obj/item/clothing/glasses/sunglasses, WEAR_EYES) new_human.equip_if_possible(new /obj/item/clipboard, WEAR_WAIST) -//*****************************************************************************************************/ - -/datum/equipment_preset/other/compression_suit - name = "Mk50 Compression Suit" - flags = EQUIPMENT_PRESET_EXTRA - faction = FACTION_PMC - skills = /datum/skills/pfc - idtype = /obj/item/card/id/data - -/datum/equipment_preset/other/compression_suit/load_gear(mob/living/carbon/human/new_human) - //TODO: add backpacks and satchels - new_human.equip_to_slot_or_del(new /obj/item/clothing/shoes/magboots, WEAR_FEET) - - new_human.equip_to_slot_or_del(new /obj/item/clothing/under/colonist, WEAR_BODY) - new_human.equip_to_slot_or_del(new /obj/item/clothing/suit/space/compression, WEAR_JACKET) - new_human.equip_to_slot_or_del(new /obj/item/clothing/head/helmet/space/compression, WEAR_HEAD) - var /obj/item/tank/jetpack/J = new /obj/item/tank/jetpack/oxygen(new_human) - new_human.equip_to_slot_or_del(J, WEAR_BACK) - J.toggle() - new_human.equip_to_slot_or_del(new /obj/item/clothing/mask/breath, WEAR_FACE) - J.Topic(null, list("stat" = 1)) - spawn_merc_weapon(new_human) - //*****************************************************************************************************/ diff --git a/code/modules/mentor/looc_toggle.dm b/code/modules/mentor/looc_toggle.dm index 7c5b95b1fcb0..b224e72e79d2 100644 --- a/code/modules/mentor/looc_toggle.dm +++ b/code/modules/mentor/looc_toggle.dm @@ -13,6 +13,7 @@ // Called when the action is clicked on. /datum/action/looc_toggle/action_activate() + . = ..() if(owner.looc_overhead) button.icon_state = "template" owner.looc_overhead = FALSE diff --git a/code/modules/mob/camera/imaginary_friend.dm b/code/modules/mob/camera/imaginary_friend.dm index 4e7be80056de..0a4d5ee65c5c 100644 --- a/code/modules/mob/camera/imaginary_friend.dm +++ b/code/modules/mob/camera/imaginary_friend.dm @@ -280,6 +280,7 @@ action_icon_state = "joinmob" /datum/action/innate/imaginary_orbit/action_activate() + . = ..() var/mob/camera/imaginary_friend/friend = owner friend.recall() @@ -288,6 +289,7 @@ action_icon_state = "hidemob" /datum/action/innate/imaginary_hide/action_activate() + . = ..() var/mob/camera/imaginary_friend/friend = owner if(friend.hidden) friend.hidden = FALSE diff --git a/code/modules/mob/dead/observer/actions.dm b/code/modules/mob/dead/observer/actions.dm index 7daae802dc7a..192c6cd1e3b8 100644 --- a/code/modules/mob/dead/observer/actions.dm +++ b/code/modules/mob/dead/observer/actions.dm @@ -3,6 +3,7 @@ action_icon_state = "ghost" /datum/action/ghost/action_activate() + . = ..() if(!owner.client) return @@ -38,6 +39,7 @@ qdel(src) /datum/action/join_ert/action_activate() + . = ..() if(!owner.client) return @@ -50,6 +52,7 @@ listen_signal = COMSIG_KB_OBSERVER_JOIN_PREDATOR /datum/action/join_predator/action_activate() + . = ..() var/mob/dead/observer/activator = owner activator.join_as_yautja() @@ -58,6 +61,7 @@ action_icon_state = "view_crew_manifest" /datum/action/observer_action/view_crew_manifest/action_activate() + . = ..() show_browser(owner, GLOB.data_core.get_manifest(), "Crew Manifest", "manifest", "size=450x750") /datum/action/observer_action/view_hive_status @@ -65,6 +69,7 @@ action_icon_state = "view_hive_status" /datum/action/observer_action/view_hive_status/action_activate() + . = ..() var/mob/dead/observer/activator = owner activator.hive_status() @@ -74,6 +79,7 @@ listen_signal = COMSIG_KB_OBSERVER_JOIN_XENO /datum/action/observer_action/join_xeno/action_activate() + . = ..() if(!owner.client) return @@ -90,6 +96,7 @@ listen_signal = COMSIG_KB_OBSERVER_JOIN_LESSER_DRONE /datum/action/observer_action/join_lesser_drone/action_activate() + . = ..() if(!owner.client) return diff --git a/code/modules/mob/living/carbon/human/human_abilities.dm b/code/modules/mob/living/carbon/human/human_abilities.dm index 76ebbed06de6..9976fe37a4ff 100644 --- a/code/modules/mob/living/carbon/human/human_abilities.dm +++ b/code/modules/mob/living/carbon/human/human_abilities.dm @@ -20,6 +20,7 @@ cooldown = COMMAND_ORDER_COOLDOWN /datum/action/human_action/issue_order/action_activate() + . = ..() if(!ishuman(owner)) return var/mob/living/carbon/human/H = owner @@ -58,6 +59,7 @@ return FALSE /datum/action/human_action/smartpack/action_activate() + . = ..() if(!istype(owner, /mob/living/carbon/human)) return var/mob/living/carbon/human/H = owner @@ -129,6 +131,7 @@ CULT // Called when the action is clicked on. /datum/action/human_action/activable/action_activate() + . = ..() if(!ishuman(owner)) return var/mob/living/carbon/human/H = owner @@ -286,6 +289,7 @@ CULT action_icon_state = "cultist_channel_hivemind" /datum/action/human_action/activable/cult/speak_hivemind/action_activate() + . = ..() if(!can_use_action()) return @@ -316,6 +320,7 @@ CULT var/list/items_to_spawn = list(/obj/item/clothing/suit/cultist_hoodie/, /obj/item/clothing/head/cultist_hood/) /datum/action/human_action/activable/cult/obtain_equipment/action_activate() + . = ..() if(!can_use_action()) return @@ -515,6 +520,7 @@ CULT action_icon_state = "mutineer_begin" /datum/action/human_action/activable/mutineer/mutineer_begin/action_activate() + . = ..() if(!can_use_action()) return @@ -549,6 +555,7 @@ CULT UnregisterSignal(L, COMSIG_MOB_RESET_VIEW) /datum/action/human_action/cancel_view/action_activate() + . = ..() if(!can_use_action()) return @@ -575,6 +582,7 @@ CULT UnregisterSignal(L, COMSIG_MOB_RESET_VIEW) /datum/action/human_action/vehicle_unbuckle/action_activate() + . = ..() if(!can_use_action()) return @@ -600,6 +608,7 @@ CULT action_icon_state = "cancel_view" /datum/action/human_action/mg_exit/action_activate() + . = ..() if(!can_use_action()) return @@ -619,6 +628,7 @@ CULT UnregisterSignal(user, COMSIG_MOB_RESET_VIEW) /datum/action/human_action/toggle_arc_antenna/action_activate() + . = ..() if(!can_use_action()) return diff --git a/code/modules/mob/living/carbon/human/human_damage.dm b/code/modules/mob/living/carbon/human/human_damage.dm index 8a528df92de5..48dea97699ea 100644 --- a/code/modules/mob/living/carbon/human/human_damage.dm +++ b/code/modules/mob/living/carbon/human/human_damage.dm @@ -335,7 +335,11 @@ In most cases it makes more sense to use apply_damage() instead! And make sure t for(var/obj/limb/L as anything in parts) var/armor = getarmor(L, armour_type) var/modified_damage = armor_damage_reduction(armour_config, damage, armor, penetration, 0, 0) - L.take_damage(modified_damage / amount_of_parts) + if(damage_type == BURN) + L.take_damage(burn = modified_damage / amount_of_parts) + else + L.take_damage(modified_damage / amount_of_parts) + updatehealth() UpdateDamageIcon() diff --git a/code/modules/mob/living/carbon/human/human_movement.dm b/code/modules/mob/living/carbon/human/human_movement.dm index 7cb2d04e67de..c9a36d283794 100644 --- a/code/modules/mob/living/carbon/human/human_movement.dm +++ b/code/modules/mob/living/carbon/human/human_movement.dm @@ -105,12 +105,6 @@ //Can we act if(is_mob_restrained()) return 0 - //Do we have a working jetpack - if(istype(back, /obj/item/tank/jetpack)) - var/obj/item/tank/jetpack/J = back - if(((!check_drift) || (check_drift && J.stabilization_on)) && (body_position == STANDING_UP) && (J.allow_thrust(0.01, src))) - inertia_dir = 0 - return 1 // if(!check_drift && J.allow_thrust(0.01, src)) // return 1 diff --git a/code/modules/mob/living/carbon/human/species/working_joe/_species.dm b/code/modules/mob/living/carbon/human/species/working_joe/_species.dm index c032e25708eb..f2c0e8d4cf26 100644 --- a/code/modules/mob/living/carbon/human/species/working_joe/_species.dm +++ b/code/modules/mob/living/carbon/human/species/working_joe/_species.dm @@ -50,6 +50,7 @@ /datum/action/joe_emote_panel/action_activate() + . = ..() if(!can_use_action()) return diff --git a/code/modules/mob/living/carbon/xenomorph/Embryo.dm b/code/modules/mob/living/carbon/xenomorph/Embryo.dm index d0890bd3cf37..61ba87cd001b 100644 --- a/code/modules/mob/living/carbon/xenomorph/Embryo.dm +++ b/code/modules/mob/living/carbon/xenomorph/Embryo.dm @@ -191,7 +191,7 @@ if(!picked) // Get a candidate from observers - var/list/candidates = get_alien_candidates(hive) + var/list/candidates = get_alien_candidates(hive, abomination = (isyautja(affected_mob) || (flags_embryo & FLAG_EMBRYO_PREDATOR))) if(candidates && length(candidates)) // If they were facehugged by a player thats still in queue, they get second dibs on the new larva. if(hugger_ckey) diff --git a/code/modules/mob/living/carbon/xenomorph/XenoOverwatch.dm b/code/modules/mob/living/carbon/xenomorph/XenoOverwatch.dm index 1fb48f699efa..3f37845380f0 100644 --- a/code/modules/mob/living/carbon/xenomorph/XenoOverwatch.dm +++ b/code/modules/mob/living/carbon/xenomorph/XenoOverwatch.dm @@ -18,6 +18,7 @@ return TRUE /datum/action/xeno_action/watch_xeno/action_activate() + . = ..() var/mob/living/carbon/xenomorph/X = owner if (!X.check_state(TRUE)) return FALSE diff --git a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm index f0fd8a4d86a7..e7320b17c333 100644 --- a/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm +++ b/code/modules/mob/living/carbon/xenomorph/XenoProcs.dm @@ -264,7 +264,7 @@ /mob/living/carbon/xenomorph/proc/pounced_mob(mob/living/L) // This should only be called back by a mob that has pounce, so no need to check - var/datum/action/xeno_action/activable/pounce/pounceAction = get_xeno_action_by_type(src, /datum/action/xeno_action/activable/pounce) + var/datum/action/xeno_action/activable/pounce/pounceAction = get_action(src, /datum/action/xeno_action/activable/pounce) // Unconscious or dead, or not throwing but used pounce. if(!check_state() || (!throwing && !pounceAction.action_cooldown_check())) @@ -336,7 +336,7 @@ pounced_mob(L) /mob/living/carbon/xenomorph/proc/pounced_obj(obj/O) - var/datum/action/xeno_action/activable/pounce/pounceAction = get_xeno_action_by_type(src, /datum/action/xeno_action/activable/pounce) + var/datum/action/xeno_action/activable/pounce/pounceAction = get_action(src, /datum/action/xeno_action/activable/pounce) // Unconscious or dead, or not throwing but used pounce if(!check_state() || (!throwing && !pounceAction.action_cooldown_check())) diff --git a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm index b07f766b179d..eed2dce5f7a8 100644 --- a/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm +++ b/code/modules/mob/living/carbon/xenomorph/Xenomorph.dm @@ -343,6 +343,8 @@ var/atom/movable/vis_obj/xeno_wounds/wound_icon_holder var/atom/movable/vis_obj/xeno_pack/backpack_icon_holder + /// If TRUE, the xeno cannot slash anything + var/cannot_slash = FALSE /mob/living/carbon/xenomorph/Initialize(mapload, mob/living/carbon/xenomorph/old_xeno, hivenumber) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/boiler/boiler_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/boiler/boiler_powers.dm index c749b0adb5ba..2431e4629876 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/boiler/boiler_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/boiler/boiler_powers.dm @@ -108,7 +108,7 @@ var/mob/living/carbon/xenomorph/xeno = owner if(!action_cooldown_check()) // activate c/d only if we already spit for (var/action_type in action_types_to_cd) - var/datum/action/xeno_action/xeno_action = get_xeno_action_by_type(xeno, action_type) + var/datum/action/xeno_action/xeno_action = get_action(xeno, action_type) if (!istype(xeno_action)) continue @@ -149,7 +149,7 @@ to_chat(xeno, SPAN_XENOHIGHDANGER("We dump our acid through our pores, creating a shroud of gas!")) for (var/action_type in action_types_to_cd) - var/datum/action/xeno_action/xeno_action = get_xeno_action_by_type(xeno, action_type) + var/datum/action/xeno_action/xeno_action = get_action(xeno, action_type) if (!istype(xeno_action)) continue @@ -218,7 +218,7 @@ empowered = FALSE empowering_charge_counter = 0 button.overlays -= "+empowered" - var/datum/action/xeno_action/activable/acid_mine/mine = get_xeno_action_by_type(xeno, /datum/action/xeno_action/activable/acid_mine) + var/datum/action/xeno_action/activable/acid_mine/mine = get_action(xeno, /datum/action/xeno_action/activable/acid_mine) if(!mine.empowered) mine.empowered = TRUE mine.button.overlays += "+empowered" diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm index e1af5e36a40f..1dd4dc5a1c87 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/crusher/crusher_powers.dm @@ -82,7 +82,7 @@ // This ties the pounce/throwing backend into the old collision backend /mob/living/carbon/xenomorph/crusher/pounced_obj(obj/O) - var/datum/action/xeno_action/activable/pounce/crusher_charge/CCA = get_xeno_action_by_type(src, /datum/action/xeno_action/activable/pounce/crusher_charge) + var/datum/action/xeno_action/activable/pounce/crusher_charge/CCA = get_action(src, /datum/action/xeno_action/activable/pounce/crusher_charge) if (istype(CCA) && !CCA.action_cooldown_check() && !(O.type in CCA.not_reducing_objects)) CCA.reduce_cooldown(50) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm index d7a4f987623a..8736d612c822 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/defender/defender_powers.dm @@ -183,6 +183,7 @@ return ..() /datum/action/xeno_action/activable/fortify/action_activate() + . = ..() ..() var/mob/living/carbon/xenomorph/xeno = owner if(xeno.fortify && xeno.selected_ability != src) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm index c5988f12539d..b262624bfe01 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/general_abilities.dm @@ -485,6 +485,7 @@ listen_signal = COMSIG_KB_XENO_EVOLVE /datum/action/xeno_action/onclick/evolve/action_activate() + . = ..() var/mob/living/carbon/xenomorph/xeno = owner xeno.do_evolve() diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm index 014cb3d2f24b..843cfeac540b 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/general_powers.dm @@ -398,7 +398,7 @@ return if(X.layer == XENO_HIDING_LAYER) //Xeno is currently hiding, unhide him - var/datum/action/xeno_action/onclick/xenohide/hide = get_xeno_action_by_type(X, /datum/action/xeno_action/onclick/xenohide) + var/datum/action/xeno_action/onclick/xenohide/hide = get_action(X, /datum/action/xeno_action/onclick/xenohide) if(hide) hide.post_attack() @@ -911,7 +911,7 @@ to_chat(stabbing_xeno, SPAN_XENOWARNING("We must be above ground to do this.")) return - if(!stabbing_xeno.check_state()) + if(!stabbing_xeno.check_state() || stabbing_xeno.cannot_slash) return FALSE var/pre_result = pre_ability_act(stabbing_xeno, targetted_atom) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_powers.dm index 094732300a1f..3c1d3a04543d 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/lurker/lurker_powers.dm @@ -13,7 +13,7 @@ break if(found) - var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invis = get_xeno_action_by_type(xeno, /datum/action/xeno_action/onclick/lurker_invisibility) + var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invis = get_action(xeno, /datum/action/xeno_action/onclick/lurker_invisibility) if(lurker_invis) lurker_invis.invisibility_off() // Full cooldown diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_abilities.dm b/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_abilities.dm index 199df345fb62..4fe0e9107995 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_abilities.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_abilities.dm @@ -87,7 +87,7 @@ if(!X.check_state(1)) return - var/datum/action/xeno_action/activable/cleave/cAction = get_xeno_action_by_type(X, /datum/action/xeno_action/activable/cleave) + var/datum/action/xeno_action/activable/cleave/cAction = get_action(X, /datum/action/xeno_action/activable/cleave) if (!istype(cAction)) return @@ -328,7 +328,7 @@ if(!X.check_state(1)) return - var/datum/action/xeno_action/activable/warden_heal/WH = get_xeno_action_by_type(X, /datum/action/xeno_action/activable/warden_heal) + var/datum/action/xeno_action/activable/warden_heal/WH = get_action(X, /datum/action/xeno_action/activable/warden_heal) if (!istype(WH)) return diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm index 4d3a792af89a..3cbf0769514f 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/praetorian/praetorian_powers.dm @@ -418,8 +418,8 @@ shake_camera(target_carbon, 2, 1) - var/datum/action/xeno_action/activable/prae_abduct/abduct_action = get_xeno_action_by_type(oppressor_user, /datum/action/xeno_action/activable/prae_abduct) - var/datum/action/xeno_action/activable/tail_lash/tail_lash_action = get_xeno_action_by_type(oppressor_user, /datum/action/xeno_action/activable/tail_lash) + var/datum/action/xeno_action/activable/prae_abduct/abduct_action = get_action(oppressor_user, /datum/action/xeno_action/activable/prae_abduct) + var/datum/action/xeno_action/activable/tail_lash/tail_lash_action = get_action(oppressor_user, /datum/action/xeno_action/activable/tail_lash) if(abduct_action && !abduct_action.action_cooldown_check()) abduct_action.reduce_cooldown(5 SECONDS) if(tail_lash_action && !tail_lash_action.action_cooldown_check()) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/predalien/predalien_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/predalien/predalien_powers.dm index 3ec4855f9c3a..a240c3928a3c 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/predalien/predalien_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/predalien/predalien_powers.dm @@ -117,7 +117,7 @@ xeno.anchored = FALSE unroot_human(carbon, TRAIT_SOURCE_ABILITY("Devastate")) - return ..() + return ..() /datum/action/xeno_action/onclick/feralrush/use_ability(atom/A) @@ -149,6 +149,7 @@ predatoralien.recalculate_armor() playsound(predatoralien, 'sound/voice/predalien_growl.ogg', 75, 0, status = 0) apply_cooldown() + return ..() /datum/action/xeno_action/onclick/feralrush/proc/remove_rush_effects() @@ -180,7 +181,7 @@ if(!xeno.check_state()) return - var/datum/action/xeno_action/activable/feralfrenzy/guttype = get_xeno_action_by_type(xeno, /datum/action/xeno_action/activable/feralfrenzy) + var/datum/action/xeno_action/activable/feralfrenzy/guttype = get_action(xeno, /datum/action/xeno_action/activable/feralfrenzy) if(!guttype) return @@ -248,7 +249,7 @@ else predalien_smash.visible_message(SPAN_XENOWARNING("[predalien_smash]'s claws twitch."), SPAN_XENOWARNING("We couldn't grab our target. Wait a moment to try again.")) - return TRUE + return ..() /mob/living/carbon/xenomorph/predalien/stop_pulling() if(isliving(pulling) && smashing) diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm b/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm index 381acba92a51..6ef111aed66f 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/queen/queen_powers.dm @@ -401,6 +401,7 @@ remove_personal_ally() if("Clear Personal Allies") clear_personal_allies() + return ..() /datum/action/xeno_action/onclick/manage_hive/proc/add_personal_ally() var/mob/living/carbon/xenomorph/queen/user_xeno = owner diff --git a/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm b/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm index 80cf5c1e37ac..bff59186fd04 100644 --- a/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm +++ b/code/modules/mob/living/carbon/xenomorph/abilities/xeno_action.dm @@ -51,6 +51,7 @@ // Any strain or caste-specific state should be stored on behavior_delegate objects // which use_ability invocations can modify using typechecks and typecasts where appropriate. /datum/action/xeno_action/proc/use_ability(atom/target) + SHOULD_CALL_PARENT(TRUE) if(!owner) return FALSE track_xeno_ability_stats() @@ -129,10 +130,17 @@ /// A wrapper for use_ability that sends a signal /datum/action/xeno_action/proc/use_ability_wrapper(...) // TODO: make hidden a part of can_use_action - if(!hidden && can_use_action() && use_ability(arglist(args))) + if(!can_use_action()) + SEND_SIGNAL(src, COMSIG_XENO_FAILED_ACTION_USED, owner) + return FALSE + + SEND_SIGNAL(src, COMSIG_XENO_PRE_ACTION_USED, owner) + + if(!hidden && use_ability(arglist(args))) SEND_SIGNAL(src, COMSIG_XENO_ACTION_USED, owner) return TRUE + SEND_SIGNAL(src, COMSIG_XENO_FAILED_ACTION_USED, owner) return FALSE // For actions that do something on each life tick @@ -150,6 +158,7 @@ // For non-activable Xeno actions, this is used to // actually DO the action. /datum/action/xeno_action/activable/action_activate() + . = ..() if(!owner) return if(hidden) @@ -201,6 +210,7 @@ no_cooldown_msg = TRUE /datum/action/xeno_action/onclick/action_activate() + . = ..() use_ability_wrapper(null) // Adds a cooldown to this @@ -362,17 +372,6 @@ deltimer(charge_timer_id) charge_timer_id = TIMER_ID_NULL -// Helper proc to get an action on a target Xeno by type. -// Used to interact with abilities from the outside -/proc/get_xeno_action_by_type(mob/living/carbon/xenomorph/X, typepath) - if (!istype(X)) - CRASH("xeno_action.dm: get_xeno_action_by_type invoked with non-xeno first argument.") - - for (var/datum/action/xeno_action/XA in X.actions) - if (istype(XA, typepath)) - return XA - return null - // Helper proc to check if there is anything blocking the way from mob M to the atom A // Max distance can be supplied to check some of the way instead of the whole way. /proc/check_clear_path_to_target(mob/M, atom/A, smash_windows = TRUE, max_distance = 1000) @@ -420,6 +419,7 @@ return FALSE /datum/action/xeno_action/active_toggle/action_activate() + . = ..() toggle_toggle() /datum/action/xeno_action/active_toggle/life_tick() diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm b/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm index 24ac22d6bc52..a84b9965f9c3 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Crusher.dm @@ -261,11 +261,11 @@ H.apply_armoured_damage(get_xeno_damage_slash(H, damage), ARMOR_MELEE, BRUTE, bound_xeno.zone_selected) - var/datum/action/xeno_action/activable/pounce/crusher_charge/cAction = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/pounce/crusher_charge) + var/datum/action/xeno_action/activable/pounce/crusher_charge/cAction = get_action(bound_xeno, /datum/action/xeno_action/activable/pounce/crusher_charge) if (!cAction.action_cooldown_check()) cAction.reduce_cooldown(cdr_amount) - var/datum/action/xeno_action/onclick/crusher_shield/sAction = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/crusher_shield) + var/datum/action/xeno_action/onclick/crusher_shield/sAction = get_action(bound_xeno, /datum/action/xeno_action/onclick/crusher_shield) if (!sAction.action_cooldown_check()) sAction.reduce_cooldown(base_cdr_amount) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Hellhound.dm b/code/modules/mob/living/carbon/xenomorph/castes/Hellhound.dm index 93d40820bf7b..7df87f63cf3a 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Hellhound.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Hellhound.dm @@ -136,6 +136,6 @@ /datum/behavior_delegate/hellhound_base/melee_attack_additional_effects_self() ..() - var/datum/action/xeno_action/onclick/xenohide/hide = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/xenohide) + var/datum/action/xeno_action/onclick/xenohide/hide = get_action(bound_xeno, /datum/action/xeno_action/onclick/xenohide) if(hide) hide.post_attack() diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm b/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm index 0ab9e9862b16..1dca7eb23f70 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Lurker.dm @@ -87,7 +87,7 @@ original_damage *= buffed_slash_damage_ratio target_carbon.set_effect(get_xeno_stun_duration(target_carbon, 3), SUPERSLOW) next_slash_buffed = FALSE - var/datum/action/xeno_action/onclick/lurker_assassinate/ability = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/lurker_assassinate) + var/datum/action/xeno_action/onclick/lurker_assassinate/ability = get_action(bound_xeno, /datum/action/xeno_action/onclick/lurker_assassinate) if (ability) ability.button.icon_state = "template" @@ -114,19 +114,19 @@ /datum/behavior_delegate/lurker_base/melee_attack_additional_effects_self() ..() - var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invis_action = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility) + var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invis_action = get_action(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility) if (lurker_invis_action) lurker_invis_action.invisibility_off() // Full cooldown /datum/behavior_delegate/lurker_base/proc/decloak_handler(mob/source) SIGNAL_HANDLER - var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invis_action = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility) + var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invis_action = get_action(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility) if(istype(lurker_invis_action)) lurker_invis_action.invisibility_off(0.5) // Partial refund of remaining time /// Implementation for enabling invisibility. /datum/behavior_delegate/lurker_base/proc/on_invisibility() - var/datum/action/xeno_action/activable/pounce/lurker/lurker_pounce_action = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/pounce/lurker) + var/datum/action/xeno_action/activable/pounce/lurker/lurker_pounce_action = get_action(bound_xeno, /datum/action/xeno_action/activable/pounce/lurker) if(lurker_pounce_action) lurker_pounce_action.knockdown = TRUE // pounce knocks down lurker_pounce_action.freeze_self = TRUE @@ -137,7 +137,7 @@ /// Implementation for disabling invisibility. /datum/behavior_delegate/lurker_base/proc/on_invisibility_off() - var/datum/action/xeno_action/activable/pounce/lurker/lurker_pounce_action = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/pounce/lurker) + var/datum/action/xeno_action/activable/pounce/lurker/lurker_pounce_action = get_action(bound_xeno, /datum/action/xeno_action/activable/pounce/lurker) if(lurker_pounce_action) lurker_pounce_action.knockdown = FALSE // pounce no longer knocks down lurker_pounce_action.freeze_self = FALSE @@ -155,7 +155,7 @@ . += "Invisibility Remaining: [time_left] second\s." return - var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invisibility_action = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility) + var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invisibility_action = get_action(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility) if(!lurker_invisibility_action) return @@ -177,7 +177,7 @@ if(!bound_xeno || !bound_xeno.stealth) return - var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invisibility_action = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility) + var/datum/action/xeno_action/onclick/lurker_invisibility/lurker_invisibility_action = get_action(bound_xeno, /datum/action/xeno_action/onclick/lurker_invisibility) if(!lurker_invisibility_action) return diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Predalien.dm b/code/modules/mob/living/carbon/xenomorph/castes/Predalien.dm index 830f4fc5a9cf..b60f150c442d 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Predalien.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Predalien.dm @@ -69,16 +69,19 @@ weed_food_states = list("Predalien_1","Predalien_2","Predalien_3") weed_food_states_flipped = list("Predalien_1","Predalien_2","Predalien_3") var/smashing = FALSE + /// If the pred alert/player notif should happen when the predalien spawns + var/should_announce_spawn = TRUE /mob/living/carbon/xenomorph/predalien/Initialize(mapload, mob/living/carbon/xenomorph/oldxeno, h_number) . = ..() - addtimer(CALLBACK(src, PROC_REF(announce_spawn)), 3 SECONDS) - hunter_data.dishonored = TRUE - hunter_data.dishonored_reason = "An abomination upon the honor of us all!" - hunter_data.dishonored_set = src - hud_set_hunter() + if(should_announce_spawn) + addtimer(CALLBACK(src, PROC_REF(announce_spawn)), 3 SECONDS) + hunter_data.dishonored = TRUE + hunter_data.dishonored_reason = "An abomination upon the honor of us all!" + hunter_data.dishonored_set = src + hud_set_hunter() AddComponent(/datum/component/footstep, 4, 25, 11, 2, "alien_footstep_medium") @@ -102,8 +105,20 @@ You must still listen to the queen. /mob/living/carbon/xenomorph/predalien/resist_fire() - ..() - SetKnockDown(0.1 SECONDS) + ..() + SetKnockDown(0.1 SECONDS) + +/mob/living/carbon/xenomorph/predalien/get_examine_text(mob/user) + . = ..() + var/datum/behavior_delegate/predalien_base/predalienkills = behavior_delegate + . += "It has [predalienkills.kills] kills to its name!" + +/mob/living/carbon/xenomorph/predalien/tutorial + should_announce_spawn = FALSE + +/mob/living/carbon/xenomorph/predalien/tutorial/gib(datum/cause_data/cause = create_cause_data("gibbing", src)) + death(cause, gibbed = TRUE) + /datum/behavior_delegate/predalien_base name = "Base Predalien Behavior Delegate" @@ -127,12 +142,3 @@ You must still listen to the queen. original_damage *= 1.5 return original_damage + kills * 2.5 - -/mob/living/carbon/xenomorph/predalien/get_examine_text(mob/user) - . = ..() - var/datum/behavior_delegate/predalien_base/predalienkills = behavior_delegate - var/kills = predalienkills.kills - . += "It has [kills] kills to its name!" - - - diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Ravager.dm b/code/modules/mob/living/carbon/xenomorph/castes/Ravager.dm index 6e5da79fbed1..90614e338071 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Ravager.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Ravager.dm @@ -90,7 +90,7 @@ /datum/behavior_delegate/ravager_base/melee_attack_additional_effects_self() ..() - var/datum/action/xeno_action/activable/pounce/charge/cAction = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/pounce/charge) + var/datum/action/xeno_action/activable/pounce/charge/cAction = get_action(bound_xeno, /datum/action/xeno_action/activable/pounce/charge) if (!cAction.action_cooldown_check()) cAction.reduce_cooldown(slash_charge_cdr) diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm b/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm index 8721294173e9..12fdb8d02843 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Runner.dm @@ -91,6 +91,6 @@ /datum/behavior_delegate/runner_base/melee_attack_additional_effects_self() ..() - var/datum/action/xeno_action/onclick/xenohide/hide = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/xenohide) + var/datum/action/xeno_action/onclick/xenohide/hide = get_action(bound_xeno, /datum/action/xeno_action/onclick/xenohide) if(hide) hide.post_attack() diff --git a/code/modules/mob/living/carbon/xenomorph/castes/Sentinel.dm b/code/modules/mob/living/carbon/xenomorph/castes/Sentinel.dm index 01963496f967..3e7416f39fc5 100644 --- a/code/modules/mob/living/carbon/xenomorph/castes/Sentinel.dm +++ b/code/modules/mob/living/carbon/xenomorph/castes/Sentinel.dm @@ -95,7 +95,7 @@ addtimer(CALLBACK(src, PROC_REF(paralyzing_slash), carbon_target), NEURO_TOUCH_DELAY) next_slash_buffed = FALSE if(!next_slash_buffed) - var/datum/action/xeno_action/onclick/paralyzing_slash/ability = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/onclick/paralyzing_slash) + var/datum/action/xeno_action/onclick/paralyzing_slash/ability = get_action(bound_xeno, /datum/action/xeno_action/onclick/paralyzing_slash) if (ability && istype(ability)) ability.button.icon_state = "template" return original_damage diff --git a/code/modules/mob/living/carbon/xenomorph/hive_status_ui.dm b/code/modules/mob/living/carbon/xenomorph/hive_status_ui.dm index 360b4e8bbdde..eca88761ad9b 100644 --- a/code/modules/mob/living/carbon/xenomorph/hive_status_ui.dm +++ b/code/modules/mob/living/carbon/xenomorph/hive_status_ui.dm @@ -201,7 +201,7 @@ if(xenoSrc.stat == DEAD) return - var/datum/action/xeno_action/A = get_xeno_action_by_type(xenoSrc, /datum/action/xeno_action/activable/queen_give_plasma) + var/datum/action/xeno_action/A = get_action(xenoSrc, /datum/action/xeno_action/activable/queen_give_plasma) A?.use_ability_wrapper(xenoTarget) if("heal") @@ -214,7 +214,7 @@ if(xenoSrc.stat == DEAD) return - var/datum/action/xeno_action/A = get_xeno_action_by_type(xenoSrc, /datum/action/xeno_action/activable/queen_heal) + var/datum/action/xeno_action/A = get_action(xenoSrc, /datum/action/xeno_action/activable/queen_heal) A?.use_ability_wrapper(xenoTarget, TRUE) if("overwatch") diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/boiler/trapper.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/boiler/trapper.dm index f64bfd6b500f..857a76969354 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/boiler/trapper.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/boiler/trapper.dm @@ -73,7 +73,7 @@ found = trap break - var/datum/action/xeno_action/activable/boiler_trap/trap_ability = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/boiler_trap) + var/datum/action/xeno_action/activable/boiler_trap/trap_ability = get_action(bound_xeno, /datum/action/xeno_action/activable/boiler_trap) if (found) target_human.apply_armoured_damage(bonus_damage_shotgun_trapped, ARMOR_BIO, BURN) trap_ability.empowering_charge_counter = trap_ability.empower_charge_max diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm index 5ebafc88eaef..7ceaf2fed75e 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/drone/healer.dm @@ -276,9 +276,10 @@ addtimer(CALLBACK(xeno.hive, TYPE_PROC_REF(/datum/hive_status, free_respawn), xeno.client), 5 SECONDS) xeno.gib(create_cause_data("sacrificing itself", src)) + return ..() /datum/action/xeno_action/activable/healer_sacrifice/action_activate() - ..() + . = ..() var/mob/living/carbon/xenomorph/xeno = owner if(xeno.selected_ability != src) return diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/hivelord/resin_whisperer.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/hivelord/resin_whisperer.dm index 747463eb5ee5..89737f9ff595 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/hivelord/resin_whisperer.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/hivelord/resin_whisperer.dm @@ -43,19 +43,20 @@ name = "Coerce Resin (100)" action_icon_state = "secrete_resin" ability_name = "coerce resin" - var/last_use = 0 xeno_cooldown = 1 SECONDS thick = FALSE make_message = FALSE no_cooldown_msg = TRUE - var/care_about_adjacency = TRUE build_speed_mod = 2 // the actual building part takes twice as long macro_path = /datum/action/xeno_action/verb/verb_coerce_resin action_type = XENO_ACTION_CLICK + var/last_use = 0 + var/care_about_adjacency = TRUE + /datum/action/xeno_action/activable/secrete_resin/remote/use_ability(atom/target_atom, mods) if(!can_remote_build()) to_chat(owner, SPAN_XENONOTICE("We must be standing on weeds to establish a connection to the resin.")) @@ -70,8 +71,8 @@ var/turf/target_turf = get_turf(target_atom) if(!target_turf) return - - if(!(target_turf in view(10, owner))) + + if(care_about_adjacency && !(target_turf in view(10, owner))) to_chat(owner, SPAN_XENONOTICE("We must have a direct line of sight!")) return diff --git a/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/vanguard.dm b/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/vanguard.dm index 310db35ab370..01f567398c44 100644 --- a/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/vanguard.dm +++ b/code/modules/mob/living/carbon/xenomorph/strains/castes/praetorian/vanguard.dm @@ -54,7 +54,7 @@ last_combat_time = world.time /datum/behavior_delegate/praetorian_vanguard/proc/next_pierce_spin() - var/datum/action/xeno_action/activable/pierce/pAction = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/pierce) + var/datum/action/xeno_action/activable/pierce/pAction = get_action(bound_xeno, /datum/action/xeno_action/activable/pierce) if (istype(pAction)) pAction.should_spin_instead = TRUE @@ -62,7 +62,7 @@ return /datum/behavior_delegate/praetorian_vanguard/proc/next_pierce_normal() - var/datum/action/xeno_action/activable/pierce/pAction = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/pierce) + var/datum/action/xeno_action/activable/pierce/pAction = get_action(bound_xeno, /datum/action/xeno_action/activable/pierce) if (istype(pAction)) pAction.should_spin_instead = FALSE return @@ -88,6 +88,6 @@ new_shield.explosive_armor_amount = 1.5*XENO_EXPOSIVEARMOR_MOD_VERY_LARGE to_chat(praetorian, SPAN_XENOHIGHDANGER("We feel our defensive shell regenerate! It will block one hit!")) - var/datum/action/xeno_action/activable/cleave/caction = get_xeno_action_by_type(bound_xeno, /datum/action/xeno_action/activable/cleave) + var/datum/action/xeno_action/activable/cleave/caction = get_action(bound_xeno, /datum/action/xeno_action/activable/cleave) if (istype(caction)) caction.buffed = TRUE diff --git a/code/modules/movement/movement.dm b/code/modules/movement/movement.dm index e12a5b439296..8151d2df6707 100644 --- a/code/modules/movement/movement.dm +++ b/code/modules/movement/movement.dm @@ -140,11 +140,11 @@ destination.Entered(src, oldloc) if(destarea && (old_area != destarea || !isturf(oldloc))) destarea.Entered(src, oldloc) - - for(var/atom/movable/AM in destination) - if(AM == src) - continue - AM.Crossed(src, oldloc) + if(!(SEND_SIGNAL(src, COMSIG_MOVABLE_FORCEMOVE_PRE_CROSSED) & COMPONENT_IGNORE_CROSS)) + for(var/atom/movable/AM in destination) + if(AM == src) + continue + AM.Crossed(src, oldloc) Moved(oldloc, NONE, TRUE) . = TRUE diff --git a/code/modules/projectiles/ammo_boxes/grenade_packets.dm b/code/modules/projectiles/ammo_boxes/grenade_packets.dm index 5546fe3bc520..603e2e3a712f 100644 --- a/code/modules/projectiles/ammo_boxes/grenade_packets.dm +++ b/code/modules/projectiles/ammo_boxes/grenade_packets.dm @@ -109,6 +109,12 @@ GLOBAL_LIST_INIT(grenade_packets, list( icon_state = "general_packet" content_type = /obj/item/explosive/grenade/high_explosive/m15/rubber +/obj/item/storage/box/packet/sebb + name = "\improper G2 Electroshock grenade packet" + desc = "It contains three G2 Electroshock grenades. Handle with care." + icon_state = "sebb_packet" + content_type = /obj/item/explosive/grenade/sebb + /obj/item/storage/box/packet/airburst_he name = "\improper M74 airburst grenade packet" desc = "It contains three M74 airburst fragmentation grenades. This end towards the enemy." diff --git a/code/modules/projectiles/gun.dm b/code/modules/projectiles/gun.dm index f7ffbf2875e2..d16f1b6fdd30 100644 --- a/code/modules/projectiles/gun.dm +++ b/code/modules/projectiles/gun.dm @@ -427,6 +427,10 @@ SEND_SIGNAL(src, COMSIG_GUN_RECALCULATE_ATTACHMENT_BONUSES) /obj/item/weapon/gun/proc/handle_random_attachments() + #ifdef AUTOWIKI // no randomness for my gun pictures, please + return + #endif + var/attachmentchoice var/randchance = random_spawn_chance diff --git a/code/modules/projectiles/gun_attachables.dm b/code/modules/projectiles/gun_attachables.dm index 7d015e4bac8d..e2108364e9ac 100644 --- a/code/modules/projectiles/gun_attachables.dm +++ b/code/modules/projectiles/gun_attachables.dm @@ -1054,6 +1054,7 @@ Defined in conflicts.dm of the #defines folder. button.name = name /datum/action/item_action/toggle_zoom_level/action_activate() + . = ..() var/obj/item/weapon/gun/G = holder_item var/obj/item/attachable/scope/variable_zoom/S = G.attachments["rail"] S.toggle_zoom_level() @@ -1674,6 +1675,7 @@ Defined in conflicts.dm of the #defines folder. /datum/action/item_action/vulture /datum/action/item_action/vulture/action_activate() + . = ..() var/obj/item/weapon/gun/gun_holder = holder_item var/obj/item/attachable/vulture_scope/scope = gun_holder.attachments["rail"] if(!istype(scope)) @@ -3515,6 +3517,7 @@ Defined in conflicts.dm of the #defines folder. button.overlays += image('icons/mob/hud/actions.dmi', button, action_icon_state) /datum/action/item_action/bipod/toggle_full_auto_switch/action_activate() + . = ..() var/obj/item/weapon/gun/holder_gun = holder_item var/obj/item/attachable/bipod/attached_bipod = holder_gun.attachments["under"] diff --git a/code/modules/projectiles/guns/energy.dm b/code/modules/projectiles/guns/energy.dm index b2ec3dea63ce..717914e38eba 100644 --- a/code/modules/projectiles/guns/energy.dm +++ b/code/modules/projectiles/guns/energy.dm @@ -268,6 +268,7 @@ /datum/action/item_action/taser/action_activate() + . = ..() var/obj/item/weapon/gun/energy/taser/taser = holder_item if(!ishuman(owner)) return diff --git a/code/modules/projectiles/guns/lever_action.dm b/code/modules/projectiles/guns/lever_action.dm index a8fb78f72a9c..179ce8d787d0 100644 --- a/code/modules/projectiles/guns/lever_action.dm +++ b/code/modules/projectiles/guns/lever_action.dm @@ -378,7 +378,6 @@ their unique feature is that a direct hit will buff your damage and firerate /obj/item/attachable/bayonet/upp, // Barrel /obj/item/attachable/bayonet, /obj/item/attachable/extended_barrel, - /obj/item/attachable/heavy_barrel, /obj/item/attachable/suppressor, /obj/item/attachable/compensator, /obj/item/attachable/reddot, // Rail @@ -393,9 +392,9 @@ their unique feature is that a direct hit will buff your damage and firerate /obj/item/weapon/gun/lever_action/xm88/set_gun_config_values() ..() - set_fire_delay(FIRE_DELAY_TIER_2) + set_fire_delay(FIRE_DELAY_TIER_2 + FIRE_DELAY_TIER_11) lever_delay = FIRE_DELAY_TIER_3 - accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_5 + accuracy_mult = BASE_ACCURACY_MULT + HIT_ACCURACY_MULT_TIER_2 accuracy_mult_unwielded = BASE_ACCURACY_MULT - HIT_ACCURACY_MULT_TIER_10 scatter = SCATTER_AMOUNT_TIER_8 burst_scatter_mult = 0 diff --git a/code/modules/projectiles/guns/rifles.dm b/code/modules/projectiles/guns/rifles.dm index ad85220400fb..fbe24434d542 100644 --- a/code/modules/projectiles/guns/rifles.dm +++ b/code/modules/projectiles/guns/rifles.dm @@ -557,6 +557,7 @@ //---ability actions--\\ /datum/action/item_action/m46c/action_activate() + . = ..() var/obj/item/weapon/gun/rifle/m46c/protag_gun = holder_item if(!ishuman(owner)) return diff --git a/code/modules/projectiles/guns/shotguns.dm b/code/modules/projectiles/guns/shotguns.dm index b1b3bb3c2ab4..a0bb3f8f852c 100644 --- a/code/modules/projectiles/guns/shotguns.dm +++ b/code/modules/projectiles/guns/shotguns.dm @@ -838,6 +838,7 @@ can cause issues with ammo types getting mixed up during the burst. return TRUE /datum/action/item_action/specialist/twobore_brace/action_activate() + . = ..() var/obj/item/weapon/gun/shotgun/double/twobore/G = holder_item if(G.braced) return diff --git a/code/modules/projectiles/guns/smartgun.dm b/code/modules/projectiles/guns/smartgun.dm index e5c9fff3a126..7c628463b1ef 100644 --- a/code/modules/projectiles/guns/smartgun.dm +++ b/code/modules/projectiles/guns/smartgun.dm @@ -178,6 +178,7 @@ //---ability actions--\\ /datum/action/item_action/smartgun/action_activate() + . = ..() var/obj/item/weapon/gun/smartgun/G = holder_item if(!ishuman(owner)) return @@ -595,6 +596,7 @@ // ID lock action \\ /datum/action/item_action/co_sg/action_activate() + . = ..() var/obj/item/weapon/gun/smartgun/co/protag_gun = holder_item if(!ishuman(owner)) return diff --git a/code/modules/projectiles/guns/smgs.dm b/code/modules/projectiles/guns/smgs.dm index 69fd5d968750..466a09612c54 100644 --- a/code/modules/projectiles/guns/smgs.dm +++ b/code/modules/projectiles/guns/smgs.dm @@ -168,7 +168,8 @@ /obj/item/attachable/lasersight, // Under /obj/item/attachable/gyro, /obj/item/attachable/bipod, - /obj/item/attachable/burstfire_assembly + /obj/item/attachable/burstfire_assembly, + /obj/item/attachable/attached_gun/grenade/m203, ) flags_gun_features = GUN_CAN_POINTBLANK|GUN_ANTIQUE @@ -192,6 +193,13 @@ damage_mult = BASE_BULLET_DAMAGE_MULT + BULLET_DAMAGE_MULT_TIER_4 recoil_unwielded = RECOIL_AMOUNT_TIER_5 +/obj/item/weapon/gun/smg/mp5/Initialize(mapload, spawn_empty) + . = ..() + if(prob(10)) + var/obj/item/attachable/attached_gun/grenade/m203/UGL = new(src) + UGL.Attach(src) + update_attachable(UGL.slot) + //------------------------------------------------------- //MP27, based on the MP27, based on the M7. diff --git a/code/modules/projectiles/guns/specialist/launcher/grenade_launcher.dm b/code/modules/projectiles/guns/specialist/launcher/grenade_launcher.dm index e2643c580a16..06ac5428bfc6 100644 --- a/code/modules/projectiles/guns/specialist/launcher/grenade_launcher.dm +++ b/code/modules/projectiles/guns/specialist/launcher/grenade_launcher.dm @@ -222,6 +222,7 @@ update_icon() /datum/action/item_action/toggle_firing_level/action_activate() + . = ..() var/obj/item/weapon/gun/launcher/grenade/G = holder_item if(!ishuman(owner)) return diff --git a/code/modules/projectiles/guns/specialist/sniper.dm b/code/modules/projectiles/guns/specialist/sniper.dm index b40477a8a460..b400350e415b 100644 --- a/code/modules/projectiles/guns/specialist/sniper.dm +++ b/code/modules/projectiles/guns/specialist/sniper.dm @@ -62,6 +62,7 @@ ACTIONS SPECIALSIT SNIPER CAN TAKE */ /datum/action/item_action/specialist/aimed_shot/action_activate() + . = ..() if(!ishuman(owner)) return var/mob/living/carbon/human/H = owner @@ -276,6 +277,7 @@ return TRUE /datum/action/item_action/specialist/toggle_laser/action_activate() + . = ..() var/obj/item/weapon/gun/rifle/sniper/sniper_rifle = holder_item if(owner.get_held_item() != sniper_rifle) diff --git a/code/modules/projectiles/projectile.dm b/code/modules/projectiles/projectile.dm index 0e335aa81da3..d91e2ca47c1a 100644 --- a/code/modules/projectiles/projectile.dm +++ b/code/modules/projectiles/projectile.dm @@ -841,8 +841,8 @@ //mobs use get_projectile_hit_chance instead of get_projectile_hit_boolean /mob/living/proc/get_projectile_hit_chance(obj/projectile/P) - if((body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_NESTED)) && src != P.original) - return FALSE // Snowflake check for xeno nests, because we want bullets to fly through even though they're standing in it + if((body_position == LYING_DOWN || HAS_TRAIT(src, TRAIT_NO_STRAY)) && src != P.original) + return FALSE var/ammo_flags = P.ammo.flags_ammo_behavior | P.projectile_override_flags if(ammo_flags & AMMO_XENO) if((status_flags & XENO_HOST) && HAS_TRAIT(src, TRAIT_NESTED)) diff --git a/code/modules/shuttle/computers/dropship_computer.dm b/code/modules/shuttle/computers/dropship_computer.dm index 08a35b83071d..a28f65ce475d 100644 --- a/code/modules/shuttle/computers/dropship_computer.dm +++ b/code/modules/shuttle/computers/dropship_computer.dm @@ -314,7 +314,7 @@ var/original_evilution = hive.evolution_bonus hive.override_evilution(XENO_HIJACK_EVILUTION_BUFF, TRUE) if(hive.living_xeno_queen) - var/datum/action/xeno_action/onclick/grow_ovipositor/ovi_ability = get_xeno_action_by_type(hive.living_xeno_queen, /datum/action/xeno_action/onclick/grow_ovipositor) + var/datum/action/xeno_action/onclick/grow_ovipositor/ovi_ability = get_action(hive.living_xeno_queen, /datum/action/xeno_action/onclick/grow_ovipositor) ovi_ability.reduce_cooldown(ovi_ability.xeno_cooldown) addtimer(CALLBACK(hive, TYPE_PROC_REF(/datum/hive_status, override_evilution), original_evilution, FALSE), XENO_HIJACK_EVILUTION_TIME) diff --git a/code/modules/surgery/surgery_toggle.dm b/code/modules/surgery/surgery_toggle.dm index b9ca3ca93311..973d1c5b682f 100644 --- a/code/modules/surgery/surgery_toggle.dm +++ b/code/modules/surgery/surgery_toggle.dm @@ -18,6 +18,7 @@ // Called when the action is clicked on. /datum/action/surgery_toggle/action_activate() + . = ..() if(owner.mob_flags & SURGERY_MODE_ON) button.icon_state = "template" owner.mob_flags &= ~SURGERY_MODE_ON diff --git a/code/modules/vehicles/hardpoints/hardpoint_ammo/primary_flamer_ammo.dm b/code/modules/vehicles/hardpoints/hardpoint_ammo/primary_flamer_ammo.dm index def6016f0759..a164b38383b8 100644 --- a/code/modules/vehicles/hardpoints/hardpoint_ammo/primary_flamer_ammo.dm +++ b/code/modules/vehicles/hardpoints/hardpoint_ammo/primary_flamer_ammo.dm @@ -1,7 +1,7 @@ /obj/item/ammo_magazine/hardpoint/primary_flamer name = "DRG-N Offensive Flamer Unit Fuel Tank" desc = "A primary armament flamethrower magazine." - caliber = "Napalm X" //correlates to flamer mags + caliber = "High-Combustion Napalm" //correlates to flamer mags icon_state = "drgn_flametank" w_class = SIZE_LARGE max_rounds = 60 diff --git a/code/modules/vehicles/hardpoints/primary/flamer.dm b/code/modules/vehicles/hardpoints/primary/flamer.dm index fce6e7f6a410..60a7979cd5fb 100644 --- a/code/modules/vehicles/hardpoints/primary/flamer.dm +++ b/code/modules/vehicles/hardpoints/primary/flamer.dm @@ -1,6 +1,6 @@ /obj/item/hardpoint/primary/flamer name = "\improper DRG-N Offensive Flamer Unit" - desc = "A primary weapon for the tank that spews fire everywhere." + desc = "A primary weapon for the tank that spews out high-combustion napalm in a wide radius. The fuel burns intensely and quickly, which allows for it to be used offensively by armoured vehicles." icon_state = "drgn_flamer" disp_icon = "tank" diff --git a/colonialmarines.dme b/colonialmarines.dme index 8e01682d61e0..a799f7a155b0 100644 --- a/colonialmarines.dme +++ b/colonialmarines.dme @@ -698,6 +698,7 @@ #include "code\datums\tutorial\ss13\basic_ss13.dm" #include "code\datums\tutorial\ss13\intents.dm" #include "code\datums\tutorial\xenomorph\_xenomorph.dm" +#include "code\datums\tutorial\xenomorph\abomination.dm" #include "code\datums\tutorial\xenomorph\xenomorph_basic.dm" #include "code\datums\weather\weather_event.dm" #include "code\datums\weather\weather_map_holder.dm" @@ -1136,9 +1137,6 @@ #include "code\game\objects\items\devices\pinpointer.dm" #include "code\game\objects\items\devices\pipe_painter.dm" #include "code\game\objects\items\devices\portable_vendor.dm" -#include "code\game\objects\items\devices\RCD.dm" -#include "code\game\objects\items\devices\RSF.dm" -#include "code\game\objects\items\devices\RSP.dm" #include "code\game\objects\items\devices\scanners.dm" #include "code\game\objects\items\devices\suit_cooling.dm" #include "code\game\objects\items\devices\taperecorder.dm" @@ -1249,7 +1247,6 @@ #include "code\game\objects\items\storage\toolbox.dm" #include "code\game\objects\items\storage\toolkit.dm" #include "code\game\objects\items\storage\wallets.dm" -#include "code\game\objects\items\tanks\jetpack.dm" #include "code\game\objects\items\tanks\tank_types.dm" #include "code\game\objects\items\tanks\tanks.dm" #include "code\game\objects\items\tools\cleaning_tools.dm" @@ -1346,7 +1343,6 @@ #include "code\game\objects\structures\crates_lockers\closets\gimmick.dm" #include "code\game\objects\structures\crates_lockers\closets\job_closets.dm" #include "code\game\objects\structures\crates_lockers\closets\l3closet.dm" -#include "code\game\objects\structures\crates_lockers\closets\malfunction.dm" #include "code\game\objects\structures\crates_lockers\closets\utility_closets.dm" #include "code\game\objects\structures\crates_lockers\closets\wall_locker.dm" #include "code\game\objects\structures\crates_lockers\closets\wardrobe.dm" diff --git a/html/changelogs/AutoChangeLog-pr-6679.yml b/html/changelogs/AutoChangeLog-pr-6679.yml new file mode 100644 index 000000000000..7ffa71d87dd5 --- /dev/null +++ b/html/changelogs/AutoChangeLog-pr-6679.yml @@ -0,0 +1,4 @@ +author: "Doubleumc" +delete-after: True +changes: + - bugfix: "no longer stab with utensil when trying to feed while target full" \ No newline at end of file diff --git a/html/changelogs/archive/2024-07.yml b/html/changelogs/archive/2024-07.yml index e77f1080bb37..f50a667cbefd 100644 --- a/html/changelogs/archive/2024-07.yml +++ b/html/changelogs/archive/2024-07.yml @@ -131,3 +131,65 @@ cuberound: - rscadd: roof structures added, can be also used for lattices and billboards, go transparent when you are near them +2024-07-16: + Git-Nivrak: + - rscdel: Mortar shells no longer blow up their payload, instead they will create + a small fixed explosion. + Nomoresolvalou: + - rscadd: Added neckties and stethoscope to the synthetic snowflake vendor + Steelpoint: + - balance: The XM88 now deals higher damage per-bullet at the cost of a slightly + lower rate of fire and accuracy. This is identical to as if it had a barrel + charger attached to it. + - balance: Per the above, the barrel charger is no longer compatible with the XM88. +2024-07-17: + AndroBetel: + - rscadd: MP5 has 10% chance to spawn with M203 attached. + VileBeggar: + - rscadd: The CIC armoury now contains a plantable flag of the United Americas. + Zonespace27: + - rscadd: Added a tutorial for xenomorph Abominations. You must complete the tutorial + before being able to roll for Abomination. + harryob: + - bugfix: queens can remote build again + ihatethisengine: + - balance: being mid-paradrop won't trigger traps, fire and stray bullets before + you land. + realforest2001: + - bugfix: Fixes riflemen spec_kits not being usable by riflemen. +2024-07-18: + cuberound: + - rscdel: Removed Rapid-Service-Fabricator, rapid construction device and Rapid-Seed-Producer + (old ss13 junk) +2024-07-19: + Drathek: + - bugfix: Fixed light blue scrubs having no cost in snowflake vendor. + SpypigDev: + - bugfix: SO Armory vendors no longer infinitely supply knives + TotalEpicness5, Triiodine, monkeyfist, Blundir: + - rscadd: Adds the G2 electroshock grenade. This grenade does not stun nor deal + serious damage to xenos, but it stuns via electric shock. It can create EMP-like + effects when faced with electronic devices like sentries, synths, Area Power + Controllers, etc. It's damage is reduced by energy armor. + - bugfix: take_overall_armoured_damage now can actually deal burn damage + - balance: Marine armor has a small bit of energy armor added back. Heavy armor + has slightly more protection than medium/light. + - bugfix: Mines now check for explosive antigrief checks + VileBeggar: + - balance: The DRG-N Offensive Flamer Unit now fires a 3-tile wide glob of high-combustion + napalm. + Zonespace, Vile Beggar: + - rscadd: Handheld planted flags are now indestructible and do a small amount of + damage on hit. + - bugfix: Plantable flags can no longer be duplicated. + - rscdel: Planting a UA flag no longer forces anyone but the planter to warcry. + cuberound: + - bugfix: having left hand broken and not splinted has the same effect on wheelchair + movement speed as right hand + - bugfix: corrects holoround highligh alpha value + - rscdel: Removed malfanction closet + kiVts: + - bugfix: Surgery sound and alike is fixed + realforest2001: + - rscadd: The Combat Correspondant's civilian equipment is now in it's own category + to make it easier to tell why you can't click it as the military version. diff --git a/icons/effects/sebb.dmi b/icons/effects/sebb.dmi new file mode 100644 index 000000000000..288a1023ce3d Binary files /dev/null and b/icons/effects/sebb.dmi differ diff --git a/icons/mob/humans/onmob/items_lefthand_0.dmi b/icons/mob/humans/onmob/items_lefthand_0.dmi index 7d887799815b..a4396aeb93de 100644 Binary files a/icons/mob/humans/onmob/items_lefthand_0.dmi and b/icons/mob/humans/onmob/items_lefthand_0.dmi differ diff --git a/icons/mob/humans/onmob/items_lefthand_64.dmi b/icons/mob/humans/onmob/items_lefthand_64.dmi index 057d7f1cad66..d005d8c5f049 100644 Binary files a/icons/mob/humans/onmob/items_lefthand_64.dmi and b/icons/mob/humans/onmob/items_lefthand_64.dmi differ diff --git a/icons/mob/humans/onmob/items_righthand_0.dmi b/icons/mob/humans/onmob/items_righthand_0.dmi index 184946a13f0b..582262e88289 100644 Binary files a/icons/mob/humans/onmob/items_righthand_0.dmi and b/icons/mob/humans/onmob/items_righthand_0.dmi differ diff --git a/icons/mob/humans/onmob/items_righthand_64.dmi b/icons/mob/humans/onmob/items_righthand_64.dmi index 599ef5935f2e..72335e39bfff 100644 Binary files a/icons/mob/humans/onmob/items_righthand_64.dmi and b/icons/mob/humans/onmob/items_righthand_64.dmi differ diff --git a/icons/obj/items/weapons/grenade.dmi b/icons/obj/items/weapons/grenade.dmi index 7ee5af737066..ca8aaf9afcd6 100644 Binary files a/icons/obj/items/weapons/grenade.dmi and b/icons/obj/items/weapons/grenade.dmi differ diff --git a/icons/obj/structures/plantable_flag.dmi b/icons/obj/structures/plantable_flag.dmi new file mode 100644 index 000000000000..c92311529be3 Binary files /dev/null and b/icons/obj/structures/plantable_flag.dmi differ diff --git a/maps/map_files/CORSAT/Corsat.dmm b/maps/map_files/CORSAT/Corsat.dmm index ea56dacf0fa3..435659e102e2 100644 --- a/maps/map_files/CORSAT/Corsat.dmm +++ b/maps/map_files/CORSAT/Corsat.dmm @@ -35676,7 +35676,6 @@ /area/corsat/omega/complex) "lHI" = ( /obj/structure/surface/table/reinforced, -/obj/item/ammo_rcd, /turf/open/floor/corsat/retrosquareslight, /area/corsat/sigma/south/complex) "lHK" = ( diff --git a/maps/map_files/FOP_v3_Sciannex/Fiorina_SciAnnex.dmm b/maps/map_files/FOP_v3_Sciannex/Fiorina_SciAnnex.dmm index f66743b6388e..954a9fdbe40a 100644 --- a/maps/map_files/FOP_v3_Sciannex/Fiorina_SciAnnex.dmm +++ b/maps/map_files/FOP_v3_Sciannex/Fiorina_SciAnnex.dmm @@ -25377,7 +25377,6 @@ /turf/open/floor/prison/sterile_white/southwest, /area/fiorina/station/medbay) "tpE" = ( -/obj/item/tank/jetpack/carbondioxide, /obj/structure/surface/rack, /turf/open/floor/prison/floor_plate, /area/fiorina/tumor/servers) diff --git a/maps/map_files/Ice_Colony_v2/Ice_Colony_v2.dmm b/maps/map_files/Ice_Colony_v2/Ice_Colony_v2.dmm index 80342068f6e6..af8650e3bdb2 100644 --- a/maps/map_files/Ice_Colony_v2/Ice_Colony_v2.dmm +++ b/maps/map_files/Ice_Colony_v2/Ice_Colony_v2.dmm @@ -10137,10 +10137,6 @@ /area/ice_colony/surface/storage_unit/research) "aKo" = ( /obj/structure/surface/rack, -/obj/item/ammo_rcd, -/obj/item/ammo_rcd, -/obj/item/ammo_rcd, -/obj/item/ammo_rcd, /turf/open/floor/vault2/west, /area/ice_colony/surface/storage_unit/research) "aKp" = ( diff --git a/maps/map_files/USS_Almayer/USS_Almayer.dmm b/maps/map_files/USS_Almayer/USS_Almayer.dmm index b328b50b1b2b..331f2223e53b 100644 --- a/maps/map_files/USS_Almayer/USS_Almayer.dmm +++ b/maps/map_files/USS_Almayer/USS_Almayer.dmm @@ -2665,6 +2665,7 @@ /obj/item/device/radio/marine, /obj/item/device/radio/marine, /obj/item/folded_tent/cmd, +/obj/item/flag/plantable/ua, /turf/open/floor/almayer/redfull, /area/almayer/command/cic) "asR" = ( diff --git a/sound/effects/.wav b/sound/effects/.wav new file mode 100644 index 000000000000..a5aa273379f6 Binary files /dev/null and b/sound/effects/.wav differ diff --git a/sound/effects/flag_lowering.ogg b/sound/effects/flag_lowering.ogg new file mode 100644 index 000000000000..d514e097913d Binary files /dev/null and b/sound/effects/flag_lowering.ogg differ diff --git a/sound/effects/flag_raised.ogg b/sound/effects/flag_raised.ogg new file mode 100644 index 000000000000..5da7eca55acb Binary files /dev/null and b/sound/effects/flag_raised.ogg differ diff --git a/sound/effects/flag_raising.ogg b/sound/effects/flag_raising.ogg new file mode 100644 index 000000000000..cc2770f2ecb8 Binary files /dev/null and b/sound/effects/flag_raising.ogg differ diff --git a/sound/effects/flag_warcry_ua.ogg b/sound/effects/flag_warcry_ua.ogg new file mode 100644 index 000000000000..eb0ddecc66eb Binary files /dev/null and b/sound/effects/flag_warcry_ua.ogg differ diff --git a/sound/effects/flag_warcry_ua_extra.ogg b/sound/effects/flag_warcry_ua_extra.ogg new file mode 100644 index 000000000000..c723cca44620 Binary files /dev/null and b/sound/effects/flag_warcry_ua_extra.ogg differ diff --git a/sound/effects/sebb.ogg b/sound/effects/sebb.ogg new file mode 100644 index 000000000000..5fd1f5b396d9 Binary files /dev/null and b/sound/effects/sebb.ogg differ diff --git a/sound/effects/sebb_beep.ogg b/sound/effects/sebb_beep.ogg new file mode 100644 index 000000000000..16c9347d0be2 Binary files /dev/null and b/sound/effects/sebb_beep.ogg differ diff --git a/sound/effects/sebb_explode.ogg b/sound/effects/sebb_explode.ogg new file mode 100644 index 000000000000..999385d9f068 Binary files /dev/null and b/sound/effects/sebb_explode.ogg differ diff --git a/tgui/packages/tgui/interfaces/TutorialMenu.tsx b/tgui/packages/tgui/interfaces/TutorialMenu.tsx index 14abfa957b1c..c47db9fd746d 100644 --- a/tgui/packages/tgui/interfaces/TutorialMenu.tsx +++ b/tgui/packages/tgui/interfaces/TutorialMenu.tsx @@ -60,25 +60,30 @@ export const TutorialMenu = (props) => { {tutorial_categories.map( (tutorial_category) => tutorial_category.name === categoryIndex && - tutorial_category.tutorials.map((tutorial) => ( -
- -
- )), + + + )), )}