diff --git a/code/__DEFINES/do_afters.dm b/code/__DEFINES/do_afters.dm index 456cf940400..5b35e69d0fc 100644 --- a/code/__DEFINES/do_afters.dm +++ b/code/__DEFINES/do_afters.dm @@ -2,3 +2,4 @@ #define DOAFTER_SOURCE_MECHADRILL "doafter_mechadrill" #define DOAFTER_SOURCE_SURVIVALPEN "doafter_survivalpen" #define DOAFTER_SOURCE_GETTING_UP "doafter_gettingup" +#define DOAFTER_SOURCE_CLIMBING_LADDER "doafter_climbingladder" diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index ae0f7a89b00..2882139d7a4 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -1,13 +1,13 @@ -/// Checks for RIGHT_CLICK in modifiers and runs attack_hand_secondary if so. Returns TRUE if normal chain blocked +/// Checks for RIGHT_CLICK in modifiers and runs resolve_right_click_attack if so. Returns TRUE if normal chain blocked. /mob/living/proc/right_click_attack_chain(atom/target, list/modifiers) if (!LAZYACCESS(modifiers, RIGHT_CLICK)) return - var/secondary_result = target.attack_hand_secondary(src, modifiers) + var/secondary_result = resolve_right_click_attack(target, modifiers) if (secondary_result == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN || secondary_result == SECONDARY_ATTACK_CONTINUE_CHAIN) return TRUE else if (secondary_result != SECONDARY_ATTACK_CALL_NORMAL) - CRASH("attack_hand_secondary did not return a SECONDARY_ATTACK_* define.") + CRASH("resolve_right_click_attack (probably attack_hand_secondary) did not return a SECONDARY_ATTACK_* define.") /* Humans: @@ -37,7 +37,8 @@ if(!right_click_attack_chain(A, modifiers) && !dna?.species?.spec_unarmedattack(src, A, modifiers)) //Because species like monkeys dont use attack hand A.attack_hand(src, modifiers) - +/mob/living/carbon/human/resolve_right_click_attack(atom/target, list/modifiers) + return target.attack_hand_secondary(src, modifiers) /// Return TRUE to cancel other attack hand effects that respect it. Modifiers is the assoc list for click info such as if it was a right click. /atom/proc/attack_hand(mob/user, list/modifiers) @@ -124,16 +125,43 @@ /mob/living/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers) if(LIVING_UNARMED_ATTACK_BLOCKED(attack_target)) - return + return FALSE + if(!right_click_attack_chain(attack_target, modifiers)) + resolve_unarmed_attack(attack_target, modifiers) + return TRUE + +/** + * Called when the unarmed attack hasn't been stopped by the LIVING_UNARMED_ATTACK_BLOCKED macro or the right_click_attack_chain proc. + * This will call an attack proc that can vary from mob type to mob type on the target. + */ +/mob/living/proc/resolve_unarmed_attack(atom/attack_target, list/modifiers) attack_target.attack_animal(src, modifiers) +/** + * Called when an unarmed attack performed with right click hasn't been stopped by the LIVING_UNARMED_ATTACK_BLOCKED macro. + * This will call a secondary attack proc that can vary from mob type to mob type on the target. + * Sometimes, a target is interacted differently when right_clicked, in that case the secondary attack proc should return + * a SECONDARY_ATTACK_* value that's not SECONDARY_ATTACK_CALL_NORMAL. + * Otherwise, it should just return SECONDARY_ATTACK_CALL_NORMAL. Failure to do so will result in an exception (runtime error). + */ +/mob/living/proc/resolve_right_click_attack(atom/target, list/modifiers) + return target.attack_animal_secondary(src, modifiers) + /atom/proc/attack_animal(mob/user, list/modifiers) SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_ANIMAL, user) +/** + * Called when a simple animal or basic mob right clicks an atom. + * Returns a SECONDARY_ATTACK_* value. + */ +/atom/proc/attack_animal_secondary(mob/user, list/modifiers) + return SECONDARY_ATTACK_CALL_NORMAL + +///Apparently this is only used by AI datums for basic mobs. A player controlling a basic mob will call attack_animal() when clicking another atom. /atom/proc/attack_basic_mob(mob/user, list/modifiers) SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_BASIC_MOB, user) -///Attacked by monkey +///Attacked by monkey. It doesn't need its own *_secondary proc as it just uses attack_hand_secondary instead. /atom/proc/attack_paw(mob/user, list/modifiers) if(SEND_SIGNAL(src, COMSIG_ATOM_ATTACK_PAW, user, modifiers) & COMPONENT_CANCEL_ATTACK_CHAIN) return TRUE @@ -144,54 +172,85 @@ Aliens Defaults to same as monkey in most places */ -/mob/living/carbon/alien/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers) - if(LIVING_UNARMED_ATTACK_BLOCKED(attack_target)) - return +/mob/living/carbon/alien/resolve_unarmed_attack(atom/attack_target, list/modifiers) attack_target.attack_alien(src, modifiers) +/mob/living/carbon/alien/resolve_right_click_attack(atom/target, list/modifiers) + return target.attack_alien_secondary(src, modifiers) + /atom/proc/attack_alien(mob/living/carbon/alien/user, list/modifiers) attack_paw(user, modifiers) - return +/** + * Called when an alien right clicks an atom. + * Returns a SECONDARY_ATTACK_* value. + */ +/atom/proc/attack_alien_secondary(mob/living/carbon/alien/user, list/modifiers) + return SECONDARY_ATTACK_CALL_NORMAL // Babby aliens -/mob/living/carbon/alien/larva/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers) - if(LIVING_UNARMED_ATTACK_BLOCKED(attack_target)) - return - attack_target.attack_larva(src) +/mob/living/carbon/alien/larva/resolve_unarmed_attack(atom/attack_target, list/modifiers) + attack_target.attack_larva(src, modifiers) -/atom/proc/attack_larva(mob/user) +/mob/living/carbon/alien/larva/resolve_right_click_attack(atom/target, list/modifiers) + return target.attack_larva_secondary(src, modifiers) + +/atom/proc/attack_larva(mob/user, list/modifiers) return +/** + * Called when an alien larva right clicks an atom. + * Returns a SECONDARY_ATTACK_* value. + */ +/atom/proc/attack_larva_secondary(mob/user, list/modifiers) + return SECONDARY_ATTACK_CALL_NORMAL + /* Slimes Nothing happening here */ -/mob/living/simple_animal/slime/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers) - if(LIVING_UNARMED_ATTACK_BLOCKED(attack_target)) - return +/mob/living/simple_animal/slime/resolve_unarmed_attack(atom/attack_target, proximity_flag, list/modifiers) if(isturf(attack_target)) return ..() - attack_target.attack_slime(src) + attack_target.attack_slime(src, modifiers) -/atom/proc/attack_slime(mob/user) +/mob/living/simple_animal/slime/resolve_right_click_attack(atom/target, list/modifiers) + if(isturf(target)) + return ..() + return target.attack_slime_secondary(src, modifiers) + +/atom/proc/attack_slime(mob/user, list/modifiers) return +/** + * Called when a slime mob right clicks an atom (that is not a turf). + * Returns a SECONDARY_ATTACK_* value. + */ +/atom/proc/attack_slime_secondary(mob/user, list/modifiers) + return SECONDARY_ATTACK_CALL_NORMAL /* Drones */ -/mob/living/simple_animal/drone/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers) - if(LIVING_UNARMED_ATTACK_BLOCKED(attack_target)) - return + +/mob/living/simple_animal/drone/resolve_unarmed_attack(atom/attack_target, proximity_flag, list/modifiers) attack_target.attack_drone(src, modifiers) -/// Defaults to attack_hand or attack_hand_secondary. Override it when you don't want drones to do same stuff as humans. -/atom/proc/attack_drone(mob/living/simple_animal/drone/user, list/modifiers) - if(!user.right_click_attack_chain(src, modifiers)) - attack_hand(user, modifiers) +/mob/living/simple_animal/drone/resolve_right_click_attack(atom/target, list/modifiers) + return target.attack_drone_secondary(src, modifiers) +/// Defaults to attack_hand. Override it when you don't want drones to do same stuff as humans. +/atom/proc/attack_drone(mob/living/simple_animal/drone/user, list/modifiers) + attack_hand(user, modifiers) + +/** + * Called when a maintenance drone right clicks an atom. + * Defaults to attack_hand_secondary. + * When overriding it, remember that it ought to return a SECONDARY_ATTACK_* value. + */ +/atom/proc/attack_drone_secondary(mob/living/simple_animal/drone/user, list/modifiers) + return attack_hand_secondary(user, modifiers) /* Brain @@ -213,26 +272,28 @@ Simple animals */ -/mob/living/simple_animal/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers) - if(LIVING_UNARMED_ATTACK_BLOCKED(attack_target)) - return +/mob/living/simple_animal/resolve_unarmed_attack(atom/attack_target, list/modifiers) if(dextrous && (isitem(attack_target) || !combat_mode)) attack_target.attack_hand(src, modifiers) update_inv_hands() else return ..() +/mob/living/simple_animal/resolve_right_click_attack(atom/target, list/modifiers) + if(dextrous && (isitem(target) || !combat_mode)) + . = target.attack_hand_secondary(src, modifiers) + update_inv_hands() + else + return ..() /* Hostile animals */ -/mob/living/simple_animal/hostile/UnarmedAttack(atom/attack_target, proximity_flag, list/modifiers) - if(LIVING_UNARMED_ATTACK_BLOCKED(attack_target)) - return +/mob/living/simple_animal/hostile/resolve_unarmed_attack(atom/attack_target, list/modifiers) GiveTarget(attack_target) if(dextrous && (isitem(attack_target) || !combat_mode)) - ..() + return ..() else AttackingTarget(attack_target) diff --git a/code/game/objects/items/devices/chameleonproj.dm b/code/game/objects/items/devices/chameleonproj.dm index 343cabad61c..0d73b7b8613 100644 --- a/code/game/objects/items/devices/chameleonproj.dm +++ b/code/game/objects/items/devices/chameleonproj.dm @@ -136,7 +136,7 @@ /obj/effect/dummy/chameleon/attack_animal(mob/user, list/modifiers) master.disrupt() -/obj/effect/dummy/chameleon/attack_slime() +/obj/effect/dummy/chameleon/attack_slime(mob/user, list/modifiers) master.disrupt() /obj/effect/dummy/chameleon/attack_alien(mob/user, list/modifiers) diff --git a/code/game/objects/obj_defense.dm b/code/game/objects/obj_defense.dm index 9282f261896..5daee514f69 100644 --- a/code/game/objects/obj_defense.dm +++ b/code/game/objects/obj_defense.dm @@ -93,7 +93,7 @@ var/amt = max(0, ((force - (move_resist * MOVE_FORCE_CRUSH_RATIO)) / (move_resist * MOVE_FORCE_CRUSH_RATIO)) * 10) take_damage(amt, BRUTE) -/obj/attack_slime(mob/living/simple_animal/slime/user) +/obj/attack_slime(mob/living/simple_animal/slime/user, list/modifiers) if(!user.is_adult) return attack_generic(user, rand(10, 15), BRUTE, MELEE, 1) diff --git a/code/game/objects/structures/ladders.dm b/code/game/objects/structures/ladders.dm index c737d7f4143..b24df6bfea2 100644 --- a/code/game/objects/structures/ladders.dm +++ b/code/game/objects/structures/ladders.dm @@ -9,8 +9,8 @@ var/obj/structure/ladder/down //the ladder below this one var/obj/structure/ladder/up //the ladder above this one var/crafted = FALSE - /// Optional travel time for ladder in deciseconds - var/travel_time = 0 + /// travel time for ladder in deciseconds + var/travel_time = 1 SECONDS /obj/structure/ladder/Initialize(mapload, obj/structure/ladder/up, obj/structure/ladder/down) ..() @@ -23,8 +23,22 @@ src.down = down down.up = src down.update_appearance() + + register_context() + return INITIALIZE_HINT_LATELOAD +/obj/structure/ladder/add_context(atom/source, list/context, obj/item/held_item, mob/user) + if(up) + context[SCREENTIP_CONTEXT_LMB] = "Climb up" + if(down) + context[SCREENTIP_CONTEXT_RMB] = "Climb down" + return CONTEXTUAL_SCREENTIP_SET + +/obj/structure/ladder/examine(mob/user) + . = ..() + . += span_info("Left-click it to start moving up; Right-click to start moving down.") + /obj/structure/ladder/Destroy(force) GLOB.ladders -= src disconnect() @@ -70,50 +84,89 @@ visible_message(span_danger("[src] is torn to pieces by the gravitational pull!")) qdel(src) -/obj/structure/ladder/proc/travel(going_up, mob/user, is_ghost, obj/structure/ladder/ladder) +/obj/structure/ladder/proc/use(mob/user, going_up = TRUE) + if(!in_range(src, user) || DOING_INTERACTION(user, DOAFTER_SOURCE_CLIMBING_LADDER)) + return + + if(!up && !down) + balloon_alert(user, "doesn't lead anywhere!") + return + if(going_up ? !up : !down) + balloon_alert(user, "can't go any further [going_up ? "up" : "down"]") + return + if(travel_time) + INVOKE_ASYNC(src, .proc/start_travelling, user, going_up) + else + travel(user, going_up) + add_fingerprint(user) + +/obj/structure/ladder/proc/start_travelling(mob/user, going_up) + show_initial_fluff_message(user, going_up) + if(do_after(user, travel_time, target = src, interaction_key = DOAFTER_SOURCE_CLIMBING_LADDER)) + travel(user, going_up) + +/// The message shown when the player starts climbing the ladder +/obj/structure/ladder/proc/show_initial_fluff_message(mob/user, going_up) + var/up_down = going_up ? "up" : "down" + user.balloon_alert_to_viewers("climbing [up_down]...") + +/obj/structure/ladder/proc/travel(mob/user, going_up = TRUE, is_ghost = FALSE) + var/obj/structure/ladder/ladder = going_up ? up : down + if(!ladder) + balloon_alert(user, "there's nothing that way!") + return var/response = SEND_SIGNAL(user, COMSIG_LADDER_TRAVEL, src, ladder, going_up) if(response & LADDER_TRAVEL_BLOCK) return - if(!is_ghost) - ladder.add_fingerprint(user) - if(!do_after(user, travel_time, target = src)) - return - show_fluff_message(going_up, user) - var/turf/target = get_turf(ladder) user.zMove(target = target, z_move_flags = ZMOVE_CHECK_PULLEDBY|ZMOVE_ALLOW_BUCKLED|ZMOVE_INCLUDE_PULLED) - ladder.use(user) //reopening ladder radial menu ahead -/obj/structure/ladder/proc/use(mob/user, is_ghost=FALSE) - if (!is_ghost && !in_range(src, user)) - return + if(!is_ghost) + show_final_fluff_message(user, ladder, going_up) + // to avoid having players hunt for the pixels of a ladder that goes through several stories and is + // partially covered by the sprites of their mobs, a radial menu will be displayed over them. + // this way players can keep climbing up or down with ease until they reach an end. + if(ladder.up && ladder.down) + ladder.show_options(user, is_ghost) + +/// The messages shown after the player has finished climbing. Players can see this happen from either src or the destination so we've 2 POVs here +/obj/structure/ladder/proc/show_final_fluff_message(mob/user, obj/structure/ladder/destination, going_up) + var/up_down = going_up ? "up" : "down" + + //POV of players around the source + visible_message(span_notice("[user] climbs [up_down] [src].")) + //POV of players around the destination + user.balloon_alert_to_viewers("climbed [up_down]") + +/// Shows a radial menu that players can use to climb up and down a stair. +/obj/structure/ladder/proc/show_options(mob/user, is_ghost = FALSE) var/list/tool_list = list() - if (up) - tool_list["Up"] = image(icon = 'icons/testing/turf_analysis.dmi', icon_state = "red_arrow", dir = NORTH) - if (down) - tool_list["Down"] = image(icon = 'icons/testing/turf_analysis.dmi', icon_state = "red_arrow", dir = SOUTH) - if (!length(tool_list)) - to_chat(user, span_warning("[src] doesn't seem to lead anywhere!")) - return + tool_list["Up"] = image(icon = 'icons/testing/turf_analysis.dmi', icon_state = "red_arrow", dir = NORTH) + tool_list["Down"] = image(icon = 'icons/testing/turf_analysis.dmi', icon_state = "red_arrow", dir = SOUTH) - var/result = show_radial_menu(user, src, tool_list, custom_check = CALLBACK(src, .proc/check_menu, user, is_ghost), require_near = !is_ghost, tooltips = TRUE) - if (!is_ghost && !in_range(src, user)) - return // nice try + var/datum/callback/check_menu + if(!is_ghost) + check_menu = CALLBACK(src, .proc/check_menu, user) + var/result = show_radial_menu(user, src, tool_list, custom_check = check_menu, require_near = !is_ghost, tooltips = TRUE) + + var/going_up switch(result) if("Up") - travel(TRUE, user, is_ghost, up) + going_up = TRUE if("Down") - travel(FALSE, user, is_ghost, down) + going_up = FALSE if("Cancel") return - if(!is_ghost) - add_fingerprint(user) + if(is_ghost || !travel_time) + travel(user, going_up, is_ghost) + else + INVOKE_ASYNC(src, .proc/start_travelling, user, going_up) /obj/structure/ladder/proc/check_menu(mob/user, is_ghost) - if(user.incapacitated() || (!user.Adjacent(src) && !is_ghost)) + if(user.incapacitated() || (!user.Adjacent(src))) return FALSE return TRUE @@ -123,39 +176,101 @@ return use(user) +/obj/structure/ladder/attack_hand_secondary(mob/user, list/modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return + use(user, going_up = FALSE) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +//Not be called when right clicking as a monkey. attack_hand_secondary() handles that. /obj/structure/ladder/attack_paw(mob/user, list/modifiers) - return use(user) + use(user) + return TRUE /obj/structure/ladder/attack_alien(mob/user, list/modifiers) - return use(user) + use(user) + return TRUE -/obj/structure/ladder/attack_larva(mob/user) - return use(user) +/obj/structure/ladder/attack_alien_secondary(mob/user, list/modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return + use(user, going_up = FALSE) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN -/obj/structure/ladder/attack_animal(mob/user) - return use(user) +/obj/structure/ladder/attack_larva(mob/user, list/modifiers) + use(user) + return TRUE -/obj/structure/ladder/attack_slime(mob/user) - return use(user) +/obj/structure/ladder/attack_larva_secondary(mob/user, list/modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return + use(user, going_up = FALSE) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN -/obj/structure/ladder/attackby(obj/item/W, mob/user, params) - return use(user) +/obj/structure/ladder/attack_animal(mob/user, list/modifiers) + use(user) + return TRUE -/obj/structure/ladder/attack_robot(mob/living/silicon/robot/R) - if(R.Adjacent(src)) - return use(R) +/obj/structure/ladder/attack_animal_secondary(mob/user, list/modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return + use(user, going_up = FALSE) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/structure/ladder/attack_slime(mob/user, list/modifiers) + use(user) + return TRUE + +/obj/structure/ladder/attack_slime_secondary(mob/user, list/modifiers) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return + use(user, going_up = FALSE) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/structure/ladder/attackby(obj/item/item, mob/user, params) + use(user) + return TRUE + +/obj/structure/ladder/attackby_secondary(obj/item/item, mob/user, params) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN) + return + use(user, going_up = FALSE) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + +/obj/structure/ladder/attack_robot(mob/living/silicon/robot/user) + if(user.Adjacent(src)) + use(user) + return TRUE + +/obj/structure/ladder/attack_robot_secondary(mob/living/silicon/robot/user) + . = ..() + if(. == SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN || !user.Adjacent(src)) + return SECONDARY_ATTACK_CONTINUE_CHAIN + use(user, going_up = FALSE) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN //ATTACK GHOST IGNORING PARENT RETURN VALUE /obj/structure/ladder/attack_ghost(mob/dead/observer/user) - use(user, TRUE) + ghost_use(user) return ..() -/obj/structure/ladder/proc/show_fluff_message(going_up, mob/user) - if(going_up) - user.visible_message(span_notice("[user] climbs up [src]."), span_notice("You climb up [src].")) - else - user.visible_message(span_notice("[user] climbs down [src]."), span_notice("You climb down [src].")) - +///Ghosts use the byond default popup menu function on right click, so this is going to work a little differently for them. +/obj/structure/ladder/proc/ghost_use(mob/user) + if (!up && !down) + balloon_alert(user, "doesn't lead anywhere!") + return + if(!up) //only goes down + travel(user, going_up = FALSE, is_ghost = TRUE) + else if(!down) //only goes up + travel(user, going_up = TRUE, is_ghost = TRUE) + else //goes both ways + show_options(user, is_ghost = TRUE) // Indestructible away mission ladders which link based on a mapped ID and height value rather than X/Y/Z. /obj/structure/ladder/unbreakable diff --git a/code/modules/awaymissions/mission_code/Cabin.dm b/code/modules/awaymissions/mission_code/Cabin.dm index 560942117a6..de3c1010f7e 100644 --- a/code/modules/awaymissions/mission_code/Cabin.dm +++ b/code/modules/awaymissions/mission_code/Cabin.dm @@ -114,11 +114,22 @@ . = ..() AddElement(/datum/element/update_icon_blocker) -/obj/structure/ladder/unbreakable/rune/show_fluff_message(up,mob/user) - user.visible_message(span_notice("[user] activates \the [src]."), span_notice("You activate \the [src].")) +/obj/structure/ladder/add_context(atom/source, list/context, obj/item/held_item, mob/user) + if(up) + context[SCREENTIP_CONTEXT_LMB] = "Warp up" + if(down) + context[SCREENTIP_CONTEXT_RMB] = "Warp down" + return CONTEXTUAL_SCREENTIP_SET -/obj/structure/ladder/unbreakable/rune/use(mob/user, is_ghost=FALSE) - if(is_ghost || !IS_WIZARD(user)) +/obj/structure/ladder/unbreakable/rune/show_initial_fluff_message(mob/user, going_up) + user.balloon_alert_to_viewers("activating...") + +/obj/structure/ladder/unbreakable/rune/show_final_fluff_message(mob/user, going_up) + visible_message(span_notice("[user] activates [src] and teleports away.")) + user.balloon_alert_to_viewers("warped in") + +/obj/structure/ladder/unbreakable/rune/use(mob/user, going_up = TRUE) + if(!IS_WIZARD(user)) ..() /*Cabin's forest. Removed in the new cabin map since it was buggy and I prefer manual placement.*/ diff --git a/code/modules/awaymissions/signpost.dm b/code/modules/awaymissions/signpost.dm index ea0d22ac39f..64aaca7aa99 100644 --- a/code/modules/awaymissions/signpost.dm +++ b/code/modules/awaymissions/signpost.dm @@ -39,14 +39,14 @@ /obj/structure/signpost/attack_hulk(mob/user) return -/obj/structure/signpost/attack_larva(mob/user) +/obj/structure/signpost/attack_larva(mob/user, list/modifiers) return interact(user) /obj/structure/signpost/attack_robot(mob/user) if (Adjacent(user)) return interact(user) -/obj/structure/signpost/attack_slime(mob/user) +/obj/structure/signpost/attack_slime(mob/user, list/modifiers) return interact(user) /obj/structure/signpost/attack_animal(mob/user, list/modifiers) diff --git a/code/modules/awaymissions/super_secret_room.dm b/code/modules/awaymissions/super_secret_room.dm index 83c85808256..fa29e662bc3 100644 --- a/code/modules/awaymissions/super_secret_room.dm +++ b/code/modules/awaymissions/super_secret_room.dm @@ -99,13 +99,13 @@ /obj/structure/speaking_tile/attack_hulk(mob/user) return -/obj/structure/speaking_tile/attack_larva(mob/user) +/obj/structure/speaking_tile/attack_larva(mob/user, list/modifiers) return interact(user) /obj/structure/speaking_tile/attack_ai(mob/user) return interact(user) -/obj/structure/speaking_tile/attack_slime(mob/user) +/obj/structure/speaking_tile/attack_slime(mob/user, list/modifiers) return interact(user) /obj/structure/speaking_tile/attack_animal(mob/user, list/modifiers) diff --git a/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm b/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm index c9d36928a65..383d78d76d5 100644 --- a/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm +++ b/code/modules/mapfluff/ruins/spaceruin_code/hilbertshotel.dm @@ -307,10 +307,10 @@ GLOBAL_VAR_INIT(hhMysteryRoomNumber, rand(1, 999999)) /turf/closed/indestructible/hoteldoor/attack_hulk(mob/living/carbon/human/user) promptExit(user) -/turf/closed/indestructible/hoteldoor/attack_larva(mob/user) +/turf/closed/indestructible/hoteldoor/attack_larva(mob/user, list/modifiers) promptExit(user) -/turf/closed/indestructible/hoteldoor/attack_slime(mob/user) +/turf/closed/indestructible/hoteldoor/attack_slime(mob/user, list/modifiers) promptExit(user) /turf/closed/indestructible/hoteldoor/attack_robot(mob/user) diff --git a/code/modules/mob/living/basic/basic_defense.dm b/code/modules/mob/living/basic/basic_defense.dm index 06993b1d1ea..16bf15d46fd 100644 --- a/code/modules/mob/living/basic/basic_defense.dm +++ b/code/modules/mob/living/basic/basic_defense.dm @@ -87,7 +87,7 @@ log_combat(user, src, "attacked") return 1 -/mob/living/basic/attack_larva(mob/living/carbon/alien/larva/L) +/mob/living/basic/attack_larva(mob/living/carbon/alien/larva/L, list/modifiers) . = ..() if(. && stat != DEAD) //successful larva bite var/damage = rand(5, 10) @@ -107,7 +107,7 @@ var/damage = rand(user.melee_damage_lower, user.melee_damage_upper) return attack_threshold_check(damage, user.melee_damage_type) -/mob/living/basic/attack_slime(mob/living/simple_animal/slime/M) +/mob/living/basic/attack_slime(mob/living/simple_animal/slime/M, list/modifiers) if(..()) //successful slime attack var/damage = rand(15, 25) if(M.is_adult) @@ -119,6 +119,11 @@ return return ..() +/mob/living/basic/attack_drone_secondary(mob/living/simple_animal/drone/M) + if(M.combat_mode) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + return ..() + /mob/living/basic/proc/attack_threshold_check(damage, damagetype = BRUTE, armorcheck = MELEE, actuallydamage = TRUE) var/temp_damage = damage if(!damage_coeff[damagetype]) diff --git a/code/modules/mob/living/carbon/alien/alien_defense.dm b/code/modules/mob/living/carbon/alien/alien_defense.dm index 2b2ede04d64..fe613aaaa63 100644 --- a/code/modules/mob/living/carbon/alien/alien_defense.dm +++ b/code/modules/mob/living/carbon/alien/alien_defense.dm @@ -43,7 +43,7 @@ In all, this is a lot like the monkey code. /N -/mob/living/carbon/alien/attack_larva(mob/living/carbon/alien/larva/L) +/mob/living/carbon/alien/attack_larva(mob/living/carbon/alien/larva/L, list/modifiers) return attack_alien(L) @@ -91,7 +91,7 @@ In all, this is a lot like the monkey code. /N if(STAMINA) adjustStaminaLoss(damage) -/mob/living/carbon/alien/attack_slime(mob/living/simple_animal/slime/M) +/mob/living/carbon/alien/attack_slime(mob/living/simple_animal/slime/M, list/modifiers) if(..()) //successful slime attack var/damage = rand(5, 35) if(M.is_adult) diff --git a/code/modules/mob/living/carbon/carbon_defense.dm b/code/modules/mob/living/carbon/carbon_defense.dm index f1270a9f3e9..48b527a4b8c 100644 --- a/code/modules/mob/living/carbon/carbon_defense.dm +++ b/code/modules/mob/living/carbon/carbon_defense.dm @@ -144,6 +144,9 @@ /mob/living/carbon/attack_drone(mob/living/simple_animal/drone/user) return //so we don't call the carbon's attack_hand(). +/mob/living/carbon/attack_drone_secondary(mob/living/simple_animal/drone/user) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + //ATTACK HAND IGNORING PARENT RETURN VALUE /mob/living/carbon/attack_hand(mob/living/carbon/human/user, list/modifiers) @@ -199,7 +202,7 @@ return TRUE -/mob/living/carbon/attack_slime(mob/living/simple_animal/slime/M) +/mob/living/carbon/attack_slime(mob/living/simple_animal/slime/M, list/modifiers) if(..()) //successful slime attack if(M.powerlevel > 0) var/stunprob = M.powerlevel * 7 + 10 // 17 at level 1, 80 at level 10 diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm index 3005e0dc511..3cecdb6350c 100644 --- a/code/modules/mob/living/carbon/human/human_defense.dm +++ b/code/modules/mob/living/carbon/human/human_defense.dm @@ -321,7 +321,7 @@ -/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L) +/mob/living/carbon/human/attack_larva(mob/living/carbon/alien/larva/L, list/modifiers) . = ..() if(!.) return //successful larva bite. @@ -375,7 +375,7 @@ apply_damage(damage, user.melee_damage_type, affecting, armor, wound_bonus = user.wound_bonus, bare_wound_bonus = user.bare_wound_bonus, sharpness = user.sharpness, attack_direction = attack_direction) -/mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M) +/mob/living/carbon/human/attack_slime(mob/living/simple_animal/slime/M, list/modifiers) . = ..() if(!.) // slime attack failed return diff --git a/code/modules/mob/living/living_defense.dm b/code/modules/mob/living/living_defense.dm index e080475e1af..6d99a50b09a 100644 --- a/code/modules/mob/living/living_defense.dm +++ b/code/modules/mob/living/living_defense.dm @@ -208,7 +208,7 @@ return TRUE -/mob/living/attack_slime(mob/living/simple_animal/slime/M) +/mob/living/attack_slime(mob/living/simple_animal/slime/M, list/modifiers) if(!SSticker.HasRoundStarted()) to_chat(M, "You cannot attack people before the game has started.") return @@ -315,7 +315,7 @@ return FALSE -/mob/living/attack_larva(mob/living/carbon/alien/larva/L) +/mob/living/attack_larva(mob/living/carbon/alien/larva/L, list/modifiers) if(L.combat_mode) if(HAS_TRAIT(L, TRAIT_PACIFISM)) to_chat(L, span_warning("You don't want to hurt anyone!")) diff --git a/code/modules/mob/living/silicon/ai/ai_defense.dm b/code/modules/mob/living/silicon/ai/ai_defense.dm index 17e894ccc9f..5124f5c221e 100644 --- a/code/modules/mob/living/silicon/ai/ai_defense.dm +++ b/code/modules/mob/living/silicon/ai/ai_defense.dm @@ -17,7 +17,7 @@ return ..() -/mob/living/silicon/ai/attack_slime(mob/living/simple_animal/slime/user) +/mob/living/silicon/ai/attack_slime(mob/living/simple_animal/slime/user, list/modifiers) return //immune to slimes /mob/living/silicon/ai/blob_act(obj/structure/blob/B) diff --git a/code/modules/mob/living/silicon/robot/robot_defense.dm b/code/modules/mob/living/silicon/robot/robot_defense.dm index 721ab6422f7..f24136d4757 100644 --- a/code/modules/mob/living/silicon/robot/robot_defense.dm +++ b/code/modules/mob/living/silicon/robot/robot_defense.dm @@ -204,7 +204,7 @@ GLOBAL_LIST_INIT(blacklisted_borg_hats, typecacheof(list( //Hats that don't real ..() return -/mob/living/silicon/robot/attack_slime(mob/living/simple_animal/slime/M) +/mob/living/silicon/robot/attack_slime(mob/living/simple_animal/slime/M, list/modifiers) if(..()) //successful slime shock flash_act() var/stunprob = M.powerlevel * 7 + 10 diff --git a/code/modules/mob/living/silicon/silicon_defense.dm b/code/modules/mob/living/silicon/silicon_defense.dm index 7370930b811..587d3410cb3 100644 --- a/code/modules/mob/living/silicon/silicon_defense.dm +++ b/code/modules/mob/living/silicon/silicon_defense.dm @@ -45,7 +45,7 @@ /mob/living/silicon/attack_paw(mob/living/user, list/modifiers) return attack_hand(user, modifiers) -/mob/living/silicon/attack_larva(mob/living/carbon/alien/larva/L) +/mob/living/silicon/attack_larva(mob/living/carbon/alien/larva/L, list/modifiers) if(!L.combat_mode) visible_message(span_notice("[L.name] rubs its head against [src].")) @@ -85,6 +85,11 @@ return return ..() +/mob/living/silicon/attack_drone_secondary(mob/living/simple_animal/drone/M) + if(M.combat_mode) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + return ..() + /mob/living/silicon/electrocute_act(shock_damage, source, siemens_coeff = 1, flags = NONE) if(buckled_mobs) for(var/mob/living/M in buckled_mobs) diff --git a/code/modules/mob/living/simple_animal/animal_defense.dm b/code/modules/mob/living/simple_animal/animal_defense.dm index 3610bc8633a..7301344cc71 100644 --- a/code/modules/mob/living/simple_animal/animal_defense.dm +++ b/code/modules/mob/living/simple_animal/animal_defense.dm @@ -84,7 +84,7 @@ log_combat(user, src, "attacked") return 1 -/mob/living/simple_animal/attack_larva(mob/living/carbon/alien/larva/L) +/mob/living/simple_animal/attack_larva(mob/living/carbon/alien/larva/L, list/modifiers) . = ..() if(. && stat != DEAD) //successful larva bite var/damage = rand(5, 10) @@ -104,7 +104,7 @@ var/damage = rand(user.melee_damage_lower, user.melee_damage_upper) return attack_threshold_check(damage, user.melee_damage_type) -/mob/living/simple_animal/attack_slime(mob/living/simple_animal/slime/M) +/mob/living/simple_animal/attack_slime(mob/living/simple_animal/slime/M, list/modifiers) if(..()) //successful slime attack var/damage = rand(15, 25) if(M.is_adult) @@ -116,6 +116,11 @@ return return ..() +/mob/living/simple_animal/attack_drone_secondary(mob/living/simple_animal/drone/M) + if(M.combat_mode) + return SECONDARY_ATTACK_CANCEL_ATTACK_CHAIN + return ..() + /mob/living/simple_animal/proc/attack_threshold_check(damage, damagetype = BRUTE, armorcheck = MELEE, actuallydamage = TRUE) var/temp_damage = damage if(!damage_coeff[damagetype]) diff --git a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm index 305c221f319..effd7faa3b0 100644 --- a/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm +++ b/code/modules/mob/living/simple_animal/friendly/drone/interaction.dm @@ -28,6 +28,9 @@ else to_chat(drone, span_warning("You need to remain still to cannibalize [src]!")) +/mob/living/simple_animal/drone/attack_drone_secondary(mob/living/simple_animal/drone/drone) + return SECONDARY_ATTACK_CALL_NORMAL + //ATTACK HAND IGNORING PARENT RETURN VALUE /mob/living/simple_animal/drone/attack_hand(mob/user, list/modifiers) if(ishuman(user)) diff --git a/code/modules/mob/living/simple_animal/slime/slime.dm b/code/modules/mob/living/simple_animal/slime/slime.dm index 6e4c0cf8539..754e5e73d15 100644 --- a/code/modules/mob/living/simple_animal/slime/slime.dm +++ b/code/modules/mob/living/simple_animal/slime/slime.dm @@ -277,7 +277,7 @@ /mob/living/simple_animal/slime/attack_ui(slot, params) return -/mob/living/simple_animal/slime/attack_slime(mob/living/simple_animal/slime/M) +/mob/living/simple_animal/slime/attack_slime(mob/living/simple_animal/slime/M, list/modifiers) if(..()) //successful slime attack if(M == src) return @@ -304,7 +304,7 @@ if(..()) //successful monkey bite. attacked += 10 -/mob/living/simple_animal/slime/attack_larva(mob/living/carbon/alien/larva/L) +/mob/living/simple_animal/slime/attack_larva(mob/living/carbon/alien/larva/L, list/modifiers) if(..()) //successful larva bite. attacked += 10