Files
fnl/Assets/Scripts/VNData.cs

784 lines
27 KiB
C#
Raw Permalink Normal View History

2026-02-21 16:40:15 -08:00
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class DialogueInteraction {
// This is the ID of whoever's talking.
public Character character;
// This is the text being spoken.
public string text;
// Set this when you want completing this interaction to unlock something.
public Unlockable unlock = Unlockable.None;
// Reserved index -1 to mean "do not set".
// See VNObjectController for canonical lists.
public int backgroundIndex { get; set; } = -1;
public int audioClipIndex { get; set; } = -1;
public int musicClipIndex { get; set; } = -1;
// Fade the currently playing music out on this interaction.
public bool fadeMusicOut { get; set; } = false;
// Optional flags for overriding the girl's outfit and hair.
// Used for long-format scenes.
public Body bodyOverride { get; set; } = Body.None;
public Hair hairOverride { get; set; } = Hair.None;
// Use the background VNSprite instead of the centered one.
// Should be set for most AssignedTask scenes.
public bool setBGSprite { get; set; } = false;
// Flag to transition to the MainMenu instead of the Manager.
// Maybe this also wipes your save.
public bool gameOver { get; set; } = false;
public bool showBody { get; set; } = false;
public bool removeBody { get; set; } = false;
public Expression expression { get; set; } = Expression.None;
public DialogueEffect effect { get; set; } = DialogueEffect.None;
public DialogueInteraction(Character name,
string text,
Unlockable unlock = Unlockable.None) {
this.character = name;
this.text = text;
this.unlock = unlock;
}
}
public enum Dialogue {
None,
Intro,
GameOver,
YouWin,
// Generic greetings.
Manager_Default,
Manager_Default2,
Manager_Default3,
// Scenes for hitting the town.
Manager_Boutique,
Manager_Diner,
Manager_Salon,
Manager_Hungry1,
Manager_BoughtFood1,
Manager_Farty1,
Manager_Farty2,
Manager_Farty3,
Manager_Farty4,
Manager_Farty5,
Manager_Farty6,
Manager_Moody1,
Manager_Moody2,
Manager_RanAway,
// AssignedTasks.
Task_Clean1,
Task_Clean2,
Task_Clean3,
Task_Games1,
Task_Games2,
Task_RockOut,
Task_Suck1,
Task_Suck2,
Task_Suck3,
Task_SuckCosplay,
Task_Fuck1,
Task_Fuck2,
Task_FuckCosplay,
Task_Photos1,
Task_Photos2,
Task_Photos3,
Task_Cosplay,
// Special scenes.
Special_CakeAndIceCream,
Special_HappyBirthday,
Special_OnlyFarts,
Special_ThereSheBlows,
}
public enum DialogueEffect {
None,
Dip,
Bounce,
}
public enum Body {
None,
Undies,
EmoUndies,
Swimsuit,
Rockstar,
Business,
Devil,
Messy
}
public enum Hair {
None,
Messy,
Bratty,
Pigtails,
PrimProper,
FizzyPop
}
public enum Food {
None,
Salad,
BurgerCombo,
Pizza,
Sushi,
Steak,
}
public enum AssignedTask {
None,
Clean,
Games,
RockOut,
Suck,
SuckCosplay,
Fuck,
FuckCosplay,
Photos,
Cosplay,
Spank,
}
public enum Expression {
None,
Neutral,
Happy,
Angry,
}
public enum Effect {
None,
}
public enum Character {
None,
Her,
You,
OldRoommate
}
public class Description {
public string name { get; set; }
public string description { get; set; }
public string warnings { get; set; }
}
public class ItemInfo {
public string name { get; set; }
public int cost { get; set; }
public string description { get; set; }
public int affection { get; set; } = 0;
// Exclusive to Food.
public int hunger { get; set; }
public int mood { get; set; }
// Chance to make her farty.
public float fartiness { get; set; } = 0f;
}
public class AssignedTaskInfo {
public string name { get; set; }
public string description { get; set; }
public Dialogue dialogue { get; set; } = Dialogue.None;
public AssignedTask task { get; set; } = AssignedTask.None;
// Gameplay effects of selecting this task.
public int hunger { get; set; } = 0;
public int mood { get; set; } = 0;
public int money { get; set; } = 0;
public int affection { get; set; } = 0;
public AssignedTaskRequirements progressionRequirements { get; set; } = new AssignedTaskRequirements();
}
public class AssignedTaskRequirements {
public int maxHunger { get; set; } = 4;
public int minMood { get; set; } = 1;
public int minAffection { get; set; } = 0;
public int minDay { get; set; } = 1;
public Body requiredOutfit { get; set; } = Body.None;
public Hair requiredHair { get; set; } = Hair.None;
public Dialogue requiredViewedScene { get; set; } = Dialogue.None;
public Status requiredStatus { get; set; } = Status.Normal;
// Check if you can progress to the next version of this AssignedTask.
// Dialogue should be set to the current version's Dialogue interaction sequence.
// Optionally, the scene might also require that you've seen some other scene in the game.
// For example, Cosplay requires a Photos scene to have been seen.
public bool Check(Dialogue d) {
return
GameData.GLOBAL.hunger <= maxHunger &&
GameData.GLOBAL.mood >= minMood &&
GameData.GLOBAL.affection >= minAffection &&
GameData.GLOBAL.day >= minDay &&
(requiredOutfit == Body.None || GameData.GLOBAL.unlockedOutfits.Contains(requiredOutfit)) &&
(requiredHair == Hair.None || GameData.GLOBAL.unlockedHairs.Contains(requiredHair)) &&
(d == Dialogue.None || GameData.GLOBAL.viewedScenes.Contains(d)) &&
(requiredViewedScene == Dialogue.None || GameData.GLOBAL.viewedScenes.Contains(requiredViewedScene)) &&
(requiredStatus == Status.Normal || GameData.GLOBAL.status == requiredStatus);
}
}
public class VNData {
// Manager sets this value before loading SceneViewer.
public static Dialogue NextScene = Dialogue.Intro;
public static List<Dialogue> managerScenes = new List<Dialogue>()
{
Dialogue.Manager_Default,
Dialogue.Manager_Default2,
Dialogue.Manager_Default3,
};
public static List<Dialogue> fartyScenes = new List<Dialogue>()
{
Dialogue.Manager_Farty1,
Dialogue.Manager_Farty2,
Dialogue.Manager_Farty3,
Dialogue.Manager_Farty4,
// TODO: uncomment when audio is fixed
// Dialogue.Manager_Farty5,
// Dialogue.Manager_Farty6,
};
public static List<Dialogue> moodyScenes = new List<Dialogue>()
{
Dialogue.Manager_Moody1,
Dialogue.Manager_Moody2,
};
public static Dictionary<Body, ItemInfo> OUTFIT_INFO = new Dictionary<Body, ItemInfo>()
{
{ Body.Undies, new ItemInfo() {
name = "Simple Undies",
cost = 0,
description = "A simple bra and pair of worn panties."
} },
{ Body.Rockstar, new ItemInfo() {
name = "Rockstar",
cost = 300,
description = "A frilly skirt and ripped crop top.\nLots of jewelry.",
affection = 100
} },
{ Body.Messy, new ItemInfo() {
name = "Messy Undies",
cost = 300,
description = "Comfortable but messy set of underwear\nand mismatched socks.",
affection = 100
} },
{ Body.Swimsuit, new ItemInfo() {
name = "Swimsuit",
cost = 500,
description = "A tight bikini.",
affection = 200
} },
{ Body.EmoUndies, new ItemInfo() {
name = "Emo Undies",
cost = 700,
description = "An intricate two-piece and matching jacket.",
affection = 200
} },
{ Body.Business, new ItemInfo() {
name = "Businesswoman",
cost = 1000,
description = "Silky sweater and pencil skirt, with leggings.\nMakes her look entitled.",
affection = 300
} },
{ Body.Devil, new ItemInfo() {
name = "Demoness",
cost = 2000,
description = "Black frilly lingerie and pink bows,\ncomplete with a womb tattoo.",
affection = 500
} },
};
public static Dictionary<Hair, ItemInfo> HAIR_INFO = new Dictionary<Hair, ItemInfo>()
{
{ Hair.Messy, new ItemInfo() {
name = "Messy",
cost = 0,
description = "Unkempt, natural, short hair."
} },
{ Hair.Bratty, new ItemInfo() {
name = "Bratty Waves",
cost = 300,
description = "Long and voluminous.\nLooks fluffy to the touch.",
affection = 100
} },
{ Hair.Pigtails, new ItemInfo() {
name = "Zap Cutie",
cost = 500,
description = "Short hair with tiny pigtails.\nVery cute... Too cute.",
affection = 100
} },
{ Hair.PrimProper, new ItemInfo() {
name = "Prim & Proper",
cost = 700,
description = "A simple mid-length ponytail.\nBusinesswoman's cut.",
affection = 150
} },
{ Hair.FizzyPop, new ItemInfo() {
name = "Fizzy Pop",
cost = 1000,
description = "Crazy-long pink twintails.\nMakes her look annoying.",
affection = 200
} },
};
public static Dictionary<Food, ItemInfo> FOOD_INFO = new Dictionary<Food, ItemInfo>()
{
{ Food.Salad, new ItemInfo() {
name = "Soup & Salad",
cost = 20,
description = "A no-frills tomato soup and small salad.\nCheap, healthy... and flavorless.",
mood = -1,
hunger = 1,
} },
{ Food.BurgerCombo, new ItemInfo() {
name = "Burger Combo",
cost = 50,
description = "Greasy old-fashioned burger and fries.\nMight make her gassy.",
affection = 10,
mood = 1,
hunger = 2,
fartiness = 0.5f,
} },
{ Food.Pizza, new ItemInfo() {
name = "Pizza",
cost = 70,
description = "Several slices of pepperoni pizza.\nVery thick and filling.",
affection = 25,
mood = 1,
hunger = 3,
} },
{ Food.Steak, new ItemInfo() {
name = "Steak Dinner",
cost = 150,
description = "A luxurious steak dinner with asparagus.\nDelicious and nutritious!",
affection = 50,
mood = 2,
hunger = 3,
} },
{ Food.Sushi, new ItemInfo() {
name = "Designer Sushi Plate",
cost = 250,
description = "A smorgasboard fit for a queen.\nLive a little.",
affection = 200,
mood = 4,
hunger = 4,
} },
};
// Maps a task to its list of info objects.
// You get further in the list as you gain affection, or skill in that particular task.
public static Dictionary<AssignedTask, List<AssignedTaskInfo>> TASK_INFO = new Dictionary<AssignedTask, List<AssignedTaskInfo>>() {
{ AssignedTask.Clean, new List<AssignedTaskInfo>() {
new AssignedTaskInfo() {
task = AssignedTask.Clean,
name = "Clean House",
description = "Force her to tidy up around the house...",
dialogue = Dialogue.Task_Clean1,
mood = -1,
progressionRequirements = new AssignedTaskRequirements () {
minAffection = 100
}
},
new AssignedTaskInfo() {
task = AssignedTask.Clean,
name = "Clean House",
description = "Make her tidy up the house.",
dialogue = Dialogue.Task_Clean2,
mood = -1,
progressionRequirements = new AssignedTaskRequirements () {
minAffection = 400,
}
},
new AssignedTaskInfo() {
task = AssignedTask.Clean,
name = "Clean House",
description = "Ask her to tidy up the house.",
dialogue = Dialogue.Task_Clean3,
mood = 0,
affection = 10
},
} },
{ AssignedTask.Games, new List<AssignedTaskInfo>() {
new AssignedTaskInfo() {
task = AssignedTask.Games,
name = "Play Games",
description = "Goof off with some mind-numbing videogames.",
dialogue = Dialogue.Task_Games1,
mood = 1,
affection = 20,
progressionRequirements = new AssignedTaskRequirements () {
minAffection = 500,
}
},
new AssignedTaskInfo() {
task = AssignedTask.Games,
name = "Hardcore Gaming",
description = "Play a competitive videogame against her.",
dialogue = Dialogue.Task_Games2,
mood = 1,
affection = 40,
},
} },
{ AssignedTask.RockOut, new List<AssignedTaskInfo>() {
new AssignedTaskInfo() {
task = AssignedTask.Games, // Only for tasksDoneToday
name = "Rock Out!",
description = "Put on some tunes and go completely spastic.",
dialogue = Dialogue.Task_RockOut,
mood = 2,
affection = 60,
},
} },
{ AssignedTask.Suck, new List<AssignedTaskInfo>() {
new AssignedTaskInfo() {
task = AssignedTask.Suck,
name = "Fellatio",
description = "A nice, simple blowjob.\nHow hard could it be?",
dialogue = Dialogue.Task_Suck1,
mood = -1,
progressionRequirements = new AssignedTaskRequirements () {
minAffection = 400
}
},
new AssignedTaskInfo() {
task = AssignedTask.Suck,
name = "Blowjob",
description = "Have her give you a classic sucking-off.",
dialogue = Dialogue.Task_Suck2,
mood = 0,
affection = 10,
progressionRequirements = new AssignedTaskRequirements () {
minAffection = 600
}
},
new AssignedTaskInfo() {
task = AssignedTask.Suck,
name = "Premium Blowjob",
description = "Ask and you shall receive.",
dialogue = Dialogue.Task_Suck3,
mood = 1,
affection = 20
},
} },
{ AssignedTask.SuckCosplay, new List<AssignedTaskInfo>() {
new AssignedTaskInfo() {
task = AssignedTask.Suck,
name = "Blowjob in Cosplay",
description = "Have her blow you in a cute little outfit.",
dialogue = Dialogue.Task_SuckCosplay,
affection = 20,
},
} },
{ AssignedTask.Fuck, new List<AssignedTaskInfo>() {
new AssignedTaskInfo() {
task = AssignedTask.Fuck,
name = "Copulate",
description = "Just fuck her already.",
dialogue = Dialogue.Task_Fuck1,
mood = 1,
affection = 10,
progressionRequirements = new AssignedTaskRequirements () {
minAffection = 500
}
},
new AssignedTaskInfo() {
task = AssignedTask.Fuck,
name = "Fuck",
description = "Rose petals and all that.",
dialogue = Dialogue.Task_Fuck2,
mood = 1,
affection = 20,
},
} },
{ AssignedTask.FuckCosplay, new List<AssignedTaskInfo>() {
new AssignedTaskInfo() {
task = AssignedTask.Fuck,
name = "Fuck in Cosplay",
description = "Do her from behind in that shiny new outfit.",
dialogue = Dialogue.Task_FuckCosplay,
mood = 2,
affection = 40,
},
} },
{ AssignedTask.Photos, new List<AssignedTaskInfo>() {
new AssignedTaskInfo() {
task = AssignedTask.Photos,
name = "Post Photos Online",
description = "Take some sexy pics to sell online.\nMaybe someone will buy them?",
dialogue = Dialogue.Task_Photos1,
affection = 10,
money = 30,
progressionRequirements = new AssignedTaskRequirements () {
minAffection = 700
}
},
new AssignedTaskInfo() {
task = AssignedTask.Photos,
name = "Make an OnlyFarts Video",
description = "You've built a small following with her photos.\nFilm a naughty video for your followers!",
dialogue = Dialogue.Task_Photos2,
affection = 20,
money = 50,
progressionRequirements = new AssignedTaskRequirements () {
minAffection = 1100
}
},
new AssignedTaskInfo() {
task = AssignedTask.Photos,
name = "Film LottaClips Customs",
description = "An anonymous client would like a custom video.\nCater to your fans!",
dialogue = Dialogue.Task_Photos3,
affection = 30,
mood = 1,
money = 100
},
} },
{ AssignedTask.Cosplay, new List<AssignedTaskInfo>() {
new AssignedTaskInfo() {
task = AssignedTask.Photos,
name = "Film Cosplay",
description = "Dress her up in some sexy cosplay and sell saucy pics online.\nMore valuable than regular photos!",
dialogue = Dialogue.Task_Cosplay,
affection = 30,
money = 150
},
} },
{ AssignedTask.Spank, new List<AssignedTaskInfo>() {
new AssignedTaskInfo() {
task = AssignedTask.Spank,
name = "Spank",
description = "A bit of corporal punishment, just for fun.",
progressionRequirements = new AssignedTaskRequirements () {
minAffection = 1300
}
},
new AssignedTaskInfo() {
task = AssignedTask.Spank,
name = "Spank Hard",
description = "She's starting to like this one.",
mood = 1,
affection = 30,
},
} },
};
public static Dictionary<AssignedTask, AssignedTaskRequirements> TASK_REQUIREMENTS = new Dictionary<AssignedTask, AssignedTaskRequirements>() {
{ AssignedTask.Clean, new AssignedTaskRequirements() {
minMood = 1,
minAffection = 0,
} },
{ AssignedTask.Games, new AssignedTaskRequirements() {
minMood = 0,
minAffection = 0,
} },
{ AssignedTask.RockOut, new AssignedTaskRequirements() {
minMood = 4,
minAffection = 1000,
minDay = 10,
requiredHair = Hair.FizzyPop,
requiredOutfit = Body.Rockstar,
requiredViewedScene = Dialogue.Task_Games2,
} },
{ AssignedTask.Suck, new AssignedTaskRequirements() {
minMood = 2,
minAffection = 0,
} },
{ AssignedTask.SuckCosplay, new AssignedTaskRequirements() {
minMood = 1,
minAffection = 1000,
minDay = 10,
requiredHair = Hair.Pigtails,
requiredOutfit = Body.Swimsuit,
requiredViewedScene = Dialogue.Task_Suck2,
} },
{ AssignedTask.Photos, new AssignedTaskRequirements() {
minMood = 1,
minAffection = 300,
minDay = 3
} },
{ AssignedTask.Cosplay, new AssignedTaskRequirements() {
minMood = 3,
minAffection = 800,
minDay = 8,
requiredHair = Hair.PrimProper,
requiredOutfit = Body.Business,
requiredViewedScene = Dialogue.Task_Photos1,
} },
{ AssignedTask.Fuck, new AssignedTaskRequirements() {
minMood = 1,
minAffection = 500,
minDay = 5
} },
{ AssignedTask.FuckCosplay, new AssignedTaskRequirements() {
minMood = 3,
minAffection = 800,
minDay = 8,
requiredHair = Hair.Bratty,
requiredOutfit = Body.EmoUndies,
requiredViewedScene = Dialogue.Task_Fuck1,
} },
{ AssignedTask.Spank, new AssignedTaskRequirements() {
minMood = 2,
minAffection = 800,
minDay = 7
} },
};
public static AssignedTaskInfo GetCurrentUnlockedVersionOf(AssignedTask task) {
if (!TASK_REQUIREMENTS[task].Check(Dialogue.None)) {
return null;
}
int numVersions = TASK_INFO[task].Count;
AssignedTaskInfo info = TASK_INFO[task][0];
int i = 0;
while (i < numVersions - 1 && info.progressionRequirements.Check(info.dialogue)) {
info = TASK_INFO[task][++i];
}
return info;
}
public static HashSet<Dialogue> RED_TAG_SCENES = new HashSet<Dialogue>() {
Dialogue.Intro,
Dialogue.Special_CakeAndIceCream,
Dialogue.Special_HappyBirthday,
Dialogue.Special_OnlyFarts,
Dialogue.Special_ThereSheBlows,
};
// Used to tell which dialogue sequences are unlockable.
// Mapped via DIALOGUE_DESCRIPTIONS.keys() by the Scene Picker to make a list of unlocked dialogues.
// TODO: use this?
public static Dictionary<Dialogue, Unlockable> UNLOCKABLES = new Dictionary<Dialogue, Unlockable>() {
};
public static string GetDialogueAssetPackFor(Dialogue d) {
return "VNAssetPacks/VNA_" + d.ToString();
}
public static Dictionary<Dialogue, Description> DIALOGUE_DESCRIPTIONS = new Dictionary<Dialogue, Description>() {
{ Dialogue.Intro, new Description() {
name = "Intro",
description = "Your old high school friend calls you for a big favor." } },
{ Dialogue.Task_Clean1, new Description() {
name = "Task: Clean",
description = "You goad her into cleaning the house. She does this... poorly." } },
{ Dialogue.Task_Clean2, new Description() {
name = "Task: Clean (Version 2)",
description = "You have her tidy up the house, and she does a decent job." } },
{ Dialogue.Task_Clean3, new Description() {
name = "Task: Clean (Version 3)",
description = "You ask her to clean the house. She's warmed up to the occasional chore." } },
{ Dialogue.Task_Games1, new Description() {
name = "Task: Goofin' Off",
description = "You goof off with her for a while." } },
{ Dialogue.Task_Games2, new Description() {
name = "Task: Goofin' Off (Version 2)",
description = "You play some videogames and get into a heated argument." } },
{ Dialogue.Task_RockOut, new Description() {
name = "Task: Goofin' Off (Cosplay)",
description = "You both rock out like lunatics!" } },
{ Dialogue.Task_Suck1, new Description() {
name = "Task: Suck",
description = "You make her begrudgingly suck you off." } },
{ Dialogue.Task_Suck2, new Description() {
name = "Task: Suck (Version 2)",
description = "You have her tend to the ol' trouser snake." } },
{ Dialogue.Task_Suck3, new Description() {
name = "Task: Suck (Version 3)",
description = "You let her lovingly service your member." } },
{ Dialogue.Task_SuckCosplay, new Description() {
name = "Task: Suck (Cosplay)",
description = "You dress her up like a cutie and watch her do some slurpin'." } },
{ Dialogue.Task_Fuck1, new Description() {
name = "Task: Fuck",
description = "You let her bounce up and down on top of you." } },
{ Dialogue.Task_Fuck2, new Description() {
name = "Task: Fuck (Version 2)",
description = "You bounce up and down on top of her." } },
{ Dialogue.Task_FuckCosplay, new Description() {
name = "Task: Fuck (Cosplay)",
description = "You dress her up like a brat and fuck her from behind." } },
{ Dialogue.Task_Photos1, new Description() {
name = "Task: Take Photos",
description = "You take some sexy photos to sell online for cash." } },
{ Dialogue.Task_Photos2, new Description() {
name = "Task: Take Photos (Version 2)",
description = "You take some vids of her ass for her OnlyFarts account." } },
{ Dialogue.Task_Photos3, new Description() {
name = "Task: Take Photos (Version 3)",
description = "You film a custom video for an anonymous client." } },
{ Dialogue.Task_Cosplay, new Description() {
name = "Task: Take Photos (Cosplay)",
description = "You take some pics for a special cosplay photo pack." } },
{ Dialogue.Special_CakeAndIceCream, new Description() {
name = "Special: Cake & Ice Cream",
description = "You pump her pooper until she pumps poop. Gross." } },
{ Dialogue.Special_OnlyFarts, new Description() {
name = "Special: OnlyFarts",
description = "She treats her viewers (and you) to a very unique ASMR session." } },
{ Dialogue.Special_ThereSheBlows, new Description() {
name = "Special: There She Blows",
description = "She needs to \"go\", but is too lazy to get up." } },
{ Dialogue.Special_HappyBirthday, new Description() {
name = "Special: Happy Birthday!",
description = "For a fan's birthday, she, uhh... well... um..." } },
};
public static Dictionary<Dialogue, List<DialogueInteraction>> Conglomerate(
List<Dictionary<Dialogue, List<DialogueInteraction>>> scriptChunks) {
Dictionary<Dialogue, List<DialogueInteraction>> d = new Dictionary<Dialogue, List<DialogueInteraction>>();
foreach (Dictionary<Dialogue, List<DialogueInteraction>> chunk in scriptChunks) {
foreach (var dialoguePair in chunk) {
d[dialoguePair.Key] = dialoguePair.Value;
}
}
return d;
}
public Dictionary<Dialogue, List<DialogueInteraction>> DIALOGUE =
Conglomerate(new List<Dictionary<Dialogue, List<DialogueInteraction>>>() {
VNDataScripts.MANAGER_SCRIPTS,
VNDataScripts.TASK_SCRIPTS,
VNDataScripts.TASK_SCRIPTS2,
VNDataScripts.GAMEPLAY_SCRIPTS,
VNDataScripts.SPECIAL_SCRIPTS,
});
public static VNData GLOBAL = new VNData();
}