Add precise hardcore pose positioning

This commit is contained in:
2026-06-24 16:24:47 +02:00
parent 536254f4a5
commit 669a893e7c
2 changed files with 208 additions and 12 deletions
+197 -11
View File
@@ -286,17 +286,29 @@ def _hardcore_pose_anchor(role_graph: str, hard_item: str, composition: str = ""
if not text:
return ""
if "double penetration" in text or "vaginal and anal penetration" in text or "front-and-back" in text:
if "face-down ass-up" in text:
return "face-down rear-entry double-penetration pose"
if "doggy style" in text or "doggy-style" in text:
return "doggy-style double-penetration pose"
if "bent-over" in text:
return "bent-over double-penetration pose"
if "spooning anal" in text or "side-lying anal" in text:
return "side-lying double-penetration pose"
if "bed-edge" in text or "edge-of-bed" in text:
return "bed-edge front-and-back double-penetration pose"
if "standing anal" in text or "standing supported" in text:
return "standing supported front-and-back double-penetration pose"
if "kneeling anal" in text:
return "kneeling rear-entry double-penetration pose"
if "standing supported" in text:
return "standing supported front-and-back double-penetration pose"
if "kneeling" in text:
return "kneeling front-and-back double-penetration pose"
return "front-and-back double-penetration pose"
if "face-sitting" in text:
return "face-sitting oral pose"
if "sixty-nine" in text:
return "sixty-nine oral pose"
if "face-sitting" in text:
return "face-sitting oral pose"
if "cunnilingus" in text or "pussy licking" in text or "mouth on her pussy" in text:
if "reclining" in text:
return "reclining cunnilingus pose"
@@ -328,17 +340,27 @@ def _hardcore_pose_anchor(role_graph: str, hard_item: str, composition: str = ""
return "chair oral pose"
return "mouth-to-genitals oral pose"
if "anal" in text or "ass" in text or "rear-entry" in text:
if "face-down ass-up" in text:
return "face-down ass-up rear-entry anal pose"
if "doggy style" in text or "doggy-style" in text:
return "doggy-style anal pose"
if "bed-edge" in text or "edge-of-bed" in text:
return "bed-edge rear-entry anal pose"
if "bent-over" in text:
return "bent-over rear-entry anal pose"
if "spooning anal" in text or "side-lying anal" in text:
return "side-lying rear-entry anal pose"
if "kneeling anal" in text:
return "kneeling rear-entry anal pose"
if "standing anal" in text:
return "standing rear-entry anal pose"
if "doggy" in text:
return "doggy-style anal pose"
return "rear-entry anal pose"
positions = (
"missionary",
"cowgirl",
"reverse cowgirl",
"cowgirl",
"doggy style",
"standing sex",
"spooning sex",
@@ -363,19 +385,175 @@ def _hardcore_pose_arrangement(anchor: str, role_graph: str, hard_item: str, com
text = " ".join(_clean(part).lower() for part in (anchor, role_graph, hard_item, composition) if _clean(part))
if not text:
return ""
mixed_woman_man = "the woman" in text and "the man" in text
is_double = "double-penetration" in text or "double penetration" in text
def cast_phrase(mixed: str, generic: str) -> str:
return mixed if mixed_woman_man else generic
def double_tail() -> str:
return ", with the toy aligned at the second penetration point" if "toy" in text else ", with the second penetration point aligned"
if "sixty-nine" in text:
return cast_phrase(
"with the woman and man inverted head-to-hips so both mouths align with genitals",
"with both bodies inverted head-to-hips so both mouths align with genitals",
)
if "face-sitting" in text:
return cast_phrase(
"with the man lying back while the woman straddles his face",
"with one partner lying back while the other straddles the face",
)
if "reclining cunnilingus" in text or "spread-leg oral" in text:
if "takes the man's penis" in text or "penis in her mouth" in text:
return cast_phrase(
"with the man seated or lying back with legs apart and the woman positioned at his hips",
"with the receiver seated or lying back with legs apart and the giver positioned at the hips",
)
return cast_phrase(
"with the woman lying back, thighs spread, and the man positioned between her legs",
"with the receiving partner lying back, thighs spread, and the giver positioned between the legs",
)
if "straddled cunnilingus" in text or "straddled oral" in text:
return cast_phrase(
"with the woman straddling above the man's mouth and her thighs framing his face",
"with the receiver straddling above the giver's mouth",
)
if "edge-of-bed oral" in text:
if "takes the man's penis" in text or "penis in her mouth" in text:
return cast_phrase(
"with the man at the bed edge and the woman kneeling at his hips",
"with the receiver at the bed edge and the giver positioned at hip height",
)
return cast_phrase(
"with the woman lying at the bed edge and the man positioned between her open thighs",
"with the receiver lying at the bed edge and the giver positioned between open thighs",
)
if "standing oral" in text:
if "takes the man's penis" in text or "penis in her mouth" in text:
return cast_phrase(
"with the man standing and the woman kneeling in front of his hips",
"with the receiver standing and the giver kneeling at hip height",
)
return cast_phrase(
"with the woman standing braced and the man kneeling between her thighs",
"with the receiver standing braced and the giver kneeling between the thighs",
)
if "chair oral" in text:
if "takes the man's penis" in text or "penis in her mouth" in text:
return cast_phrase(
"with the man seated in the chair and the woman kneeling between his legs at hip level",
"with the receiver seated in the chair and the giver kneeling between the legs at hip level",
)
return cast_phrase(
"with one partner seated in a chair and the other kneeling between the open thighs",
"with the receiver seated in a chair and the giver kneeling between the open thighs",
)
if "side-lying oral" in text:
return "with both bodies lying on their sides and mouth aligned to genitals"
if "kneeling oral" in text:
if "takes the man's penis" in text or "penis in her mouth" in text:
return cast_phrase(
"with the woman kneeling in front of the man's hips, her mouth at penis level",
"with the giver kneeling in front of the receiver's hips",
)
if "mouth on her pussy" in text or "uses his mouth on" in text:
return cast_phrase(
"with the man kneeling between the woman's open thighs, his mouth at her pussy",
"with the giver kneeling between the receiver's open thighs",
)
return "with the giver kneeling at the receiver's hips"
if "reverse cowgirl" in text:
return cast_phrase(
"with the man lying on his back under the woman while she straddles his hips facing away",
"with the lower partner lying on their back while the upper partner straddles them facing away",
)
if "cowgirl" in text:
return cast_phrase(
"with the man lying on his back under the woman while she straddles his hips on top",
"with the lower partner lying on their back while the upper partner straddles their hips on top",
)
if "missionary" in text:
return cast_phrase(
"with the woman lying on her back under the man, legs open around his hips",
"with the receiving partner lying on their back under the penetrating partner, legs open around the hips",
)
if "lotus" in text:
return cast_phrase(
"with the man seated upright and the woman seated in his lap facing him, legs wrapped around his hips",
"with one partner seated upright and the other seated in their lap facing them, legs wrapped around the hips",
)
if "kneeling straddle" in text:
return cast_phrase(
"with the woman straddling the man's kneeling lap, both torsos upright and hips pressed together",
"with one partner straddling the other's kneeling lap, torsos upright and hips pressed together",
)
if "doggy-style" in text:
return cast_phrase(
f"with the woman on all fours and the man positioned behind her at hip level{double_tail() if is_double else ''}",
f"with the receiving partner on all fours and the penetrating partner positioned behind at hip level{double_tail() if is_double else ''}",
)
if "face-down" in text:
return cast_phrase(
f"with the woman face-down, hips raised, and the man positioned behind her{double_tail() if is_double else ''}",
f"with the receiving partner face-down, hips raised, and the penetrating partner positioned behind{double_tail() if is_double else ''}",
)
if "bent-over" in text:
return cast_phrase(
f"with the woman bent forward at the waist and the man positioned behind her{double_tail() if is_double else ''}",
f"with the receiving partner bent forward at the waist and the penetrating partner positioned behind{double_tail() if is_double else ''}",
)
if "spooning" in text or ("side-lying" in text and "oral" not in text):
return cast_phrase(
f"with both lying on their sides and the man positioned behind the woman{double_tail() if is_double else ''}",
f"with both bodies lying on their sides and the penetrating partner positioned behind{double_tail() if is_double else ''}",
)
if "edge-of-bed" in text or "bed-edge" in text:
return cast_phrase(
f"with the woman lying at the bed edge, hips at the edge, and the man standing or kneeling between her legs{double_tail() if is_double else ''}",
f"with the receiver lying at the bed edge, hips at the edge, and the penetrating partner standing or kneeling between the legs{double_tail() if is_double else ''}",
)
if "standing" in text:
return cast_phrase(
f"with the woman braced standing and the man aligned at her hips{double_tail() if is_double else ''}",
f"with both partners standing and the penetrating partner aligned at the receiver's hips{double_tail() if is_double else ''}",
)
if "kneeling" in text and ("anal" in text or "rear-entry" in text):
return cast_phrase(
f"with the woman kneeling forward and the man positioned behind her{double_tail() if is_double else ''}",
f"with the receiving partner kneeling forward and the penetrating partner positioned behind{double_tail() if is_double else ''}",
)
if "double-penetration" in text or "double penetration" in text:
if "toy" in text:
return "with the woman's hips spread and front-and-back alignment visible"
return "with the central body held between front-and-back contact"
return cast_phrase(
"with the woman bent forward or on all fours, the man behind her, and the toy aligned at the second penetration point",
"with the receiving body bent forward or on all fours and the toy aligned at the second penetration point",
)
if "from the front" in text:
return cast_phrase(
"with the woman held between the man behind her and a second partner in front",
"with the receiving body held between one partner behind and a second partner in front",
)
return cast_phrase(
"with the woman held in a front-and-back position so both contact points are visible",
"with the central body held in a front-and-back position so both contact points are visible",
)
if "anal" in text or "rear-entry" in text:
return "with the woman's hips raised, ass exposed, and penetration alignment visible"
return cast_phrase(
"with the woman's hips raised, ass exposed, and the man positioned behind her",
"with the receiving partner's hips raised and the penetrating partner positioned behind",
)
if "cunnilingus" in text or "mouth on her pussy" in text or "pussy licking" in text:
return "with the woman's thighs open and the giver's mouth pressed to her pussy"
return cast_phrase(
"with the woman's thighs open and the man's mouth pressed to her pussy",
"with the receiver's thighs open and the giver's mouth pressed to genitals",
)
if "oral" in text or "blowjob" in text or "penis in her mouth" in text or "penis in mouth" in text:
if "sixty-nine" in text:
return "with both bodies arranged mouth-to-genitals"
if "takes the man's penis in her mouth" in text or "penis in her mouth" in text:
return "with the woman's mouth close to the man's hips"
return cast_phrase(
"with the woman's mouth at the man's hips",
"with the giver's mouth positioned at the receiver's hips",
)
return "with mouth and genitals aligned clearly"
if "threesome" in text or "three-body" in text:
return "with all three adult bodies clearly placed around the central subject"
@@ -485,9 +663,10 @@ def _dedupe_hardcore_detail(detail: str, anchor: str) -> str:
"straddled cunnilingus": (r"straddled oral position", r"straddled cunnilingus position"),
"open-thigh cunnilingus": (r"reclining cunnilingus position", r"straddled cunnilingus position"),
"bent-over": (r"bent-over position",),
"face-down": (r"face-down ass-up position",),
"missionary": (r"missionary position",),
"cowgirl": (r"cowgirl position",),
"reverse cowgirl": (r"reverse cowgirl position",),
"cowgirl": (r"cowgirl position",),
"doggy-style": (r"doggy style position",),
"edge-of-bed": (r"edge-of-bed position",),
}
@@ -553,6 +732,13 @@ def _hardcore_action_sentence(role_graph: str, hard_item: str, composition: str
)
detail = _hardcore_item_detail(hard_item)
anchor = _hardcore_pose_anchor(role_graph, hard_item, composition)
if "double-penetration" in anchor.lower() and "toy" in role_graph.lower():
role_graph = re.sub(
r"\s+while a toy adds (?:the|a) second penetration point\b",
"",
role_graph,
flags=re.IGNORECASE,
)
detail = _dedupe_hardcore_detail(detail, anchor) if anchor else detail
arrangement = _hardcore_pose_arrangement(anchor, role_graph, hard_item, composition)
anchor_phrase = _with_indefinite_article(anchor) if anchor else ""