Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions code/__DEFINES/economy.dm
Original file line number Diff line number Diff line change
Expand Up @@ -90,13 +90,13 @@
/// The symbol for the default type of money used in the code.
#define MONEY_SYMBOL "♎︎︎" // REDSHIFT EDIT - #define MONEY_SYMBOL "cr"
/// The name for the default type of money used in the code.
#define MONEY_NAME = "libre" // REDSHIFT EDIT - #define MONEY_NAME "credits"
#define MONEY_NAME_SINGULAR = "libra" // REDSHIFT EDIT - #define MONEY_NAME_SINGULAR "credit"
#define MONEY_NAME_CAPITALIZED = "Libre" // REDSHIFT EDIT - #define MONEY_NAME_CAPITALIZED "Credits"
#define MONEY_NAME "libre" // REDSHIFT EDIT - #define MONEY_NAME "credits"
#define MONEY_NAME_SINGULAR "libra" // REDSHIFT EDIT - #define MONEY_NAME_SINGULAR "credit"
#define MONEY_NAME_CAPITALIZED "Libre" // REDSHIFT EDIT - #define MONEY_NAME_CAPITALIZED "Credits"
// Due to the ways macros work, I cant just directly use credit\s.
// You will need to verify there is no loose use cases of credit\s.
// As of present there is none left floating around.
#define MONEY_NAME_AUTOPLURAL(amount) "libr[##amount == 1 ? "a" : "e"]" // REDSHIFT EDIT - #define MONEY_NAME_AUTOPURAL(amount) "credit[##amount == 1 ? "" : "s"]"
#define MONEY_NAME_AUTOPURAL(amount) "libr[##amount == 1 ? "a" : "e"]" // REDSHIFT EDIT - #define MONEY_NAME_AUTOPURAL(amount) "credit[##amount == 1 ? "" : "s"]"

#define MONEY_MINING_SYMBOL "mp"
#define MONEY_BITRUNNING_SYMBOL "np"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,10 @@
#define MAX_ATTRIBUTE_SCORE 10
/// The default value of an attribute
#define DEFAULT_ATTRIBUTE_SCORE 5

/// The maximum value that a skill can hold
#define MAX_SKILL_LEVEL 15

// All skills that a mob can have are defined below
/// Skill at using non-weapon items as a weapon
#define SKILL_WEAPON_ECCENTRIC "Eccentric Weapon User"
22 changes: 19 additions & 3 deletions code/_onclick/item_attack.dm
Original file line number Diff line number Diff line change
Expand Up @@ -317,12 +317,24 @@
return ATTACK_FAILED

/mob/living/attacked_by(obj/item/attacking_item, mob/living/user, list/modifiers, list/attack_modifiers)

// REDSHIFT ADDITION
var/chance_to_actually_get_hit = 100
if(user != src) // If we're attacking ourselves we always hit
chance_to_actually_get_hit += get_melee_dodge_modifier()
if(!isnull(attacking_item.combat_skill_hit_chance))
chance_to_actually_get_hit += user.target_chance_skill_modifier(attacking_item.combat_skill_hit_chance)
if(!prob(chance_to_actually_get_hit))
make_attack_dodge_message(attacking_item, user)
// REDSHIFT ADDITION END
var/targeting = check_zone(user.zone_selected)
if(user != src)
var/zone_hit_chance = 80
if(body_position == LYING_DOWN)
zone_hit_chance += 10
// REDSHIFT ADDITION
if(!isnull(attacking_item.combat_skill_hit_chance))
zone_hit_chance += user.target_chance_skill_modifier(attacking_item.combat_skill_hit_chance)
// REDSHIFT ADDITION END
targeting = get_random_valid_zone(targeting, zone_hit_chance)
var/targeting_human_readable = parse_zone_with_bodypart(targeting)

Expand All @@ -339,6 +351,10 @@
), ARMOR_MAX_BLOCK)

var/final_force = CALCULATE_FORCE(attacking_item, attack_modifiers)
// REDSHIFT ADDITION
if(!isnull(attacking_item.combat_attribute_damage_modifier))
final_force = get_weapon_damage_mod(attacking_item.combat_attribute_damage_modifier, final_force)
// REDSHIFT ADDITION END
if(mob_biotypes & (MOB_ROBOTIC|MOB_MINERAL|MOB_SKELETAL)) // this should probably check hit bodypart for humanoids
final_force *= attacking_item.get_demolition_modifier(src)

Expand Down Expand Up @@ -530,9 +546,9 @@
if(user == src)
attack_message_victim = "You [message_verb_simple] yourself[message_hit_area] with [weapon]."
visible_message(span_danger("[attack_message_spectator]"),\
span_userdanger("[attack_message_victim]"), null, COMBAT_MESSAGE_RANGE, user)
span_boldselfwarning("[attack_message_victim]"), null, COMBAT_MESSAGE_RANGE, user) // REDSHIFT EDIT - span_userdanger("[attack_message_victim]") , null, COMBAT_MESSAGE_RANGE, user)
if(is_blind())
to_chat(src, span_danger("Someone hits you[message_hit_area]!"))
to_chat(src, span_selfwarning("Someone hits you[message_hit_area]!")) // REDSHIFT EDIT - to_chat(src, span_danger("Someone hits you[message_hit_area]!"))
to_chat(user, span_danger("[attack_message_attacker]"))
return 1

Expand Down
2 changes: 1 addition & 1 deletion code/modules/mob/living/carbon/carbon_defense.dm
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
if(user == src)
attack_message_victim = "You [message_verb_simple] yourself[message_hit_area] with [weapon][extra_wound_details]!"
visible_message(span_danger("[attack_message_spectator]"),\
span_userdanger("[attack_message_victim]"), null, COMBAT_MESSAGE_RANGE, user)
span_boldselfwarning("[attack_message_victim]"), null, COMBAT_MESSAGE_RANGE, user) // REDSHIFT EDIT - span_userdanger("[attack_message_victim]"), null, COMBAT_MESSAGE_RANGE, user)
if(user != src)
to_chat(user, span_danger("[attack_message_attacker]"))
return TRUE
Expand Down
18 changes: 9 additions & 9 deletions code/modules/mob/living/carbon/human/_species.dm
Original file line number Diff line number Diff line change
Expand Up @@ -860,7 +860,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
if(!damage || !affecting || prob(miss_chance))//future-proofing for species that have 0 damage/weird cases where no zone is targeted
playsound(target.loc, attacking_bodypart.unarmed_miss_sound, 25, TRUE, -1)
target.visible_message(span_danger("[user]'s [atk_verb] misses [target]!"), \
span_danger("You avoid [user]'s [atk_verb]!"), span_hear("You hear a swoosh!"), COMBAT_MESSAGE_RANGE, user)
span_selfwarning("You avoid [user]'s [atk_verb]!"), span_hear("You hear a swoosh!"), COMBAT_MESSAGE_RANGE, user) // REDSHIFT EDIT - span_danger("You avoid [user]'s [atk_verb]!"), span_hear("You hear a swoosh!"), COMBAT_MESSAGE_RANGE, user)
to_chat(user, span_warning("Your [atk_verb] misses [target]!"))
log_combat(user, target, "attempted to punch")
return FALSE
Expand Down Expand Up @@ -888,7 +888,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
atk_verb_continuous = attacking_bodypart.grappled_attack_verb_continuous

target.visible_message(span_danger("[user] [atk_verb_continuous] [target]!"), \
span_userdanger("[user] [atk_verb_continuous] you!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), COMBAT_MESSAGE_RANGE, user)
span_boldselfwarning("[user] [atk_verb_continuous] you!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), COMBAT_MESSAGE_RANGE, user) // REDSHIFT EDIT - span_userdanger("[user] [atk_verb_continuous] you!"), span_hear("You hear a sickening sound of flesh hitting flesh!"), COMBAT_MESSAGE_RANGE, user)
to_chat(user, span_danger("You [atk_verb] [target]!"))

target.lastattacker = user.real_name
Expand Down Expand Up @@ -944,43 +944,43 @@ GLOBAL_LIST_EMPTY(features_by_species)
if (-INFINITY to 0) //Mostly a gimmie, this one just keeps them staggered briefly
target.adjust_staggered_up_to(1 SECONDS, 10 SECONDS)
target.visible_message(span_warning("[user]'s [atk_verb] briefly winds [target]!"), \
span_warning("You are briefly winded by [user]'s [atk_verb]!"), span_hear("You hear a thud!"), COMBAT_MESSAGE_RANGE, user)
span_boldselfwarning("You are briefly winded by [user]'s [atk_verb]!"), span_hear("You hear a thud!"), COMBAT_MESSAGE_RANGE, user) // REDSHIFT EDIT - span_warning("You are briefly winded by [user]'s [atk_verb]!"), span_hear("You hear a thud!"), COMBAT_MESSAGE_RANGE, user)
to_chat(user, span_warning("Your [atk_verb] briefly winds [target]!"))

if (1 to 10)
target.adjust_eye_blur_up_to(5 SECONDS, 10 SECONDS)
target.visible_message(span_warning("[user]'s [atk_verb] hits [target] so hard, their eyes water! Ouch!"), \
span_warning("You are hit viciously by [user]'s [atk_verb], and your eyes begin to water!"), span_hear("You hear a thud!"), COMBAT_MESSAGE_RANGE, user)
span_boldselfwarning("You are hit viciously by [user]'s [atk_verb], and your eyes begin to water!"), span_hear("You hear a thud!"), COMBAT_MESSAGE_RANGE, user) // REDSHIFT EDIT - span_warning("You are hit viciously by [user]'s [atk_verb], and your eyes begin to water!"), span_hear("You hear a thud!"), COMBAT_MESSAGE_RANGE, user)
to_chat(user, span_warning("Your [atk_verb] causes [target] to tear up!"))

if (11 to 30)
target.adjust_dizzy_up_to(5 SECONDS, 10 SECONDS)
target.adjust_eye_blur_up_to(5 SECONDS, 10 SECONDS)
target.adjust_confusion_up_to(5 SECONDS, 10 SECONDS)
target.visible_message(span_warning("[user]'s [atk_verb] hits [target] so hard, they are sent reeling in agony! Damn!"), \
span_warning("You are hit viciously by [user]'s [atk_verb], and everything becomes a dizzying blur!"), span_hear("You hear a thud!"), COMBAT_MESSAGE_RANGE, user)
span_boldselfwarning("You are hit viciously by [user]'s [atk_verb], and everything becomes a dizzying blur!"), span_hear("You hear a thud!"), COMBAT_MESSAGE_RANGE, user) // REDSHIFT EDIT - pan_warning("You are hit viciously by [user]'s [atk_verb], and everything becomes a dizzying blur!"), span_hear("You hear a thud!"), COMBAT_MESSAGE_RANGE, user)
to_chat(user, span_warning("Your [atk_verb] causes [target] to go stumbling about in a confuzed daze!"))

if(31 to 40)
target.adjust_dizzy_up_to(5 SECONDS, 10 SECONDS)
target.adjust_confusion_up_to(5 SECONDS, 10 SECONDS)
target.adjust_temp_blindness_up_to(5 SECONDS, 10 SECONDS)
target.visible_message(span_warning("[user]'s [atk_verb] hits [target] so hard, they are sent reeling blindly in agony! Goddamn!"), \
span_warning("You are hit viciously by [user]'s [atk_verb], and everything becomes a dizzying, blinding blur!"), span_hear("You hear a thud!"), COMBAT_MESSAGE_RANGE, user)
span_boldselfwarning("You are hit viciously by [user]'s [atk_verb], and everything becomes a dizzying, blinding blur!"), span_hear("You hear a thud!"), COMBAT_MESSAGE_RANGE, user) // REDSHIFT EDIT - span_warning("You are hit viciously by [user]'s [atk_verb], and everything becomes a dizzying, blinding blur!"), span_hear("You hear a thud!"), COMBAT_MESSAGE_RANGE, user)
to_chat(user, span_warning("Your [atk_verb] causes [target] to go stumbling about in a confuzed, blind daze!"))

if (41 to 45)
target.apply_effect(4 SECONDS, EFFECT_KNOCKDOWN, armor_block)
target.visible_message(span_warning("[user]'s [atk_verb] hits [target] so hard, you knock them off their feet! Holy shit!"), \
span_warning("You are hit viciously by [user]'s [atk_verb] and sent toppling head over heels!"), span_hear("You hear a sickening thud!"), COMBAT_MESSAGE_RANGE, user)
span_boldselfwarning("You are hit viciously by [user]'s [atk_verb] and sent toppling head over heels!"), span_hear("You hear a sickening thud!"), COMBAT_MESSAGE_RANGE, user) // REDSHIFT EDIT - span_warning("You are hit viciously by [user]'s [atk_verb] and sent toppling head over heels!"), span_hear("You hear a sickening thud!"), COMBAT_MESSAGE_RANGE, user)
to_chat(user, span_warning("Your [atk_verb] lands, and you send [target] sailing off their feet!"))

if (46 to INFINITY)
target.apply_effect(4 SECONDS, EFFECT_KNOCKDOWN, armor_block)
var/obj/item/bodypart/affecting = target.get_bodypart(target.get_random_valid_zone(user.zone_selected))
target.apply_damage(5, BRUTE, affecting, armor_block, wound_bonus = limb_accuracy * 2) //Mostly for the crunchy wounding effect than actually doing damage
target.visible_message(span_warning("[user]'s [atk_verb] hits [target] so hard, you hit them off their feet with a loud crunch! Fucking hell!"), \
span_warning("You are hit viciously by [user]'s [atk_verb], and suddenly feel an overwhelming pain as you topple head over heels!"), span_hear("You hear a sickening crack and a loud thud!"), COMBAT_MESSAGE_RANGE, user)
span_boldselfwarning("You are hit viciously by [user]'s [atk_verb], and suddenly feel an overwhelming pain as you topple head over heels!"), span_hear("You hear a sickening crack and a loud thud!"), COMBAT_MESSAGE_RANGE, user) // REDSHIFT EDIT - span_warning("You are hit viciously by [user]'s [atk_verb], and suddenly feel an overwhelming pain as you topple head over heels!"), span_hear("You hear a sickening crack and a loud thud!"), COMBAT_MESSAGE_RANGE, user)
to_chat(user, span_warning("Your [atk_verb] lands, and [target] is sent crashing to the floor with the immense force! Good god!"))


Expand All @@ -1006,7 +1006,7 @@ GLOBAL_LIST_EMPTY(features_by_species)
if((owner != target) && target.check_block(owner, 0, owner.name, attack_type = UNARMED_ATTACK))
log_combat(owner, target, "attempted to touch")
target.visible_message(span_warning("[owner] attempts to touch [target]!"), \
span_danger("[owner] attempts to touch you!"), span_hear("You hear a swoosh!"), COMBAT_MESSAGE_RANGE, owner)
span_selfwarning("[owner] attempts to touch you!"), span_hear("You hear a swoosh!"), COMBAT_MESSAGE_RANGE, owner) // REDSHIFT EDIT - span_danger("[owner] attempts to touch you!"), span_hear("You hear a swoosh!"), COMBAT_MESSAGE_RANGE, owner)
to_chat(owner, span_warning("You attempt to touch [target]!"))
return

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
/mob/living/carbon
/mob/living
/// List of all of this mob's attributes and their values
var/list/attributes = list(
ATTRIBUTE_AURA = DEFAULT_ATTRIBUTE_SCORE,
Expand All @@ -10,39 +10,39 @@
)
/// List of current attribute modifiers, ATTRIBUTE_WHATEVER = modifier number
var/list/attribute_modifiers = list(
ATTRIBUTE_AURA = 0,
ATTRIBUTE_SMARTS = 0,
ATTRIBUTE_INTUITION = 0,
ATTRIBUTE_MUSCLE = 0,
ATTRIBUTE_REFLEX = 0,
ATTRIBUTE_AWARENESS = 0,
ATTRIBUTE_AURA = -INFINITY,
ATTRIBUTE_SMARTS = 3,
ATTRIBUTE_INTUITION = -3,
ATTRIBUTE_MUSCLE = -4,
ATTRIBUTE_REFLEX = 1,
ATTRIBUTE_AWARENESS = 5,
)

/mob/living/carbon/verb/view_attributes()
/mob/living/verb/view_attributes()
set name = "Attributes"
set category = "Redshift"
set desc = "View your character's attributes."
attributes_to_chat()

/// Prints a box with all of the carbon's attributes to chat
/mob/living/carbon/proc/attributes_to_chat()
/mob/living/proc/attributes_to_chat()
var/attributes_text = ""
for(var/attribute in attributes)
var/modifier = attribute_modifiers[attribute]
attributes_text += "[capitalize(attribute)] ([get_attribute_title(attribute, get_attribute_score(attribute))])"
attributes_text += "[get_attribute_title(attribute, get_attribute_score(attribute))] [capitalize(attribute)]"
attributes_text += " - [get_attribute_score(attribute)]"
if(modifier == 0)
attributes_text += "<br>"
continue
attributes_text += " - [attributes[attribute]][modifier < 0 ? span_red("[modifier]") : span_green("+[modifier]")]<br>"
attributes_text += "([attributes[attribute]][modifier < 0 ? span_red("[modifier]") : span_green("+[modifier]")])<br>"
to_chat(src, fieldset_block("Attributes", attributes_text, "boxed_message"))

/// Adjusts a carbon's attribute modifier by a given amount
/mob/living/carbon/proc/adjust_attribute_modifier(attribute, adjustment)
/mob/living/proc/adjust_attribute_modifier(attribute, adjustment)
attribute_modifiers[attribute] += adjustment

/// Get's a carbon's score for an attribute, optionally adjusted by modifiers
/mob/living/carbon/proc/get_attribute_score(attribute, modified = TRUE)
/mob/living/proc/get_attribute_score(attribute, modified = TRUE)
if(!attribute)
return 0
var/score = attributes[attribute]
Expand All @@ -51,8 +51,30 @@
score += attribute_modifiers[attribute]
return score

/// Returns a modifier to a chance to get hit by a melee attack depending on both awareness and reflex
/mob/living/proc/get_melee_dodge_modifier()
var/reflex_score = get_attribute_score(ATTRIBUTE_REFLEX, TRUE)
var/awareness_score = get_attribute_score(ATTRIBUTE_AWARENESS, TRUE)
var/dodge_attribute_score = (reflex_score + awareness_score) / 2
switch(dodge_attribute_score)
if(1 to 5)
return 0
if(6 to MAX_ATTRIBUTE_SCORE)
return (dodge_attribute_score - 5) * -5

/// Returns a multiplied damage amount based on the user's relevant attribute
/mob/living/proc/get_weapon_damage_mod(relevant_attribute, original_force)
var/relevant_score = get_attribute_score(relevant_attribute)
switch(relevant_score)
if(0 to 4) // * 0.5 at 0, * 0.9 at 4
return original_force * (0.5 + (0.1 * relevant_score))
if(5 to 7)
return original_force
if(8 to MAX_ATTRIBUTE_SCORE) // * 1.1 (8) to * 1.3 (10)
return original_force * (1 + (0.1 * (relevant_score - 7)))

/// Returns a multiplied time for a given attribute or attributes via a list and an original time
/proc/attributes_adjusted_time(mob/living/carbon/holder, list/attributes_to_check, original_time)
/proc/attributes_adjusted_time(mob/living/holder, list/attributes_to_check, original_time)
if(isnull(holder) || isnull(attributes_to_check) || isnull(original_time))
return
var/score_to_use = 0
Expand All @@ -75,15 +97,16 @@

/// Returns a title for a specific attribute level per attribute
/proc/get_attribute_title(attribute, score)
score = clamp(score, 0, MAX_ATTRIBUTE_SCORE)
switch(attribute)
if(ATTRIBUTE_AURA)
switch(score)
if(0)
return "Indebted"
return "Bankrupt"
if(1)
return "Zero"
if(2)
return "Nobody"
return "Unobservable"
if(3 to 4)
return "Small-Time"
if(5 to 8)
Expand All @@ -93,7 +116,7 @@
if(ATTRIBUTE_SMARTS)
switch(score)
if(0)
return "Thoughtless"
return "Zero"
if(1 to 3)
return "Low"
if(4 to 6)
Expand All @@ -115,7 +138,7 @@
if(8 to 9)
return "Quick"
if(10)
return "Engineer"
return "Engineer's"
if(ATTRIBUTE_MUSCLE)
switch(score)
if(0 to 1)
Expand All @@ -141,7 +164,7 @@
if(ATTRIBUTE_AWARENESS)
switch(score)
if(0)
return "Practically Blind"
return "Practically No"
if(1 to 2)
return "Unobservant"
if(3 to 4)
Expand Down
82 changes: 82 additions & 0 deletions redshift/attributes_and_skills/skills.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
/mob/living
/// List of all skills a mob has
var/list/skills = list(
// Weapons skills
SKILL_WEAPON_ECCENTRIC = 0
)

/// Get's a mob's score for a skill
/mob/living/proc/get_skill_value(skill)
if(!skill)
return 0
var/score = skills[skill]
return score

/mob/living/verb/view_skills()
set name = "Skills"
set category = "Redshift"
set desc = "View your character's skills."
skills_to_chat()

/// Prints a box with all of the mob's skills to chat
/mob/living/proc/skills_to_chat()
var/skills_text = ""
for(var/skill in skills)
skills_text += "[get_skill_title(get_skill_value(skill))] [skill]"
skills_text += " - [get_skill_value(skill)]"
to_chat(src, fieldset_block("Skills", skills_text, "boxed_message"))

/// Returns a title for a skill value
/proc/get_skill_title(score)
switch(score)
if(0)
return "Miserable"
if(1)
return "Novice"
if(2)
return "Adequate"
if(3)
return "Competent"
if(4)
return "Skilled"
if(5)
return "Proficient"
if(6)
return "Talented"
if(7)
return "Adept"
if(8)
return "Expert"
if(9)
return "Professional"
if(10)
return "Accomplished"
if(11)
return "Elite"
if(12)
return "Master"
if(13)
return "High Master"
if(14)
return "Grand Master"
if(15)
return "Legendary"

/// Returns a modifier for chance to hit the target (or target limb) depending on relevant weapon skill
/mob/living/proc/target_chance_skill_modifier(target_skill)
var/skill_value = get_skill_value(target_skill)
switch(skill_value)
if(0)
return -25
if(1 to 2)
return -10
if(3 to 4)
return -5
if(5 to 6)
return 0
if(7 to 10)
return 5
if(11 to 13)
return 10
if(14 to INFINITY)
return 25
2 changes: 0 additions & 2 deletions redshift/species/species_types/aquatic/bodyparts.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,6 @@
limb_id = SPECIES_AQUATIC
should_draw_greyscale = TRUE
unarmed_attack_verbs = list("slash", "scratch", "claw")
unarmed_attack_verbs = list("slashed", "scratched", "clawed")
grappled_attack_verb = "lacerate"
grappled_attack_verb_continuous = "lacerates"
unarmed_attack_effect = ATTACK_EFFECT_CLAW
Expand All @@ -29,7 +28,6 @@
limb_id = SPECIES_AQUATIC
should_draw_greyscale = TRUE
unarmed_attack_verbs = list("slash", "scratch", "claw")
unarmed_attack_verbs = list("slashed", "scratched", "clawed")
grappled_attack_verb = "lacerate"
grappled_attack_verb_continuous = "lacerates"
unarmed_attack_effect = ATTACK_EFFECT_CLAW
Expand Down
Loading
Loading