Skip to content
Open
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
1 change: 1 addition & 0 deletions code/__DEFINES/combat.dm
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@
#define BCLASS_EFFECT "effect"
#define BCLASS_PUNISH "punish"
#define BCLASS_SUNDER "sunder"
#define BCLASS_HALFSWORD "stab"

//Material class (what material is striking)
#define MCLASS_GENERIC 1
Expand Down
13 changes: 13 additions & 0 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@
#define TRAIT_TALENTED_ALCHEMIST "Talented Alchemist" // Allows alchemy XP gain past apprentice
#define TRAIT_LAMIAN_TAIL "Lamian Tail"
#define TRAIT_DUNGEONMASTER "Ruthless Jailor"
#define TRAIT_SKILLBLESSED "Skill Blessed"
#define TRAIT_LONGSWORDSMAN "Master Longswordman"
#define TRAIT_SABRIST "Renowned Sabrist"
#define TRAIT_ARMOUR_LIKED "Fitting Armour"
#define TRAIT_ARMOUR_DISLIKED "Misfitting Armour"
#define TRAIT_FENCERDEXTERITY "Fencer's Dexterity"
#define TRAIT_HONORBOUND "Honorbound" // no idea what this trait even is
#define TRAIT_DEATHBARGAIN "Death Bargain" // Used by UNDERMAIDEN'S BARGAIN
#define TRAIT_RITUALIST "Ritualist" // Allows use of ritual chalk
#define TRAIT_INQUISITION "Member of the Otavan Inquisition"
Expand Down Expand Up @@ -276,6 +283,12 @@ GLOBAL_LIST_INIT(roguetraits, list(
TRAIT_DISGRACED_NOBLE = span_warning("I was a scion of a noble house... long ago."),
TRAIT_EMPATH = span_info("I can notice when people are in pain, and I feel peace when they're happy."),
TRAIT_BREADY = span_info("Defensive stance does not passively fatigue me."),
TRAIT_ARMOUR_LIKED = span_greentext("I'm wearing something more suited to my style."),
TRAIT_ARMOUR_DISLIKED = span_warning("I'm wearing something that burdens me."),
TRAIT_FENCERDEXTERITY = span_info("I've trained my entire lyfe around the art of unarmoured fencing, affording myself unmatched speed when wearing very light armour. I'm very choosy otherwise."),
TRAIT_SKILLBLESSED = span_greentext("I've reunited with an old friend of mine. All is well."),
TRAIT_LONGSWORDSMAN = span_info("\"I will crush anyone who opposes me. I am of royal blood. I dispense justice, advance the cause of good and destroy evil. To those who learn my crossings I will grant great fame and renown in the art of armed fighting.\" - I fight like a Master when I wield any longsword, though I can only perform master strikes with a perfectly balanced basket-hilted or reformist longsword."),
TRAIT_SABRIST = span_info("I've learned all there is to know about the Southern curve. When using a szöréndnížine sabre, I fight like a Master. My swings are innately more accurate when targetting hands and arms."),
TRAIT_MEDIUMARMOR = span_info("I can move freely in medium armor."),
TRAIT_HEAVYARMOR = span_info("I can move freely in heavy armor."),
TRAIT_DODGEEXPERT = span_info("I can dodge easily while only wearing light armor."),
Expand Down
4 changes: 4 additions & 0 deletions code/_globalvars/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,10 @@ GLOBAL_LIST_INIT(traits_by_type, list(
TRAIT_CRIMSON_CURSE,
TRAIT_MONK_ROBE,
TRAIT_ENGINEERING_GOGGLES,
TRAIT_LONGSWORDSMAN,
TRAIT_SABRIST,
TRAIT_FENCERDEXTERITY,
TRAIT_HONORBOUND,
TRAIT_MASTER_CARPENTER,
TRAIT_MASTER_MASON,
TRAIT_FOOD_STIPEND,
Expand Down
152 changes: 152 additions & 0 deletions code/datums/components/armour_filtering.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
/datum/component/armour_filtering
dupe_mode = COMPONENT_DUPE_ALLOWED
var/required_trait
var/additive
var/positive

/datum/component/armour_filtering/Initialize(skill_trait, positive_bonus, bonus_additive = FALSE)
. = ..()
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
required_trait = skill_trait
additive = bonus_additive

RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equip))
RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_drop))

/datum/component/armour_filtering/positive
positive = TRUE

/datum/component/armour_filtering/negative
positive = FALSE

/datum/component/armour_filtering/proc/on_equip()
SIGNAL_HANDLER
var/obj/item/I = parent
var/mob/living/carbon/human/user

if(ishuman(I.loc))
user = I.loc

if(!user)
return
if(!HAS_TRAIT(user, required_trait))
return

if(!isclothing(I))
return
var/obj/item/clothing/worn_thing = I
spawn(0)
if(!(worn_thing.item_flags & IN_INVENTORY))
return
if(worn_thing.item_flags & IN_STORAGE)
return
var/list/obj/item/held_list = user.get_held_items()
for(var/obj/item/held_thing in held_list)
if(held_thing == parent)
return
handle_boons(user, TRUE)

return

/datum/component/armour_filtering/proc/on_drop()
SIGNAL_HANDLER
var/obj/item/I = parent
var/mob/living/carbon/human/user

if(ishuman(I.loc))
user = I.loc

if(!user)
return
if(!HAS_TRAIT(user, required_trait))
return

handle_boons(user, FALSE)

for(var/thing in user.contents)
if(!isclothing(thing))
return
var/obj/item/clothing/worn_thing = thing
if(worn_thing == I)
continue
if(!(worn_thing.item_flags & IN_INVENTORY))
return
if(worn_thing.item_flags & IN_STORAGE)
return
var/list/datum/component/armour_filtering/comps = worn_thing.GetComponents(/datum/component/armour_filtering)
if(!comps)
continue
for(var/datum/component/armour_filtering/af_comp in comps)
if(af_comp.required_trait != required_trait)
continue
if(af_comp.positive != positive)
continue
if(!af_comp.additive)
handle_boons(user, TRUE)
return
if(af_comp.positive)
ADD_TRAIT(user, TRAIT_ARMOUR_LIKED, TRAIT_GENERIC)
else
ADD_TRAIT(user, TRAIT_ARMOUR_DISLIKED, TRAIT_GENERIC)

return


/datum/component/armour_filtering/proc/handle_boons(mob/living/carbon/human/user, equip)
if(equip)
if(!positive)
to_chat(user, span_info("[parent] is not to my liking. ([required_trait])"))
if(HAS_TRAIT(user, TRAIT_ARMOUR_DISLIKED) && !additive)
to_chat(user, span_info("...yet, another piece of my armour is on my mind."))
return
ADD_TRAIT(user, TRAIT_ARMOUR_DISLIKED, TRAIT_GENERIC)
else
to_chat(user, span_info("[parent] fits me well. ([required_trait])"))
if(HAS_TRAIT(user, TRAIT_ARMOUR_LIKED) && !additive)
to_chat(user, span_info("..yet another piece of my armour is on my mind."))
return
ADD_TRAIT(user, TRAIT_ARMOUR_LIKED, TRAIT_GENERIC)
trait_boon_equip(user)
return

if(!positive)
to_chat(user, span_info("Free at last of [parent]. ([required_trait])"))
if(HAS_TRAIT(user, TRAIT_ARMOUR_DISLIKED))
REMOVE_TRAIT(user, TRAIT_ARMOUR_DISLIKED, TRAIT_GENERIC)
else
to_chat(user, span_info("I miss [parent] already. ([required_trait])"))
if(HAS_TRAIT(user, TRAIT_ARMOUR_LIKED))
REMOVE_TRAIT(user, TRAIT_ARMOUR_LIKED, TRAIT_GENERIC)
trait_boon_drop(user)
return


/*
TRAIT UNIQUE PROCS
*/


/datum/component/armour_filtering/proc/trait_boon_equip(mob/living/carbon/human/user)
if(HAS_TRAIT(user, TRAIT_FENCERDEXTERITY))
if(!positive)
user.dropItemToGround(parent, TRUE, TRUE)
if(!HAS_TRAIT(user, TRAIT_ARMOUR_DISLIKED))
return
REMOVE_TRAIT(user, TRAIT_ARMOUR_DISLIKED, TRAIT_GENERIC)
return

if(HAS_TRAIT(user, TRAIT_PSYDONIAN_GRIT))
if(positive)
user.apply_status_effect(/datum/status_effect/buff/psydonic_endurance)
return
return

/datum/component/armour_filtering/proc/trait_boon_drop(mob/living/carbon/human/user)
if(HAS_TRAIT(user, TRAIT_PSYDONIAN_GRIT))
if(positive)
if(!user.has_status_effect(/datum/status_effect/buff/psydonic_endurance))
return
user.remove_status_effect(/datum/status_effect/buff/psydonic_endurance)
return
return
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain what the armor_filtering component is doing?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you explain what the armor_filtering component is doing?

nope

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright I'll take a deeper look when I have time

141 changes: 141 additions & 0 deletions code/datums/components/skill_blessed.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,141 @@
/datum/component/skill_blessed
dupe_mode = COMPONENT_DUPE_UNIQUE
var/required_trait
var/datum/skill/weapon_skill
var/skill_amount
var/original_skill
var/mob/living/carbon/human/original_user
var/unique

/datum/component/skill_blessed/Initialize(skill_trait, skillgiven_type, skillgiven_amount, trait_unique = FALSE)
. = ..()
if(!isitem(parent))
return COMPONENT_INCOMPATIBLE
required_trait = skill_trait
weapon_skill = skillgiven_type
skill_amount = skillgiven_amount
unique = trait_unique

RegisterSignal(parent, COMSIG_ITEM_EQUIPPED, PROC_REF(on_equip))
RegisterSignal(parent, COMSIG_ITEM_DROPPED, PROC_REF(on_drop))
RegisterSignal(parent, COMSIG_PARENT_EXAMINE, PROC_REF(on_obj_examine))

/datum/component/skill_blessed/proc/on_equip()
SIGNAL_HANDLER
var/obj/item/I = parent
var/mob/living/carbon/human/user

if(ishuman(I.loc))
user = I.loc
else if(ishuman(I.loc.loc))
user = I.loc.loc

if(!user)
return
if(!HAS_TRAIT(user, required_trait))
return

var/list/obj/item/held_list = user.get_held_items()
for(var/obj/item/held_thing in held_list)
if(held_thing == parent)
give_skill(user)
return
remove_skill(user)

/datum/component/skill_blessed/proc/on_drop()
SIGNAL_HANDLER

if(!original_user)
return
if(!ishuman(original_user))
return

if(!HAS_TRAIT(original_user, required_trait))
return
if(!HAS_TRAIT(original_user, TRAIT_SKILLBLESSED))
return

for(var/obj/item/held_thing in original_user.get_held_items())
if(istype(held_thing, parent.type))
return

remove_skill(original_user)

/datum/component/skill_blessed/proc/on_obj_examine(datum/source, mob/M)
if(!HAS_TRAIT(M, required_trait))
return
to_chat(M, span_green("[parent] and I are well acquainted. ([required_trait])"))


/datum/component/skill_blessed/proc/give_skill(mob/user)
if(!HAS_TRAIT(user, required_trait))
return
if(HAS_TRAIT(user, TRAIT_SKILLBLESSED))
to_chat(user, span_warning("My mind is already focused on a different weapon."))
return

to_chat(user, span_info("[parent] and I are old friends. ([required_trait])"))
original_skill = user.get_skill_level(weapon_skill)
user.adjust_skillrank_up_to(weapon_skill, skill_amount, silent = TRUE)
ADD_TRAIT(user, TRAIT_SKILLBLESSED, TRAIT_GENERIC)

original_user = user
if(unique)
trait_unique_equip(user)

return

/datum/component/skill_blessed/proc/remove_skill(mob/user)
if(!HAS_TRAIT(user, required_trait))
return
if(!HAS_TRAIT(original_user, TRAIT_SKILLBLESSED))
return

var/datum/component/skill_blessed/other_skill

for(var/obj/item/held_thing in user.get_held_items())
if(held_thing == parent)
return
var/list/datum/component/skill_blessed/comps = held_thing.GetComponents(/datum/component/skill_blessed)
if(!comps)
continue
for(var/datum/component/skill_blessed/sb_comp in comps)
if(!HAS_TRAIT(user, sb_comp.required_trait))
continue
other_skill = sb_comp
break

user.adjust_skillrank_down_to(weapon_skill, original_skill, silent = TRUE)
to_chat(user, span_info("Another tyme, old friend. ([required_trait])"))
REMOVE_TRAIT(user, TRAIT_SKILLBLESSED, TRAIT_GENERIC)

if(unique)
trait_unique_drop(user)
if(original_user)
original_user = null
if(original_skill)
original_skill = null
if(other_skill)
other_skill.on_equip()

return


/*
TRAIT UNIQUE PROCS
*/


/datum/component/skill_blessed/proc/trait_unique_equip(mob/user)
if(HAS_TRAIT(user, TRAIT_SABRIST))
var/obj/item/rogueweapon/sword/sabre/steppesman/shashka = parent
for(var/datum/intent/sword/sab_intent in shashka.possible_item_intents)
sab_intent.accuracy_modifier += 10
return

/datum/component/skill_blessed/proc/trait_unique_drop(mob/user)
if(HAS_TRAIT(user, TRAIT_SABRIST))
var/obj/item/rogueweapon/sword/sabre/steppesman/shashka = parent
for(var/datum/intent/sword/sab_intent in shashka.possible_item_intents)
sab_intent.accuracy_modifier = initial(sab_intent.accuracy_modifier)
return
50 changes: 50 additions & 0 deletions code/datums/status_effects/rogue/debuff.dm
Original file line number Diff line number Diff line change
Expand Up @@ -637,6 +637,56 @@
desc = "Something has chilled me to the bone! It's hard to move."
icon_state = "muscles"

//// Freifechter Daze Variants /////
/datum/status_effect/debuff/dazed/longsword
id = "durchlauffen"
alert_type = /atom/movable/screen/alert/status_effect/debuff/dazed/longsword
effectedstats = list(STATKEY_SPD = -3, STATKEY_INT = -1)
duration = 11 SECONDS
status_type = STATUS_EFFECT_REFRESH

/atom/movable/screen/alert/status_effect/debuff/dazed/longsword
name = "Master Strike"
desc = "How the fuck did they do that!? My ears are ringing!"
icon_state = "mstrike"

/datum/status_effect/debuff/dazed/longsword2h
id = "zorn ort"
alert_type = /atom/movable/screen/alert/status_effect/debuff/dazed/longsword2h
effectedstats = list(STATKEY_PER = -4, STATKEY_LCK = -3)
duration = 8 SECONDS
status_type = STATUS_EFFECT_REFRESH

/atom/movable/screen/alert/status_effect/debuff/dazed/longsword2h
name = "Master Strike"
desc = "How the fuck did they do that!? My eye!"
icon_state = "mstrike"

/datum/status_effect/debuff/dazed/freisabre
id = "uszkodzić"
alert_type = /atom/movable/screen/alert/status_effect/debuff/dazed/freisabre
effectedstats = list(STATKEY_STR = -2, STATKEY_SPD = -3)
duration = 11 SECONDS
status_type = STATUS_EFFECT_REFRESH

/atom/movable/screen/alert/status_effect/debuff/dazed/freisabre
name = "Master Strike"
desc = "How the fuck did they do that!? My wrist!"
icon_state = "mstrike"

/datum/status_effect/debuff/dazed/swipe
id = "clinch & swipe"
alert_type = /atom/movable/screen/alert/status_effect/debuff/dazed/swipe
effectedstats = list(STATKEY_CON = -4, STATKEY_STR = -1)
duration = 1.5 SECONDS //Should last BARELY ENOUGH for someone who's actively grappling and swiping you to get a constant refresh of the dedbuff, otherwise it's useless.
status_type = STATUS_EFFECT_REFRESH

/atom/movable/screen/alert/status_effect/debuff/dazed/swipe
name = "Clinched and Swiped!"
desc = "Urgh! My face! My grip is weakened!"
icon_state = "swiped"


/datum/status_effect/debuff/blackvitae
id = "blackvitae"
alert_type = /atom/movable/screen/alert/status_effect/debuff/blackvitae
Expand Down
Loading
Loading