Clarify partially removed clothing for penetration
This commit is contained in:
+101
-1
@@ -6342,7 +6342,98 @@ def _insta_of_softcore_pose(rng: random.Random, level: str) -> str:
|
|||||||
return g.choose(rng, pool)
|
return g.choose(rng, pool)
|
||||||
|
|
||||||
|
|
||||||
def _insta_of_hardcore_clothing_state(mode: str, softcore_outfit: str) -> str:
|
PENETRATION_LOWER_ACCESS_TERMS = (
|
||||||
|
"penetrat",
|
||||||
|
"thrust",
|
||||||
|
"vaginal",
|
||||||
|
"anal",
|
||||||
|
"rear-entry",
|
||||||
|
"rear entry",
|
||||||
|
"front-and-back",
|
||||||
|
"front and back",
|
||||||
|
"double",
|
||||||
|
"doggy",
|
||||||
|
"missionary",
|
||||||
|
"cowgirl",
|
||||||
|
"straddles",
|
||||||
|
"hips aligned",
|
||||||
|
"penis into",
|
||||||
|
"penis inside",
|
||||||
|
"penis entering",
|
||||||
|
"toy aligned",
|
||||||
|
"second penetration point",
|
||||||
|
)
|
||||||
|
|
||||||
|
LOWER_BODY_CLOTHING_TERMS = (
|
||||||
|
"panty",
|
||||||
|
"panties",
|
||||||
|
"brief",
|
||||||
|
"briefs",
|
||||||
|
"thong",
|
||||||
|
"bottom",
|
||||||
|
"bottoms",
|
||||||
|
"bodysuit",
|
||||||
|
"teddy",
|
||||||
|
"dress",
|
||||||
|
"skirt",
|
||||||
|
"shorts",
|
||||||
|
"jeans",
|
||||||
|
"trousers",
|
||||||
|
"pants",
|
||||||
|
"bikini",
|
||||||
|
"towel",
|
||||||
|
"sheet",
|
||||||
|
"blanket",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def _hardcore_row_needs_lower_access(row: dict[str, Any]) -> bool:
|
||||||
|
axis_values = row.get("item_axis_values")
|
||||||
|
axis_text = " ".join(str(value) for value in axis_values.values()) if isinstance(axis_values, dict) else ""
|
||||||
|
text = " ".join(
|
||||||
|
str(part or "")
|
||||||
|
for part in (
|
||||||
|
row.get("source_role_graph"),
|
||||||
|
row.get("role_graph"),
|
||||||
|
row.get("item"),
|
||||||
|
row.get("source_composition"),
|
||||||
|
row.get("composition"),
|
||||||
|
axis_text,
|
||||||
|
)
|
||||||
|
).lower()
|
||||||
|
return any(term in text for term in PENETRATION_LOWER_ACCESS_TERMS)
|
||||||
|
|
||||||
|
|
||||||
|
def _outfit_without_lower_body_blockers(outfit: str) -> str:
|
||||||
|
text = str(outfit or "").strip()
|
||||||
|
if not text:
|
||||||
|
return ""
|
||||||
|
text = re.sub(r"\blingerie set\b", "lingerie top details", text, flags=re.IGNORECASE)
|
||||||
|
text = re.sub(r"\bbrief set\b", "bra set", text, flags=re.IGNORECASE)
|
||||||
|
text = re.sub(r"\bbodysuit with\b", "upper bodysuit detail with", text, flags=re.IGNORECASE)
|
||||||
|
fragments = re.split(r"\s*,\s*|\s+\band\b\s+|\s+\bwith\b\s+|\s+\bunder\b\s+|\s+\bover\b\s+", text)
|
||||||
|
kept = []
|
||||||
|
for fragment in fragments:
|
||||||
|
fragment = fragment.strip(" ,.;")
|
||||||
|
if not fragment:
|
||||||
|
continue
|
||||||
|
lower = fragment.lower()
|
||||||
|
if any(term in lower for term in LOWER_BODY_CLOTHING_TERMS):
|
||||||
|
continue
|
||||||
|
kept.append(fragment)
|
||||||
|
if not kept:
|
||||||
|
return ""
|
||||||
|
deduped = []
|
||||||
|
seen = set()
|
||||||
|
for fragment in kept:
|
||||||
|
key = re.sub(r"\W+", " ", fragment.lower()).strip()
|
||||||
|
if key and key not in seen:
|
||||||
|
deduped.append(fragment)
|
||||||
|
seen.add(key)
|
||||||
|
return ", ".join(deduped)
|
||||||
|
|
||||||
|
|
||||||
|
def _insta_of_hardcore_clothing_state(mode: str, softcore_outfit: str, needs_lower_access: bool = False) -> str:
|
||||||
mode = mode if mode in INSTA_OF_HARDCORE_CLOTHING_CONTINUITY else "none"
|
mode = mode if mode in INSTA_OF_HARDCORE_CLOTHING_CONTINUITY else "none"
|
||||||
outfit = str(softcore_outfit or "").strip()
|
outfit = str(softcore_outfit or "").strip()
|
||||||
if mode == "none" or not outfit:
|
if mode == "none" or not outfit:
|
||||||
@@ -6352,6 +6443,14 @@ def _insta_of_hardcore_clothing_state(mode: str, softcore_outfit: str) -> str:
|
|||||||
return f"Body exposure: {base}."
|
return f"Body exposure: {base}."
|
||||||
if mode == "implied_nude":
|
if mode == "implied_nude":
|
||||||
return f"Body exposure: {base}."
|
return f"Body exposure: {base}."
|
||||||
|
if mode == "partially_removed" and needs_lower_access:
|
||||||
|
detail = _outfit_without_lower_body_blockers(outfit)
|
||||||
|
base = (
|
||||||
|
"Woman A's lower body is clear for penetration; any lower garment is pulled aside or removed below the hips"
|
||||||
|
)
|
||||||
|
if detail:
|
||||||
|
return f"Clothing state: {base}; visible remaining styling: {detail}."
|
||||||
|
return f"Clothing state: {base}."
|
||||||
return f"Clothing state: {base}; teaser outfit detail: {outfit}."
|
return f"Clothing state: {base}; teaser outfit detail: {outfit}."
|
||||||
|
|
||||||
|
|
||||||
@@ -6637,6 +6736,7 @@ def build_insta_of_pair(
|
|||||||
fallback_hard_clothing_state = "" if has_primary_hardcore_clothing else _insta_of_hardcore_clothing_state(
|
fallback_hard_clothing_state = "" if has_primary_hardcore_clothing else _insta_of_hardcore_clothing_state(
|
||||||
options["hardcore_clothing_continuity"],
|
options["hardcore_clothing_continuity"],
|
||||||
soft_row["item"],
|
soft_row["item"],
|
||||||
|
needs_lower_access=_hardcore_row_needs_lower_access(hard_row),
|
||||||
)
|
)
|
||||||
hard_clothing_parts = [part for part in (fallback_hard_clothing_state, *character_hardcore_clothing_entries) if part]
|
hard_clothing_parts = [part for part in (fallback_hard_clothing_state, *character_hardcore_clothing_entries) if part]
|
||||||
hard_clothing_state = " ".join(hard_clothing_parts)
|
hard_clothing_state = " ".join(hard_clothing_parts)
|
||||||
|
|||||||
+1
-1
@@ -145,7 +145,7 @@ def _split_tag_text(text: Any) -> list[str]:
|
|||||||
text = re.sub(r"\bWoman [A-Z]\b", "woman", text)
|
text = re.sub(r"\bWoman [A-Z]\b", "woman", text)
|
||||||
text = re.sub(r"\bMan [A-Z]\b", "man", text)
|
text = re.sub(r"\bMan [A-Z]\b", "man", text)
|
||||||
text = re.sub(
|
text = re.sub(
|
||||||
r"\b(?:Clothing state|Visual clothing state|teaser outfit detail|softcore visual reference|Sexual scene|Role graph):\s*",
|
r"\b(?:Clothing state|Visual clothing state|visible remaining styling|teaser outfit detail|softcore visual reference|Sexual scene|Role graph):\s*",
|
||||||
"",
|
"",
|
||||||
text,
|
text,
|
||||||
flags=re.IGNORECASE,
|
flags=re.IGNORECASE,
|
||||||
|
|||||||
Reference in New Issue
Block a user