diff --git a/code/_onclick/click.dm b/code/_onclick/click.dm index b7ec77eacc7a..145607375a26 100644 --- a/code/_onclick/click.dm +++ b/code/_onclick/click.dm @@ -183,15 +183,13 @@ return /mob/living/UnarmedAttack(var/atom/A, var/proximity_flag) - if(GAME_STATE < RUNLEVEL_GAME) to_chat(src, "You cannot attack people before the game has started.") - return 0 - + return FALSE if(stat) - return 0 - - return 1 + return FALSE + try_maneuver(A) + return TRUE /* Ranged unarmed attack: @@ -204,6 +202,9 @@ /mob/proc/RangedAttack(var/atom/A, var/params) return FALSE +/mob/living/RangedAttack(var/atom/A, var/params) + return try_maneuver(A) + /* Restrained ClickOn diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm index a40889dc4d61..7871fe1c9b16 100644 --- a/code/_onclick/hud/human.dm +++ b/code/_onclick/hud/human.dm @@ -65,6 +65,13 @@ using.alpha = ui_alpha src.hotkeybuttons += using + mymob.maneuver_icon = new + mymob.maneuver_icon.icon = ui_style + mymob.maneuver_icon.color = ui_color + mymob.maneuver_icon.alpha = ui_alpha + src.hotkeybuttons += mymob.maneuver_icon + hud_elements |= mymob.maneuver_icon + if(hud_data.has_throw) mymob.throw_icon = new /obj/screen() mymob.throw_icon.icon = ui_style diff --git a/code/_onclick/hud/screen/_screen.dm b/code/_onclick/hud/screen/_screen.dm new file mode 100644 index 000000000000..7dd4349ee7ff --- /dev/null +++ b/code/_onclick/hud/screen/_screen.dm @@ -0,0 +1,7 @@ +/obj/screen/proc/handle_click(mob/user, params) + return + +/obj/screen/Click(location, control, params) + if(ismob(usr) && usr.client && usr.canClick() && !usr.incapacitated()) + return handle_click(usr, params) + return FALSE \ No newline at end of file diff --git a/code/_onclick/hud/screen/screen_maneuver.dm b/code/_onclick/hud/screen/screen_maneuver.dm new file mode 100644 index 000000000000..76c524467e5e --- /dev/null +++ b/code/_onclick/hud/screen/screen_maneuver.dm @@ -0,0 +1,19 @@ +/obj/screen/maneuver + name = "Prepare Maneuver" + icon_state = "maneuver_off" + screen_loc = ui_pull_resist + +/obj/screen/maneuver/handle_click(mob/user, params) + if(isliving(user)) + var/mob/living/user_living = user + user_living.prepare_maneuver() + +/obj/screen/maneuver/examine(mob/user) + . = ..() + if(!isliving(user)) + return + var/mob/living/user_living = user + if(user_living.prepared_maneuver) + to_chat(src, SPAN_NOTICE("You are prepared to [user_living.prepared_maneuver.name].")) + else + to_chat(src, SPAN_NOTICE("You are not prepared to perform a maneuver.")) diff --git a/code/_onclick/other_mobs.dm b/code/_onclick/other_mobs.dm index d529f620b2fc..0ea491ceec68 100644 --- a/code/_onclick/other_mobs.dm +++ b/code/_onclick/other_mobs.dm @@ -43,12 +43,6 @@ /mob/living/carbon/human/RestrainedClickOn(var/atom/A) return -/mob/living/CtrlClickOn(var/atom/A) - . = ..() - if(!. && a_intent == I_GRAB && length(available_maneuvers)) - . = perform_maneuver(prepared_maneuver || available_maneuvers[1], A) - - /mob/living/carbon/human/RangedAttack(var/atom/A, var/params) //Climbing up open spaces if(isturf(loc) && bound_overlay && !is_physically_disabled() && istype(A) && A.can_climb_from_below(src)) diff --git a/code/modules/mob/living/living_maneuvers.dm b/code/modules/mob/living/living_maneuvers.dm index 5637a34e83e0..85a2a06bcbec 100644 --- a/code/modules/mob/living/living_maneuvers.dm +++ b/code/modules/mob/living/living_maneuvers.dm @@ -21,10 +21,19 @@ /mob/living/proc/reflexive_maneuver_callback(var/turf/origin, var/turf/check) if(prepared_maneuver) - if(origin) + if(origin) // Used to avoid falling into open space. forceMove(get_turf(origin)) prepared_maneuver.perform(src, check, get_acrobatics_multiplier(prepared_maneuver), reflexively = TRUE) prepared_maneuver = null + maneuver_icon.icon_state = "maneuver_off" + +/mob/living/proc/try_maneuver(var/atom/target) + if(prepared_maneuver && (isturf(target) || isturf(target.loc))) // Avoid trying to jump at your backpack contents. + prepared_maneuver.perform(src, get_turf(target), get_acrobatics_multiplier(prepared_maneuver)) + prepared_maneuver = null + maneuver_icon.icon_state = "maneuver_off" + return TRUE + return FALSE /mob/living/verb/prepare_maneuver() set name = "Prepare To Maneuver" @@ -35,22 +44,34 @@ to_chat(src, SPAN_WARNING("You are unable to perform any maneuvers.")) return + var/list/maneuvers_by_name = list() var/list/maneuvers = list() for(var/maneuver in available_maneuvers) - maneuvers += GET_DECL(maneuver) + var/decl/maneuver/maneuver_decl = GET_DECL(maneuver) + maneuvers_by_name[maneuver_decl.name] = maneuver_decl + var/image/I = image(maneuver_decl.selection_icon, maneuver_decl.selection_icon_state) + I.name = capitalize(maneuver_decl.name) + maneuvers[maneuver_decl.name] = I - var/next_maneuver = input(src, "Select a maneuver.") as null|anything in maneuvers + var/next_maneuver = show_radial_menu(src, src, maneuvers, require_near = TRUE, radius = 42, tooltips = TRUE, check_locs = list(src), use_labels = TRUE) if(next_maneuver) - prepared_maneuver = next_maneuver + var/decl/maneuver/maneuver = maneuvers_by_name[next_maneuver] + if(!maneuver.can_be_used_by(src, null)) + return + prepared_maneuver = maneuver + maneuver_icon.icon_state = "maneuver_on" to_chat(src, SPAN_NOTICE("You prepare to [prepared_maneuver.name].")) else prepared_maneuver = null + maneuver_icon.icon_state = "maneuver_off" to_chat(src, SPAN_NOTICE("You are no longer preparing to perform a maneuver.")) /mob/living/proc/perform_maneuver(var/maneuver, var/atom/target) var/decl/maneuver/performing_maneuver = ispath(maneuver) ? GET_DECL(maneuver) : maneuver if(istype(performing_maneuver)) . = performing_maneuver.perform(src, target, get_acrobatics_multiplier(performing_maneuver)) + prepared_maneuver = null + maneuver_icon.icon_state = "maneuver_off" /mob/living/proc/get_acrobatics_multiplier(var/decl/maneuver/attempting_maneuver) return 1 diff --git a/code/modules/mob/living/maneuvers/_maneuver.dm b/code/modules/mob/living/maneuvers/_maneuver.dm index e3effad65188..788c299aa2d2 100644 --- a/code/modules/mob/living/maneuvers/_maneuver.dm +++ b/code/modules/mob/living/maneuvers/_maneuver.dm @@ -1,9 +1,21 @@ /decl/maneuver + abstract_type = /decl/maneuver var/name = "unnamed" var/delay = 2 SECONDS var/cooldown = 10 SECONDS var/stamina_cost = 10 var/reflexive_modifier = 1 + var/selection_icon = 'icons/screen/maneuver.dmi' + var/selection_icon_state + +/decl/maneuver/validate() + . = ..() + if(!selection_icon) + . += "no selection icon" + else if(!selection_icon_state) + . += "no selection icon_state" + else if(!check_state_in_icon(selection_icon_state, selection_icon)) + . += "selection icon_state [selection_icon_state] not found in icon [selection_icon]" /decl/maneuver/proc/can_be_used_by(var/mob/living/user, var/atom/target, var/silent = FALSE) if(!istype(user) || !user.can_do_maneuver(src, silent)) @@ -22,7 +34,7 @@ return FALSE if(user.is_on_special_ability_cooldown()) if(!silent) - to_chat(user, SPAN_WARNING("You cannot maneuver again for another [user.get_seconds_until_next_special_ability_string()]")) + to_chat(user, SPAN_WARNING("You cannot maneuver again for another [user.get_seconds_until_next_special_ability_string()].")) return FALSE if(user.get_stamina() < stamina_cost) if(!silent) diff --git a/code/modules/mob/living/maneuvers/maneuver_leap.dm b/code/modules/mob/living/maneuvers/maneuver_leap.dm index e148d33e705b..72243454579d 100644 --- a/code/modules/mob/living/maneuvers/maneuver_leap.dm +++ b/code/modules/mob/living/maneuvers/maneuver_leap.dm @@ -2,6 +2,7 @@ name = "leap" stamina_cost = 10 reflexive_modifier = 1.5 + selection_icon_state = "leap" /decl/maneuver/leap/perform(var/mob/living/user, var/atom/target, var/strength, var/reflexively = FALSE) . = ..() @@ -29,6 +30,8 @@ if(.) var/can_leap_distance = user.get_jump_distance() * user.get_acrobatics_multiplier() . = (can_leap_distance > 0 && (!target || get_dist(user, target) <= can_leap_distance)) + if(!. && !silent) + to_chat(user, SPAN_WARNING("You cannot leap that far!")) /decl/maneuver/leap/spider stamina_cost = 0 diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm index 5029ce8c14d7..c4da4cdcd8cd 100644 --- a/code/modules/mob/mob.dm +++ b/code/modules/mob/mob.dm @@ -44,6 +44,7 @@ QDEL_NULL_SCREEN(bodytemp) QDEL_NULL_SCREEN(healths) QDEL_NULL_SCREEN(throw_icon) + QDEL_NULL_SCREEN(maneuver_icon) QDEL_NULL_SCREEN(nutrition_icon) QDEL_NULL_SCREEN(hydration_icon) QDEL_NULL_SCREEN(pressure) diff --git a/code/modules/mob/mob_defines.dm b/code/modules/mob/mob_defines.dm index 595b81c515b8..56a221ded68c 100644 --- a/code/modules/mob/mob_defines.dm +++ b/code/modules/mob/mob_defines.dm @@ -49,6 +49,7 @@ var/obj/screen/bodytemp = null var/obj/screen/healths = null var/obj/screen/throw_icon = null + var/obj/screen/maneuver/maneuver_icon = null var/obj/screen/nutrition_icon = null var/obj/screen/hydration_icon = null var/obj/screen/pressure = null diff --git a/icons/mob/screen/midnight.dmi b/icons/mob/screen/midnight.dmi index 01dbd6c64791..e1dab709439b 100644 Binary files a/icons/mob/screen/midnight.dmi and b/icons/mob/screen/midnight.dmi differ diff --git a/icons/mob/screen/minimalist.dmi b/icons/mob/screen/minimalist.dmi index e87aebf13123..27659edeaa86 100644 Binary files a/icons/mob/screen/minimalist.dmi and b/icons/mob/screen/minimalist.dmi differ diff --git a/icons/mob/screen/old-noborder.dmi b/icons/mob/screen/old-noborder.dmi index 18e49fc9c881..7b4802324595 100644 Binary files a/icons/mob/screen/old-noborder.dmi and b/icons/mob/screen/old-noborder.dmi differ diff --git a/icons/mob/screen/old.dmi b/icons/mob/screen/old.dmi index cc52abc3909b..c2dec58411a0 100644 Binary files a/icons/mob/screen/old.dmi and b/icons/mob/screen/old.dmi differ diff --git a/icons/mob/screen/orange.dmi b/icons/mob/screen/orange.dmi index cb94ada06c88..e04a5729f4d7 100644 Binary files a/icons/mob/screen/orange.dmi and b/icons/mob/screen/orange.dmi differ diff --git a/icons/mob/screen/white.dmi b/icons/mob/screen/white.dmi index 10d35d02cff4..709ff0cab015 100644 Binary files a/icons/mob/screen/white.dmi and b/icons/mob/screen/white.dmi differ diff --git a/icons/screen/maneuver.dmi b/icons/screen/maneuver.dmi new file mode 100644 index 000000000000..0a4676979c2d Binary files /dev/null and b/icons/screen/maneuver.dmi differ diff --git a/nebula.dme b/nebula.dme index d023feafb73b..c59f1c82b9ad 100644 --- a/nebula.dme +++ b/nebula.dme @@ -182,6 +182,8 @@ #include "code\_onclick\hud\robot.dm" #include "code\_onclick\hud\screen_objects.dm" #include "code\_onclick\hud\skybox.dm" +#include "code\_onclick\hud\screen\_screen.dm" +#include "code\_onclick\hud\screen\screen_maneuver.dm" #include "code\controllers\admin.dm" #include "code\controllers\autotransfer.dm" #include "code\controllers\communications.dm"