Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
7f5ac90
0.01
dwinters99 Apr 22, 2026
d90239f
icons by @Major00
dwinters99 Apr 22, 2026
b4e6542
empty inhand sprite files
dwinters99 Apr 22, 2026
37b2612
lol!
dwinters99 Apr 23, 2026
e40f915
how did this get unticked
dwinters99 Apr 23, 2026
a131423
procs
dwinters99 Apr 23, 2026
e7b55f4
spelling standardize
dwinters99 Apr 23, 2026
00f5873
the barbs in question
dwinters99 Apr 25, 2026
3d96336
Merge branch 'master' into freak-legion
dwinters99 Apr 28, 2026
a3c013c
darksight and chameleon coloration
dwinters99 Apr 28, 2026
d3689eb
put fomor on the splat screen (WIP)
dwinters99 Apr 29, 2026
c91ab11
combat bites
dwinters99 May 3, 2026
c74ef5f
horns 0.1
dwinters99 May 3, 2026
54bd879
fangs 0.1
dwinters99 May 3, 2026
01dd5a4
some weapon power refactoring/fixes
dwinters99 May 4, 2026
d02064d
i can't get bodypart_overlays to work
dwinters99 May 4, 2026
7c762ce
apperances work
dwinters99 May 4, 2026
e8b96e4
sprite edits
dwinters99 May 4, 2026
c50cee2
layerswap
dwinters99 May 4, 2026
92a3080
fangs are done
dwinters99 May 4, 2026
8de4705
hopefully this doesn't break everything
dwinters99 May 4, 2026
19952c5
syntax
dwinters99 May 4, 2026
fd74f9b
oh for sure
dwinters99 May 4, 2026
a92030b
credite
dwinters99 May 4, 2026
8c33b25
credite?
dwinters99 May 4, 2026
c6eae16
fomorgans
dwinters99 May 4, 2026
77b15a2
external organs aren't going to work here
dwinters99 May 4, 2026
356424a
oversight
dwinters99 May 5, 2026
a84958f
exoskeleton and regen
dwinters99 May 8, 2026
c5a9c75
ex
dwinters99 May 8, 2026
10ad7b7
infectious touch, hide of the wyrm, masq breaches
dwinters99 May 10, 2026
e73a08a
masq + compile
dwinters99 May 11, 2026
82be151
forgot one
dwinters99 May 11, 2026
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
4 changes: 4 additions & 0 deletions code/__DEFINES/~darkpack/splats.dm
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,15 @@
#define SPLAT_CORAX "splat_corax" // DARKPACK TODO - CORAX
#define SPLAT_SHIFTERS list(SPLAT_GAROU, SPLAT_CORAX)

#define SPLAT_FOMORI "splat_fomori"

#define SPLAT_PRIO_HALFSPLAT 100
#define SPLAT_PRIO_SPLAT 200

#define SPLAT_PRIO_KINFOLK 40 + SPLAT_PRIO_HALFSPLAT
#define SPLAT_PRIO_GHOUL 70 + SPLAT_PRIO_HALFSPLAT

#define SPLAT_PRIO_FOMORI 20 + SPLAT_PRIO_SPLAT
#define SPLAT_PRIO_SHIFTER 40 + SPLAT_PRIO_SPLAT
#define SPLAT_PRIO_KINDRED 60 + SPLAT_PRIO_SPLAT

5 changes: 5 additions & 0 deletions code/__DEFINES/~darkpack/traits/declarations.dm
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,8 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_BLOODY_SUCKER "bloody_sucker"
#define TRAIT_NON_INT "non_intellectual"
#define TRAIT_COFFIN_THERAPY "coffin_therapy"
// If we use combat_bite instead of vamp_bite
#define TRAIT_COMBAT_BITE "combat_bite"
#define TRAIT_RUBICON "rubicon"
#define TRAIT_HUNGRY "hungry"
#define TRAIT_STAKE_RESISTANT "stake_resistant"
Expand Down Expand Up @@ -145,6 +147,9 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_LOUD_HOWLER "loud_howler"
#define TRAIT_RAZOR_CLAWS "razor_claws"

// Fomori Traits
#define TRAIT_FOMOR_REGEN "fomor_regen"

/// Sixth sense restricted to view range
#define TRAIT_LOCAL_SIXTHSENSE "local_sixth_sense"
/// If the mob can't have surgery done on it. See: Blood form Tzimisce
Expand Down
2 changes: 2 additions & 0 deletions code/_globalvars/traits/_traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -680,6 +680,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_CAN_ENTER_TORPOR" = TRAIT_CAN_ENTER_TORPOR, // DARKPACK EDIT ADD
"TRAIT_CHARMER" = TRAIT_CHARMER, // DARKPACK EDIT ADD
"TRAIT_COFFIN_THERAPY" = TRAIT_COFFIN_THERAPY, // DARKPACK EDIT ADD
"TRAIT_COMBAT_BITE" = TRAIT_COMBAT_BITE, // DARKPACK EDIT ADD
"TRAIT_CONSENSUAL_FEEDING_ONLY" = TRAIT_CONSENSUAL_FEEDING_ONLY, // DARKPACK EDIT ADD
"TRAIT_DECEPTIVE_AURA" = TRAIT_DECEPTIVE_AURA, // DARKPACK EDIT ADD
"TRAIT_DEFICIENT_VITAE" = TRAIT_DEFICIENT_VITAE, // DARKPACK EDIT ADD
Expand All @@ -692,6 +693,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_FEEDING_RESTRICTION" = TRAIT_FEEDING_RESTRICTION, // DARKPACK EDIT ADD
"TRAIT_FERA_FUR" = TRAIT_FERA_FUR, // DARKPACK EDIT ADD - WEREWOLF
"TRAIT_FERA_RENOWN" = TRAIT_FERA_RENOWN, // DARKPACK EDIT ADD - WEREWOLF
"TRAIT_FOMOR_REGEN" = TRAIT_FOMOR_REGEN, // DARKPACK EDIT ADD - FOMORI
"TRAIT_FORCED_EMOTION" = TRAIT_FORCED_EMOTION, // DARKPACK EDIT ADD - Melpominee
"TRAIT_FRENETIC_AURA" = TRAIT_FRENETIC_AURA, // DARKPACK EDIT ADD
"TRAIT_GHOST_VISION" = TRAIT_GHOST_VISION, // DARKPACK EDIT ADD - POWERS - (Necromancy)
Expand Down
2 changes: 2 additions & 0 deletions code/_globalvars/traits/admin_tooling.dm
Original file line number Diff line number Diff line change
Expand Up @@ -370,6 +370,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list(
"TRAIT_CAN_ENTER_TORPOR" = TRAIT_CAN_ENTER_TORPOR, // DARKPACK EDIT ADD
"TRAIT_CHARMER" = TRAIT_CHARMER, // DARKPACK EDIT ADD
"TRAIT_COFFIN_THERAPY" = TRAIT_COFFIN_THERAPY, // DARKPACK EDIT ADD
"TRAIT_COMBAT_BITE" = TRAIT_COMBAT_BITE, // DARKPACK EDIT ADD
"TRAIT_CONSENSUAL_FEEDING_ONLY" = TRAIT_CONSENSUAL_FEEDING_ONLY, // DARKPACK EDIT ADD
"TRAIT_DECEPTIVE_AURA" = TRAIT_DECEPTIVE_AURA, // DARKPACK EDIT ADD
"TRAIT_DEFICIENT_VITAE" = TRAIT_DEFICIENT_VITAE, // DARKPACK EDIT ADD
Expand All @@ -382,6 +383,7 @@ GLOBAL_LIST_INIT(admin_visible_traits, list(
"TRAIT_FEEDING_RESTRICTION" = TRAIT_FEEDING_RESTRICTION, // DARKPACK EDIT ADD
"TRAIT_FERA_FUR" = TRAIT_FERA_FUR, // DARKPACK EDIT ADD - WEREWOLF
"TRAIT_FERA_RENOWN" = TRAIT_FERA_RENOWN, // DARKPACK EDIT ADD - WEREWOLF
"TRAIT_FOMOR_REGEN" = TRAIT_FOMOR_REGEN, // DARKPACK EDIT ADD - FOMORI
"TRAIT_FRENETIC_AURA" = TRAIT_FRENETIC_AURA, // DARKPACK EDIT ADD
"TRAIT_GHOST_VISION" = TRAIT_GHOST_VISION, // DARKPACK EDIT ADD - POWERS - (Necromancy)
"TRAIT_GULLET" = TRAIT_GULLET, // DARKPACK EDIT ADD
Expand Down
1 change: 1 addition & 0 deletions config/darkpack_config.txt
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ ROUNDSTART_SPLATS splat_kindred
ROUNDSTART_SPLATS splat_ghoul
ROUNDSTART_SPLATS splat_kinfolk
ROUNDSTART_SPLATS splat_garou
ROUNDSTART_SPLATS splat_fomori

## If dead people and ghosts can LOOC to people who are alive.
DISABLE_GHOST_LOOC
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,7 @@
var/fakediablerist = FALSE
var/can_be_embraced = TRUE

//stats for combat bites // used for lupus, crinos, hispo, fomori, etc.
var/list/combat_bite_damages = list(BRUTE = 1 LETHAL_TTRPG_DAMAGE, BURN = 0, TOX = 0, OXY = 0, AGGRAVATED = 0)
var/list/combat_bite_stats = list(STAT_DEXTERITY, STAT_BRAWL)
var/list/combat_bite_difficulty = 5
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@

if(ishuman(user.mob))
var/mob/living/carbon/human/human_user = user.mob
human_user.vamp_bite()
if(HAS_TRAIT(human_user, TRAIT_COMBAT_BITE))
human_user.combat_bite()
else
human_user.vamp_bite()

return TRUE
71 changes: 71 additions & 0 deletions modular_darkpack/modules/blood_drinking/code/combat_bite.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
// Thanks to @hex37 for most of this
/**
* Biting for purposes other than drinking blood
*
* Arguments:
* * pulling - The mob we're biting
* * damage_type - What kind of damage we're doing as a list. If blank, grabs from vars. (ex. list(BRUTE = 0, BURN = 0, TOX = 0, OXY = 0, AGGRAVATED = 0))
*/
/mob/living/carbon/proc/combat_bite(list/damage_types)
if(!COOLDOWN_FINISHED(src, drinkblood_use_cd) || !COOLDOWN_FINISHED(src, drinkblood_click_cd))
return
COOLDOWN_START(src, drinkblood_click_cd, 1 SECONDS)
if(!damage_types)
damage_types = combat_bite_damages

var/skipface = (wear_mask && (wear_mask.flags_inv & HIDEFACE)) || (head && (head.flags_inv & HIDEFACE))
if(skipface)
to_chat(src, span_warning("Take your mask off first!"))
return

if(grab_state > GRAB_PASSIVE)
if(isliving(pulling))
var/mob/living/bit_living = pulling
visible_message(span_warning("[src] starts biting [bit_living] with [p_their()] sharp teeth!"), span_warning("You start biting [bit_living] with your sharp teeth!"), span_warning("You hear the sound of flesh tearing!"))
bit_living.emote("scream")
if(ishuman(bit_living))
var/mob/living/carbon/human/bit_human = bit_living
bit_human.add_bite_animation()

do_combat_bite(bit_living, damage_types, TRUE)

/mob/living/carbon/proc/do_combat_bite(mob/living/chewed_on, list/damage_types, first_bite = FALSE)

COOLDOWN_START(src, drinkblood_use_cd, 3 SECONDS)

if(isnpc(chewed_on))
var/mob/living/carbon/human/npc/NPC = chewed_on
NPC.danger_source = null
chewed_on.Stun(10) // NPCs can't resist right away

if(chewed_on.health < (values_sum(damage_types)*1.5))
to_chat(src, span_userdanger("Your victim is near death."))

if(!do_after(src, 2 SECONDS, target = chewed_on, timed_action_flags = NONE, progress = FALSE))
stop_chewing(chewed_on)
return

if(iscarbon(chewed_on))
var/mob/living/carbon/chewtoy = chewed_on
var/datum/storyteller_roll/roll_datum = new /datum/storyteller_roll/damage/bite
roll_datum.difficulty = combat_bite_difficulty
var/roll_result = roll_datum.st_roll(src, chewtoy)+1
if(roll_result)
for(var/damage_type, damage_amount in damage_types)
if(roll_result > 0)
chewtoy.apply_damage((damage_amount*roll_result), damage_type, sharpness = SHARP_POINTY)
playsound(get_turf(src), 'sound/items/weapons/bite.ogg', 50, TRUE)

if(chewtoy.reagents) // We might ingest some blood on accident
if(length(chewtoy.reagents.reagent_list))
if(prob(15)) // We might ingest some blood on accident
chewtoy.reagents.trans_to(src, min(10, chewtoy.reagents.total_volume), transferred_by = chewed_on, methods = INGEST)

if(grab_state > GRAB_PASSIVE)
stop_sound_channel(CHANNEL_BLOOD)
do_combat_bite(chewed_on, damage_types)

/mob/living/carbon/proc/stop_chewing()
stop_sound_channel(CHANNEL_BLOOD)
COOLDOWN_RESET(src, drinkblood_use_cd)
return
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,7 @@
/atom/movable/screen/drinkblood/proc/bite()
if(ishuman(usr))
var/mob/living/carbon/human/human_user = usr
human_user.vamp_bite()
if(HAS_TRAIT(human_user, TRAIT_COMBAT_BITE))
human_user.combat_bite()
else
human_user.vamp_bite()
25 changes: 25 additions & 0 deletions modular_darkpack/modules/fomori/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
https://github.com/DarkPack13/SecondCity/pull/953

## \<Fomori>

Module ID: FOMORI

### Description:

This module handles everything related to Fomori and their Powers, Taints, and Merits/Flaws. Dependent on BLOOD_DRINKING for the Combat Bite code.

### TG Proc/File Changes:

### Modular Overrides:

### Defines:

- N/A

### Included files that are not contained in this module:

- modular_darkpack/modules/blood_drinking/code/combat_bite.dm

### Credits:

dwinters99 (code), Major00 (sprites), Minzeyes (sprites) ((BLOCK PR IF THIS WARNING IS STILL HERE)), FalloutFallcon (troubleshooting), Chazzyjazzy (for gargoyle wings), hex37 (for blood-drinking code)
64 changes: 64 additions & 0 deletions modular_darkpack/modules/fomori/code/powers/_fomori_power.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
// Presently a dummy placeholder, might want to do stuff like flavor the ui, change the dice roll, make fomori_powers private by default or the like
/datum/storyteller_roll/fomori_power

/datum/action/cooldown/power/fomori_power
background_icon = 'modular_darkpack/modules/fomori/icons/fomori_abilities.dmi'
background_icon_state = "bg_fomori_power"
button_icon = 'modular_darkpack/modules/fomori/icons/fomori_abilities.dmi'
//button_icon_state = ""
overlay_icon = 'modular_darkpack/modules/fomori/icons/fomori_abilities.dmi'

check_flags = AB_CHECK_IMMOBILE|AB_CHECK_CONSCIOUS

// Snowflake toggle behavior
var/deployed = FALSE

// Body feature for horns, fangs, etc.
var/datum/bodypart_overlay/simple/fomor_part
// What bodypart are we putting our feature on?
var/feature_bodypart = BODY_ZONE_HEAD

// What organ are we adding?
var/obj/item/organ/fomor_organ
// Where are we inserting it?
var/fomor_organ_slot

/atom/movable/screen/alert/status_effect/fomori_power
icon = 'modular_darkpack/modules/fomori/icons/fomori_abilities.dmi'
icon_state = "bg_fomori_power"
overlay_icon = 'modular_darkpack/modules/fomori/icons/fomori_abilities.dmi'


///checks if we lose a limb a feature is attached to
/datum/action/cooldown/power/fomori_power/proc/on_removed_limb(datum/source, obj/item/bodypart/removed_limb, special, dismembered)
SIGNAL_HANDLER

var/mob/living/carbon/human/carbon_owner = astype(owner, /mob/living/carbon)
var/obj/item/bodypart/bodypart = carbon_owner.get_bodypart(feature_bodypart)

if(fomor_part && istype(removed_limb, bodypart.type))
remove_feature()

///for adding fomor features i.e. fangs, horns
/datum/action/cooldown/power/fomori_power/proc/add_feature()
var/mob/living/carbon/human/fomor = owner
var/obj/item/bodypart/bodypart = fomor?.get_bodypart(feature_bodypart)
if(isnull(bodypart))
return
fomor_part = new fomor_part() //creates our overlay
bodypart.add_bodypart_overlay(fomor_part)

///removes the fomor feature
/datum/action/cooldown/power/fomori_power/proc/remove_feature()
var/mob/living/carbon/human/fomor = owner
var/obj/item/bodypart/bodypart = fomor?.get_bodypart(feature_bodypart)
bodypart?.remove_bodypart_overlay(fomor_part)
QDEL_NULL(fomor_part)

///toggles the feature, TRUE for remove and FALSE for add
/datum/action/cooldown/power/fomori_power/proc/toggle_feature(current_state)
if(current_state)
remove_feature()
fomor_part = initial(fomor_part)
else
add_feature()
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
/datum/action/cooldown/power/fomori_power/weapon
name = "fomor weapon power"
desc = "Report on github if you see this!"
cooldown_time = 1 TURNS // Can't sheathe/unsheathe for at least 5 seconds after use

shared_cooldown = MOB_SHARED_COOLDOWN_2

var/sheathe_text = "Your skub melts back into your skin."

var/weapon_type = /obj/item/skub
var/unsheathe_sound = 'sound/effects/blob/blobattack.ogg'
var/sheathe_sound = 'sound/effects/meatslap.ogg'

/datum/action/cooldown/power/fomori_power/weapon/Activate(atom/target)
var/obj/item/held = owner.get_active_held_item()
var/obj/item/off_held = owner.get_inactive_held_item()
if(held && off_held && deployed)
qdel(held)
qdel(off_held)
to_chat(owner, span_warning(sheathe_text))
playsound(get_turf(owner), sheathe_sound, 50)
deployed = FALSE
return

if(held && !owner.dropItemToGround(held))
owner.balloon_alert(owner, "hand occupied!")
return FALSE
else if(off_held && !owner.dropItemToGround(off_held))
owner.balloon_alert(owner, "off-hand occupied!")
return FALSE

. = ..()

var/obj/item/weapon = new weapon_type(owner)
var/obj/item/weapon_offhand = new weapon_type(owner)

deployed = TRUE

playsound(get_turf(owner), unsheathe_sound, 50)
owner.put_in_l_hand(weapon)
owner.put_in_r_hand(weapon_offhand)





65 changes: 65 additions & 0 deletions modular_darkpack/modules/fomori/code/powers/body_barbs.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/obj/item/melee/body_barbs // Largely copied from changeling armblade
name = "body barb"
icon = 'modular_darkpack/modules/fomori/icons/fomori_items48x32.dmi'
icon_state = "body_barb"
inhand_icon_state = "body_barb"
lefthand_file = 'modular_darkpack/modules/fomori/icons/fomori_inhand_left.dmi'
righthand_file = 'modular_darkpack/modules/fomori/icons/fomori_inhand_right.dmi'
item_flags = ABSTRACT | DROPDEL
w_class = WEIGHT_CLASS_HUGE
force = 40 // Identical to Machete
throwforce = 0
throw_range = 0
throw_speed = 0
hitsound = 'sound/items/weapons/bladeslice.ogg'
wound_bonus = 10
exposed_wound_bonus = 10
armour_penetration = 35
attack_verb_continuous = list("attacks", "slashes", "slices", "tears", "lacerates", "rips", "dices", "cuts")
attack_verb_simple = list("attack", "slash", "slice", "tear", "lacerate", "rip", "dice", "cut")
sharpness = SHARP_EDGED
wound_bonus = 10
exposed_wound_bonus = 10
armour_penetration = 35
var/list/alt_continuous = list("stabs", "pierces", "impales")
var/list/alt_simple = list("stab", "pierce", "impale")

abstract_type = /obj/item/melee/body_barbs

/obj/item/melee/body_barbs/Initialize(mapload,silent) // Largely copied from changeling armblade
. = ..()
ADD_TRAIT(src, TRAIT_NODROP, INNATE_TRAIT)
alt_continuous = string_list(alt_continuous)
alt_simple = string_list(alt_simple)
AddComponent(/datum/component/alternative_sharpness, SHARP_POINTY, alt_continuous, alt_simple, -5)
AddComponent(/datum/component/butchering, \
speed = 6 SECONDS, \
effectiveness = 80, \
)

/datum/action/cooldown/power/fomori_power/weapon/body_barbs
name = "Body Barbs"
desc = "Use the grotesque spikes on your body to amplify your brawling ability."
button_icon_state = "body_barbs"
rank = 1 // of 10 // Determines how many extra dice we get
weapon_type = /obj/item/melee/body_barbs
sheathe_text = "Your body barbs retract into your arms."

/datum/action/cooldown/power/fomori_power/weapon/body_barbs/Activate(atom/target)
. = ..()
if(deployed)
owner.visible_message(span_warning("A pair of grotesque barbs extend from [owner]\'s arms!"), \
span_warning("Your body barbs extend from your arms."), \
span_hear("You hear organic matter ripping and tearing!"))
SEND_SIGNAL(owner, COMSIG_MASQUERADE_VIOLATION)

/datum/action/cooldown/power/fomori_power/weapon/body_barbs/two
rank = 2

/datum/action/cooldown/power/fomori_power/weapon/body_barbs/three
rank = 3

/datum/action/cooldown/power/fomori_power/weapon/body_barbs/four
rank = 4
/datum/action/cooldown/power/fomori_power/weapon/body_barbs/five
rank = 5
Loading
Loading