Taj rebalance patch (#22451)

This is based on requests from the taj lore team. A future PR will do
more for the sensitive hearing as well, but the PR was growing by quite
a lot so it was best to split it up.

New: 
- Tajaran eyes can now extend their vision by 3 tiles while they stand
still.
- Taj can hear people whispering and talking into radios from 1 tiles
further away, if they are listening intently.

Bugfixes:
- Flashbangs no longer fuck taj up as much unless they got intent listen
active.
- The message for autakh farseer eyes no longer gives the wrong message
if it is disabled by moving.

Balance & Change:
- Taj have new heights. Before it was 150 to 190 cm
  - Hharar: 145-180
  - M'sai: 155-175
  - Zhan: 160-195
- The brute mod have been adjusted on tajara
  - Zhan: 10% -> 5%
  - Hharar: 20% -> 10%
  - M'sai: 30% -> 15%

Backend stuff:
- Action buttons were changed to accept lists, so multiple actions can
be given to a single item.
This commit is contained in:
Casper3667
2026-06-01 10:36:57 +00:00
committed by GitHub
parent 1b60e9948d
commit 8e53577ee7
14 changed files with 162 additions and 32 deletions
@@ -166,6 +166,7 @@
icon_state = "revenant_eyes"
eye_emote = null
vision_color = null
action_button_name = list("Activate Low Light Vision")
default_action_type = /datum/action/item_action/organ/night_eyes/rev
/obj/item/organ/internal/eyes/night/revenant/flash_act()
@@ -5,8 +5,8 @@
category_name = "Tajara"
bodytype = BODYTYPE_TAJARA
species_height = HEIGHT_CLASS_SHORT
height_min = 150
height_max = 190
height_min = 145 // human default: 145
height_max = 180 // human default: 203
icobase = 'icons/mob/human_races/tajara/r_tajaran.dmi'
deform = 'icons/mob/human_races/tajara/r_def_tajaran.dmi'
preview_icon = 'icons/mob/human_races/tajara/tajaran_preview.dmi'
@@ -27,7 +27,7 @@
darksight = 8
slowdown = -0.4
brute_mod = 1.2
brute_mod = 1.1
fall_mod = 0.5
grab_mod = 1.25 // Fur easy to cling onto
@@ -10,6 +10,8 @@
an easy path to education. Zhan-Khazan are in a transformative state in modern Tajaran society, \
but still deal with the many barriers from centuries of the caste system."
species_height = HEIGHT_CLASS_TALL
height_min = 160 // taj default: 145
height_max = 195 // taj default: 180
secondary_langs = list(LANGUAGE_SIIK_TAJR, LANGUAGE_DELVAHII)
@@ -17,7 +19,7 @@
sprint_speed_factor = 0.55
standing_jump_range = 2
stamina = 100 // As opposed to 90
brute_mod = 1.1 // Less Brute Damage
brute_mod = 1.05 // Less Brute Damage
ethanol_resistance = 1 // Default value
climb_coeff = 1.1
@@ -59,12 +61,14 @@
When these roles were shrunken down however, the M'sai commonly found themselves taking \
similar work to the Zhan-Khazan. As a result, the two races share much in common with their culture."
species_height = HEIGHT_CLASS_AVERAGE
height_min = 155 // taj default: 145
height_max = 175 // taj default: 180
slowdown = -0.6
sprint_speed_factor = 0.75
standing_jump_range = 3
stamina = 80 // As opposed to 90
brute_mod = 1.3 // More Brute Damage
brute_mod = 1.15 // More Brute Damage
ethanol_resistance = 0.7 // Species Default 0.9
maneuvers = list(
+39 -8
View File
@@ -503,19 +503,50 @@
A.Remove(src)
for(var/obj/item/I in src)
if(I.action_button_name)
if(!I.action_button_name)
continue
//If the item_action object does not exist, try to create it
var/list/action_names = islist(I.action_button_name) ? I.action_button_name : list(I.action_button_name)
var/list/action_types = islist(I.default_action_type) ? I.default_action_type : list(I.default_action_type)
if(action_names.len > 1)
if(!islist(I.action))
I.action = I.action ? list(I.action) : list()
var/list/actions_list = I.action
for(var/i in 1 to action_names.len)
var/action_name = action_names[i]
if(!action_name)
continue
var/datum/action/item_action = (i <= actions_list.len) ? actions_list[i] : null
if(!item_action)
var/action_type = action_types.len >= i ? action_types[i] : action_types[1]
if(!action_type)
continue
item_action = new action_type
actions_list.Add(item_action)
item_action.name = action_name
item_action.SetTarget(I)
item_action.Grant(src)
else
if(!I.action)
//Try to use the default action type, if there is none, skip this implant
if(I.default_action_type)
I.action = new I.default_action_type
var/action_type = action_types.len ? action_types[1] : null
if(action_type)
I.action = new action_type
else
continue
I.action.name = I.action_button_name
I.action.SetTarget(I)
I.action.Grant(src)
var/datum/action/item_action = I.action
item_action.name = action_names[1]
item_action.SetTarget(I)
item_action.Grant(src)
return
/mob/living/update_action_buttons()
+3
View File
@@ -330,6 +330,9 @@ var/list/channel_to_radio_key = new
listening = get_hearers_in_view(message_range, src)
var/sensitive_listener = get_intent_listeners(src, message_range + 1)
listening = mergelists(listening, sensitive_listener, TRUE)
if(client)
for (var/mob/player_mob in GLOB.player_list)
if(!player_mob || player_mob.stat != DEAD || (player_mob in listening))
+6 -3
View File
@@ -60,11 +60,14 @@
var/list/observers = list()
var/list/all_in_range = hearers(watching_range, src)
for(var/mob/M as anything in all_in_range)
if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS)) //Preventing duplicate messages to ghostear'd observers
// If they got sensitive hearing enabled, increase the whisper hearing range by one
var/sensitive = astype(M, /mob/living/carbon/human)?.is_listening() ? 1 : 0
//Preventing duplicate messages to ghostear'd observers
if(M.stat == DEAD && M.client && (M.client.prefs.toggles & CHAT_GHOSTEARS))
continue
if(get_dist(src, M) <= message_range) //In range to hear
if(get_dist(src, M) <= (message_range + sensitive)) //In range to hear
continue
else if(get_dist(src, M) <= eavesdropping_range)
else if(get_dist(src, M) <= (eavesdropping_range + sensitive))
if(M.stat == DEAD && M.client)
observers += M
else
+34 -8
View File
@@ -2,14 +2,16 @@
name = "light sensitive eyes"
desc = "A pair of Tajaran eyes accustomed to the low light conditions of Adhomai."
icon = 'icons/obj/organs/tajara_organs.dmi'
action_button_name = "Activate Low Light Vision"
default_action_type = /datum/action/item_action/organ/night_eyes
action_button_name = list("Activate Low Light Vision", "Extend vision")
default_action_type = list(/datum/action/item_action/organ/night_eyes, /datum/action/item_action/organ/extended_eyes)
relative_size = 8
var/night_vision = FALSE
var/datum/client_color/vision_color = /datum/client_color/monochrome
var/datum/client_color/vision_mechanical_color = /datum/client_color/monochrome
var/eye_emote = "'s eyes dilate!"
var/allowed_model = PROSTHETIC_TESLA //what robotic model allows this eyes to use the night vision
var/cooldown = 30
zoom_out_message = "'s eyes widens as they stop focusing ahead."
/obj/item/organ/internal/eyes/night/Destroy()
disable_night_vision()
@@ -25,25 +27,49 @@
/obj/item/organ/internal/eyes/night/attack_self(var/mob/user)
. = ..()
/obj/item/organ/internal/eyes/night/proc/ability_check()
if(owner.last_special > world.time)
return
return FALSE
if(owner.stat || owner.paralysis || owner.stunned || owner.weakened)
return
return FALSE
if(is_broken())
return
return FALSE
if(status & ORGAN_ROBOT)
if(!robotic_check())
return
return FALSE
owner.last_special = world.time + 20
return TRUE
/obj/item/organ/internal/eyes/night/proc/night_vision()
if(attack_self())
return
if(!ability_check())
return
if(!night_vision)
enable_night_vision()
else
disable_night_vision()
owner.last_special = world.time + 20
/obj/item/organ/internal/eyes/night/proc/extended_vision()
if(attack_self())
return
if(!ability_check())
return
if(zoom)
owner.visible_message("[SPAN_BOLD("\The [owner]")]'s eyes widens as they stop focusing ahead.", range = 3)
else
owner.visible_message("[SPAN_BOLD("\The [owner]")]'s eyes begins to narrow as they focus on something in the distance.", range = 3)
if(!do_after(owner, 1.5 SECONDS))
owner.visible_message("[SPAN_BOLD("\The [owner]")]'s eyes stop focusing.", range = 3)
return
owner.visible_message("[SPAN_BOLD("\The [owner]")]'s eyes narrows as their lenses shift to focus ahead.", range = 3)
zoom(owner, 3, 7, FALSE, FALSE)
/obj/item/organ/internal/eyes/night/proc/robotic_check(var/mob/user)
if(robotize_type == allowed_model)
@@ -89,7 +115,7 @@
show_message = FALSE
break
if(show_message && eye_emote)
owner.visible_message("<b>[owner]</b>[eye_emote]")
owner.visible_message("[SPAN_BOLD("\The [owner]")][eye_emote]")
night_vision = TRUE
if(can_change_invisible())
@@ -3,6 +3,8 @@
desc = "A set of four vaurcaesian eyes, adapted to the low or no light tunnels of Sedantis."
icon = 'icons/obj/organs/vaurca_organs.dmi'
robotic_sprite = FALSE
action_button_name = list("Activate Low Light Vision")
default_action_type = list(/datum/action/item_action/organ/night_eyes)
vision_color = /datum/client_color/vaurca
vision_mechanical_color = /datum/client_color/monochrome
eye_emote = "'s eyes gently shift."
+1
View File
@@ -190,6 +190,7 @@
action_button_icon = "hunterseye"
cooldown = 30
activable = TRUE
zoom_out_message = " eyes whirrs loudly as the zoom lenses retract."
/obj/item/organ/internal/augment/farseer_eye/attack_self(var/mob/user)
. = ..()