bondage-college-mirr/BondageClub/Scripts/Dialog.js
Ben987 94193ddf6a Official Release
Official Release
2018-12-16 13:05:23 -05:00

580 lines
No EOL
25 KiB
JavaScript

var DialogText = "";
var DialogTextDefault = "";
var DialogTextDefaultTimer = -1;
var DialogProgress = -1;
var DialogProgressAuto = 0;
var DialogProgressClick = 0;
var DialogProgressOperation = "...";
var DialogProgressPrevItem = null;
var DialogProgressNextItem = null;
var DialogProgressSkill = 0;
var DialogProgressLastKeyPress = 0;
var DialogInventory = [];
function DialogReputationLess(RepType, Value) { return (ReputationGet(RepType) <= Value); } // Returns TRUE if a specific reputation type is less or equal than a given value
function DialogReputationGreater(RepType, Value) { return (ReputationGet(RepType) >= Value); } // Returns FALSE if a specific reputation type is greater or equal than a given value
function DialogChangeReputation(RepType, Value) { ReputationProgress(RepType, Value); } // Change the player reputation progressively through dialog options (a reputation is easier to break than to build)
function DialogWearItem(AssetName, AssetGroup) { InventoryWear(Player, AssetName, AssetGroup); } // Equips a specific item on the player from dialog
function DialogWearRandomItem(AssetGroup) { InventoryWearRandom(Player, AssetGroup); } // Equips a random item from a given group to the player from dialog
function DialogRelease(C) { CharacterRelease(C); } // Releases a character from restraints
function DialogNaked(C) { CharacterNaked(C); } // Strips a character naked and removes the restrains
function DialogSetCharacter(C) { CharacterSetCurrent(C); } // Sets a new character as the current one in the dialog
// Returns TRUE if the dialog prerequisite condition is met
function DialogPrerequisite(D) {
if (CurrentCharacter.Dialog[D].Prerequisite == null)
return true;
else
if (CurrentCharacter.Dialog[D].Prerequisite.indexOf("Player.") == 0)
return Player[CurrentCharacter.Dialog[D].Prerequisite.substring(7, 250).replace("()", "").trim()]();
else
if (CurrentCharacter.Dialog[D].Prerequisite.indexOf("!Player.") == 0)
return !Player[CurrentCharacter.Dialog[D].Prerequisite.substring(8, 250).replace("()", "").trim()]();
else
if ((CurrentCharacter.Dialog[D].Prerequisite.indexOf("Dialog") == 0) || (CurrentCharacter.Dialog[D].Prerequisite.indexOf("Dialog") == 1))
return eval(CurrentCharacter.Dialog[D].Prerequisite);
else
if (CurrentCharacter.Dialog[D].Prerequisite.substring(0, 1) != "!")
return eval(CurrentScreen + CurrentCharacter.Dialog[D].Prerequisite);
else
return !eval(CurrentScreen + CurrentCharacter.Dialog[D].Prerequisite.substr(1, 250));
}
// Searches for an item in the player inventory to unlock a specific item
function DialogCanUnlock(C) {
var UnlockName = "Unlock-" + CharacterAppearanceGetCurrentValue(C, C.FocusGroup.Name, "Name");
for (var I = 0; I < Player.Inventory.length; I++)
if ((Player.Inventory[I].Asset.Effect != null) && (Player.Inventory[I].Asset.Effect.indexOf(UnlockName) >= 0))
return true;
return false;
}
// Returns the current character dialog intro
function DialogIntro() {
for(var D = 0; D < CurrentCharacter.Dialog.length; D++)
if ((CurrentCharacter.Dialog[D].Stage == CurrentCharacter.Stage) && (CurrentCharacter.Dialog[D].Option == null) && (CurrentCharacter.Dialog[D].Result != null) && DialogPrerequisite(D)) {
return CurrentCharacter.Dialog[D].Result;
break;
}
return "";
}
// Generic dialog function to leave conversation
function DialogLeave() {
Player.FocusGroup = null;
CurrentCharacter.FocusGroup = null;
DialogInventory = null;
CurrentCharacter = null;
}
// Generic dialog function to remove a piece of the conversation that's already done
function DialogRemove() {
// Finds the dialog spot and removes it
var pos = 0;
for(var D = 0; D < CurrentCharacter.Dialog.length; D++)
if ((CurrentCharacter.Dialog[D].Stage == CurrentCharacter.Stage) && (CurrentCharacter.Dialog[D].Option != null) && DialogPrerequisite(D)) {
if ((MouseX >= 1025) && (MouseX <= 1975) && (MouseY >= 160 + pos * 105) && (MouseY <= 240 + pos * 105)) {
CurrentCharacter.Dialog.splice(D, 1);
break;
}
pos++;
}
}
// Leaves the item menu for both characters
function DialogLeaveItemMenu() {
Player.FocusGroup = null;
CurrentCharacter.FocusGroup = null;
DialogInventory = null;
DialogProgress = -1;
}
// Adds the item in the dialog list
function DialogInventoryAdd(NewInv, NewInvWorn) {
// Make sure we do not duplicate the item
for(var I = 0; I < DialogInventory.length; I++)
if ((DialogInventory[I].Asset.Group.Name == NewInv.Group.Name) && (DialogInventory[I].Asset.Name == NewInv.Name))
return;
// Creates a new dialog inventory item
var DI = {
Asset: NewInv,
Worn: NewInvWorn,
Icon: ""
};
// Loads the correct icon and push the item in the array
if (NewInvWorn && (NewInv.Effect != null) && (NewInv.Effect.indexOf("Lock") >= 0)) DI.Icon = "Locked";
if (!NewInvWorn && (NewInv.Effect != null) && (NewInv.Effect.indexOf("Lock") >= 0)) DI.Icon = "Unlocked";
DialogInventory.push(DI);
}
// Build the inventory listing for the dialog which is what's equipped, the player inventory and the character inventory for that group
function DialogInventoryBuild(C) {
// Make sure there's a focused group
DialogInventory = [];
if (C.FocusGroup != null) {
// First, we add anything that's currently equipped
for(var A = 0; A < C.Appearance.length; A++)
if (C.Appearance[A].Asset.Group.Name == C.FocusGroup.Name)
DialogInventoryAdd(C.Appearance[A].Asset, true);
// Second, we add everything from the victim inventory
for(var A = 0; A < C.Inventory.length; A++)
if ((C.Inventory[A].Asset != null) && (C.Inventory[A].Asset.Group.Name == C.FocusGroup.Name))
DialogInventoryAdd(C.Inventory[A].Asset, false);
// Third, we add everything from the player inventory if the player isn't the victim
if (C.ID != 0)
for(var A = 0; A < Player.Inventory.length; A++)
if ((Player.Inventory[A].Asset != null) && (Player.Inventory[A].Asset.Group.Name == C.FocusGroup.Name))
DialogInventoryAdd(Player.Inventory[A].Asset, false);
}
}
// Gets the correct label for the current operation (struggling, removing, swaping, adding, etc.)
function DialogProgressGetOperation(PrevItem, NextItem) {
if ((PrevItem != null) && (NextItem != null)) return DialogFind(Player, "Swapping");
if ((PrevItem != null) && (PrevItem.Asset != null) && (PrevItem.Asset.Effect != null) && (Player.FocusGroup != null) && (PrevItem.Asset.Effect.indexOf("Struggle") >= 0)) return DialogFind(Player, "Struggling");
if ((PrevItem != null) && (PrevItem.Asset != null) && (PrevItem.Asset.Effect != null) && (PrevItem.Asset.Effect.indexOf("Lock") >= 0)) return DialogFind(Player, "Unlocking");
if (PrevItem != null) return DialogFind(Player, "Removing");
if ((PrevItem == null) && (NextItem != null) && (NextItem.Asset != null) && (NextItem.Asset.Effect != null) && (NextItem.Asset.Effect.indexOf("Lock") >= 0)) return DialogFind(Player, "Locking");
if ((PrevItem == null) && (NextItem != null)) return DialogFind(Player, "Adding");
return "...";
}
// Starts the dialog progress bar and keeps the items that needs to be added / swaped / removed
function DialogProgressStart(C, PrevItem, NextItem) {
// Gets the standard time to do the operation (minimum 1 second) and the player skill level associated
var Timer = 0;
var S = 0;
if (PrevItem != null) {
if ((PrevItem.Asset != null) && (PrevItem.Asset.RemoveTime != null)) Timer = Timer + PrevItem.Asset.RemoveTime;
if (C.ID == 0) {
S = S + SkillGetLevel(Player, "Evasion");
if (PrevItem.Difficulty != null) S = S - PrevItem.Difficulty;
if (!C.CanInteract() || (C.Effect.indexOf("Suspension") >= 0)) Timer = Timer * 2;
}
}
if ((NextItem != null) && (NextItem.Asset != null) && (NextItem.Asset.WearTime != null)) Timer = Timer + NextItem.Asset.WearTime;
if ((C.ID != 0) || ((C.ID == 0) && (PrevItem == null))) S = S + SkillGetLevel(Player, "Bondage");
if (Timer < 1) Timer = 1;
if (Player.IsBlind()) Timer = Timer * 2;
// Prepares the progress bar and timer
DialogProgress = 0;
DialogProgressAuto = CommonRunInterval * (0.1133 + (S * 0.1133)) / (Timer * CheatFactor("DoubleItemSpeed", 0.5));
DialogProgressClick = CommonRunInterval * 2.5 / (Timer * CheatFactor("DoubleItemSpeed", 0.5));
DialogProgressPrevItem = PrevItem;
DialogProgressNextItem = NextItem;
DialogProgressOperation = DialogProgressGetOperation(PrevItem, NextItem);
DialogProgressSkill = Timer;
DialogProgressLastKeyPress = 0;
}
// The player can use the space bar to speed up the dialog progress, just like clicking
function DialogKeyDown() {
if (((KeyPress == 65) || (KeyPress == 83) || (KeyPress == 97) || (KeyPress == 115)) && (DialogProgress >= 0)) {
DialogProgress = DialogProgress + DialogProgressClick * ((DialogProgressLastKeyPress == KeyPress) ? -0.5 : 0.5);
if (DialogProgress < 0) DialogProgress = 0;
DialogProgressLastKeyPress = KeyPress;
}
}
// When the user clicks on a dialog option
function DialogClick() {
// If the user clicked on the interaction character or herself, we check to use an item
if ((CurrentCharacter.AllowItem || (MouseX < 500)) && (MouseX >= 0) && (MouseX <= 1000) && (MouseY >= 0) && (MouseY < 1000) && ((CurrentCharacter.ID != 0) || (MouseX > 500)) && (DialogIntro() != "")) {
DialogLeaveItemMenu();
var C = (MouseX < 500) ? Player : CurrentCharacter;
var X = (MouseX < 500) ? 0 : 500;
for(var A = 0; A < AssetGroup.length; A++)
if ((AssetGroup[A].Category == "Item") && (AssetGroup[A].Zone != null))
for(var Z = 0; Z < AssetGroup[A].Zone.length; Z++)
if (((C.Pose.indexOf("Suspension") < 0) && (MouseX - X >= AssetGroup[A].Zone[Z][0]) && (MouseY >= AssetGroup[A].Zone[Z][1] - C.HeightModifier) && (MouseX - X <= AssetGroup[A].Zone[Z][0] + AssetGroup[A].Zone[Z][2]) && (MouseY <= AssetGroup[A].Zone[Z][1] + AssetGroup[A].Zone[Z][3] - C.HeightModifier))
|| ((C.Pose.indexOf("Suspension") >= 0) && (MouseX - X >= AssetGroup[A].Zone[Z][0]) && (MouseY >= 1000 - (AssetGroup[A].Zone[Z][1] + AssetGroup[A].Zone[Z][3]) - C.HeightModifier) && (MouseX - X <= AssetGroup[A].Zone[Z][0] + AssetGroup[A].Zone[Z][2]) && (MouseY <= 1000 - AssetGroup[A].Zone[Z][1] - C.HeightModifier)))
{
C.FocusGroup = AssetGroup[A];
DialogInventoryBuild(C);
DialogText = DialogTextDefault;
break;
}
}
// In item menu mode VS text dialog mode
if (((Player.FocusGroup != null) || ((CurrentCharacter.FocusGroup != null) && CurrentCharacter.AllowItem)) && (DialogIntro() != "")) {
// If the user wants to speed up the add / swap / remove progress
if ((MouseX >= 1000) && (MouseX < 2000) && (MouseY >= 600) && (MouseY < 1000) && (DialogProgress >= 0))
DialogProgress = DialogProgress + DialogProgressClick;
// If the user removes wants to remove an item
if ((MouseX >= 1500) && (MouseX <= 1725) && (MouseY >= 25) && (MouseY <= 100) && (DialogProgress < 0)) {
// If the player can interact, we simply remove the item
var C = (Player.FocusGroup != null) ? Player : CurrentCharacter;
var Item = InventoryGet(C, C.FocusGroup.Name);
if (Player.CanInteract()) {
if ((C.FocusGroup != null) && (Item != null)) {
// Do not allow to remove if it's locked
if ((Item.Asset.Effect == null) || (Item.Asset.Effect.indexOf("Lock") < 0))
if ((Item.Asset.Prerequisite == null) || eval(Item.Asset.Prerequisite.replace("CharacterObject", "C")))
if (!InventoryGroupIsBlocked(C))
DialogProgressStart(C, Item, null);
}
} else {
// If the player can struggle out or unlock herself
if ((C.ID == 0) && (Item.Asset.Effect != null) && (Item.Asset.Effect.indexOf("Struggle") >= 0) && (DialogProgress == -1)) DialogProgressStart(C, Item, null);
if ((C.ID == 0) && (Item.Asset.Effect != null) && (Item.Asset.Effect.indexOf("Block") >= 0) && (Item.Asset.Effect.indexOf("Lock") >= 0) && DialogCanUnlock(C)) DialogProgressStart(C, Item, null);
}
}
// If the user cancels the menu
if ((MouseX >= 1750) && (MouseX <= 1975) && (MouseY >= 25) && (MouseY <= 100))
DialogLeaveItemMenu();
// If the user clicks on one of the items
if ((MouseX >= 1025) && (MouseX <= 1975) && (MouseY >= 125) && (MouseY <= 850) && Player.CanInteract() && (DialogProgress < 0)) {
// For each items in the player inventory
var X = 1000;
var Y = 125;
var C = (Player.FocusGroup != null) ? Player : CurrentCharacter;
for(var I = 0; I < DialogInventory.length; I++) {
// If the item at position is clicked
if ((MouseX >= X) && (MouseX < X + 225) && (MouseY >= Y) && (MouseY < Y + 275) && DialogInventory[I].Asset.Enable) {
// Cannot change item if the previous one is locked
var Item = InventoryGet(C, C.FocusGroup.Name);
if ((Item == null) || (Item.Asset.Effect == null) || (Item.Asset.Effect.indexOf("Lock") < 0)) {
if (DialogInventory[I].Asset.Wear && !InventoryGroupIsBlocked(C))
if ((DialogInventory[I].Asset.Prerequisite == null) || eval(DialogInventory[I].Asset.Prerequisite.replace("CharacterObject", "C")))
if ((Item == null) || (Item.Asset.Name != DialogInventory[I].Asset.Name))
if (DialogInventory[I].Asset.SelfBondage || (C.ID != 0)) DialogProgressStart(C, Item, DialogInventory[I]);
else DialogSetText("CannotUseOnSelf");
} else {
// If the item can unlock another item
if ((DialogInventory[I].Asset.Effect != null) && (DialogInventory[I].Asset.Effect.indexOf("Unlock-" + Item.Asset.Name) >= 0))
DialogProgressStart(C, Item, null);
}
break;
}
// Change the X and Y position to get the next square
X = X + 250;
if (X > 1800) {
X = 1000;
Y = Y + 300;
}
}
}
} else {
// If we need to leave the dialog (only allowed when there's an entry point to the dialog, not in the middle of a conversation)
if ((DialogIntro() != "") && (MouseX >= 1885) && (MouseX <= 1975) && (MouseY >= 25) && (MouseY <= 110))
DialogLeave();
// If the user clicked on a text dialog option, we trigger it
if ((MouseX >= 1025) && (MouseX <= 1975) && (MouseY >= 100) && (MouseY <= 975) && (CurrentCharacter != null)) {
var pos = 0;
for(var D = 0; D < CurrentCharacter.Dialog.length; D++)
if ((CurrentCharacter.Dialog[D].Stage == CurrentCharacter.Stage) && (CurrentCharacter.Dialog[D].Option != null) && DialogPrerequisite(D)) {
if ((MouseX >= 1025) && (MouseX <= 1975) && (MouseY >= 160 + pos * 105) && (MouseY <= 240 + pos * 105)) {
// If the player is gagged, the answer will always be the same
if (!Player.CanTalk()) CurrentCharacter.CurrentDialog = DialogFind(CurrentCharacter, "PlayerGagged");
else CurrentCharacter.CurrentDialog = CurrentCharacter.Dialog[D].Result;
// A dialog option can change the conversation stage, show text or launch a custom function
if ((Player.CanTalk() && CurrentCharacter.CanTalk()) || DialogFullEmote(CurrentCharacter.Dialog[D].Option)) {
CurrentCharacter.CurrentDialog = CurrentCharacter.Dialog[D].Result;
if (CurrentCharacter.Dialog[D].NextStage != null) CurrentCharacter.Stage = CurrentCharacter.Dialog[D].NextStage;
if (CurrentCharacter.Dialog[D].Function != null) CommonDynamicFunction(CurrentCharacter.Dialog[D].Function);
} else
if ((CurrentCharacter.Dialog[D].Function != null) && (CurrentCharacter.Dialog[D].Function.trim() == "DialogLeave()"))
DialogLeave();
break;
}
pos++;
}
}
}
}
// Sets the dialog 5 seconds text
function DialogSetText(NewText) {
DialogTextDefaultTimer = CommonTime() + 5000;
DialogText = DialogFind(Player, NewText);
}
// Draw the item menu dialog
function DialogDrawItemMenu(C) {
// Gets the default text that will reset after 5 seconds
if (DialogTextDefault == "") DialogTextDefault = DialogFind(Player, "SelectItem");
if (DialogTextDefaultTimer < CommonTime()) DialogText = DialogTextDefault;
// Inventory is only accessible if the player can interact and there's no progress bar
if (Player.CanInteract() && (DialogProgress < 0) && !InventoryGroupIsBlocked(C)) {
// Builds the item dialog if we need too
if (DialogInventory == null) DialogInventoryBuild(C);
// Draws the top menu
if ((C.FocusGroup != null) && (InventoryGet(C, C.FocusGroup.Name) != null)) {
DrawText(DialogText, 1250, 62, "White", "Black");
DrawButton(1500, 25, 225, 75, "Remove", "White");
} else DrawText(DialogText, 1375, 62, "White", "Black");
DrawButton(1750, 25, 225, 75, "Cancel", "White");
// For each items in the player inventory
var X = 1000;
var Y = 125;
for(var I = 0; I < DialogInventory.length; I++) {
DrawRect(X, Y, 225, 275, ((MouseX >= X) && (MouseX < X + 225) && (MouseY >= Y) && (MouseY < Y + 275) && !CommonIsMobile) ? "cyan" : DialogInventory[I].Worn ? "pink" : "white");
DrawImageResize("Assets/" + DialogInventory[I].Asset.Group.Family + "/" + DialogInventory[I].Asset.Group.Name + "/Preview/" + DialogInventory[I].Asset.Name + ".png", X + 2, Y + 2, 221, 221);
DrawTextFit(DialogInventory[I].Asset.Description, X + 112, Y + 250, 221, "black");
if (DialogInventory[I].Icon != "") DrawImage("Icons/" + DialogInventory[I].Icon + ".png", X + 2, Y + 110);
X = X + 250;
if (X > 1800) {
X = 1000;
Y = Y + 300;
}
}
} else {
// Can always cancel out
var C = (Player.FocusGroup != null) ? Player : CurrentCharacter;
DrawButton(1750, 25, 225, 75, "Cancel", "White");
// If the player is progressing
if (DialogProgress >= 0) {
// Draw one or both items
if ((DialogProgressPrevItem != null) && (DialogProgressNextItem != null)) {
DrawItemPreview(1200, 250, DialogProgressPrevItem);
DrawItemPreview(1575, 250, DialogProgressNextItem);
} else DrawItemPreview(1387, 250, (DialogProgressPrevItem != null) ? DialogProgressPrevItem : DialogProgressNextItem);
// Add or subtract to the automatic progression
DialogProgress = DialogProgress + DialogProgressAuto;
if (DialogProgress < 0) DialogProgress = 0;
// Draw the current operation and progress
DrawText(DialogProgressOperation, 1500, 650, "White", "Black");
DrawProgressBar(1200, 700, 600, 100, DialogProgress);
DrawText((CommonIsMobile) ? "Click here to speed up the progress" : "Click here or hit keys A and S to speed up", 1500, 900, "White", "Black");
// If the operation is completed
if (DialogProgress >= 100) {
// Add / swap / remove the item
if (DialogProgressNextItem == null) InventoryRemove(C, C.FocusGroup.Name);
else InventoryWear(C, DialogProgressNextItem.Asset.Name, DialogProgressNextItem.Asset.Group.Name);
// The player can use another item right away, for another character we jump back to her reaction
if (C.ID == 0) {
if (DialogProgressNextItem == null) SkillProgress("Evasion", DialogProgressSkill);
DialogInventoryBuild(C);
DialogProgress = -1;
} else {
if (DialogProgressNextItem != null) SkillProgress("Bondage", DialogProgressSkill);
C.CurrentDialog = DialogFind(C, ((DialogProgressNextItem == null) ? ("Remove" + DialogProgressPrevItem.Asset.Name) : DialogProgressNextItem.Asset.Name), ((DialogProgressNextItem == null) ? "Remove" : "") + C.FocusGroup.Name);
DialogLeaveItemMenu();
}
}
} else {
// If we must draw the struggle/unlock dialog
var Item = InventoryGet(C, C.FocusGroup.Name);
if (Item != null) {
// Draw the item preview
DrawItemPreview(1387, 250, Item);
// Draw the struggle option
if ((C.ID == 0) && (Item.Asset.Effect != null) && (Item.Asset.Effect.indexOf("Block") >= 0) && (Item.Asset.Effect.indexOf("Struggle") >= 0)) {
DrawText("Struggle to free yourself", 1250, 62, "White", "Black");
DrawButton(1500, 25, 225, 75, "Struggle", "White");
}
// Draw the unlock option
if ((C.ID == 0) && (Item.Asset.Effect != null) && (Item.Asset.Effect.indexOf("Block") >= 0) && (Item.Asset.Effect.indexOf("Lock") >= 0)) {
if (DialogCanUnlock(C)) {
DrawText("You can unlock yourself", 1250, 62, "White", "Black");
DrawButton(1500, 25, 225, 75, "Unlock", "White");
} else DrawText("You don't have the proper key", 1350, 62, "White", "Black");
}
// Draw the no struggle option
if ((C.ID == 0) && (Item.Asset.Effect != null) && (Item.Asset.Effect.indexOf("Block") >= 0) && (Item.Asset.Effect.indexOf("Lock") < 0) && (Item.Asset.Effect.indexOf("Struggle") < 0))
DrawText("You'll need help to get out", 1250, 62, "White", "Black");
}
// Show the no access text
if (InventoryGroupIsBlocked(C)) DrawText("This zone is out of reach from another item", 1500, 700, "White", "Black");
else DrawText("You cannot access your items", 1500, 700, "White", "Black");
}
}
}
// Returns TRUE if the current dialog option is a full emote (all between parentheses)
function DialogFullEmote(D) {
return ((D.indexOf("(") == 0) && (D.indexOf(")") == D.length - 1));
}
// Garbles the speech if the character is gagged, anything between parentheses isn't touched
function DialogGarble(C, CD) {
// Variables to build the new string and check if we are in a parentheses
var NS = "";
var Par = false;
// Total gags always returns "..."
if (C.Effect.indexOf("GagTotal") >= 0) {
NS = "... ";
for (var L = 0; L < CD.length; L++) {
var H = CD.charAt(L).toLowerCase();
if (H == "(") Par = true;
if (Par) NS = NS + CD.charAt(L);
if (H == ")") Par = false;
}
return NS;
}
// Heavy garble - Almost no letter stays the same
if (C.Effect.indexOf("GagHeavy") >= 0) {
for (var L = 0; L < CD.length; L++) {
var H = CD.charAt(L).toLowerCase();
if (H == "(") Par = true;
if (!Par) {
if (H == "a" || H == "e" || H == "i" || H == "o" || H == "u" || H == "y" || H == "t") NS = NS + "e";
if (H == "c" || H == "q" || H == "x") NS = NS + "k";
if (H == "j" || H == "k" || H == "l" || H == "r" || H == "w") NS = NS + "a";
if (H == "s" || H == "z" || H == "h") NS = NS + "h";
if (H == "b" || H == "p" || H == "v") NS = NS + "f";
if (H == "d" || H == "f" || H == "g" || H == "n" || H == "m") NS = NS + "m";
if (H == " " || H == "!") NS = NS + H;
} else NS = NS + CD.charAt(L);
if (H == ")") Par = false;
}
return NS;
}
// Normal garble, keep vowels and a few letters the same
if (C.Effect.indexOf("GagNormal") >= 0) {
for (var L = 0; L < CD.length; L++) {
var H = CD.charAt(L).toLowerCase();
if (H == "(") Par = true;
if (!Par) {
if (H == "v" || H == "b" || H == "c" || H == "t") NS = NS + "e";
if (H == "q" || H == "k" || H == "x") NS = NS + "k";
if (H == "w" || H == "y" || H == "j" || H == "l" || H == "r") NS = NS + "a";
if (H == "s" || H == "z") NS = NS + "h";
if (H == "d" || H == "f") NS = NS + "m";
if (H == "p") NS = NS + "f";
if (H == "g") NS = NS + "n";
if (H == " " || H == "!" || H == "." || H == "a" || H == "e" || H == "i" || H == "o" || H == "u" || H == "m" || H == "n" || H == "h") NS = NS + H;
} else NS = NS + CD.charAt(L);
if (H == ")") Par = false;
}
return NS;
}
// Light garble, half of the letters stay the same
if (C.Effect.indexOf("GagLight") >= 0) {
for (var L = 0; L < CD.length; L++) {
var H = CD.charAt(L).toLowerCase();
if (H == "(") Par = true;
if (!Par) {
if (H == "c" || H == "t") NS = NS + "e";
if (H == "q" || H == "k" || H == "x") NS = NS + "k";
if (H == "j" || H == "l" || H == "r") NS = NS + "a";
if (H == "s") NS = NS + "z";
if (H == "z") NS = NS + "s";
if (H == "d" || H == "f" || H == "m" || H == "g") NS = NS + "m";
if (H == "b" || H == "h" || H == "n" || H == "v" || H == "w" || H == "p" || H == " " || H == "'" || H == "?" || H == "!" || H == "." || H == "," || H == "a" || H == "e" || H == "i" || H == "o" || H == "u" || H == "y") NS = NS + H;
} else NS = NS + CD.charAt(L);
if (H == ")") Par = false;
}
return NS;
}
// No gag effect, we return the regular text
return CD;
}
// Searches in the dialog for a specific stage keyword and returns that dialog option if we find it
function DialogFind(C, KeyWord1, KeyWord2) {
for(var D = 0; D < C.Dialog.length; D++)
if (C.Dialog[D].Stage == KeyWord1)
return C.Dialog[D].Result;
if (KeyWord2 != null)
for(var D = 0; D < C.Dialog.length; D++)
if (C.Dialog[D].Stage == KeyWord2)
return C.Dialog[D].Result;
return CurrentCharacter.CurrentDialog;
}
// Draw all the possible interactions
function DialogDraw() {
// Draw both the player and the interaction character
if (CurrentCharacter.ID != 0) DrawCharacter(Player, 0, 0, 1);
DrawCharacter(CurrentCharacter, 500, 0, 1);
// If we must show the item menu
if (((Player.FocusGroup != null) || ((CurrentCharacter.FocusGroup != null) && CurrentCharacter.AllowItem)) && (DialogIntro() != ""))
DialogDrawItemMenu((Player.FocusGroup != null) ? Player : CurrentCharacter);
else {
// Draws the intro text or dialog result
if (DialogIntro() != "") {
DrawTextWrap(DialogGarble(CurrentCharacter, CurrentCharacter.CurrentDialog), 1025, -10, 840, 160, "white");
DrawButton(1885, 25, 90, 90, "", "White", "Icons/Exit.png");
} else DrawTextWrap(DialogGarble(CurrentCharacter, CurrentCharacter.CurrentDialog), 1025, -10, 950, 160, "white");
// Draws the possible answers
var pos = 0;
for(var D = 0; D < CurrentCharacter.Dialog.length; D++)
if ((CurrentCharacter.Dialog[D].Stage == CurrentCharacter.Stage) && (CurrentCharacter.Dialog[D].Option != null) && DialogPrerequisite(D)) {
DrawTextWrap(DialogGarble(Player, CurrentCharacter.Dialog[D].Option), 1025, 160 + 105 * pos, 950, 80, "black", ((MouseX >= 1025) && (MouseX <= 1975) && (MouseY >= 160 + pos * 105) && (MouseY <= 240 + pos * 105) && !CommonIsMobile) ? "cyan" : "white");
pos++;
}
}
}