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
2 changes: 0 additions & 2 deletions code/__DEFINES/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -521,5 +521,3 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
#define TRAIT_SLAVEBOURNE_EXAMINE "trait_slavebourne_examine"

#define TRAIT_LOVESTRUCK "lovestruck" // For collar master's force love effect

#define TRAIT_PONYGIRL_RIDEABLE "ponygirl_rider"
1 change: 0 additions & 1 deletion code/_globalvars/traits.dm
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,6 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_LEARNMAGIC" = TRAIT_LEARNMAGIC,
"TRAIT_ALCHEMYKNOWLEDGE" = TRAIT_ALCHEMYKNOWLEDGE,

"TRAIT_PONYGIRL_RIDEABLE" = TRAIT_PONYGIRL_RIDEABLE,
),
/obj/item/bodypart = list(
"TRAIT_PARALYSIS" = TRAIT_PARALYSIS
Expand Down
12 changes: 0 additions & 12 deletions code/modules/clothing/head/_head.dm
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,3 @@
armor_class = ARMOR_CLASS_LIGHT
sewrepair = TRUE
smeltresult = /obj/item/stack/sheet/leather

/obj/item/clothing/head/hblinders/mob_can_equip(mob/living/M, slot, disable_warning = FALSE)
. = ..()
if(!HAS_TRAIT(M, TRAIT_PONYGIRL_RIDEABLE))
to_chat(M, span_warning("You lack the proper training to wear this harness!"))
return FALSE

/obj/item/clothing/head/hbit/mob_can_equip(mob/living/M, slot, disable_warning = FALSE)
. = ..()
if(!HAS_TRAIT(M, TRAIT_PONYGIRL_RIDEABLE))
to_chat(M, span_warning("You lack the proper training to wear this harness!"))
return FALSE
6 changes: 0 additions & 6 deletions code/modules/clothing/rogueclothes/armor.dm
Original file line number Diff line number Diff line change
Expand Up @@ -1002,9 +1002,3 @@
smeltresult = /obj/item/stack/sheet/leather
boobed = TRUE
flags_inv = 0

/obj/item/clothing/suit/roguetown/armor/hcorset/mob_can_equip(mob/living/M, slot, disable_warning = FALSE)
. = ..()
if(!HAS_TRAIT(M, TRAIT_PONYGIRL_RIDEABLE))
to_chat(M, span_warning("You lack the proper training to wear this harness!"))
return FALSE
6 changes: 0 additions & 6 deletions code/modules/clothing/rogueclothes/gloves.dm
Original file line number Diff line number Diff line change
Expand Up @@ -289,9 +289,3 @@
sewrepair = TRUE
smeltresult = /obj/item/stack/sheet/leather
sleeved = FALSE

/obj/item/clothing/gloves/roguetown/armor/harms/mob_can_equip(mob/living/M, slot, disable_warning = FALSE)
. = ..()
if(!HAS_TRAIT(M, TRAIT_PONYGIRL_RIDEABLE))
to_chat(M, span_warning("You lack the proper training to wear this harness!"))
return FALSE
6 changes: 0 additions & 6 deletions code/modules/clothing/rogueclothes/pants.dm
Original file line number Diff line number Diff line change
Expand Up @@ -453,9 +453,3 @@
armor_class = ARMOR_CLASS_LIGHT
sewrepair = TRUE
smeltresult = /obj/item/stack/sheet/leather

/obj/item/clothing/under/roguetown/armor/hlegs/mob_can_equip(mob/living/M, slot, disable_warning = FALSE)
. = ..()
if(!HAS_TRAIT(M, TRAIT_PONYGIRL_RIDEABLE))
to_chat(M, span_warning("You lack the proper training to wear this harness!"))
return FALSE
51 changes: 3 additions & 48 deletions code/modules/jobs/job_types/roguetown/peasants/town slave.dm
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,14 @@
allowed_races = RACES_ALL_KINDSPLUS
tutorial = "Though the title 'public servant' may sound like you are not a slave, matter of fact you are. Stripped of your rights to even your own body, you must work to try to pay off your debt you made previously so you may reclaim your freedom."

outfit = null // Let subclasses handle outfit
outfit = /datum/outfit/job/roguetown/prisonerd
display_order = JDO_PRISONERD
give_bank_account = 10
min_pq = -14
max_pq = null
can_random = FALSE

cmode_music = 'sound/music/combat_bum.ogg'

advsetup = 1
advclass_cat_rolls = list(CTAG_SERVANT = 100)

Expand Down Expand Up @@ -46,27 +45,9 @@
post_equip(H)
H.advjob = name

/datum/advclass/ponygirl
name = "Ponygirl"
tutorial = "Trained to serve as a mount and beast of burden, you are equipped with special gear and training."
outfit = /datum/outfit/job/roguetown/prisonerd/ponygirl
category_tags = list(CTAG_SERVANT)
allowed_sexes = list(MALE, FEMALE)
pickprob = 100
traits_applied = list(TRAIT_PONYGIRL_RIDEABLE, TRAIT_CRITICAL_RESISTANCE, TRAIT_EMPATH,
TRAIT_NOPAIN, TRAIT_NOPAINSTUN, TRAIT_STABLELIVER, TRAIT_PACIFISM,
TRAIT_BOG_TREKKING, TRAIT_NASTY_EATER, TRAIT_GOODLOVER, TRAIT_BLOODLOSS_IMMUNE)

/datum/advclass/ponygirl/equipme(mob/living/carbon/human/H)
. = ..()
if(!H)
return FALSE
H.equipOutfit(outfit)
post_equip(H)
H.advjob = name
H.mind.adjust_skillrank_up_to(/datum/skill/misc/athletics, 9)

/datum/outfit/job/roguetown/prisonerd/servant/pre_equip(mob/living/carbon/human/H)

/datum/outfit/job/roguetown/prisonerd/pre_equip(mob/living/carbon/human/H)
..()
neck = /obj/item/clothing/neck/roguetown/gorget/servant
if(H.gender == FEMALE)
Expand Down Expand Up @@ -96,32 +77,6 @@
ADD_TRAIT(H, TRAIT_NASTY_EATER, TRAIT_GENERIC)
ADD_TRAIT(H, TRAIT_GOODLOVER, TRAIT_GENERIC)

/datum/outfit/job/roguetown/prisonerd/ponygirl/pre_equip(mob/living/carbon/human/H)
..()
mask = /obj/item/clothing/head/hbit
head = /obj/item/clothing/head/hblinders
armor = /obj/item/clothing/suit/roguetown/armor/hcorset
gloves = /obj/item/clothing/gloves/roguetown/armor/harms
pants = /obj/item/clothing/under/roguetown/armor/hlegs
H.change_stat("constitution", 10)
H.change_stat("speed", 10)
if(H.mind)
ADD_TRAIT(H, TRAIT_PONYGIRL_RIDEABLE, TRAIT_GENERIC)
ADD_TRAIT(H, TRAIT_CRITICAL_RESISTANCE, TRAIT_GENERIC)
ADD_TRAIT(H, TRAIT_EMPATH, TRAIT_GENERIC)
ADD_TRAIT(H, TRAIT_NOPAIN, TRAIT_GENERIC)
ADD_TRAIT(H, TRAIT_NOPAINSTUN, TRAIT_GENERIC)
ADD_TRAIT(H, TRAIT_STABLELIVER, TRAIT_GENERIC)
ADD_TRAIT(H, TRAIT_PACIFISM, TRAIT_GENERIC)
ADD_TRAIT(H, TRAIT_BOG_TREKKING, TRAIT_GENERIC)
ADD_TRAIT(H, TRAIT_NASTY_EATER, TRAIT_GENERIC)
ADD_TRAIT(H, TRAIT_GOODLOVER, TRAIT_GENERIC)
ADD_TRAIT(H, TRAIT_BLOODLOSS_IMMUNE, TRAIT_GENERIC)
H.mind.adjust_skillrank_up_to(/datum/skill/misc/athletics, 6)
H.mind.adjust_skillrank_up_to(/datum/skill/misc/climbing, 6)
H.mind.adjust_skillrank_up_to(/datum/skill/misc/swimming, 6)

/datum/job/roguetown/prisonerd/New()
. = ..()
new /datum/advclass/basic()
new /datum/advclass/ponygirl()
52 changes: 32 additions & 20 deletions code/modules/mob/living/carbon/human/human.dm
Original file line number Diff line number Diff line change
Expand Up @@ -846,32 +846,44 @@

//Target = what was clicked on, User = thing doing the clicking
/mob/living/carbon/human/MouseDrop_T(mob/living/target, mob/living/user)
// Seelie shoulder sitting
if(isseelie(target) && user == target)
shoulder_ride(target)
return
// Seelies can sit on anyone's shoulders
if(isseelie(target) && !(HAS_TRAIT(src, TRAIT_TINY)))
if(can_piggyback(target))
shoulder_ride(target)
return TRUE

// Ponygirl mounting
if(HAS_TRAIT(src, TRAIT_PONYGIRL_RIDEABLE))
if(user == target && can_buckle && !buckled_mobs?.len)
if(user.incapacitated() || user.stat || user.restrained())
return
user.visible_message(span_notice("[user] starts mounting [src]..."))
if(do_after(user, 15, target = src))
if(user.incapacitated())
return
if(buckle_mob(user, TRUE, FALSE))
return TRUE
return
return ..()
// Anyone can sit on anthromorphbig's shoulders
if(istype(src.dna?.species, /datum/species/anthromorphbig))
if(user == target && can_piggyback(target)) // Make sure the person dragging is the one trying to sit
shoulder_ride(target)
return TRUE

if(user == target)
return FALSE
//normal vore check.
if(user.pulling == target && user.grab_state && user.voremode)
if(ismob(user.pulling))
user.vore_attack(user, target, src) // User, Pulled, Predator target (which can be user, pulling, or src)
return TRUE
if(pulling == target && stat == CONSCIOUS)
//If they dragged themselves and we're currently aggressively grabbing them try to piggyback
if(user == target && can_piggyback(target))
piggyback(target)
return TRUE
//If you dragged them to you and you're aggressively grabbing try to carry them
else if(user != target && can_be_firemanned(target))
var/obj/G = get_active_held_item()
if(G)
if(istype(G, /obj/item/grabbing))
fireman_carry(target)
return TRUE
. = ..()

/mob/living/carbon/human/proc/shoulder_ride(mob/living/carbon/target)
if(!isseelie(target))
return
buckle_mob(target, TRUE, TRUE, FALSE, 0, 0)
visible_message(span_notice("[target] gently sits on [src]'s shoulder."))
target.pixel_y += 6 // Adjust for proper visual alignment
if(istype(target.dna?.species, /datum/species/anthromorphbig))
target.pixel_y += 6 // Adjust this value as needed for proper visual alignment

/mob/living/carbon/human/proc/can_piggyback(mob/living/carbon/target)
return (istype(target) && target.stat == CONSCIOUS)
Expand Down
180 changes: 0 additions & 180 deletions code/modules/mob/living/carbon/human/human_movement.dm
Original file line number Diff line number Diff line change
Expand Up @@ -112,183 +112,3 @@
if(dna.species.space_move(src))
return TRUE
return ..()

/mob/living/carbon/human
var/pony_sprint = 0
var/pony_sprint_cooldown = 0
var/pony_max_sprint = 50
var/spurred = FALSE
var/last_damage_data = null // to track damage

/mob/living/carbon/human/proc/handle_pony_riding()
if(!HAS_TRAIT(src, TRAIT_PONYGIRL_RIDEABLE))
return FALSE

var/mob/living/carbon/human/rider = locate() in src.buckled_mobs
if(!rider)
return FALSE

// Transfer damage from rider to ponygirl using Roguetown's damage system
if(rider.getBruteLoss() > 0)
var/damage = rider.getBruteLoss()
apply_damage(damage, BRUTE, null, 0)
rider.heal_overall_damage(damage, 0)

if(rider.getFireLoss() > 0)
var/damage = rider.getFireLoss()
apply_damage(damage, BURN, null, 0)
rider.heal_overall_damage(0, damage)

// Handle bleeding transfer
if(rider.bleed_rate > 0)
var/old_bleed = rider.bleed_rate
rider.bleed_rate = 0
bleed_rate += old_bleed
to_chat(src, span_warning("You feel [rider]'s wounds transfer to you!"))
to_chat(rider, span_notice("Your wounds seem to transfer to [src]!"))

// Reset sprint if cooldown passed
if(pony_sprint_cooldown && world.timeofday > pony_sprint_cooldown)
pony_sprint = initial(pony_sprint)
spurred = FALSE
change_stat("speed", -pony_sprint * 0.1) // Remove speed boost
ADD_TRAIT(src, TRAIT_NOROGSTAM, TRAIT_GENERIC)

// Handle spanking speed boost
if(rider.a_intent == INTENT_HARM && rider.zone_selected == "groin")
pony_sprint = min(pony_sprint + 5, pony_max_sprint)
change_stat("speed", pony_sprint * 0.1) // Apply speed boost
spurred = TRUE
REMOVE_TRAIT(src, TRAIT_NOROGSTAM, TRAIT_GENERIC)
visible_message(span_notice("[rider] spurs [src], increasing their pace!"), \
span_notice("The sharp sting drives you to move faster!"), \
span_notice("You hear a sharp slap!"))
pony_sprint_cooldown = world.timeofday + 50

// Maintain speed boost while spurred
if(spurred)
change_stat("speed", pony_sprint * 0.1) // Maintain speed boost
REMOVE_TRAIT(src, TRAIT_NOROGSTAM, TRAIT_GENERIC)

return TRUE

/mob/living/carbon/human/buckle_mob(mob/living/M, force = FALSE, check_loc = TRUE)
if(!force && !HAS_TRAIT(src, TRAIT_PONYGIRL_RIDEABLE))
return FALSE

if(..()) // If parent buckle succeeds
var/datum/component/riding/human/riding_datum = LoadComponent(/datum/component/riding/human)
riding_datum.vehicle_move_delay = 2 // Base movement delay

// Apply riding skill modifiers
if(M.mind)
var/riding_skill = M.mind.get_skill_level(/datum/skill/misc/riding)
if(riding_skill)
riding_datum.vehicle_move_delay = max(1, 2 - (riding_skill * 0.2))

// Set proper riding offsets
riding_datum.set_riding_offsets(RIDING_OFFSET_ALL, list(
TEXT_NORTH = list(0, 6),
TEXT_SOUTH = list(0, 6),
TEXT_EAST = list(-6, 4),
TEXT_WEST = list(6, 4)
))

// Set proper layering
riding_datum.set_vehicle_dir_layer(SOUTH, ABOVE_MOB_LAYER)
riding_datum.set_vehicle_dir_layer(NORTH, OBJ_LAYER)
riding_datum.set_vehicle_dir_layer(EAST, OBJ_LAYER)
riding_datum.set_vehicle_dir_layer(WEST, OBJ_LAYER)

return TRUE
return FALSE

/mob/living/carbon/human/unbuckle_mob(mob/living/M, force = FALSE)
. = ..()
if(.)
pony_sprint = initial(pony_sprint)
spurred = FALSE
ADD_TRAIT(src, TRAIT_NOROGSTAM, TRAIT_GENERIC)

/mob/living/carbon/human/MouseDrop(atom/over_object)
if(HAS_TRAIT(src, TRAIT_PONYGIRL_RIDEABLE) && over_object == usr)
var/mob/living/user = usr
if(can_buckle && !buckled_mobs?.len)
if(user.incapacitated() || user.lying || user.restrained())
return
user.visible_message(span_notice("[user] starts mounting [src]..."))
if(do_after(user, 15, target = src))
if(user.incapacitated() || user.lying || user.restrained())
return
if(buckle_mob(user, TRUE, FALSE))
var/datum/component/riding/human/riding_datum = LoadComponent(/datum/component/riding/human)
riding_datum.vehicle_move_delay = 2 // Base movement delay
if(user.mind)
var/riding_skill = user.mind.get_skill_level(/datum/skill/misc/riding)
if(riding_skill)
riding_datum.vehicle_move_delay = max(1, 2 - (riding_skill * 0.2))
return TRUE
return
return ..()

/mob/living/carbon/human/relaymove(mob/user, direction)
if(HAS_TRAIT(src, TRAIT_PONYGIRL_RIDEABLE))
var/datum/component/riding/riding_datum = GetComponent(/datum/component/riding)
if(riding_datum)
return riding_datum.handle_ride(user, direction)
return ..()

/mob/living/carbon/human/Life()
. = ..()
if(HAS_TRAIT(src, TRAIT_PONYGIRL_RIDEABLE))
handle_pony_riding()

/mob/living/carbon/human/attack_hand(mob/living/carbon/human/M)
// Check if target is riding a ponygirl
if(buckled && istype(buckled, /mob/living/carbon/human))
var/mob/living/carbon/human/mount = buckled
if(HAS_TRAIT(mount, TRAIT_PONYGIRL_RIDEABLE))
visible_message(span_warning("[M]'s attack is redirected to [mount]'s chest!"))
// Redirect the attack to the mount's chest
M.zone_selected = BODY_ZONE_CHEST // Force target chest
return mount.attack_hand(M) // Use normal attack_hand instead of secondary
return ..()

/mob/living/carbon/human/attackby(obj/item/I, mob/living/user, params)
// Check if target is riding a ponygirl
if(buckled && istype(buckled, /mob/living/carbon/human))
var/mob/living/carbon/human/mount = buckled
if(HAS_TRAIT(mount, TRAIT_PONYGIRL_RIDEABLE))
visible_message(span_warning("[user]'s attack is redirected to [mount]'s chest!"))
// Redirect the attack to the mount's chest
user.zone_selected = BODY_ZONE_CHEST // Force target chest
return mount.attackby(I, user, params) // Use normal attackby instead of secondary
return ..()

// Add these helper procs to handle the redirected attacks
/mob/living/carbon/human/proc/attack_hand_secondary(mob/living/carbon/human/M)
return ..() // Call parent attack_hand without redirection checks

/mob/living/carbon/human/proc/attackby_secondary(obj/item/I, mob/living/user, params)
return ..() // Call parent attackby without redirection checks

// Add these new procs to handle other attack types
/mob/living/carbon/human/attack_animal(mob/living/simple_animal/M)
if(buckled && istype(buckled, /mob/living/carbon/human))
var/mob/living/carbon/human/mount = buckled
if(HAS_TRAIT(mount, TRAIT_PONYGIRL_RIDEABLE))
visible_message(span_warning("[M]'s attack is redirected to [mount]!"))
mount.attack_animal(M)
mount.handle_pony_riding()
return TRUE
return ..()

/mob/living/carbon/human/bullet_act(obj/projectile/P)
if(buckled && istype(buckled, /mob/living/carbon/human))
var/mob/living/carbon/human/mount = buckled
if(HAS_TRAIT(mount, TRAIT_PONYGIRL_RIDEABLE))
visible_message(span_warning("The [P] is redirected to [mount]!"))
mount.bullet_act(P)
mount.handle_pony_riding()
return BULLET_ACT_HIT
return ..()
Loading
Loading