use of com.lilithsthrone.game.character.GameCharacter in project liliths-throne-public by Innoxia.
the class MainController method manageRightListeners.
private void manageRightListeners() {
documentRight = (Document) webEngineRight.executeScript("document");
EventListenerDataMap.put(documentRight, new ArrayList<>());
List<InventorySlot> concealedSlots = new ArrayList<>();
if (RenderingEngine.getCharacterToRender() != null) {
concealedSlots = RenderingEngine.getCharacterToRender().getInventorySlotsConcealed();
}
// Inventory:
String id;
for (InventorySlot invSlot : InventorySlot.values()) {
id = invSlot.toString() + "Slot";
if (invSlot != InventorySlot.WEAPON_MAIN && invSlot != InventorySlot.WEAPON_OFFHAND) {
if (((EventTarget) documentRight.getElementById(id)) != null) {
if (concealedSlots.contains(invSlot)) {
addEventListener(documentRight, id, "mousemove", moveTooltipListener, false);
addEventListener(documentRight, id, "mouseleave", hideTooltipListener, false);
TooltipInformationEventListener el2 = new TooltipInformationEventListener().setInformation(Util.capitaliseSentence(invSlot.getName()) + " - [style.boldBad(Concealed!)]", "");
addEventListener(documentRight, id, "mouseenter", el2, false);
} else {
InventorySelectedItemEventListener el = new InventorySelectedItemEventListener().setClothingEquipped(RenderingEngine.getCharacterToRender(), invSlot);
addEventListener(documentRight, id, "click", el, false);
addEventListener(documentRight, id, "mousemove", moveTooltipListener, false);
addEventListener(documentRight, id, "mouseleave", hideTooltipListener, false);
InventoryTooltipEventListener el2 = new InventoryTooltipEventListener().setInventorySlot(invSlot, RenderingEngine.getCharacterToRender());
addEventListener(documentRight, id, "mouseenter", el2, false);
}
}
} else {
if (((EventTarget) documentRight.getElementById(id)) != null) {
InventorySelectedItemEventListener el = new InventorySelectedItemEventListener().setWeaponEquipped(RenderingEngine.getCharacterToRender(), invSlot);
addEventListener(documentRight, id, "click", el, false);
addEventListener(documentRight, id, "mousemove", moveTooltipListener, false);
addEventListener(documentRight, id, "mouseleave", hideTooltipListener, false);
InventoryTooltipEventListener el2 = new InventoryTooltipEventListener().setInventorySlot(invSlot, RenderingEngine.getCharacterToRender());
addEventListener(documentRight, id, "mouseenter", el2, false);
}
}
}
for (NPC character : Main.game.getCharactersPresent()) {
id = "CHARACTERS_PRESENT_" + character.getId();
if (((EventTarget) documentRight.getElementById(id)) != null) {
((EventTarget) documentRight.getElementById(id)).addEventListener("click", e -> {
openCharactersPresent(Main.game.getNPCById(character.getId()));
}, false);
}
}
if (Main.game.getPlayer() != null) {
// Weapons on floor:
for (Entry<AbstractWeapon, Integer> entry : Main.game.getPlayerCell().getInventory().getMapOfDuplicateWeapons().entrySet()) {
id = "WEAPON_FLOOR_" + entry.getKey().hashCode();
if (((EventTarget) documentRight.getElementById(id)) != null) {
if (!Main.game.getCurrentDialogueNode().isInventoryDisabled()) {
InventorySelectedItemEventListener el = new InventorySelectedItemEventListener().setWeaponInventory(entry.getKey(), null);
addEventListener(documentRight, id, "click", el, false);
}
addEventListener(documentRight, id, "mousemove", moveTooltipListener, false);
addEventListener(documentRight, id, "mouseleave", hideTooltipListener, false);
InventoryTooltipEventListener el2 = new InventoryTooltipEventListener().setWeapon(entry.getKey(), null);
addEventListener(documentRight, id, "mouseenter", el2, false);
}
}
// Clothing on floor:
for (Entry<AbstractClothing, Integer> entry : Main.game.getPlayerCell().getInventory().getMapOfDuplicateClothing().entrySet()) {
id = "CLOTHING_FLOOR_" + entry.getKey().hashCode();
if (((EventTarget) documentRight.getElementById(id)) != null) {
if (!Main.game.getCurrentDialogueNode().isInventoryDisabled()) {
InventorySelectedItemEventListener el = new InventorySelectedItemEventListener().setClothingInventory(entry.getKey(), null);
addEventListener(documentRight, id, "click", el, false);
}
addEventListener(documentRight, id, "mousemove", moveTooltipListener, false);
addEventListener(documentRight, id, "mouseleave", hideTooltipListener, false);
InventoryTooltipEventListener el2 = new InventoryTooltipEventListener().setClothing(entry.getKey(), null, null);
addEventListener(documentRight, id, "mouseenter", el2, false);
}
}
// Items on floor:
for (Entry<AbstractItem, Integer> entry : Main.game.getPlayerCell().getInventory().getMapOfDuplicateItems().entrySet()) {
id = "ITEM_FLOOR_" + entry.getKey().hashCode();
if (((EventTarget) documentRight.getElementById(id)) != null) {
if (!Main.game.getCurrentDialogueNode().isInventoryDisabled()) {
InventorySelectedItemEventListener el = new InventorySelectedItemEventListener().setItemInventory(entry.getKey(), null);
addEventListener(documentRight, id, "click", el, false);
}
addEventListener(documentRight, id, "mousemove", moveTooltipListener, false);
addEventListener(documentRight, id, "mouseleave", hideTooltipListener, false);
InventoryTooltipEventListener el2 = new InventoryTooltipEventListener().setItem(entry.getKey(), null, null);
addEventListener(documentRight, id, "mouseenter", el2, false);
}
}
}
if (RenderingEngine.getCharacterToRender() != null) {
Attribute[] attributes = { Attribute.HEALTH_MAXIMUM, Attribute.MANA_MAXIMUM, Attribute.EXPERIENCE, Attribute.MAJOR_PHYSIQUE, Attribute.MAJOR_ARCANE, Attribute.MAJOR_CORRUPTION, Attribute.AROUSAL, Attribute.LUST };
List<GameCharacter> charactersBeingRendered = new ArrayList<>();
if (Main.game.isInSex()) {
charactersBeingRendered.addAll(Sex.getDominantParticipants().keySet());
charactersBeingRendered.addAll(Sex.getSubmissiveParticipants().keySet());
} else if (Main.game.isInCombat()) {
charactersBeingRendered.addAll(Combat.getEnemies());
} else {
charactersBeingRendered.add(RenderingEngine.getCharacterToRender());
}
charactersBeingRendered.remove(Main.game.getPlayer());
for (GameCharacter character : charactersBeingRendered) {
String idModifier = character.getId() + "_";
for (Attribute a : attributes) {
if (((EventTarget) documentRight.getElementById("NPC_" + idModifier + a.getName())) != null) {
if (a == Attribute.EXPERIENCE) {
((EventTarget) documentRight.getElementById("NPC_" + idModifier + a.getName())).addEventListener("click", e -> {
openCharactersPresent(character);
}, false);
}
addEventListener(documentRight, "NPC_" + idModifier + a.getName(), "mousemove", moveTooltipListener, false);
addEventListener(documentRight, "NPC_" + idModifier + a.getName(), "mouseleave", hideTooltipListener, false);
TooltipInformationEventListener el = new TooltipInformationEventListener().setAttribute(a, character);
addEventListener(documentRight, "NPC_" + idModifier + a.getName(), "mouseenter", el, false);
}
}
// Extra attribute info:
if (((EventTarget) documentRight.getElementById("NPC_" + idModifier + "ATTRIBUTES")) != null) {
// ((EventTarget) documentRight.getElementById("NPC_"+idModifier+"ATTRIBUTES")).addEventListener("click", e -> {
// openCharactersPresent(Main.game.getNPCById(Main.game.getActiveNPC().getId()));
// }, false);
addEventListener(documentRight, "NPC_" + idModifier + "ATTRIBUTES", "mousemove", moveTooltipListener, false);
addEventListener(documentRight, "NPC_" + idModifier + "ATTRIBUTES", "mouseleave", hideTooltipListener, false);
TooltipInformationEventListener el = new TooltipInformationEventListener().setExtraAttributes(character);
addEventListener(documentRight, "NPC_" + idModifier + "ATTRIBUTES", "mouseenter", el, false);
}
// For status effect slots:
for (StatusEffect se : character.getStatusEffects()) {
if (((EventTarget) documentRight.getElementById("SE_NPC_" + idModifier + se)) != null) {
addEventListener(documentRight, "SE_NPC_" + idModifier + se, "mousemove", moveTooltipListener, false);
addEventListener(documentRight, "SE_NPC_" + idModifier + se, "mouseleave", hideTooltipListener, false);
TooltipInformationEventListener el = new TooltipInformationEventListener().setStatusEffect(se, character);
addEventListener(documentRight, "SE_NPC_" + idModifier + se, "mouseenter", el, false);
}
}
// For perk slots:
for (Perk p : character.getMajorPerks()) {
if (((EventTarget) documentRight.getElementById("PERK_NPC_" + idModifier + p)) != null) {
addEventListener(documentRight, "PERK_NPC_" + idModifier + p, "mousemove", moveTooltipListener, false);
addEventListener(documentRight, "PERK_NPC_" + idModifier + p, "mouseleave", hideTooltipListener, false);
TooltipInformationEventListener el = new TooltipInformationEventListener().setPerk(p, character);
addEventListener(documentRight, "PERK_NPC_" + idModifier + p, "mouseenter", el, false);
}
}
for (Fetish f : character.getFetishes()) {
if (((EventTarget) documentRight.getElementById("FETISH_NPC_" + idModifier + f)) != null) {
addEventListener(documentRight, "FETISH_NPC_" + idModifier + f, "mousemove", moveTooltipListener, false);
addEventListener(documentRight, "FETISH_NPC_" + idModifier + f, "mouseleave", hideTooltipListener, false);
TooltipInformationEventListener el = new TooltipInformationEventListener().setFetish(f, character);
addEventListener(documentRight, "FETISH_NPC_" + idModifier + f, "mouseenter", el, false);
}
}
for (SpecialAttack sa : character.getSpecialAttacks()) {
if (((EventTarget) documentRight.getElementById("SA_NPC_" + idModifier + sa)) != null) {
addEventListener(documentRight, "SA_NPC_" + idModifier + sa, "mousemove", moveTooltipListener, false);
addEventListener(documentRight, "SA_NPC_" + idModifier + sa, "mouseleave", hideTooltipListener, false);
TooltipInformationEventListener el = new TooltipInformationEventListener().setSpecialAttack(sa, character);
addEventListener(documentRight, "SA_NPC_" + idModifier + sa, "mouseenter", el, false);
}
}
for (Spell s : character.getAllSpells()) {
if (((EventTarget) documentAttributes.getElementById("SPELL_" + idModifier + s)) != null) {
addEventListener(documentAttributes, "SPELL_" + idModifier + s, "mousemove", moveTooltipListener, false);
addEventListener(documentAttributes, "SPELL_" + idModifier + s, "mouseleave", hideTooltipListener, false);
TooltipInformationEventListener el = new TooltipInformationEventListener().setSpell(s, character.getLevel(), character);
addEventListener(documentAttributes, "SPELL_" + idModifier + s, "mouseenter", el, false);
}
}
}
}
}
use of com.lilithsthrone.game.character.GameCharacter in project liliths-throne-public by Innoxia.
the class Game method setContent.
public void setContent(int index) {
Response response = currentDialogueNode.getResponse(responseTab, index);
if (response != null) {
String corruptionGains = "";
if (!response.isAvailable()) {
if (!response.isAbleToBypass()) {
return;
} else {
Main.game.getPlayer().incrementAttribute(Attribute.MAJOR_CORRUPTION, response.getCorruptionNeeded().getCorruptionBypass());
corruptionGains = ("<p style='text-align:center;'>" + "<b>You have gained +" + response.getCorruptionNeeded().getCorruptionBypass() + "</b> <b style='color:" + Attribute.MAJOR_CORRUPTION.getColour().toWebHexString() + ";'>corruption</b><b>!</b>" + "</p>");
}
}
String chosenResponse = response.getTitle();
DialogueNodeOld node = response.getNextDialogue();
response.applyEffects();
if (response instanceof ResponseCombat) {
setContent(new Response("", "", ((ResponseCombat) response).initCombat()));
return;
} else if (response instanceof ResponseSex) {
setContent(new Response("", "", ((ResponseSex) response).initSex()));
return;
} else if (response instanceof ResponseEffectsOnly) {
return;
} else if (response instanceof ResponseTrade) {
((ResponseTrade) response).openTrade();
return;
}
if (node != null) {
// Add characters in this scene to the player's encountered characters list:
if (started) {
if (!getCharactersPresent().isEmpty()) {
for (GameCharacter character : getCharactersPresent()) {
if (!Main.game.getPlayer().getCharactersEncountered().contains(character.getId())) {
if (character instanceof NPC) {
if (((NPC) character).isAddedToContacts()) {
Main.game.getPlayer().addCharacterEncountered(character);
}
if (!character.isRaceConcealed()) {
Main.getProperties().addRaceDiscovered(character.getRace());
}
((NPC) character).setLastTimeEncountered(minutesPassed);
}
}
}
}
}
String headerContent = node.getHeaderContent();
String content = node.getContent();
if (currentDialogueNode != null) {
if (node.isContinuesDialogue()) {
if (!node.isNoTextForContinuesDialogue()) {
if (Main.game.isInSex()) {
dialogueTitle = UtilText.parse(node.getLabel());
}
if (node.isDisplaysActionTitleOnContinuesDialogue()) {
if (currentDialogueNode.getMapDisplay() == MapDisplay.NORMAL) {
positionAnchor++;
}
pastDialogueSB.append("<hr id='position" + positionAnchor + "'><p class='option-disabled'>> " + chosenResponse + "</p>");
}
if (getMapDisplay() == MapDisplay.NORMAL)
initialPositionAnchor = positionAnchor;
pastDialogueSB.append(UtilText.parse(corruptionGains + textStartStringBuilder.toString() + content + textEndStringBuilder.toString()));
}
} else {
dialogueTitle = UtilText.parse(node.getLabel());
if (getMapDisplay() == MapDisplay.NORMAL)
initialPositionAnchor = positionAnchor;
if (currentDialogueNode.getMapDisplay() == MapDisplay.NORMAL)
positionAnchor = 0;
pastDialogueSB.setLength(0);
pastDialogueSB.append(UtilText.parse(corruptionGains + textStartStringBuilder.toString() + content + textEndStringBuilder.toString()));
}
} else {
dialogueTitle = UtilText.parse(node.getLabel());
}
// currentDialogueNode.applyResponse(index, true);
// updateUIAttributes();
boolean resetPointer = true;
if (node != currentDialogueNode) {
responsePage = 0;
currentDialogueNode = node;
} else {
currentDialogueNode = node;
checkForResponsePage();
resetPointer = false;
}
if (node.isContinuesDialogue()) {
currentDialogue = "<body onLoad='scrollToElement()'>" + "<script>function scrollToElement() {document.getElementById('content-block').scrollTop = document.getElementById('position" + (positionAnchor) + "').offsetTop -64;}</script>" + "<div id='main-content'>" + getTitleDiv(dialogueTitle) + "<div class='div-center' id='content-block'>" + // + "<div class='inner-text-content'>"
getMapDiv() + (headerContent != null ? "<div id='header-content' style='font-size:" + Main.getProperties().fontSize + "px; line-height:" + (Main.getProperties().fontSize + 6) + "px;-webkit-user-select: none;'>" + (currentDialogueNode.disableHeaderParsing() ? headerContent : UtilText.parse(headerContent)) + "</div>" : "") + (content != null ? "<div " + (Main.getProperties().fadeInText ? "id='text-content'" : "") + " style='font-size:" + Main.getProperties().fontSize + "px; line-height:" + (Main.getProperties().fontSize + 6) + "px;'>" + pastDialogueSB.toString() + "</div>" : "") + // + "</div>"
"</div>" + "<div id='bottom-text'>Game saved!</div>" + getResponsesDiv(currentDialogueNode, resetPointer) + "</div>" + "</body>";
} else {
currentDialogue = "<body>" + "<div id='main-content'>" + getTitleDiv(dialogueTitle) + "<span id='position" + positionAnchor + "'></span>" + "<div class='div-center' id='content-block'>" + // + "<div class='inner-text-content'>"
getMapDiv() + (headerContent != null ? "<div id='header-content' style='font-size:" + Main.getProperties().fontSize + "px; line-height:" + (Main.getProperties().fontSize + 6) + "px;-webkit-user-select: none;'>" + (currentDialogueNode.disableHeaderParsing() ? headerContent : UtilText.parse(headerContent)) + "</div>" : "") + (content != null ? "<div " + (Main.getProperties().fadeInText ? "id='text-content'" : "") + " style='font-size:" + Main.getProperties().fontSize + "px; line-height:" + (Main.getProperties().fontSize + 6) + "px;'>" + pastDialogueSB.toString() + "</div>" : "") + // + "</div>"
"</div>" + "<div id='bottom-text'>Game saved!</div>" + getResponsesDiv(currentDialogueNode, resetPointer) + "</div>" + "</body>";
}
// Main.mainController.unbindListeners();
Main.mainController.setMainContent(currentDialogue);
textEndStringBuilder.setLength(0);
textStartStringBuilder.setLength(0);
if (started) {
Main.game.endTurn(getCurrentDialogueNode().getMinutesPassed());
}
TooltipUpdateThread.cancelThreads = true;
// Main.mainController.processNewDialogue();
}
}
}
use of com.lilithsthrone.game.character.GameCharacter in project liliths-throne-public by Innoxia.
the class Game method setContent.
public void setContent(Response response, boolean allowTimeProgress, Colour flashMessageColour, String flashMessageText) {
DialogueNodeOld node = response.getNextDialogue();
response.applyEffects();
if (node == null) {
return;
}
int currentPosition = 0;
if (getCurrentDialogueNode() != null) {
currentPosition = (int) Main.mainController.getWebEngine().executeScript("document.getElementById('content-block').scrollTop");
}
String headerContent = node.getHeaderContent();
String content = node.getContent();
boolean resetPointer = false;
if (getMapDisplay() == MapDisplay.NORMAL) {
initialPositionAnchor = positionAnchor;
}
// Add characters in this scene to the player's encountered characters list:
if (started) {
if (!getCharactersPresent().isEmpty()) {
for (GameCharacter character : getCharactersPresent()) {
if (character instanceof NPC) {
if (((NPC) character).isAddedToContacts()) {
Main.game.getPlayer().addCharacterEncountered(character);
}
if (!character.isRaceConcealed()) {
Main.getProperties().addRaceDiscovered(character.getRace());
}
((NPC) character).setLastTimeEncountered(minutesPassed);
}
}
}
}
if (currentDialogueNode != null) {
if (node.isContinuesDialogue()) {
if (!node.isNoTextForContinuesDialogue()) {
if (Main.game.isInSex()) {
dialogueTitle = UtilText.parse(node.getLabel());
}
if (node.isDisplaysActionTitleOnContinuesDialogue()) {
if (currentDialogueNode.getMapDisplay() == MapDisplay.NORMAL) {
positionAnchor++;
}
pastDialogueSB.append(UtilText.parse("<hr id='position" + positionAnchor + "'><p class='option-disabled'>> " + currentDialogueNode.getLabel() + "</p>"));
}
pastDialogueSB.append(content);
}
} else {
dialogueTitle = UtilText.parse(node.getLabel());
if (currentDialogueNode.getMapDisplay() == MapDisplay.NORMAL)
positionAnchor = 0;
pastDialogueSB.setLength(0);
pastDialogueSB.append(UtilText.parse("<b id='position" + positionAnchor + "'></b>" + textStartStringBuilder.toString() + content + textEndStringBuilder.toString()));
}
} else {
dialogueTitle = UtilText.parse(node.getLabel());
pastDialogueSB.setLength(0);
pastDialogueSB.append(UtilText.parse(textStartStringBuilder.toString() + content + textEndStringBuilder.toString()));
}
if (node != currentDialogueNode) {
responsePage = 0;
currentDialogueNode = node;
resetPointer = true;
} else {
currentDialogueNode = node;
checkForResponsePage();
resetPointer = false;
}
if (node.isContinuesDialogue()) {
currentDialogue = "<body onLoad='scrollToElement()'>" + "<script>function scrollToElement() {document.getElementById('content-block').scrollTop = document.getElementById('position" + (positionAnchor) + "').offsetTop -64;}</script>" + "<div id='main-content'>" + getTitleDiv(dialogueTitle) + "<div class='div-center' id='content-block'>" + // + "<div class='inner-text-content'>"
getMapDiv() + (headerContent != null ? "<div id='header-content' style='font-size:" + Main.getProperties().fontSize + "px; line-height:" + (Main.getProperties().fontSize + 6) + "px;-webkit-user-select: none;'>" + (currentDialogueNode.disableHeaderParsing() ? headerContent : UtilText.parse(headerContent)) + "</div>" : "") + (content != null ? "<div " + (Main.getProperties().fadeInText ? "id='text-content'" : "") + " style='font-size:" + Main.getProperties().fontSize + "px; line-height:" + (Main.getProperties().fontSize + 6) + "px;'>" + pastDialogueSB.toString() + "</div>" : "") + // + "</div>"
"</div>" + "<div id='bottom-text'>Game saved!</div>" + getResponsesDiv(currentDialogueNode, resetPointer) + "</div>" + "</body>";
} else {
currentDialogue = "<body onLoad='scrollBack()'>" + "<script>function scrollBack() {document.getElementById('content-block').scrollTop = " + currentPosition + ";}</script>" + "<div id='main-content'>" + getTitleDiv(dialogueTitle) + "<span id='position" + positionAnchor + "'></span>" + "<div class='div-center' id='content-block'>" + // + "<div class='inner-text-content'>"
getMapDiv() + (headerContent != null ? "<div id='header-content' style='font-size:" + Main.getProperties().fontSize + "px; line-height:" + (Main.getProperties().fontSize + 6) + "px;-webkit-user-select: none;'>" + (currentDialogueNode.disableHeaderParsing() ? headerContent : UtilText.parse(headerContent)) + "</div>" : "") + (content != null ? "<div " + (Main.getProperties().fadeInText ? "id='text-content'" : "") + " style='font-size:" + Main.getProperties().fontSize + "px; line-height:" + (Main.getProperties().fontSize + 6) + "px;'>" + pastDialogueSB.toString() + "</div>" : "") + // + "</div>"
"</div>" + "<div id='bottom-text'>Game saved!</div>" + getResponsesDiv(currentDialogueNode, resetPointer) + "</div>" + "</body>";
}
Main.mainController.setFlashMessageColour(flashMessageColour);
Main.mainController.setFlashMessageText(flashMessageText);
// -------------------- MEMORY LEAK PROBLEM
Main.mainController.setMainContent(currentDialogue);
// --------------------
textEndStringBuilder.setLength(0);
textStartStringBuilder.setLength(0);
// -------------------- MEMORY LEAK PROBLEM
if (started) {
if (allowTimeProgress) {
Main.game.endTurn(getCurrentDialogueNode().getMinutesPassed());
} else {
Main.game.endTurn(0);
}
}
// --------------------
}
use of com.lilithsthrone.game.character.GameCharacter in project liliths-throne-public by Innoxia.
the class SlaveryEventLogEntry method getDescription.
public String getDescription() {
descriptionSB.setLength(0);
descriptionSB.append(event.getDescription());
if (tags != null) {
for (SlaveEventTag tag : tags) {
if (descriptionSB.length() > 0) {
descriptionSB.append("</br>");
}
descriptionSB.append(tag.getDescription());
}
}
if (extraEffects != null) {
for (String s : extraEffects) {
if (descriptionSB.length() > 0) {
descriptionSB.append("</br>");
}
descriptionSB.append(s);
}
}
GameCharacter slave = Main.game.getNPCById(slaveID);
if (slave != null) {
return UtilText.parse(Main.game.getNPCById(slaveID), descriptionSB.toString());
} else {
return descriptionSB.toString();
}
}
use of com.lilithsthrone.game.character.GameCharacter in project liliths-throne-public by Innoxia.
the class NPC method generatePreferredBody.
private Body generatePreferredBody() {
// Preferred gender:
Gender preferredGender = Gender.N_P_V_B_HERMAPHRODITE;
Map<Gender, Integer> desiredGenders = new HashMap<>();
switch(this.getSexualOrientation()) {
case AMBIPHILIC:
if (this.isFeminine() && // complex but fair logic doesn't feel too required
Main.getProperties().forcedTFTendency != ForcedTFTendency.FEMININE && Main.getProperties().forcedTFTendency != ForcedTFTendency.FEMININE_HEAVY) {
desiredGenders.put(Gender.M_P_MALE, 14);
// maybe it would be appropriate to raise these chances for impregnators?
desiredGenders.put(Gender.M_P_V_HERMAPHRODITE, 2);
desiredGenders.put(Gender.M_V_CUNTBOY, 2);
desiredGenders.put(Gender.F_P_TRAP, 2);
} else {
// basic chances of cis-female preference
desiredGenders.put(Gender.F_V_B_FEMALE, 14);
// increase chances of growing a penis if fetishes increase desirability
if (this.hasVagina() && (this.hasFetish(Fetish.FETISH_PREGNANCY) || this.hasFetish(Fetish.FETISH_BROODMOTHER))) {
desiredGenders.put(Gender.F_P_V_B_FUTANARI, 4);
desiredGenders.put(Gender.F_P_B_SHEMALE, 4);
desiredGenders.put(Gender.F_P_TRAP, 4);
} else {
desiredGenders.put(Gender.F_P_V_B_FUTANARI, 2);
desiredGenders.put(Gender.F_P_B_SHEMALE, 2);
desiredGenders.put(Gender.F_P_TRAP, 2);
}
;
// heavy masculine forcedTFTendency option adds a bit of a chance for masculine preferenes here
if (Main.getProperties().forcedTFTendency == ForcedTFTendency.MASCULINE_HEAVY) {
desiredGenders.put(Gender.M_P_V_HERMAPHRODITE, 4);
desiredGenders.put(Gender.M_V_CUNTBOY, 4);
desiredGenders.put(Gender.F_P_TRAP, 4);
desiredGenders.put(Gender.M_V_B_BUTCH, 4);
}
}
break;
case ANDROPHILIC:
// Heavy feminine forcedTFTendency causes androphiles to lose the majority of masculine options
if (Main.getProperties().forcedTFTendency != ForcedTFTendency.FEMININE_HEAVY) {
desiredGenders.put(Gender.M_P_MALE, 14);
}
// base chance options regardless of forcedTFTendency option
desiredGenders.put(Gender.M_P_V_HERMAPHRODITE, 2);
desiredGenders.put(Gender.M_V_CUNTBOY, 2);
// both feminine forcedTFTendency options add decent chances to get some feminine options despite tastes
if (Main.getProperties().forcedTFTendency == ForcedTFTendency.FEMININE || Main.getProperties().forcedTFTendency == ForcedTFTendency.FEMININE_HEAVY) {
desiredGenders.put(Gender.F_P_V_B_FUTANARI, 2);
desiredGenders.put(Gender.F_P_B_SHEMALE, 2);
desiredGenders.put(Gender.F_P_TRAP, 2);
desiredGenders.put(Gender.M_V_B_BUTCH, 2);
}
break;
case GYNEPHILIC:
// base level of feminine options even if forcedTFTendency is heavy male
if (this.hasVagina() && (this.hasFetish(Fetish.FETISH_PREGNANCY) || this.hasFetish(Fetish.FETISH_BROODMOTHER))) {
desiredGenders.put(Gender.F_P_V_B_FUTANARI, 2);
desiredGenders.put(Gender.F_P_B_SHEMALE, 2);
desiredGenders.put(Gender.F_P_TRAP, 2);
// much lower base chance of pure female preference for heavy masculine forcedTFTendency
} else if (Main.getProperties().forcedTFTendency == ForcedTFTendency.MASCULINE_HEAVY) {
desiredGenders.put(Gender.F_V_B_FEMALE, 4);
} else {
desiredGenders.put(Gender.F_V_B_FEMALE, 14);
}
// both masculine forcedTFTendency options add decent chances to get some masculine options despite tastes
if (Main.getProperties().forcedTFTendency == ForcedTFTendency.MASCULINE || Main.getProperties().forcedTFTendency == ForcedTFTendency.MASCULINE_HEAVY) {
desiredGenders.put(Gender.M_P_V_HERMAPHRODITE, 2);
desiredGenders.put(Gender.M_V_CUNTBOY, 2);
desiredGenders.put(Gender.M_V_B_BUTCH, 2);
desiredGenders.put(Gender.F_P_TRAP, 2);
}
break;
}
int total = 0;
for (Entry<Gender, Integer> entry : desiredGenders.entrySet()) {
total += entry.getValue();
}
int count = Util.random.nextInt(total) + 1;
total = 0;
for (Entry<Gender, Integer> entry : desiredGenders.entrySet()) {
if (total < count && total + entry.getValue() >= count) {
preferredGender = entry.getKey();
break;
}
total += entry.getValue();
}
// Leaving this present but commented out so it can be easily re-enabled by anyone wanting to tweak or check
// the results of gender selection and the forcedTFTendency setting
// System.out.println("PREFERRED GENDER");
// System.out.println(preferredGender);
// System.out.println(desiredGenders);
// Preferred race:
Subspecies species = getSubspecies();
RaceStage stage = getRaceStage();
if (Main.getProperties().forcedTFPreference == FurryPreference.HUMAN) {
species = Subspecies.HUMAN;
stage = RaceStage.HUMAN;
} else {
// Chance for predator races to prefer prey races:
if (getRace() == Race.CAT_MORPH && Math.random() > 0.8f) {
species = Subspecies.HARPY;
}
if ((getRace() == Race.WOLF_MORPH || getRace() == Race.DOG_MORPH) && Math.random() > 0.8f) {
List<Subspecies> availableRaces = new ArrayList<>();
availableRaces.add(Subspecies.CAT_MORPH);
availableRaces.add(Subspecies.HARPY);
availableRaces.add(Subspecies.COW_MORPH);
availableRaces.add(Subspecies.SQUIRREL_MORPH);
species = availableRaces.get(Util.random.nextInt(availableRaces.size()));
}
// Chance for race to be random:
if (Math.random() > 0.85f) {
List<Subspecies> availableRaces = new ArrayList<>();
availableRaces.add(Subspecies.CAT_MORPH);
availableRaces.add(Subspecies.DOG_MORPH);
availableRaces.add(Subspecies.HARPY);
availableRaces.add(Subspecies.HORSE_MORPH);
availableRaces.add(Subspecies.HUMAN);
availableRaces.add(Subspecies.SQUIRREL_MORPH);
availableRaces.add(Subspecies.COW_MORPH);
availableRaces.add(Subspecies.WOLF_MORPH);
species = availableRaces.get(Util.random.nextInt(availableRaces.size()));
}
if (preferredGender.isFeminine()) {
switch(Main.getProperties().subspeciesFeminineFurryPreferencesMap.get(species)) {
case HUMAN:
stage = RaceStage.HUMAN;
break;
case MAXIMUM:
stage = RaceStage.GREATER;
break;
case MINIMUM:
stage = RaceStage.PARTIAL_FULL;
break;
case NORMAL:
stage = RaceStage.GREATER;
break;
case REDUCED:
stage = RaceStage.LESSER;
break;
}
} else {
switch(Main.getProperties().subspeciesMasculineFurryPreferencesMap.get(species)) {
case HUMAN:
stage = RaceStage.HUMAN;
break;
case MAXIMUM:
stage = RaceStage.GREATER;
break;
case MINIMUM:
stage = RaceStage.PARTIAL_FULL;
break;
case NORMAL:
stage = RaceStage.GREATER;
break;
case REDUCED:
stage = RaceStage.LESSER;
break;
}
}
}
Body body = CharacterUtils.generateBody(preferredGender, species, stage);
// Apply fetish modifiers:
GameCharacter genericOwner = Main.game.getGenericAndrogynousNPC();
// Ass:
if (hasFetish(Fetish.FETISH_ANAL_GIVING)) {
if (this.getAttributeValue(Attribute.MAJOR_CORRUPTION) >= CorruptionLevel.THREE_DIRTY.getMinimumValue()) {
body.getAss().getAnus().getOrificeAnus().addOrificeModifier(genericOwner, OrificeModifier.RIBBED);
body.getAss().getAnus().getOrificeAnus().addOrificeModifier(genericOwner, OrificeModifier.MUSCLE_CONTROL);
body.getAss().getAnus().getOrificeAnus().addOrificeModifier(genericOwner, OrificeModifier.PUFFY);
}
if (this.getAttributeValue(Attribute.MAJOR_CORRUPTION) >= CorruptionLevel.FOUR_LUSTFUL.getMinimumValue()) {
body.getAss().getAnus().getOrificeAnus().addOrificeModifier(genericOwner, OrificeModifier.TENTACLED);
}
body.getAss().setAssSize(genericOwner, AssSize.FIVE_HUGE.getValue());
body.getAss().setAssSize(genericOwner, HipSize.FIVE_VERY_WIDE.getValue());
}
// Body:
if (preferredGender.isFeminine()) {
// Want feminine bodies to be smaller than them:
body.setHeight(getHeightValue() - Util.random.nextInt(25));
} else {
// Want masculine bodies to be taller than them:
body.setHeight(getHeightValue() + Util.random.nextInt(25));
}
// Breasts:
if (Main.getProperties().multiBreasts == 0) {
body.getBreast().setRows(genericOwner, 1);
} else if (Main.getProperties().multiBreasts == 1) {
if (stage != RaceStage.GREATER) {
body.getBreast().setRows(genericOwner, 1);
}
}
if (hasFetish(Fetish.FETISH_BREASTS_OTHERS) && preferredGender.isFeminine()) {
body.getBreast().setSize(genericOwner, CupSize.DD.getMeasurement() + (Util.random.nextInt(5)));
}
// Face:
if (hasFetish(Fetish.FETISH_ORAL_RECEIVING)) {
body.getFace().getMouth().getOrificeMouth().addOrificeModifier(genericOwner, OrificeModifier.PUFFY);
body.getFace().getMouth().setLipSize(genericOwner, LipSize.FOUR_HUGE.getValue());
if (this.getAttributeValue(Attribute.MAJOR_CORRUPTION) >= CorruptionLevel.THREE_DIRTY.getMinimumValue()) {
body.getFace().getMouth().getOrificeMouth().addOrificeModifier(genericOwner, OrificeModifier.RIBBED);
body.getFace().getMouth().getOrificeMouth().addOrificeModifier(genericOwner, OrificeModifier.MUSCLE_CONTROL);
}
if (this.getAttributeValue(Attribute.MAJOR_CORRUPTION) >= CorruptionLevel.FOUR_LUSTFUL.getMinimumValue()) {
body.getFace().getMouth().getOrificeMouth().addOrificeModifier(genericOwner, OrificeModifier.TENTACLED);
}
}
// Hair:
if (preferredGender.isFeminine()) {
body.getHair().setLength(genericOwner, HairLength.THREE_SHOULDER_LENGTH.getMedianValue() + Util.random.nextInt(HairLength.SEVEN_TO_FLOOR.getMinimumValue() - HairLength.THREE_SHOULDER_LENGTH.getMedianValue()));
} else {
body.getHair().setLength(genericOwner, HairLength.ONE_VERY_SHORT.getMedianValue() + Util.random.nextInt(HairLength.THREE_SHOULDER_LENGTH.getMinimumValue() - HairLength.ONE_VERY_SHORT.getMedianValue()));
}
// Penis:
if (body.getPenis().getType() != PenisType.NONE) {
if (preferredGender == Gender.F_P_TRAP && Math.random() >= 0.1f) {
// Most traps have a small cock:
body.getPenis().setPenisSize(genericOwner, PenisSize.ONE_TINY.getMedianValue() + Util.random.nextInt(4));
body.getPenis().getTesticle().setTesticleSize(genericOwner, TesticleSize.ONE_TINY.getValue());
body.getPenis().getTesticle().setCumProduction(genericOwner, CumProduction.ONE_TRICKLE.getMedianValue());
} else {
body.getPenis().setPenisSize(genericOwner, body.getPenis().getSize().getMinimumValue() + Util.random.nextInt(body.getPenis().getSize().getMaximumValue() - body.getPenis().getSize().getMinimumValue()) + 1);
}
}
// Vagina:
if (body.getVagina().getType() != VaginaType.NONE) {
if (this.getAttributeValue(Attribute.MAJOR_CORRUPTION) >= CorruptionLevel.THREE_DIRTY.getMinimumValue()) {
body.getVagina().getOrificeVagina().addOrificeModifier(genericOwner, OrificeModifier.RIBBED);
body.getVagina().getOrificeVagina().addOrificeModifier(genericOwner, OrificeModifier.MUSCLE_CONTROL);
}
if (this.getAttributeValue(Attribute.MAJOR_CORRUPTION) >= CorruptionLevel.FOUR_LUSTFUL.getMinimumValue()) {
body.getVagina().getOrificeVagina().addOrificeModifier(genericOwner, OrificeModifier.TENTACLED);
}
body.getVagina().getOrificeVagina().setWetness(genericOwner, Wetness.THREE_WET.getValue() + Util.random.nextInt(4));
}
return body;
}
Aggregations