Insanely huge initial commit

This commit is contained in:
2026-02-21 16:40:15 -08:00
parent 2ba1c94b88
commit ee9aee0a1b
33825 changed files with 5213498 additions and 0 deletions

View File

@@ -0,0 +1,123 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using Michsky.MUIP;
using TMPro;
using Febucci.UI;
public class DialogueController : MonoBehaviour, IPointerClickHandler {
[SerializeField] TextMeshProUGUI textTMPro;
[SerializeField] TextMeshProUGUI nameTMPro;
[SerializeField] TextAnimatorPlayer typer;
[SerializeField] ButtonManager button;
[SerializeField] RectTransform optionMenu;
[SerializeField] bool clickAnywhere = false;
[SerializeField] VNController vn = null;
[HideInInspector] List<DialogueInteraction> interactions;
[HideInInspector] public int dialogueIndex = 0;
// Whether to use VNData.NextScene or to pick a random Manager scene.
[SerializeField] public bool chooseManagerScene = false;
private string Compile(string text) {
// TODO: Compile for all possible names, controllable via DialogueInteraction flags
return text.Replace("%Her%", GameData.GLOBAL.characterNames[Character.Her]);
}
private void Interact() {
if (dialogueIndex >= interactions.Count && optionMenu != null) {
optionMenu.gameObject.SetActive(true);
return;
}
if (dialogueIndex >= interactions.Count) {
vn.Done();
return;
}
DialogueInteraction d = interactions[dialogueIndex];
if (vn != null) {
vn.Interact(d);
}
nameTMPro.SetText(GameData.GLOBAL.characterNames[d.character]);
string text = Compile(d.text);
textTMPro.SetText(text);
if (d.unlock != Unlockable.None) {
GameData.Unlock(d.unlock);
}
if (d.gameOver) {
vn.gameOverAfterDone = true;
}
dialogueIndex += 1;
}
public void NextButtonPressed() {
if (typer.textAnimator.allLettersShown) {
if (button.enabled) {
button.enabled = false;
}
Interact();
} else {
typer.SkipTypewriter();
}
}
public void OnPointerClick(PointerEventData eventData) {
if (clickAnywhere) {
NextButtonPressed();
}
}
// Set up and start a dialogue interaction.
// "fresh" means it's the first scene on Start, which triggers an appropriate load of VN assets.
// In the manager, "fresh" also causes the background to be set based on the time of day.
// Turn "fresh" off when the same VNAsset pack is used for multiple Dialogue scenes
// i.e. in the Manager, Studio, or tutorial.
public void SetUp(bool fresh = true) {
dialogueIndex = 0;
if (clickAnywhere) {
button.gameObject.SetActive(false);
} else {
button.enabled = false;
}
if (optionMenu != null) {
optionMenu.gameObject.SetActive(false);
}
if (fresh && chooseManagerScene) {
if (GameData.GLOBAL.ranAway) {
VNData.NextScene = Dialogue.Manager_RanAway;
} else if (GameData.GLOBAL.status == Status.Farty) {
VNData.NextScene = VNData.fartyScenes[Random.Range(0, VNData.fartyScenes.Count)];
} else if (GameData.GLOBAL.hunger > 2 && Random.Range(0f, 1f) > 0.5f) {
VNData.NextScene = Dialogue.Manager_Hungry1;
} else if (GameData.GLOBAL.status == Status.Moody) {
VNData.NextScene = VNData.moodyScenes[Random.Range(0, VNData.moodyScenes.Count)];
} else {
VNData.NextScene = VNData.managerScenes[Random.Range(0, VNData.managerScenes.Count)];
}
}
// The scene to play is pre-loaded here.
interactions = VNData.GLOBAL.DIALOGUE[VNData.NextScene];
GameData.GLOBAL.viewedScenes.Add(VNData.NextScene);
vn.SetUp(VNData.NextScene, chooseManagerScene, fresh);
Interact();
}
// Start is called before the first frame update
void Start() {
SetUp();
}
// Update is called once per frame
void Update() {
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 239872e7fb3c97046a9e450b0af3e3d2
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

230
Assets/Scripts/GameData.cs Normal file
View File

@@ -0,0 +1,230 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO;
using System.Threading.Tasks;
public enum Unlockable {
None,
Bubuus,
}
public enum Status {
Normal,
Farty,
Horny,
Drunk,
Moody,
}
[System.Serializable]
public class GameData {
// Whether or not the game's Red Tag content is available.
// Red Tag is the supporter-only version of the game.
// It unlocks heavy fetish content in special scenes.
public static bool RED_TAG = false;
public bool isNewGame = true;
// Set temporarily when the game first notices that you've unlocked all the content.
// Should show a special scene.
public bool hasShownWinScene = false;
public int money = 100000;
public int day = 15;
public int time = 1;
public int mood = 4;
public int hunger = 0;
public int affection = 55550;
public int fartCounter = 0;
public Status status = Status.Normal;
public bool workedToday = false;
public bool boughtFood = false;
public bool ranAway = false;
public Body bodyChoice = Body.Undies;
public Hair hairChoice = Hair.Messy;
public HashSet<AssignedTask> tasksDoneToday = new HashSet<AssignedTask>();
// Populated when the Manager notices that you've unlocked a new version of a task.
// See ManagerController.NotifyTaskUnlocks.
public HashSet<Dialogue> notifiedTaskUnlocks = new HashSet<Dialogue>() {
Dialogue.None,
Dialogue.Task_Clean1,
Dialogue.Task_Games1,
Dialogue.Task_Suck1,
};
public HashSet<Unlockable> unlocked = new HashSet<Unlockable>() {
};
public HashSet<Body> unlockedOutfits = new HashSet<Body>()
{
Body.Undies
};
public HashSet<Hair> unlockedHairs = new HashSet<Hair>()
{
Hair.Messy
};
public HashSet<Body> forSaleOutfits = new HashSet<Body>();
public HashSet<Hair> forSaleHairs = new HashSet<Hair>();
public HashSet<Dialogue> viewedScenes = new HashSet<Dialogue>();
public Dictionary<Character, string> characterNames = new Dictionary<Character, string>()
{
{ Character.None, "" },
{ Character.Her, "Bitch" },
{ Character.You, "Player" },
{ Character.OldRoommate, "Jeanine" }
};
public GameData() {}
// Populate the for-sale outfits and hairs according to game progress.
public void UpdateForSale() {
forSaleOutfits.Clear();
forSaleHairs.Clear();
MaybeAddOutfitForSale(Body.EmoUndies, 2, 1000);
MaybeAddOutfitForSale(Body.Rockstar, 5, 3000);
MaybeAddOutfitForSale(Body.Swimsuit, 8, 5500);
MaybeAddOutfitForSale(Body.Messy, 11, 8000);
MaybeAddOutfitForSale(Body.Business, 14, 10000);
MaybeAddOutfitForSale(Body.Devil, 17, 15000);
MaybeAddHairForSale(Hair.Bratty, 3, 2000);
MaybeAddHairForSale(Hair.Pigtails, 6, 5500);
MaybeAddHairForSale(Hair.PrimProper, 13, 11500);
MaybeAddHairForSale(Hair.FizzyPop, 18, 17500);
}
private void MaybeAddOutfitForSale(Body _outfit, int minDay, int minAffection) {
if (!unlockedOutfits.Contains(_outfit)
&& day >= minDay
&& affection >= minAffection
) {
forSaleOutfits.Add(_outfit);
}
}
private void MaybeAddHairForSale(Hair _hair, int minDay, int minAffection) {
if (!unlockedHairs.Contains(_hair)
&& day >= minDay
&& affection >= minAffection
) {
forSaleHairs.Add(_hair);
}
}
// Whether you've done everything: all outfits, all hairs, all tasks.
public bool CheckWin() {
for (int i = 1; i < System.Enum.GetNames(typeof(Body)).Length; i++) {
if (!unlockedOutfits.Contains((Body)i))
return false;
}
for (int i = 1; i < System.Enum.GetNames(typeof(Hair)).Length; i++) {
if (!unlockedHairs.Contains((Hair)i))
return false;
}
foreach (var progressionKey in VNData.TASK_INFO.Keys) {
foreach (AssignedTaskInfo info in VNData.TASK_INFO[progressionKey]) {
if (info.dialogue != Dialogue.None &&
!viewedScenes.Contains(info.dialogue))
return false;
}
}
return true;
}
public static bool IsUnlocked(Unlockable u) {
return GLOBAL.unlocked.Contains(u);
}
public static void Unlock(Unlockable u) {
GLOBAL.unlocked.Add(u);
}
public static GameData GLOBAL = new GameData();
public static void Save() {
Debug.Log("Save");
ES3.Save<GameData>("save", GameData.GLOBAL);
}
public static bool Load() {
Debug.Log("Save");
ES3.LoadInto<GameData>("save", GameData.GLOBAL);
return true;
}
public void Feed(Food food) {
ItemInfo foodInfo = VNData.FOOD_INFO[food];
hunger -= foodInfo.hunger;
if (hunger < 0)
hunger = 0;
mood += foodInfo.mood;
if (mood < 0)
mood = 0;
if (mood > 4)
mood = 4;
affection += foodInfo.affection;
if (foodInfo.fartiness > 0f && Random.Range(0f,1f) < foodInfo.fartiness) {
// uh-oh spaghetti-o's
fartCounter = 2;
status = Status.Farty;
}
}
public void IncrementTime() {
boughtFood = false;
ranAway = false;
if (time == 4) {
time = 1;
day += 1;
workedToday = false;
tasksDoneToday.Clear();
if (status == Status.Moody) {
status = Status.Normal;
}
if (day > 1 && day % 3 == 1) {
// Pay the bills every third day, starting day 4.
money -= 200;
}
} else {
time += 1;
}
if (fartCounter == 0 && status == Status.Farty) {
status = Status.Normal;
}
fartCounter -= 1;
if (fartCounter < 0) {
fartCounter = 0;
}
// Process mood
if (hunger > 2 || Random.Range(0f, 1f) < 0.3f) {
mood -= 1;
}
if (mood < 1) {
mood = 0;
status = Status.Moody;
}
// Process hunger
hunger += 1;
if (hunger > 4) {
// Going too long without feeding her triggers a runaway event.
// She steals your credit card and takes a cab to take herself out to dinner.
// She also becomes moody and won't cooperate with you for a full day.
ranAway = true;
mood = 0;
hunger = 0;
status = Status.Moody;
money -= 200;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e92e006e4bdda9141b2cc4ba2c0878c6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,33 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine.SceneManagement;
using UnityEngine;
public class IntroController : MonoBehaviour
{
[SerializeField] List<IntroFadeController> faders;
[SerializeField] string nextSceneName;
// Start is called before the first frame update
void Start()
{
Cursor.visible = false;
if (faders.Count > 0) {
faders[0].gameObject.SetActive(true);
}
}
// Update is called once per frame
void Update()
{
if (faders.Count == 0) {
SceneManager.LoadScene(nextSceneName, LoadSceneMode.Single);
} else if (!faders[0].gameObject.activeSelf) {
// Start the timer of a new fader.
faders[0].gameObject.SetActive(true);
} else if (faders[0].turnedOff) {
faders[0].gameObject.SetActive(false);
faders.RemoveAt(0);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 909cd6fdd069ed946a8eb9bffe018c78
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,63 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine.EventSystems;
using UnityEngine.UI;
using UnityEngine;
using TMPro;
public class IntroFadeController : MonoBehaviour, IPointerDownHandler {
[SerializeField] List<TextMeshProUGUI> text;
[SerializeField] List<Image> images;
[SerializeField] float crossFadeTime = 1.0f;
[SerializeField] float waitTime = 1.5f;
[HideInInspector] bool readyToTurnOff = false;
[HideInInspector] bool turningOff = false;
[HideInInspector] public bool turnedOff = false;
public void OnPointerDown(PointerEventData eventData) {
if (readyToTurnOff && !turningOff) {
foreach (TextMeshProUGUI tmPro in text) {
tmPro.GetComponent<CanvasRenderer>().SetAlpha(1.0f);
tmPro.CrossFadeAlpha(0.0f, crossFadeTime, false);
}
foreach (Image image in images) {
image.GetComponent<CanvasRenderer>().SetAlpha(1.0f);
image.CrossFadeAlpha(0.0f, crossFadeTime, false);
}
turningOff = true;
StartCoroutine("DoNextWait");
}
}
// Start is called before the first frame update
void Awake()
{
readyToTurnOff = false;
foreach (TextMeshProUGUI tmPro in text) {
tmPro.GetComponent<CanvasRenderer>().SetAlpha(0.0f);
tmPro.CrossFadeAlpha(1.0f, crossFadeTime, false);
}
foreach (Image image in images) {
image.GetComponent<CanvasRenderer>().SetAlpha(0.0f);
image.CrossFadeAlpha(1.0f, crossFadeTime, false);
}
StartCoroutine("DoWait");
}
IEnumerator DoWait() {
yield return new WaitForSeconds(waitTime);
readyToTurnOff = true;
}
IEnumerator DoNextWait() {
yield return new WaitForSeconds(crossFadeTime);
turnedOff = true;
}
// Update is called once per frame
void Update()
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a13398db43f545044911b32991f6b2db
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,85 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Com.LuisPedroFonseca.ProCamera2D;
using UnityEngine.SceneManagement;
using TMPro;
public class MainMenuController : MonoBehaviour
{
[SerializeField] ProCamera2DTransitionsFX transition;
[SerializeField] RectTransform menuPanel;
[SerializeField] RectTransform newGamePanel;
[SerializeField] TMP_InputField girlName;
[SerializeField] TMP_InputField playerName;
[SerializeField] AudioClip mainMenuMusicIntro;
[SerializeField] AudioClip mainMenuMusic;
MusicFadeController music;
void NewGame() {
GameData.GLOBAL = new GameData();
GameData.GLOBAL.characterNames[Character.Her] = girlName.text;
GameData.GLOBAL.characterNames[Character.You] = playerName.text;
GameData.Save();
Debug.Log("She's named " + GameData.GLOBAL.characterNames[Character.Her]);
Debug.Log("You're named " + GameData.GLOBAL.characterNames[Character.You]);
VNData.NextScene = Dialogue.Intro;
SceneManager.LoadScene("SceneViewer");
}
void Continue() {
GameData.Load();
SceneManager.LoadScene("Manager");
}
void Quit() {
Application.Quit();
}
void StartTransition() {
Debug.Log("TODO: Make a sound");
transition.TransitionExit();
music.FadeOut(0.5f);
menuPanel.gameObject.SetActive(false);
}
public void PressedNewGame() {
newGamePanel.gameObject.SetActive(true);
menuPanel.gameObject.SetActive(false);
}
public void PressedNewGameBack() {
newGamePanel.gameObject.SetActive(false);
menuPanel.gameObject.SetActive(true);
}
public void PressedNewGameStart() {
transition.OnTransitionExitEnded = NewGame;
StartTransition();
}
public void PressedContinue() {
transition.OnTransitionExitEnded = Continue;
StartTransition();
}
public void PressedQuit() {
transition.OnTransitionExitEnded = Quit;
StartTransition();
}
// Start is called before the first frame update
void Start()
{
transition.TransitionEnter();
music = GameObject.FindWithTag("Music").GetComponent<MusicFadeController>();
music.audioSource.clip = mainMenuMusicIntro;
music.audioSource.Play();
music.shouldLoop = true;
music.PlayMainMenuLoopAfter(mainMenuMusicIntro.length, mainMenuMusic);
music.FadeIn(0.0f);
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2d77c97613374b940bf1ccd3cec326aa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,303 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Com.LuisPedroFonseca.ProCamera2D;
using UnityEngine.SceneManagement;
using UnityEngine.UI;
public class ManagerController : MonoBehaviour {
[SerializeField] ProCamera2DTransitionsFX transition;
[SerializeField] GameObject shopBackButton;
[SerializeField] GameObject mainMenuButton;
[SerializeField] ShopController outfitShopScrollView;
[SerializeField] ShopController hairShopScrollView;
[SerializeField] ShopController foodShopScrollView;
[SerializeField] ScenePickerController taskPickerScrollView;
[SerializeField] ScenePickerController scenePickerScrollView;
[SerializeField] GameObject selectorPanel;
[SerializeField] VNController vn;
[SerializeField] AudioClip managerTheme;
[SerializeField] DialogueController dialogue;
[SerializeField] Transform cityPanel;
[SerializeField] Transform homePanel;
[SerializeField] Transform boutiquePanel;
[SerializeField] Transform salonPanel;
[SerializeField] Transform dinerPanel;
[SerializeField] Transform statsPanel;
[SerializeField] Transform studioButton;
[SerializeField] Transform boutiqueButton;
[SerializeField] Transform salonButton;
[SerializeField] Transform dinerButton;
[SerializeField] Transform dinerPanelBackButton;
[SerializeField] Image bg;
[HideInInspector] MusicFadeController music;
private void Start() {
if (GameData.GLOBAL.money < 0) {
// Losing via runaway should show the runaway VN scene first.
if (GameData.GLOBAL.ranAway) {
vn.runawayGameOverAfterDone = true;
} else {
VNData.NextScene = Dialogue.GameOver;
ShowVNScene();
}
} else if (GameData.GLOBAL.CheckWin() && !GameData.GLOBAL.hasShownWinScene) {
GameData.GLOBAL.hasShownWinScene = true;
VNData.NextScene = Dialogue.YouWin;
ShowVNScene();
}
transition.TransitionEnter();
music = GameObject.FindWithTag("Music").GetComponent<MusicFadeController>();
if (music.audioSource.clip != managerTheme) {
music.FadeOutThenIn(2.0f, 4.0f, managerTheme);
}
}
private void Awake() {
// TODO: Set this in main menu as well
// TODO: Maybe 60?
#if UNITY_EDITOR
QualitySettings.vSyncCount = 0; // VSync must be disabled
Application.targetFrameRate = 120;
#endif
NotifyTaskUnlocks();
}
private void NotifyTaskUnlocks() {
foreach (AssignedTask task in System.Enum.GetValues(typeof(AssignedTask))) {
if (task == AssignedTask.None) {
continue;
}
AssignedTaskInfo info = VNData.GetCurrentUnlockedVersionOf(task);
if (info != null &&
info.dialogue != Dialogue.None &&
!GameData.GLOBAL.notifiedTaskUnlocks.Contains(info.dialogue)) {
GameData.GLOBAL.notifiedTaskUnlocks.Add(info.dialogue);
GameObject.FindWithTag("Notifier").GetComponent<NotifierController>().Notify(
"New Task",
"Unlocked or progressed a task! Task: " + info.name);
}
}
}
public void CloseViews(bool showBackButton = false) {
outfitShopScrollView.gameObject.SetActive(false);
foodShopScrollView.gameObject.SetActive(false);
hairShopScrollView.gameObject.SetActive(false);
taskPickerScrollView.gameObject.SetActive(false);
scenePickerScrollView.gameObject.SetActive(false);
shopBackButton.SetActive(showBackButton);
mainMenuButton.SetActive(!showBackButton);
selectorPanel.SetActive(false);
}
public void TransitionToVNScene() {
vn.CloseManager();
transition.OnTransitionExitEnded = ShowVNScene;
StartTransition();
}
public void ShopBackButtonPressed() {
CloseViews();
selectorPanel.SetActive(true);
}
public void OutfitShopButtonPressed() {
CloseViews(true);
outfitShopScrollView.gameObject.SetActive(true);
outfitShopScrollView.SetUp();
}
public void HairShopButtonPressed() {
CloseViews(true);
hairShopScrollView.gameObject.SetActive(true);
hairShopScrollView.SetUp();
}
public void FoodShopButtonPressed() {
if (GameData.GLOBAL.hunger == 0) {
GameObject.FindWithTag("Notifier").GetComponent<NotifierController>().Notify(
"Purchase Failed",
"She's not hungry.");
return;
}
CloseViews(true);
foodShopScrollView.gameObject.SetActive(true);
foodShopScrollView.SetUp();
}
public void TaskPressed() {
CloseViews(true);
taskPickerScrollView.gameObject.SetActive(true);
taskPickerScrollView.SetUp();
}
public void ScenePickerPressed() {
CloseViews(true);
scenePickerScrollView.gameObject.SetActive(true);
scenePickerScrollView.SetUp();
}
public void HomeClicked() {
homePanel.gameObject.SetActive(true);
cityPanel.gameObject.SetActive(false);
}
public void CityClicked() {
cityPanel.gameObject.SetActive(true);
homePanel.gameObject.SetActive(false);
// You can only use the studio in the morning or early afternoon.
studioButton.gameObject.SetActive(
GameData.GLOBAL.time == 0 ||
GameData.GLOBAL.time == 1
);
// You can only shop during mall hours (noon to evening).
boutiqueButton.gameObject.SetActive(
GameData.GLOBAL.time == 1 ||
GameData.GLOBAL.time == 2
);
salonButton.gameObject.SetActive(
GameData.GLOBAL.time == 1 ||
GameData.GLOBAL.time == 2
);
// You can always go to the diner... assuming you can afford it.
dinerButton.gameObject.SetActive(
true
);
}
public void FoodPurchased() {
// TODO: More dynamic VN scene based on food, mood, etc
CloseViews(true);
vn.awakenOnFinish = new List<Transform>() { foodShopScrollView.transform };
VNData.NextScene = Dialogue.Manager_BoughtFood1; // TODO: Bought food thing
dialogue.SetUp(false);
}
public void SalonClicked() {
// TODO: Check Vero's status (moody or low mood = can't shop)
// TODO: Check money and locked hairs (if can't afford anything, can't shop)
CloseViews(true);
vn.awakenOnFinish = new List<Transform>() { salonPanel, statsPanel };
VNData.NextScene = Dialogue.Manager_Salon;
dialogue.SetUp(false);
hairShopScrollView.gameObject.SetActive(true);
hairShopScrollView.SetUp();
cityPanel.gameObject.SetActive(false);
}
public void BoutiqueClicked() {
// TODO: Check Vero's status (moody or low mood = can't shop)
// TODO: Check money and locked hairs (if can't afford anything, can't shop)
CloseViews(true);
vn.awakenOnFinish = new List<Transform>() { boutiquePanel, statsPanel };
VNData.NextScene = Dialogue.Manager_Boutique;
dialogue.SetUp(false);
outfitShopScrollView.gameObject.SetActive(true);
outfitShopScrollView.SetUp();
cityPanel.gameObject.SetActive(false);
}
public void DinerClicked() {
// TODO: Check money (if can't afford food, can't dine)
if (GameData.GLOBAL.hunger == 0) {
GameObject.FindWithTag("Notifier").GetComponent<NotifierController>().Notify(
"Nope.",
"She's not hungry.");
return;
}
dinerPanel.gameObject.SetActive(true);
vn.awakenOnFinish = new List<Transform>() { foodShopScrollView.transform, dinerPanelBackButton };
VNData.NextScene = Dialogue.Manager_Diner;
dialogue.SetUp(false);
foodShopScrollView.SetUp();
foodShopScrollView.gameObject.SetActive(false); // Will reactivate after the dialogue sequence
cityPanel.gameObject.SetActive(false);
}
public void StudioClicked() {
WorkPressed();
}
public void DoneShoppingButtonPressed() {
SkipPressed();
}
public void SaveButtonPressed() {
Debug.Log("TODO: Autosave toggle as option");
GameData.Save();
Debug.Log("TODO: Play a save noise");
}
void MainMenu() {
SceneManager.LoadScene("MainMenu");
}
// Used as a generic Action, which cannot have parameters.
void IncrementOnce() {
Increment();
}
void Increment(int times = 1) {
for (int i = 0; i < times; i++) {
GameData.GLOBAL.IncrementTime();
}
SceneManager.LoadScene("Manager");
}
void ShowVNScene() {
SceneManager.LoadScene("SceneViewer");
}
void StartWork() {
SceneManager.LoadScene("Work");
}
void ResetManager() {
SceneManager.LoadScene("Manager");
}
void StartTransition() {
// Disable all interactions somehow
GameData.Save();
transition.TransitionExit();
}
public void SceneViewButtonPressed(Dialogue scene) {
VNData.NextScene = scene;
transition.OnTransitionExitEnded = ShowVNScene;
StartTransition();
Debug.Log("TODO: Make a sound");
}
public void MainMenuPressed() {
vn.CloseManager();
transition.OnTransitionExitEnded = MainMenu;
StartTransition();
Debug.Log("TODO: Make a sound");
}
public void SkipPressed() {
vn.CloseManager();
transition.OnTransitionExitEnded = IncrementOnce;
StartTransition();
Debug.Log("TODO: Make a sound");
}
public void WorkPressed() {
vn.CloseManager();
transition.OnTransitionExitEnded = StartWork;
StartTransition();
Debug.Log("TODO: Make a sound");
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 68e06da9fc3d5c444890b9baaae86b7a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,17 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using Michsky.MUIP;
public class NotifierController : MonoBehaviour {
[SerializeField] GameObject PopupGameObject;
[SerializeField] NotificationStacking notifier;
public void Notify(string title, string description) {
NotificationManager popup = Instantiate(PopupGameObject).GetComponent<NotificationManager>();
popup.title = title;
popup.description = description;
popup.transform.SetParent(notifier.transform);
popup.UpdateUI();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 75c8c0f1606cef84a943abab1251dcfa
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,45 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class SceneItemController : MonoBehaviour {
[SerializeField] public TextMeshProUGUI itemTitle;
[SerializeField] public TextMeshProUGUI itemDescription;
[SerializeField] public Image redTagImage;
Dialogue dialogue = Dialogue.None;
AssignedTaskInfo info = null;
public void SetSceneFields(Dialogue dialogue, Description description) {
this.dialogue = dialogue;
itemTitle.SetText(description.name);
itemDescription.SetText(description.description);
redTagImage.color = (VNData.RED_TAG_SCENES.Contains(dialogue)) ? Color.white : Color.clear;
}
public void SetTaskFields(AssignedTaskInfo info) {
this.info = info;
this.dialogue = info.dialogue;
itemTitle.SetText(info.name);
itemDescription.SetText(info.description);
redTagImage.color = (VNData.RED_TAG_SCENES.Contains(this.dialogue)) ? Color.white : Color.clear;
}
public void ShowScene() {
// Execute the gameplay effects of the task, if set.
if (info != null) {
GameData.GLOBAL.hunger += info.hunger;
GameData.GLOBAL.mood += info.mood;
GameData.GLOBAL.money += info.money;
GameData.GLOBAL.affection += info.affection;
GameData.GLOBAL.IncrementTime();
}
ManagerController manager = GameObject.FindWithTag("Notifier").GetComponent<ManagerController>();
GameData.GLOBAL.tasksDoneToday.Add(info.task);
VNData.NextScene = dialogue;
manager.TransitionToVNScene();
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bfeae64774da19a47956284fba0332f7
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,46 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class ScenePickerController : MonoBehaviour {
[SerializeField] Transform verticalLayoutGroup;
[SerializeField] GameObject SceneItemPrefab;
public enum LoadType {
TASK,
SCENE
};
[SerializeField] LoadType loadType = LoadType.TASK;
public void SetUp() {
while (verticalLayoutGroup.childCount > 0) {
DestroyImmediate(verticalLayoutGroup.GetChild(0).gameObject);
}
if (loadType == LoadType.TASK) {
foreach (AssignedTask task in System.Enum.GetValues(typeof(AssignedTask))) {
if (task == AssignedTask.None)
continue;
if (task != AssignedTask.Clean &&
task != AssignedTask.Games &&
GameData.GLOBAL.tasksDoneToday.Contains(task)) {
continue;
}
AssignedTaskInfo info = VNData.GetCurrentUnlockedVersionOf(task);
if (info != null) {
GameObject item = Instantiate(SceneItemPrefab);
item.GetComponent<SceneItemController>().SetTaskFields(info);
item.transform.SetParent(verticalLayoutGroup);
}
}
} else {
foreach (Dialogue dialogue in GameData.GLOBAL.viewedScenes) {
if (!VNData.DIALOGUE_DESCRIPTIONS.ContainsKey(dialogue))
continue;
GameObject item = Instantiate(SceneItemPrefab);
item.GetComponent<SceneItemController>().SetSceneFields(dialogue, VNData.DIALOGUE_DESCRIPTIONS[dialogue]);
item.transform.SetParent(verticalLayoutGroup);
}
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: d0b4d1c9a7c319a43ac0ca2bba6034c8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: b460c1cb129bf694b9e324970b55a08d
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,215 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public partial class VNDataScripts {
public static Dictionary<Dialogue, List<DialogueInteraction>>
GAMEPLAY_SCRIPTS = new Dictionary<Dialogue, List<DialogueInteraction>>() {
// ==============
{ Dialogue.GameOver,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.You, ".....") {
musicClipIndex = 0,
},
new DialogueInteraction(Character.You, "Damn...") {
backgroundIndex = 0,
},
new DialogueInteraction(Character.None, "Fresh out of cash."),
new DialogueInteraction(Character.None, "I knew I shouldn't have agreed to take care of this bitch."),
new DialogueInteraction(Character.None, "We've been barely paying bills on time, and now we can't pay at all."),
new DialogueInteraction(Character.None, "But what was I supposed to do? Leave her stranded and homeless?"),
new DialogueInteraction(Character.None, "What could I have done better?"),
new DialogueInteraction(Character.None, "........"),
new DialogueInteraction(Character.None, "Game Over") {
gameOver = true,
fadeMusicOut = true,
},
}
},
// ==============
{ Dialogue.YouWin,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.You, "Well, now.") {
musicClipIndex = 0,
backgroundIndex = 0,
},
new DialogueInteraction(Character.You, "It's been quite some time since this bitch moved in."),
new DialogueInteraction(Character.You, "There have definitely been some ups and some downs..."),
new DialogueInteraction(Character.You, "But I'm glad she's here with me - safe, and not out on the streets."),
new DialogueInteraction(Character.None, "........"),
new DialogueInteraction(Character.None, "You Win! Feel free to continue indefinitely.") {
fadeMusicOut = true,
},
new DialogueInteraction(Character.None, "Thank you for playing!"),
}
},
// ==============
{ Dialogue.Intro,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.None, "[This game automatically saves your progress.]"),
new DialogueInteraction(Character.You, "Phew...") {
backgroundIndex = 0, // Manager BG, afternoon
musicClipIndex = 0,
},
new DialogueInteraction(Character.None, "Another hard day's work."),
new DialogueInteraction(Character.None, "It's getting tiresome working this remote gig day after day..."),
new DialogueInteraction(Character.None, "But at least it pays the bills - and with no commute."),
new DialogueInteraction(Character.None, "Today was about to be like any other, but just as you're getting up to shower..."),
new DialogueInteraction(Character.None, "*ring ring ring*") {
audioClipIndex = 0,
},
new DialogueInteraction(Character.None, "A ring on the phone. It's... Wow.") {
backgroundIndex = 1, // View of phone, maybe
},
new DialogueInteraction(Character.You, "I haven't heard from this bitch in months."),
new DialogueInteraction(Character.You, "And it's been years since she called for anything other than favors."),
new DialogueInteraction(Character.You, "Maybe I'll just let it ring for once."),
new DialogueInteraction(Character.None, "...") {
audioClipIndex = 0,
},
new DialogueInteraction(Character.You, "....."),
new DialogueInteraction(Character.You, "Well, she's usually in pretty hot water whenever she calls..."),
new DialogueInteraction(Character.You, "This had better be important.") {
audioClipIndex = 1, // Pick up phone noise
},
new DialogueInteraction(Character.You, "Hello?"),
new DialogueInteraction(Character.Her, "Hey? Hey?! It's %Her%. This is still your number, right? I need some help here!"),
new DialogueInteraction(Character.You, "Ugh... Is it always favors with you? When was the last time you called to say hi?"),
new DialogueInteraction(Character.Her, "Bitch, HI. Now listen!"),
new DialogueInteraction(Character.Her, "You know these guys I said I'd move in with? Jeanine and Carly?"),
new DialogueInteraction(Character.You, "...Who? You haven't told me shit since high school!"),
new DialogueInteraction(Character.Her, "Okay, well I've been dealing with these losers for almost a year."),
new DialogueInteraction(Character.Her, "These fuckers said I'm out in an hour! Jeanine pawned off all my shit, talking about \"paying rent\"."),
new DialogueInteraction(Character.Her, "That bitch knows I lost my damn job! How am I supposed to pay rent? I can't even afford food!"),
new DialogueInteraction(Character.You, "....."),
new DialogueInteraction(Character.Her, "...Hello? Are you listening?!"),
new DialogueInteraction(Character.None, "This bitch..."),
new DialogueInteraction(Character.You, "Just get another job and pay them back. What's the big deal?"),
new DialogueInteraction(Character.Her, "You don't think I've tried that already?"),
new DialogueInteraction(Character.Her, "These retail managers have lost their damn mind! I got fired three times this month and I've had it."),
new DialogueInteraction(Character.Her, "It's always... nebatism with them."),
new DialogueInteraction(Character.You, "You mean \"nepotism,\" right?"),
new DialogueInteraction(Character.Her, "Shut up."),
new DialogueInteraction(Character.None, "What does this lady look like again? You haven't seen her face in years."),
new DialogueInteraction(Character.None, "You check out her FaceNovel account... Somehow she hasn't been banned yet. She posts dogshit about every job she's ever had.") {
backgroundIndex = 2, // Cell phone with sexy photo of her
},
new DialogueInteraction(Character.None, "...Damn, she's hot now."),
new DialogueInteraction(Character.Her, "Hello?"),
new DialogueInteraction(Character.Her, "Look, can I just stay with you? Please? I'll do anything!"),
new DialogueInteraction(Character.You, "Anything, huh..."),
new DialogueInteraction(Character.None, "Maybe there's some value here after all. When was the last time you got some action?"),
new DialogueInteraction(Character.None, "Looks-wise, she's way out of your league. But when she's this trashy, she probably wouldn't have any options among dudes."),
new DialogueInteraction(Character.None, "And even if she doesn't put out, it'd be useful to have some help around the house..."),
new DialogueInteraction(Character.Her, "...Please?"),
new DialogueInteraction(Character.You, "Mmm... Fine. Text me the address and I'll pick you up. But--"),
new DialogueInteraction(Character.Her, "YES!!"),
new DialogueInteraction(Character.You, "Hey! My house has a few ground rules. And you're gonna follow them."),
new DialogueInteraction(Character.Her, "Yeah, okay, whatever. I'm texting the address now."),
new DialogueInteraction(Character.None, "*bzzt*") {
audioClipIndex = 2, // Phone hang up noise
},
new DialogueInteraction(Character.None, "She abruptly hangs up on you, and a single text with an address pops up soon after."),
new DialogueInteraction(Character.None, "At least her friends live pretty close."),
new DialogueInteraction(Character.None, "Ten minutes of driving later, you roll up to the spot.") {
backgroundIndex = 3, // Driving
},
new DialogueInteraction(Character.None, "It's a run-down duplex in the seedy part of town."),
new DialogueInteraction(Character.None, "As soon as you pull up, you notice some seedy shit going down in the house."),
new DialogueInteraction(Character.OldRoommate, "Get the fuck out!!!") {
audioClipIndex = 3, // Wham
},
new DialogueInteraction(Character.Her, "Ough!"),
new DialogueInteraction(Character.None, "The front door flies open and %Her% gets her ass booted right through it, falling onto the wooden front porch."),
new DialogueInteraction(Character.None, "The window opens soon after, and someone hurls a backpack out of it, landing halfway down the front yard."),
new DialogueInteraction(Character.None, "%Her% slowly gets up and meanders over to the backpack, stuffing the strewn contents back into it."),
new DialogueInteraction(Character.None, "She saunters over to your car, swings the passenger door open, and hops in, shutting it and crossing her arms silently."),
new DialogueInteraction(Character.You, "...Damn."),
new DialogueInteraction(Character.None, "You rev the car in neutral to pay respects. That was some grade-A drama."),
new DialogueInteraction(Character.None, "Wait... Has she eaten recently? She did mention not being able to afford food on the phone."),
new DialogueInteraction(Character.None, "...") {
backgroundIndex = 4, // Car body shot
},
new DialogueInteraction(Character.None, "But damn... They really did sell off all her clothes. Just some tattered undies remain."),
new DialogueInteraction(Character.None, "It looks-- and smells-- like she hasn't changed them in weeks."),
new DialogueInteraction(Character.None, "She's coated in sweat, making her tube top a bit see-through. This bitch is looking crazy right now..."),
new DialogueInteraction(Character.None, "Not a bad view, though."),
new DialogueInteraction(Character.None, "Anyways, even if she's not hungry, you are."),
new DialogueInteraction(Character.You, "Let's get Bubuu's.") {
backgroundIndex = 5, // Black screen
},
new DialogueInteraction(Character.None, "During the ride home, you lay out the ground rules for %Her% to follow."),
new DialogueInteraction(Character.None, "First of all, you're the boss. Effectively you're her new owner.") {
backgroundIndex = 6, // Just rule 1
},
new DialogueInteraction(Character.None, "You've got a good rep at work to maintain, after all. Can't have some hussy wrecking your home and jeopardizing your job."),
new DialogueInteraction(Character.None, "Second... No going out at late night.") {
backgroundIndex = 7, // Rules 1 and 2
},
new DialogueInteraction(Character.None, "This one took some convincing, but it's non-negotiable."),
new DialogueInteraction(Character.None, "After seeing those FaceNovel posts, and knowing her money-wasting habits, letting her go on nightly escapades is a huge risk."),
new DialogueInteraction(Character.None, "Besides, when she heard about all the games and booze you have at home, she felt better about being a stay-homer."),
new DialogueInteraction(Character.None, "Finally, no smartphone or laptop.") {
backgroundIndex = 8, // All three rules
},
new DialogueInteraction(Character.None, "That other bitch already pawned off her smartphone, so you bought her a flippy phone on the way home."),
new DialogueInteraction(Character.None, "She can text and make calls all day if she wants to, but her Internet access has to be restricted and monitored."),
new DialogueInteraction(Character.None, "Otherwise, she'd just spend all that time trolling online, and given her FaceNovel posts... That's a safety risk."),
new DialogueInteraction(Character.None, "Anyways, you arrive back at the pound and walk her in. She tosses her backpack aside and starts admiring the place.") {
backgroundIndex = 9, // ManagerBG, evening
},
new DialogueInteraction(Character.None, "It's a little one-bedroom house on a quiet block. Not too much, not too little. It's comfortable."),
new DialogueInteraction(Character.Her, "Damn dude - you've been living like this? I shoulda gotten my ass over here months ago!") {
showBody = true,
bodyOverride = Body.Undies,
hairOverride = Hair.Messy,
expression = Expression.Happy,
},
new DialogueInteraction(Character.You, "It's no mansion, but I make it work. And hey..."),
new DialogueInteraction(Character.You, "As long as you're staying here, you're the one keeping the place clean. Got it?"),
new DialogueInteraction(Character.Her, "Uhh-- Yeah, okay...") {
expression = Expression.Neutral
},
new DialogueInteraction(Character.You, "Anyways, the restroom is over there. Go get situated."),
new DialogueInteraction(Character.Her, "...I don't have to take a dump yet, man.") {
expression = Expression.Angry
},
new DialogueInteraction(Character.You, "I mean go take a shower! You smell like shit!"),
new DialogueInteraction(Character.None, "She takes a moment to sniff herself before scoffing and reaching between her breasts and pulling out a french fry.") {
expression = Expression.Neutral
},
new DialogueInteraction(Character.None, "...Wait, what?"),
new DialogueInteraction(Character.Her, "I smell just fine. Now show me around!"),
new DialogueInteraction(Character.Her, "I wanna see all the porn under your bed and--"),
new DialogueInteraction(Character.Her, "Oh!!") {
expression = Expression.Angry,
effect = DialogueEffect.Bounce,
},
new DialogueInteraction(Character.None, "You firmly poke her boob. Another french fry falls out, settling on the floor."),
new DialogueInteraction(Character.You, "I told you to go shower. Now."),
new DialogueInteraction(Character.You, "You're going on the street if you're gonna stink up my house."),
new DialogueInteraction(Character.None, "She looks at you incredulously for a second, but her expression softens when she realizes you're serious."),
new DialogueInteraction(Character.Her, "...Fine.") {
expression = Expression.Neutral
},
new DialogueInteraction(Character.None, "Without even looking away, she pulls off her top and lets her rack fall out right in front of you.") {
removeBody = true,
backgroundIndex = 10, // Pulling top off POV
},
new DialogueInteraction(Character.None, "Then she starts pulling down her panties. You avert your gaze instinctively, unsure of what she's thinking."),
new DialogueInteraction(Character.None, "Now fully naked, she silently walks off to the restroom, leaving the door open. Her dirty underwear remains at your feet."),
new DialogueInteraction(Character.None, "...This thing smells CRAZY.") {
backgroundIndex = 11, // Panties in hand
},
new DialogueInteraction(Character.None, "If this weren't her only pair, you'd probably hold onto it."),
new DialogueInteraction(Character.None, "Maybe you can buy her some new sets and keep these in a box somewhere."),
new DialogueInteraction(Character.None, "Or even sell them online... How much are dirty panties worth these days?"),
new DialogueInteraction(Character.None, "Anyways, you set them in the wash and put out an oversized tee for her to wear in the meantime.") {
backgroundIndex = 5, // Black screen
},
new DialogueInteraction(Character.None, "You go to your desk to check up on some e-mails."),
new DialogueInteraction(Character.None, "Half an hour later, %Her% walks in..."),
}
},
};
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: eff13e1292a9f5f428aba5afb6073dcd
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,190 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public partial class VNDataScripts {
public static Dictionary<Dialogue, List<DialogueInteraction>>
MANAGER_SCRIPTS = new Dictionary<Dialogue, List<DialogueInteraction>>() {
// ==============
{ Dialogue.Manager_Default,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, "So... What do we do now?") {
audioClipIndex = 0,
showBody = true,
expression = Expression.Neutral
},
}
},
{ Dialogue.Manager_Default2,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, "Need anything?") {
audioClipIndex = 1,
showBody = true,
expression = Expression.Neutral
},
}
},
{ Dialogue.Manager_Default3,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, "I'm bored. Can we fuck or something?") {
audioClipIndex = 2,
showBody = true,
expression = Expression.Angry
},
}
},
// ==============
{ Dialogue.Manager_Boutique,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, "Eugh... I hate window shopping.") {
backgroundIndex = 3,
showBody = true,
expression = Expression.Angry
},
new DialogueInteraction(Character.You, "We're not window shopping. I'm gonna get you a new outfit."),
new DialogueInteraction(Character.You, "We could use it at the studio.") {
expression = Expression.Neutral
},
new DialogueInteraction(Character.Her, "Oh, that's fine then."),
new DialogueInteraction(Character.Her, "Just make sure I look pretty."),
}
},
{ Dialogue.Manager_Salon,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, "Isn't my hairdo fine as-is?") {
backgroundIndex = 4,
showBody = true,
expression = Expression.Angry
},
new DialogueInteraction(Character.You, "I guess so."),
new DialogueInteraction(Character.You, "But we'd make a lot more cash at the studio if we switch things up.") {
expression = Expression.Neutral
},
new DialogueInteraction(Character.Her, "Hmm...") {
expression = Expression.Angry
},
new DialogueInteraction(Character.Her, "Fine. Make it quick."),
}
},
{ Dialogue.Manager_Diner,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, "Ough... Finally. I'm starving.") {
showBody = false,
},
new DialogueInteraction(Character.None, "What would you like to order?") {
showBody = false,
},
}
},
// ==============
{ Dialogue.Manager_Farty1,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, "Hoo... I'm feelin' farty today.") {
audioClipIndex = 8,
showBody = true,
expression = Expression.Angry
},
}
},
{ Dialogue.Manager_Farty2,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, "Ouuunnngh... My tummys goin' crazy.") {
audioClipIndex = 9,
showBody = true,
expression = Expression.Angry
},
}
},
{ Dialogue.Manager_Farty3,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, "You might wanna hold your breath for a while. Heheheh... Nngh.") {
audioClipIndex = 10,
showBody = true,
expression = Expression.Angry
},
}
},
{ Dialogue.Manager_Farty4,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, "Ouuuuugh~! Ugh, that was wet! Hahahaheh!") {
audioClipIndex = 11,
showBody = true,
expression = Expression.Happy
},
}
},
{ Dialogue.Manager_Farty5,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, "*Urrrp* Whoo!") {
audioClipIndex = 0,
showBody = true,
expression = Expression.Happy
},
}
},
{ Dialogue.Manager_Farty6,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, "Ahhn~") {
audioClipIndex = 10,
showBody = true,
expression = Expression.Neutral
},
}
},
// ==============
{ Dialogue.Manager_Hungry1,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, "Hey, dude. I'm hungry. You know what to do.") {
showBody = true,
expression = Expression.Angry
},
}
},
// ==============
{ Dialogue.Manager_BoughtFood1,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, "Yummy time!") {
showBody = false,
expression = Expression.Happy
},
}
},
// ==============
{ Dialogue.Manager_Moody1,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, "Hmph.") {
showBody = true,
expression = Expression.Angry
},
}
},
{ Dialogue.Manager_Moody2,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, "I'm not talking to you right now.") {
showBody = true,
expression = Expression.Angry
},
}
},
// ==============
{ Dialogue.Manager_RanAway,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.You, "Hey, you... What happened to the cash in my wallet?") {
showBody = true,
expression = Expression.Angry
},
new DialogueInteraction(Character.Her, "What do you think happened? You haven't fed me in forever, dipshit."),
new DialogueInteraction(Character.Her, "I took a cab and got some grub."),
new DialogueInteraction(Character.Her, "Steak and lobster. And oysters. And a sundae. Yummy!") {
expression = Expression.Happy
},
new DialogueInteraction(Character.You, "(This bitch...)"),
new DialogueInteraction(Character.You, "(I guess it's partly my fault. I should order food more often.)"),
new DialogueInteraction(Character.You, "(If I don't, she'll probably go for my credit card next.)")
{
expression = Expression.Neutral
},
}
},
};
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 611085159013ad34cb305d1010adea65
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,156 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public partial class VNDataScripts {
public static Dictionary<Dialogue, List<DialogueInteraction>>
SPECIAL_SCRIPTS = new Dictionary<Dialogue, List<DialogueInteraction>>() {
// ==============
{ Dialogue.Special_OnlyFarts,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.Her, ".....") {
musicClipIndex = 0,
audioClipIndex = 0, // Chewing
backgroundIndex = 0, // Black screen
},
new DialogueInteraction(Character.Her, "Mlaehhhhh... *gulp*") {
backgroundIndex = 1, // Panel 1
audioClipIndex = 1,
},
new DialogueInteraction(Character.None, "%Her% wanted to record a special ASMR video for all her adoring fans online-- alone."),
new DialogueInteraction(Character.None, "You figured the idea's harmless enough, so you lent her a couple microphones and left to go shopping."),
new DialogueInteraction(Character.None, "You even bought her some takeout to keep her happy while you were gone. How thoughtful."),
new DialogueInteraction(Character.Her, "..........") {
audioClipIndex = 2, // Gross chewing
},
new DialogueInteraction(Character.None, "Looks like that meal really came in handy for her film."),
new DialogueInteraction(Character.Her, "Ungh... Peh. *slurp*") {
audioClipIndex = 3, // Spit, chew, swallow
},
new DialogueInteraction(Character.Her, "..............") {
audioClipIndex = 4, // More chewing
},
new DialogueInteraction(Character.Her, "Ough-- Uh oh... Here it comes.") {
audioClipIndex = 5,
},
new DialogueInteraction(Character.Her, "Nnnngh!") {
backgroundIndex = 2, // Panel 2 (farting)
audioClipIndex = 6,
},
new DialogueInteraction(Character.Her, "Hahahahah! So gross... Feels great to let loose, though.") {
audioClipIndex = 7,
},
new DialogueInteraction(Character.Her, ".......") {
audioClipIndex = 8, // More chewing
},
new DialogueInteraction(Character.Her, "..............") {
audioClipIndex = 9, // More chewing
},
new DialogueInteraction(Character.Her, "Aeeeegggh!") {
backgroundIndex = 3, // Farting (wet)
audioClipIndex = 10,
},
new DialogueInteraction(Character.Her, "Oh, fuck- that was wet!") {
audioClipIndex = 11,
},
new DialogueInteraction(Character.Her, "Oohff.... I think I'm shitting... Ungh...") {
audioClipIndex = 12,
},
new DialogueInteraction(Character.Her, "Ohhhhh.....!") {
backgroundIndex = 4, // Messing
audioClipIndex = 13,
},
new DialogueInteraction(Character.Her, "Hahaha... I definitely shit myself.") {
audioClipIndex = 14,
},
new DialogueInteraction(Character.Her, "That's... gonna be it for now. I need to go clean up.") {
audioClipIndex = 15,
},
new DialogueInteraction(Character.Her, "Bye-bye...") {
audioClipIndex = 15,
backgroundIndex = 0, // Black screen
},
new DialogueInteraction(Character.You, "..."),
new DialogueInteraction(Character.You, "(Is this bitch for real?)"),
}
},
// ==============
{ Dialogue.Special_HappyBirthday,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.You, "Are you sure that guy is gonna like this?") {
musicClipIndex = 0,
backgroundIndex = 0, // Black screen
},
new DialogueInteraction(Character.Her, "Sure I'm sure. It's my top sub, dude. He'd chop his balls off if I said it'd be cute.") {
backgroundIndex = 1,
audioClipIndex = 0,
},
new DialogueInteraction(Character.You, "That's... kind of sad, really."),
new DialogueInteraction(Character.You, "But hey- not my problem. Let's just get this over with."),
new DialogueInteraction(Character.You, "Action!"),
new DialogueInteraction(Character.Her, "Hey, hot stuff... You didn't think I'd forget your birthday, did you?") {
audioClipIndex = 1,
},
new DialogueInteraction(Character.Her, "Well, I've got a present just for you. I'm making it myself... Ungh...") {
audioClipIndex = 2,
},
new DialogueInteraction(Character.Her, "It's about a pound of cake and honey boba, fresh from my shitter.") {
audioClipIndex = 3,
},
new DialogueInteraction(Character.Her, "Right into these cute panties you bought me. Aren't you happy?") {
audioClipIndex = 4,
},
new DialogueInteraction(Character.Her, "I think it's about ready to come out... Watch real close, now.") {
backgroundIndex = 2,
audioClipIndex = 5,
},
new DialogueInteraction(Character.None, "She turns around and shoves her ass in the camera."),
new DialogueInteraction(Character.None, "She's been farting like crazy for the last half hour, so the room already stinks..."),
new DialogueInteraction(Character.None, "But the smell from up close is ferocious. And it's about to get a whole lot worse."),
new DialogueInteraction(Character.Her, "Nnggh..... Ough....") {
backgroundIndex = 3,
audioClipIndex = 6,
},
new DialogueInteraction(Character.None, "A small lump starts to form right where her asshole was pressing up against her bikini panties."),
new DialogueInteraction(Character.Her, "Oh... It's all buttery.") {
audioClipIndex = 7,
},
new DialogueInteraction(Character.Her, "......") {
audioClipIndex = 8,
},
new DialogueInteraction(Character.None, "She starts to flex her rear end, but the lump isn't really getting any bigger."),
new DialogueInteraction(Character.Her, "It's not... coming out... Ough...") {
audioClipIndex = 9,
},
new DialogueInteraction(Character.None, "Suddenly she hunkers down and really starts to push."),
new DialogueInteraction(Character.Her, "Ohhhhhghhhhh! Nngh!") {
backgroundIndex = 4,
audioClipIndex = 10,
},
new DialogueInteraction(Character.Her, "Ahh... Nngh! All better.") {
backgroundIndex = 5,
audioClipIndex = 11,
},
new DialogueInteraction(Character.Her, "!! Oh, that is GROSS. Hahahahahah!") {
audioClipIndex = 12,
},
new DialogueInteraction(Character.Her, "I'm gona ship these panties back to you now. Enjoy the creme filling.") {
audioClipIndex = 13,
},
new DialogueInteraction(Character.Her, "Happy birthday, loser!") {
audioClipIndex = 14,
},
new DialogueInteraction(Character.None, "...") {
backgroundIndex = 0,
},
new DialogueInteraction(Character.You, "...Cut."),
new DialogueInteraction(Character.You, "Damn it, that smells! My room's gonna stink for days."),
new DialogueInteraction(Character.You, "We really should've filmed in the bathroom."),
new DialogueInteraction(Character.Her, "It'll be fine, I think... Go get a box and some wrapping paper so we can mail this shit out.") {
audioClipIndex = 15,
},
new DialogueInteraction(Character.You, "With pleasure. Take that outfit off and go shower..."),
}
},
};
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 2d7216f38b3bf5145a54f43973d14c90
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,271 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public partial class VNDataScripts {
public static Dictionary<Dialogue, List<DialogueInteraction>>
TASK_SCRIPTS = new Dictionary<Dialogue, List<DialogueInteraction>>() {
{ Dialogue.Task_Clean1,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.You, "Just go clean the house or something.") {
backgroundIndex = 0,
showBody = true,
expression = Expression.Neutral,
},
new DialogueInteraction(Character.Her, "...") {
expression = Expression.Angry,
},
new DialogueInteraction(Character.None, "She saunters off to take care of some basic chores.") {
removeBody = true,
backgroundIndex = 1,
},
new DialogueInteraction(Character.None, "Let's leave her alone for a while. Maybe I can get some extra work done."),
}
},
// =====
{ Dialogue.Task_Clean2,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.You, "What do we have here?"),
new DialogueInteraction(Character.Her, "...") {
backgroundIndex = 0,
},
new DialogueInteraction(Character.None, "Looks like she's doing the laundry like I asked."),
new DialogueInteraction(Character.None, "What a nice view... Let's cop a quick feel."),
new DialogueInteraction(Character.None, "*Slap!*") {
backgroundIndex = 1,
},
new DialogueInteraction(Character.Her, "Ungh-- What the fuck!"),
new DialogueInteraction(Character.You, "Heh, heh..."),
new DialogueInteraction(Character.Her, "Urgh..."),
new DialogueInteraction(Character.None, "You walk away and leave her to finish up those chores."),
}
},
// =====
{ Dialogue.Task_Games1,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.None, "*Bwip, bwip bwip, bwip*"),
new DialogueInteraction(Character.Her, "Hahahahaha! Get shit on!!") {
backgroundIndex = 0,
audioClipIndex = 0,
showBody = true,
expression = Expression.Happy,
},
new DialogueInteraction(Character.You, "Urk-..."),
new DialogueInteraction(Character.None, "Damn. No one told me she was this good at fighters."),
new DialogueInteraction(Character.None, "I'm getting my ass whooped."),
new DialogueInteraction(Character.Her, "Hrk-hrk-hrk-hrk-hrk--") {
audioClipIndex = 1,
effect = DialogueEffect.Bounce,
},
new DialogueInteraction(Character.None, "..."),
new DialogueInteraction(Character.None, "Well, at least she's having fun."),
}
},
// =====
{ Dialogue.Task_Games2,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.None, "We're playing some sort of fighting game together..."),
new DialogueInteraction(Character.None, "But this time, I'm winning."),
new DialogueInteraction(Character.Her, "Ungh-- What the hell, you're CHEATING! You're fucking cheating AGAIN!") {
backgroundIndex = 0,
audioClipIndex = 0,
},
new DialogueInteraction(Character.You, "Woman, I am not cheating! How the fuck can I cheat? We're using the same character!"),
new DialogueInteraction(Character.Her, "Nuh-uh! You picked the paralysis perk, piece of shit!") {
audioClipIndex = 1,
},
new DialogueInteraction(Character.You, "We picked the same perk!"),
new DialogueInteraction(Character.Her, "Well, you know how to use it and I don't!") {
audioClipIndex = 2,
},
new DialogueInteraction(Character.You, "Then why the fuck did you pick it?!"),
new DialogueInteraction(Character.Her, "Because you picked it!") {
audioClipIndex = 3,
},
new DialogueInteraction(Character.None, "---"),
new DialogueInteraction(Character.None, "Maybe we should just play a different game."),
}
},
// =====
{ Dialogue.Task_RockOut,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.None, "Dunununu nununununu nunununu--") {
//musicClipIndex = 0,
},
new DialogueInteraction(Character.You, "EEEEYYAAAAAAAAAAAAAARRRRRR!!!"),
new DialogueInteraction(Character.Her, "MUTHAFUUUUUUUUUCKAAAAAAAA") {
backgroundIndex = 0,
audioClipIndex = 0,
},
new DialogueInteraction(Character.You, "UNH! UNH! UNH! UNH! RRRRRRRAAAAAAHHHH!!"),
new DialogueInteraction(Character.Her, "RAH!! RAH!! RAH!! RAH!! RAH!! RAH!! RAH!! RAH!! RAH!! RAH!! RAH!! RAH!!") {
audioClipIndex = 1,
},
new DialogueInteraction(Character.You, "FUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUUCK!!!"),
new DialogueInteraction(Character.None, "Good thing the neighbors aren't home."),
}
},
// =====
{ Dialogue.Task_Suck1,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.You, "--Augh! Quit biting, that hurts!"),
new DialogueInteraction(Character.Her, "-- -- -- -- --.. --.. -- --") {
backgroundIndex = 0,
audioClipIndex = 0,
},
new DialogueInteraction(Character.Her, "Aeh... I've never done this shit before, man. Gimme a break.") {
audioClipIndex = 1,
},
new DialogueInteraction(Character.You, "You're gonna chomp my dick off!"),
new DialogueInteraction(Character.You, "You need to relax your jaw."),
new DialogueInteraction(Character.Her, "Hrmm.") {
audioClipIndex = 2,
},
new DialogueInteraction(Character.Her, "~~. ~~.. ~~.. ~~.. ~~.. ~~.. ~~.. ~~") {
backgroundIndex = 1,
audioClipIndex = 3,
},
new DialogueInteraction(Character.None, "Hmm..."),
new DialogueInteraction(Character.None, "Well, this feels a little better. I can finish at this rate."),
new DialogueInteraction(Character.You, "Hrk--!"),
new DialogueInteraction(Character.Her, "--! --! --! --! --! --!") {
backgroundIndex = 2,
audioClipIndex = 4,
},
new DialogueInteraction(Character.Her, "~~--!! //! Ouuugf! Dude, gimme a warning before you do that.") {
backgroundIndex = 3,
audioClipIndex = 5,
},
new DialogueInteraction(Character.You, "Phew..."),
new DialogueInteraction(Character.None, "That wasn't too bad."),
}
},
// =====
{ Dialogue.Task_Suck2,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.None, "..."),
new DialogueInteraction(Character.You, "Heh... You okay down there?"),
new DialogueInteraction(Character.Her, "~~.. ~~, ~~, ~~, ~~, ~~...") {
backgroundIndex = 0,
audioClipIndex = 0,
},
new DialogueInteraction(Character.Her, "Eggh... You really need to wash this thing. *Cough*") {
audioClipIndex = 1,
},
new DialogueInteraction(Character.You, "Why should I? I've got you right here to clean it off."),
new DialogueInteraction(Character.Her, "...Gross piece of shit.") {
audioClipIndex = 2,
},
new DialogueInteraction(Character.You, "Get back to work."),
new DialogueInteraction(Character.Her, "~-... --... --... --... -- -- --") {
audioClipIndex = 3,
},
new DialogueInteraction(Character.You, "Come on, use your tongue more."),
new DialogueInteraction(Character.Her, "~~, ~~, ~~, ~~, ~~, ~~, ~~") {
audioClipIndex = 4,
},
new DialogueInteraction(Character.Her, "~~! ~~! ~~! ~~! ~~! ~~! ~~!") {
audioClipIndex = 5,
},
new DialogueInteraction(Character.None, "Urk-- It's comin' early!"),
new DialogueInteraction(Character.Her, "!!... //... //... //...") {
backgroundIndex = 1,
audioClipIndex = 6,
},
new DialogueInteraction(Character.Her, "Nngh... *Cough*") {
audioClipIndex = 7,
},
new DialogueInteraction(Character.Her, "Are we done here? I wanna play Monster Punter.") {
audioClipIndex = 8,
},
new DialogueInteraction(Character.You, "Phew... Yep, that'll do."),
new DialogueInteraction(Character.You, "Go take a shower before any games, though."),
new DialogueInteraction(Character.Her, "...") {
audioClipIndex = 9,
},
}
},
// =====
{ Dialogue.Task_Suck3,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.None, "..."),
new DialogueInteraction(Character.None, "Goodness gracious..."),
new DialogueInteraction(Character.Her, "~~.. ~~, ~~, ~~, ~~, ~~...") {
backgroundIndex = 0,
audioClipIndex = 0,
},
new DialogueInteraction(Character.Her, "Ngahh... ~~, ~~, ~~, ~~, ~~, ~~...") {
audioClipIndex = 1,
},
new DialogueInteraction(Character.None, "She's become a real pro at this."),
new DialogueInteraction(Character.Her, "~~, ~~, ~~-- *Urrp* ~~, ~~, ~~...") {
audioClipIndex = 2,
},
new DialogueInteraction(Character.Her, "~~, ~~, ~~, ~~, ~~, ~~, ~~") {
audioClipIndex = 3,
},
new DialogueInteraction(Character.Her, "~~! ~~! ~~! ~~! ~~! ~~! ~~!") {
audioClipIndex = 4,
},
new DialogueInteraction(Character.None, "Whoa Nelly!"),
new DialogueInteraction(Character.Her, "!!... //... //... //...") {
audioClipIndex = 5,
},
new DialogueInteraction(Character.Her, "Ough... *Cough*") {
audioClipIndex = 6,
},
new DialogueInteraction(Character.Her, "Hoo... How was that?") {
audioClipIndex = 7,
},
new DialogueInteraction(Character.You, "Whoo! Yep, that was just about perfect."),
new DialogueInteraction(Character.You, "Thanks babe."),
new DialogueInteraction(Character.Her, "...Uh-huh.") {
audioClipIndex = 8,
},
}
},
// =====
{ Dialogue.Task_SuckCosplay,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.None, "Well, here we are - back at it again with another blowjob."),
new DialogueInteraction(Character.None, "But this time..."),
new DialogueInteraction(Character.None, "She's looking awfully cute while doing it.") {
backgroundIndex = 0,
},
new DialogueInteraction(Character.Her, "Nrrgh.") {
audioClipIndex = 0,
},
new DialogueInteraction(Character.You, "Come on, you look adorable. Now let's get going."),
new DialogueInteraction(Character.Her, "~~.. ~~, ~~, ~~, ~~, ~~...") {
audioClipIndex = 1,
},
new DialogueInteraction(Character.Her, "~~, ~~, ~~, ~~, ~~, ~~~, ~~, ~~~, ~~...") {
audioClipIndex = 2,
},
new DialogueInteraction(Character.You, "Jeez... Ha... That feels good."),
new DialogueInteraction(Character.Her, "~~-- ~~... ~~, ~~, ~~, ~~...") {
audioClipIndex = 3,
},
new DialogueInteraction(Character.Her, "~~! ~~! ~~! ~~! ~~! ~~! ~~! ~~...") {
audioClipIndex = 4,
},
new DialogueInteraction(Character.None, "That's it-- it's bustin' time!"),
new DialogueInteraction(Character.Her, "!! //! //! //! //! //! //...") {
audioClipIndex = 5,
},
new DialogueInteraction(Character.None, "Hoo-wee! Make sure you swallow it all."),
new DialogueInteraction(Character.Her, "~~//... //... //, //, //...") {
audioClipIndex = 6,
},
new DialogueInteraction(Character.Her, "Eugh... --... *Cough*") {
audioClipIndex = 7,
},
new DialogueInteraction(Character.Her, "Mmaahh... All gone.") {
audioClipIndex = 8,
},
new DialogueInteraction(Character.None, "Damn."),
new DialogueInteraction(Character.None, "This is the life..."),
}
},
};
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 33805e854f9c87e4fb7c93678965c83e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,261 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public partial class VNDataScripts {
public static Dictionary<Dialogue, List<DialogueInteraction>>
TASK_SCRIPTS2 = new Dictionary<Dialogue, List<DialogueInteraction>>() {
{ Dialogue.Task_Photos1,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.None, "*snap* *snap* *snap*...") {
backgroundIndex = 0,
},
new DialogueInteraction(Character.Her, "Theres no way this shit would sell, dude. Who would just want pictures?") {
audioClipIndex = 0,
},
new DialogueInteraction(Character.You, "Gotta start small. Ill put these out there to build a following."),
new DialogueInteraction(Character.You, "Well make more exciting content once theres an audience for it and believe me, theyre out there."),
new DialogueInteraction(Character.You, "Besides, you look cute in these photos."),
new DialogueInteraction(Character.None, "She pauses and blushes a little."),
new DialogueInteraction(Character.Her, "*Scoff*... Well, fine. If you say so.") {
backgroundIndex = 1,
audioClipIndex = 1,
},
new DialogueInteraction(Character.None, "*snap* *snap* *snap*..."),
}
},
// =====
{ Dialogue.Task_Photos2,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.None, "This time, we've got some vids to film for her OnlyFarts account."),
new DialogueInteraction(Character.None, "*snap* *snap* *snap*...") {
backgroundIndex = 0,
},
new DialogueInteraction(Character.Her, "I dont get it. He really just wants a closeup of me flexing my pooper?") {
audioClipIndex = 0,
},
new DialogueInteraction(Character.You, "...Can you not call it that?"),
new DialogueInteraction(Character.Her, "Everyone knows what goes on down there.") {
audioClipIndex = 1,
},
new DialogueInteraction(Character.Her, "Besides, what about all those titty pics we just took? Cant we just give him that set?") {
audioClipIndex = 2,
},
new DialogueInteraction(Character.You, "Some clients know exactly what they want. Just be glad they were specific this time."),
new DialogueInteraction(Character.You, "Its all just poses anyway. Whats the difference to you?"),
new DialogueInteraction(Character.Her, "The difference is that showing my tits off doesnt make me have to fart.") {
audioClipIndex = 3,
},
new DialogueInteraction(Character.Her, "Hurry up and start recording before I make you regret it.") {
audioClipIndex = 4,
},
new DialogueInteraction(Character.You, "...Action."),
new DialogueInteraction(Character.None, "*snap* *snap* *snap*..."),
}
},
// =====
{ Dialogue.Task_Photos3,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.You, "Action!"),
new DialogueInteraction(Character.None, "*snap* *snap* *snap*...") {
backgroundIndex = 0,
},
new DialogueInteraction(Character.Her, "Hey, big boy… Thanks for buying another custom photoset.") {
audioClipIndex = 0,
},
new DialogueInteraction(Character.Her, "Heres a little bonus just for you.") {
audioClipIndex = 1,
},
new DialogueInteraction(Character.None, "She spreads wide open right in front of the camera, showing off for her anonymous client."),
new DialogueInteraction(Character.None, "This clients one of our regulars, and always pays through the nose for her pics."),
new DialogueInteraction(Character.Her, "Heheh... *giggle* Ahnn...") {
audioClipIndex = 2,
},
new DialogueInteraction(Character.None, "Were in for a big tip this time…"),
}
},
// =====
{ Dialogue.Task_Cosplay,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.None, "*snap* *snap* *snap*...") {
backgroundIndex = 0,
},
new DialogueInteraction(Character.None, "Wearing a sexy business uniform, she takes up a haughty posture."),
new DialogueInteraction(Character.You, "Thats perfect, hold that pose."),
new DialogueInteraction(Character.Her, "Rnngh...") {
audioClipIndex = 0,
},
new DialogueInteraction(Character.Her, "I cant believe dudes online want to see this shit.") {
audioClipIndex = 1,
},
new DialogueInteraction(Character.Her, "This outfit just reminds me of my mom.") {
audioClipIndex = 2,
},
new DialogueInteraction(Character.Her, "...Stuck-up bitch.") {
audioClipIndex = 3,
},
new DialogueInteraction(Character.None, "*snap* *snap* *snap*..."),
new DialogueInteraction(Character.Her, "Are you even listening?") {
audioClipIndex = 4,
},
new DialogueInteraction(Character.You, "Honestly, not really. But your vibe right now is perfect for these photos."),
new DialogueInteraction(Character.You, "Pull up the skirt a little."),
new DialogueInteraction(Character.Her, "RRRGGH!") {
audioClipIndex = 5,
},
new DialogueInteraction(Character.None, "Slightly embarrassed, she bundles the pencil skirt up as she shifts posture."),
new DialogueInteraction(Character.None, "Some luxurious panties peek out from underneath."),
new DialogueInteraction(Character.You, "Bingo. This photo set is gonna make a killing."),
new DialogueInteraction(Character.Her, "You better be right.") {
audioClipIndex = 6,
},
new DialogueInteraction(Character.None, "*snap* *snap* *snap*..."),
}
},
// =====
{ Dialogue.Task_Fuck1,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.None, "Heh...") {
backgroundIndex = 0,
},
new DialogueInteraction(Character.You, "Looking good up there."),
new DialogueInteraction(Character.Her, "Shut up.") {
audioClipIndex = 0,
},
new DialogueInteraction(Character.Her, "I havent fked anyone in a while, so…") {
audioClipIndex = 1,
},
new DialogueInteraction(Character.Her, "Just tell me if it hurts.") {
audioClipIndex = 2,
},
new DialogueInteraction(Character.None, "She slowly lowers herself onto your member."),
new DialogueInteraction(Character.You, "Ahh..."),
new DialogueInteraction(Character.Her, "~~-- ~~... ~~, ~~, ~~, ~~...") {
audioClipIndex = 3,
},
new DialogueInteraction(Character.Her, "~~! ~~! ~~! ~~! ~~! ~~! ~~! ~~...") {
audioClipIndex = 4,
},
new DialogueInteraction(Character.Her, "Augh, fuck.") {
audioClipIndex = 5,
},
new DialogueInteraction(Character.Her, "~~! ~~! ~~! ~~! --! ~~!") {
audioClipIndex = 6,
},
new DialogueInteraction(Character.Her, "~~-- -- --- -- --- --- --!") {
audioClipIndex = 7,
},
new DialogueInteraction(Character.You, "H-hold on, Im gonna!"),
new DialogueInteraction(Character.Her, "~~//... //... //, //, //...") {
audioClipIndex = 8,
},
new DialogueInteraction(Character.Her, "Ha... ha... he...") {
audioClipIndex = 9,
},
new DialogueInteraction(Character.You, "Haa, haa, haa..."),
new DialogueInteraction(Character.Her, "Phew... That was... nice.") {
audioClipIndex = 10,
},
new DialogueInteraction(Character.None, "That was a close one."),
}
},
// =====
{ Dialogue.Task_Fuck2,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.None, "You position yourself squarely on top of her, missionary style.") {
backgroundIndex = 0,
},
new DialogueInteraction(Character.You, "Alright... You know what happens next, right?"),
new DialogueInteraction(Character.Her, "Duh. Do you think Im stupid?") {
audioClipIndex = 1,
},
new DialogueInteraction(Character.You, "..."),
new DialogueInteraction(Character.Her, "Nngh...") {
audioClipIndex = 2,
},
new DialogueInteraction(Character.You, "Im gonna go in now."),
new DialogueInteraction(Character.Her, "~~. ~~. ~~. ~~. ~~. ~~. ~~. ~~...") {
audioClipIndex = 3,
},
new DialogueInteraction(Character.Her, "~~... ~~... ~~... ~~, ~~, ~~, ~~, ~~...") {
audioClipIndex = 4,
},
new DialogueInteraction(Character.None, "Hmm. Sounds like shes a fan of this position"),
new DialogueInteraction(Character.Her, "~~! ~~! ~~!! ~~! ~~! ~~! --! --!") {
audioClipIndex = 5,
},
new DialogueInteraction(Character.You, "Ha… Ha… I cant… hold much longer"),
new DialogueInteraction(Character.Her, "--!! --!! --!! --!! !! !! !!") {
audioClipIndex = 6,
},
new DialogueInteraction(Character.You, "Urk--"),
new DialogueInteraction(Character.None, "You pull out and spray her stomach down."),
new DialogueInteraction(Character.Her, "Ha... Ha... Hmm... Not inside this time?") {
audioClipIndex = 7,
},
new DialogueInteraction(Character.You, "Phew... Nope, too dangerous."),
new DialogueInteraction(Character.Her, "Maybe next time then.") {
audioClipIndex = 8,
},
}
},
// =====
{ Dialogue.Task_FuckCosplay,
new List<DialogueInteraction>() {
new DialogueInteraction(Character.None, "We decided to do some doggy in her frilly undies.") {
backgroundIndex = 0,
},
new DialogueInteraction(Character.None, "She's being a bitch about it, as usual."),
new DialogueInteraction(Character.Her, "Well? Put it in, dickhead. I aint got all day.") {
audioClipIndex = 0,
},
new DialogueInteraction(Character.You, "I'm pretty sure you do have all day, but..."),
new DialogueInteraction(Character.Her, "Shut up and fuck me already.") {
audioClipIndex = 1,
},
new DialogueInteraction(Character.None, "You plunge deep into her, catching her off-guard."),
new DialogueInteraction(Character.Her, "Aiee!") {
audioClipIndex = 2,
},
new DialogueInteraction(Character.Her, "Ha-- ~~, ~~, ~~, ~~, ~~, ~~, ~~, ~~...") {
audioClipIndex = 3,
},
new DialogueInteraction(Character.Her, "~~! ~~! ~~! ~~! ~~! ~~! ~~! ~~!") {
audioClipIndex = 4,
},
new DialogueInteraction(Character.Her, "Come on, man. Put your back into it!") {
audioClipIndex = 5,
},
new DialogueInteraction(Character.Her, "Push harder-- aeee!") {
audioClipIndex = 6,
},
new DialogueInteraction(Character.Her, "!! !! !! !! !! !! !! !! !! !!") {
audioClipIndex = 7,
},
new DialogueInteraction(Character.Her, "-!! -!! -!! -!! -!! -!! -!! -!!") {
audioClipIndex = 8,
},
new DialogueInteraction(Character.Her, "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!") {
audioClipIndex = 9,
},
new DialogueInteraction(Character.You, "Hoo! Im getting close"),
new DialogueInteraction(Character.Her, "Auuungh-- Yeah! Cum inside me! Do it!") {
audioClipIndex = 10,
},
new DialogueInteraction(Character.Her, "Ah! !! !! ! !! !! !! !! !! ! ! !!") {
audioClipIndex = 11,
},
new DialogueInteraction(Character.Her, "!!!!!!! ~~~~~ !!!!!!!! ~~~~~~~~...") {
audioClipIndex = 12,
},
new DialogueInteraction(Character.Her, "*Cough cough cough*") {
audioClipIndex = 13,
},
new DialogueInteraction(Character.You, "Phew... Wow. That was incredible."),
new DialogueInteraction(Character.Her, "Ha... Ha... Ha... ...") {
audioClipIndex = 14,
},
}
},
};
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 79bd89344932c1f4e94bdcdf6c6ffdae
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,52 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ShopController : MonoBehaviour {
public enum ShopType {
OUTFIT,
HAIRSTYLE,
FOOD
}
[SerializeField] ShopType type = ShopType.OUTFIT;
[SerializeField] Transform verticalLayoutGroup;
[SerializeField] GameObject ShopItemPrefab;
[SerializeField] ScrollRect scroll;
[SerializeField] VNObjectController assets;
public void SetUp() {
while (verticalLayoutGroup.childCount > 0) {
DestroyImmediate(verticalLayoutGroup.GetChild(0).gameObject);
}
if (type == ShopType.OUTFIT) {
GameData.GLOBAL.UpdateForSale();
foreach (Body body in VNData.OUTFIT_INFO.Keys) {
ShopItemController item = Instantiate(ShopItemPrefab).GetComponent<ShopItemController>();
item.assets = assets;
item.SetFields(VNData.OUTFIT_INFO[body], body);
item.transform.SetParent(verticalLayoutGroup);
item.persist = true;
}
} else if (type == ShopType.HAIRSTYLE) {
GameData.GLOBAL.UpdateForSale();
foreach (Hair hair in VNData.HAIR_INFO.Keys) {
ShopItemController item = Instantiate(ShopItemPrefab).GetComponent<ShopItemController>();
item.assets = assets;
item.SetFields(VNData.HAIR_INFO[hair], hair);
item.transform.SetParent(verticalLayoutGroup);
item.persist = true;
}
} else if (type == ShopType.FOOD) {
foreach (Food food in VNData.FOOD_INFO.Keys) {
ShopItemController item = Instantiate(ShopItemPrefab).GetComponent<ShopItemController>();
item.assets = assets;
item.SetFields(VNData.FOOD_INFO[food], food);
item.transform.SetParent(verticalLayoutGroup);
item.persist = true;
}
}
scroll.verticalNormalizedPosition = 1f;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: bd962123bd80d8b4ca633344d0d289c8
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,131 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
public class ShopItemController : MonoBehaviour {
[SerializeField] public TextMeshProUGUI itemTitle;
[SerializeField] public TextMeshProUGUI itemCost;
[SerializeField] public TextMeshProUGUI itemDescription;
[SerializeField] public Image itemIcon;
[SerializeField] public Image soldIcon;
[SerializeField] public Image lockedIcon;
// The ID of the item you get for making the purchase.
[SerializeField] public Body body = Body.None;
[SerializeField] public Hair hair = Hair.None;
[SerializeField] public Food food = Food.None;
[SerializeField] public bool persist = true;
[SerializeField] public Michsky.MUIP.ButtonManager buyButton;
public VNObjectController assets;
ItemInfo itemInfo;
public void TryBuy() {
if (food != Food.None) {
if (GameData.GLOBAL.boughtFood) {
GameObject.FindWithTag("Notifier").GetComponent<NotifierController>().Notify(
"Purchase Failed",
"You've already fed her for now.");
return;
} else if (GameData.GLOBAL.hunger == 0) {
GameObject.FindWithTag("Notifier").GetComponent<NotifierController>().Notify(
"Purchase Failed",
"She's not hungry.");
return;
}
}
if (GameData.GLOBAL.money >= itemInfo.cost) {
GameData.GLOBAL.money -= itemInfo.cost;
if (body != Body.None) {
GameData.GLOBAL.unlockedOutfits.Add(body);
//UnlockSelectorController selector = GameObject.FindWithTag("OutfitSelector").GetComponent<UnlockSelectorController>();
GameObject.FindWithTag("Notifier").GetComponent<NotifierController>().Notify(
"New Outfit",
"Purchased outfit: " + itemInfo.name);
GameData.GLOBAL.affection += itemInfo.affection;
buyButton.gameObject.SetActive(false);
soldIcon.gameObject.SetActive(true);
//selector.UpdateUnlockedOutfits();
// TODO: Dialogue interact for buying outfit
// TODO: Auto-equip new outfit
}
if (hair != Hair.None) {
GameData.GLOBAL.unlockedHairs.Add(hair);
//UnlockSelectorController selector = GameObject.FindWithTag("HairSelector").GetComponent<UnlockSelectorController>();
GameObject.FindWithTag("Notifier").GetComponent<NotifierController>().Notify(
"New Hairstyle",
"Purchased hairstyle: " + itemInfo.name);
GameData.GLOBAL.affection += itemInfo.affection;
buyButton.gameObject.SetActive(false);
soldIcon.gameObject.SetActive(true);
//selector.UpdateUnlockedHairs();
// TODO: Dialogue interact for buying hairstyle
// TODO: Auto-equip new hairstyle
}
if (food != Food.None) {
// TODO: Do a food response thing
GameObject.FindWithTag("Notifier").GetComponent<NotifierController>().Notify(
"Gulp!",
"You fed her: " + itemInfo.name);
GameData.GLOBAL.boughtFood = true;
GameData.GLOBAL.Feed(food);
// TODO: Dialogue interact for buying food
GameObject.FindWithTag("Notifier").GetComponent<ManagerController>().FoodPurchased();
}
// TODO: some sort of buying animation and sound
if (!persist) {
Destroy(gameObject);
}
} else {
GameObject.FindWithTag("Notifier").GetComponent<NotifierController>().Notify(
"Purchase Failed",
"You can't afford that.");
}
}
void SetFields(ItemInfo info) {
itemInfo = info;
itemTitle.SetText(info.name);
itemCost.SetText("$" + info.cost.ToString());
}
public void SetFields(ItemInfo info, Body body) {
SetFields(info);
this.body = body;
itemDescription.SetText("");
bool sold = GameData.GLOBAL.unlockedOutfits.Contains(body);
bool forSale = !sold && GameData.GLOBAL.forSaleOutfits.Contains(body);
buyButton.gameObject.SetActive(!sold && forSale);
lockedIcon.gameObject.SetActive(!sold && !forSale);
soldIcon.gameObject.SetActive(sold);
itemIcon.sprite = assets.outfitIcons[(int)body - 1];
}
public void SetFields(ItemInfo info, Hair hair) {
SetFields(info);
this.hair = hair;
itemDescription.SetText("");
bool sold = GameData.GLOBAL.unlockedHairs.Contains(hair);
bool forSale = !sold && GameData.GLOBAL.forSaleHairs.Contains(hair);
buyButton.gameObject.SetActive(!sold && forSale);
lockedIcon.gameObject.SetActive(!sold && !forSale);
soldIcon.gameObject.SetActive(sold);
itemIcon.sprite = assets.hairIcons[(int)hair - 1];
}
public void SetFields(ItemInfo info, Food food) {
SetFields(info);
this.food = food;
itemDescription.SetText(info.description);
buyButton.gameObject.SetActive(true);
lockedIcon.gameObject.SetActive(false);
soldIcon.gameObject.SetActive(false);
// TODO: Set itemIcon.sprite
persist = true;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: a76ee5cece750eb499f5880ee06753ac
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,30 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TMPro;
public class TextFadeController : MonoBehaviour
{
[SerializeField] public TextMeshPro text;
[SerializeField] float dieTime = 1.0f;
[SerializeField] public Color baseColor = Color.white;
[HideInInspector] float alpha = 1.0f;
[HideInInspector] float startTime = -1.0f;
private void Awake()
{
startTime = Time.time;
}
// Update is called once per frame
void LateUpdate()
{
alpha = Mathf.Max(0.0f, 1.0f - (Time.time - startTime) / dieTime);
text.color = new Color(baseColor.r, baseColor.g, baseColor.b, alpha);
if (alpha == 0.0f) {
Destroy(gameObject);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 7e3b905e818ca59458b9570baebff532
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,85 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using Michsky.MUIP;
public class UnlockSelectorController : MonoBehaviour {
enum SelectorType {
Outfit,
Hair
}
[SerializeField] HorizontalSelector selector;
[SerializeField] SelectorType selectorType;
[SerializeField] Image vnSprite; // Changes when updating the selector.
[SerializeField] Image vnHairBackSprite; // Changes when updating the selector.
[SerializeField] Image vnIcon;
[SerializeField] VNObjectController managerAssets;
// Start is called before the first frame update
void Start() {
switch (selectorType) {
case SelectorType.Outfit:
UpdateUnlockedOutfits();
vnIcon.sprite = managerAssets.outfitIcons[(int)GameData.GLOBAL.bodyChoice - 1];
break;
case SelectorType.Hair:
UpdateUnlockedHairs();
vnIcon.sprite = managerAssets.hairIcons[(int)GameData.GLOBAL.hairChoice - 1];
break;
default:
break;
}
}
public void UpdateUnlockedOutfits() {
// Build a list of unlocked outfits, with the "meta" item field set to the index of the outfit (enum value).
// Meta is used later to set the outfit in the DialogueBox.
selector.items = new List<HorizontalSelector.Item>();
for (int i = 0; i < System.Enum.GetNames(typeof(Body)).Length; i++) {
if (GameData.GLOBAL.unlockedOutfits.Contains((Body)i)) {
HorizontalSelector.Item item = new HorizontalSelector.Item();
item.meta = i;
item.itemTitle = VNData.OUTFIT_INFO[(Body)i].name;
selector.items.Add(item);
if (GameData.GLOBAL.bodyChoice == (Body)i) {
selector.index = selector.items.Count - 1;
}
}
}
selector.UpdateUI();
}
public void UpdateUnlockedHairs() {
// Build a list of unlocked hairs, with the "meta" item field set to the index of the hair (enum value).
// Meta is used later to set the outfit in the DialogueBox.
selector.items = new List<HorizontalSelector.Item>();
for (int i = 0; i < System.Enum.GetNames(typeof(Hair)).Length; i++) {
if (GameData.GLOBAL.unlockedHairs.Contains((Hair)i)) {
HorizontalSelector.Item item = new HorizontalSelector.Item();
item.meta = i;
item.itemTitle = VNData.HAIR_INFO[(Hair)i].name;
selector.items.Add(item);
if (GameData.GLOBAL.hairChoice == (Hair)i) {
selector.index = selector.items.Count - 1;
}
}
}
selector.UpdateUI();
}
public void SelectedValueChanged() {
if (selectorType == SelectorType.Outfit) {
int i = selector.items[selector.index].meta;
GameData.GLOBAL.bodyChoice = (Body)i;
vnSprite.sprite = managerAssets.sprites[i - 1];
vnIcon.sprite = managerAssets.outfitIcons[i - 1];
} else if (selectorType == SelectorType.Hair) {
int i = selector.items[selector.index].meta;
GameData.GLOBAL.hairChoice = (Hair)i;
vnSprite.sprite = managerAssets.spriteHairs[i - 1];
vnHairBackSprite.sprite = managerAssets.spriteHairBacks[i - 1];
vnIcon.sprite = managerAssets.hairIcons[i - 1];
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 14431c06565a34741ad6ba44ee792b11
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,230 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
using Com.LuisPedroFonseca.ProCamera2D;
public class VNController : MonoBehaviour {
[SerializeField] float bgCrossfadeTime = 0.5f;
[SerializeField] DialogueController dialogueBox;
[SerializeField] VNSpriteController vnSpriteCenter;
[SerializeField] MoreMountains.Feedbacks.MMF_Player vnSpritePlayer;
[SerializeField] AudioSource voiceAudioSource;
[SerializeField] MusicFadeController music;
[SerializeField] Image bgBack;
// Used for cross-fading.
[SerializeField] Image bgFront;
[SerializeField] bool LeaveAfterDone = false;
[SerializeField] public List<Transform> awakenOnFinish = new List<Transform>() { };
[SerializeField] VNObjectController vnAssets;
[HideInInspector] bool isLeaving = false;
[HideInInspector] public bool gameOverAfterDone = false;
[HideInInspector] public bool runawayGameOverAfterDone = false;
[SerializeField] ProCamera2DTransitionsFX transition;
[SerializeField] Image managerBg;
private void Leave() {
if (gameOverAfterDone) {
GameData.GLOBAL = new GameData();
gameOverAfterDone = false;
SceneManager.LoadScene("MainMenu");
} else if (runawayGameOverAfterDone) {
runawayGameOverAfterDone = false;
gameOverAfterDone = true;
SceneManager.LoadScene("SceneViewer");
} else {
SceneManager.LoadScene("Manager");
}
}
public void Done() {
if (LeaveAfterDone && !isLeaving) {
transition.OnTransitionExitEnded = Leave;
transition.TransitionExit();
isLeaving = true;
} else if (runawayGameOverAfterDone) {
VNData.NextScene = Dialogue.GameOver;
transition.OnTransitionExitEnded = Leave;
transition.TransitionExit();
isLeaving = true;
} else if (!isLeaving) {
// Activate any UI elements that are gated on finishing the current Dialogue.
foreach (Transform t in awakenOnFinish) {
t.gameObject.SetActive(true);
}
}
}
public void CloseManager() {
isLeaving = true;
foreach (Transform t in awakenOnFinish) {
t.gameObject.SetActive(false);
}
}
private class SetSpriteOptions {
public Body spriteBody { get; set; } = Body.None;
public Hair spriteHair { get; set; } = Hair.None;
public Expression spriteExpression { get; set; } = Expression.None;
public bool removeSprite { get; set; } = false;
public bool showBody { get; set; } = false;
}
private void SetSprite(VNSpriteController spriteController, SetSpriteOptions options) {
int spriteIndex = (int)options.spriteBody - 1;
// Load from overrides if set.
if (options.spriteBody != Body.None && spriteIndex < vnAssets.sprites.Count) {
spriteController.body.gameObject.SetActive(true);
spriteController.body.sprite = vnAssets.sprites[spriteIndex];
spriteController.hairBack.gameObject.SetActive(true);
spriteController.hairBack.sprite = vnAssets.spriteHairBacks[(int)options.spriteHair - 1];
spriteController.hair.gameObject.SetActive(true);
spriteController.hair.sprite = vnAssets.spriteHairs[(int)options.spriteHair - 1];
} else if (options.showBody)
{
Debug.Log(GameData.GLOBAL.bodyChoice);
Debug.Log(GameData.GLOBAL.hairChoice);
// Load from GameData if no override is set.
spriteController.body.gameObject.SetActive(true);
spriteController.body.sprite = vnAssets.sprites[(int)GameData.GLOBAL.bodyChoice - 1];
spriteController.hairBack.gameObject.SetActive(true);
spriteController.hairBack.sprite = vnAssets.spriteHairBacks[(int)GameData.GLOBAL.hairChoice - 1];
spriteController.hair.gameObject.SetActive(true);
spriteController.hair.sprite = vnAssets.spriteHairs[(int)GameData.GLOBAL.hairChoice - 1];
}
int spriteExpressionIndex = (int)options.spriteExpression - 1;
if (options.spriteExpression != Expression.None && spriteExpressionIndex < vnAssets.spriteExpressions.Count) {
spriteController.expression.gameObject.SetActive(true);
spriteController.expression.sprite = vnAssets.spriteExpressions[spriteExpressionIndex];
}
if (options.removeSprite) {
spriteController.body.gameObject.SetActive(false);
spriteController.hairBack.gameObject.SetActive(false);
spriteController.hair.gameObject.SetActive(false);
spriteController.expression.gameObject.SetActive(false);
}
}
public void Interact(DialogueInteraction interaction) {
// Cancel any pending crossfades.
if (bgFront != null) {
bgFront.CrossFadeAlpha(1.0f, 0.0f, false);
}
// If there's a new background, fade into it.
if (bgFront != null && bgBack != null && interaction.backgroundIndex > -1) {
if (bgBack.sprite != null) {
bgBack.sprite = bgFront.sprite;
if (interaction.backgroundIndex < vnAssets.backgrounds.Count) {
if (bgCrossfadeTime > 0) {
bgFront.sprite = vnAssets.backgrounds[interaction.backgroundIndex];
bgFront.GetComponent<CanvasRenderer>().SetAlpha(0);
bgFront.CrossFadeAlpha(1.0f, bgCrossfadeTime, false);
Debug.Log(bgFront.color.ToString());
Debug.Log(bgFront.sprite.ToString());
} else {
bgFront.sprite = vnAssets.backgrounds[interaction.backgroundIndex];
bgFront.GetComponent<CanvasRenderer>().SetAlpha(255);
}
} else {
Debug.LogError("Background index out of range for interaction!");
}
} else {
Debug.Log(vnAssets.backgrounds.Count);
bgFront.sprite = vnAssets.backgrounds[interaction.backgroundIndex];
bgBack.sprite = bgFront.sprite;
bgFront.CrossFadeAlpha(1.0f, 0.0f, false);
}
}
// If there's an audio clip, play it.
if (voiceAudioSource != null && interaction.audioClipIndex > -1) {
if (interaction.audioClipIndex < vnAssets.voiceBank.Count) {
voiceAudioSource.Stop();
voiceAudioSource.PlayOneShot(vnAssets.voiceBank[interaction.audioClipIndex]);
} else {
Debug.LogError("AudioClip index out of range for interaction!");
}
}
// If a sprite is defined, set it.
SetSprite(vnSpriteCenter, new SetSpriteOptions() {
spriteBody = interaction.bodyOverride,
spriteHair = interaction.hairOverride,
spriteExpression = interaction.expression,
removeSprite = interaction.removeBody,
showBody = interaction.showBody,
});
if ((int)interaction.effect > 0) {
vnSpritePlayer.FeedbacksList[(int)interaction.effect - 1].Play(Vector3.one);
}
// TODO: If there's a music clip, stop the currently running clip and play it.
if (interaction.fadeMusicOut) {
music.FadeOut(1f);
} else if (interaction.musicClipIndex > -1) {
if (interaction.musicClipIndex < vnAssets.musicBank.Count) {
music.audioSource.clip = vnAssets.musicBank[interaction.musicClipIndex];
music.audioSource.Play();
music.FadeIn(1f);
} else {
Debug.LogError("AudioClip index out of range for music!");
}
}
}
// Called by DialogueControler to enforce loading before the first Interact.
public void SetUp(Dialogue scene, bool isManagerScene = true, bool useTimeBasedBg = true) {
voiceAudioSource = GameObject.FindWithTag("Voice").GetComponent<AudioSource>();
music = GameObject.FindWithTag("Music").GetComponent<MusicFadeController>();
if (isManagerScene)
{
// Do nothing - the manager VN inherits its own VNAssets object.
if (useTimeBasedBg) {
switch (GameData.GLOBAL.time) {
case 1: // Morning
case 3: // Evening
managerBg.sprite = vnAssets.backgrounds[0];
break;
case 2: // Day
managerBg.sprite = vnAssets.backgrounds[1];
break;
case 4: // Night
managerBg.sprite = vnAssets.backgrounds[2];
break;
default:
managerBg.sprite = vnAssets.backgrounds[0];
break;
}
}
} else
{
// Load the respective asset pack from Resources/VNAssetPacks.
vnAssets = Instantiate((GameObject)Resources.Load(VNData.GetDialogueAssetPackFor(scene), typeof(GameObject))).GetComponent<VNObjectController>();
}
if (LeaveAfterDone) {
transition.TransitionEnter();
}
}
// Update is called once per frame
void Update()
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: fdf464a9b371ad54390664314641f86a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

783
Assets/Scripts/VNData.cs Normal file
View File

@@ -0,0 +1,783 @@
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();
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 0465c57fefa0764459d4fc154161c110
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,30 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class VNObjectController : MonoBehaviour
{
[SerializeField] public List<Sprite> backgrounds;
[SerializeField] public List<Sprite> spriteHairBacks;
[SerializeField] public List<Sprite> sprites;
[SerializeField] public List<Sprite> spriteExpressions;
[SerializeField] public List<Sprite> spriteHairs;
[SerializeField] public List<AudioClip> voiceBank;
[SerializeField] public List<AudioClip> musicBank;
[SerializeField] public List<Sprite> outfitIcons;
[SerializeField] public List<Sprite> hairIcons;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 1c41599faf8af9645bd7b847d4aa775d
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,24 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class VNSpriteController : MonoBehaviour {
[SerializeField] public Image hairBack;
[SerializeField] public Image body;
[SerializeField] public Image expression;
[SerializeField] public Image hair;
[SerializeField] public Image effect;
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void Update()
{
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 4c413187d22613d479a7af685dddc065
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,81 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
using TMPro;
using Michsky.MUIP;
public class ValueRefreshController : MonoBehaviour
{
[SerializeField] TextMeshProUGUI text;
[SerializeField] Slider slider;
[SerializeField] ButtonManager button;
[SerializeField] GlobalValueType globalValueType = GlobalValueType.MONEY;
static string[] times = new string[4]{ "Morning", "Afternoon", "Evening", "Night" };
enum GlobalValueType
{
MONEY,
STATUS,
DAY,
TIME,
MOOD,
HUNGER,
AFFECTION,
CANWORK
};
// Start is called before the first frame update
void Start()
{
}
// Update is called once per frame
void FixedUpdate()
{
switch(globalValueType)
{
case GlobalValueType.MONEY:
text.SetText("$" + GameData.GLOBAL.money.ToString());
if (GameData.GLOBAL.money > 300) {
text.color = Color.green;
} else if (GameData.GLOBAL.money > 200) {
text.color = Color.yellow;
} else {
text.color = Color.red;
}
break;
case GlobalValueType.STATUS:
text.SetText(GameData.GLOBAL.status.ToString());
if (GameData.GLOBAL.status == Status.Farty) {
text.color = Color.yellow;
} else if (GameData.GLOBAL.status == Status.Moody) {
text.color = Color.red;
} else {
text.color = Color.green;
}
break;
case GlobalValueType.DAY:
text.SetText("Day " + GameData.GLOBAL.day.ToString());
break;
case GlobalValueType.TIME:
text.SetText(times[GameData.GLOBAL.time - 1]);
break;
case GlobalValueType.MOOD:
slider.value = GameData.GLOBAL.mood;
break;
case GlobalValueType.HUNGER:
slider.value = GameData.GLOBAL.hunger;
break;
case GlobalValueType.AFFECTION:
text.SetText(GameData.GLOBAL.affection.ToString());
break;
case GlobalValueType.CANWORK:
button.isInteractable = !GameData.GLOBAL.workedToday;
break;
default:
break;
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b75df4ba3f0081e47897855ca7eee6ba
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

8
Assets/Scripts/Work.meta Normal file
View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 1e60109d217e5644da0d25bc2d189cbf
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,38 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;
public class ArrowController : MonoBehaviour
{
// Left, down, up, right arrow sprites.
[SerializeField] public Sprite[] arrowSprites;
[SerializeField] public GameObject successObject;
[SerializeField] public GameObject failObject;
[SerializeField] public Image image;
[SerializeField] public Image bgImage;
public int key = 0;
public void Init()
{
image.sprite = arrowSprites[key];
}
public void Succeed()
{
GameObject o = Instantiate(successObject);
o.transform.position = transform.position;
o.transform.SetParent(this.transform);
image.color = Color.clear;
bgImage.color = Color.clear;
}
public void Fail()
{
GameObject o = Instantiate(failObject);
o.transform.position = transform.position;
o.transform.SetParent(this.transform);
image.color = Color.clear;
bgImage.color = Color.clear;
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 42cbbc58fd0a533479ab2710a02ede7e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,252 @@
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.SceneManagement;
public class StreamController : MonoBehaviour {
// May be a flatUI arrow or pixel art arrow.
// Pixel art is used in gameplay streams.
// FlatUI arrows are used in cutaway scene streams.
[SerializeField] public GameObject arrowPrefab;
[SerializeField] public AudioClip hitClip;
[SerializeField] public AudioClip missClip;
[SerializeField] public AudioClip winClip;
[SerializeField] public AudioClip loseClip;
[SerializeField] public GameObject arrowGroup;
[SerializeField] public AudioSource audioSource;
[SerializeField] public List<ArrowController> arrows;
[SerializeField] public float resetDelay = 0.5f;
[SerializeField] public bool debug = false;
[SerializeField] public int debugLength = 5;
[SerializeField] public float debugTimeLimit = 30f;
[SerializeField] Button continueButton;
StreamInfo info;
bool isTicking = false;
bool isOver = false;
int passed = 0;
[SerializeField] TextMeshProUGUI clearCountTMPro;
[SerializeField] TextMeshProUGUI timeTMPro;
[SerializeField] TextMeshProUGUI summaryTMPro;
[SerializeField] public int numWon = 0;
float startTimestamp = 0.0f;
float freezeTimestamp = 0.0f;
public class StreamInfo {
public int numArrows { get; set; }
public float timeLimit { get; set; }
public float startDelay { get; set; }
public float endDelay { get; set; }
// Whether or not to auto-close the Stream after winning or losing.
// Infinite scenes are for special enjoyment events.
public bool infinite { get; set; }
// In sudden death, missing one arrow fails the event even if
// the timer is still running.
public bool suddenDeath { get; set; }
public Sprite beforeBG { get; set; } = null;
public Sprite winBG { get; set; } = null;
public Sprite loseBG { get; set; } = null;
public AudioClip beforeClip { get; set; } = null;
public AudioClip winClip { get; set; } = null;
public AudioClip loseClip { get; set; } = null;
}
public void Init(StreamInfo info, bool wait = true) {
this.info = info;
passed = 0;
// Calculate int[] keys
for (int i = 0; i < info.numArrows; i++) {
ArrowController arrow = Instantiate(arrowPrefab).GetComponent<ArrowController>();
arrow.key = Random.Range(0, 4);
arrow.Init();
arrow.transform.position = arrowGroup.transform.position;
arrow.transform.SetParent(arrowGroup.transform);
arrow.transform.localScale = new Vector3(1, 1, 1);
arrows.Add(arrow);
}
if (wait) {
Invoke("StartTimer", info.startDelay);
}
}
public void Start() {
if (debug) {
Init(new StreamInfo {
numArrows = debugLength,
timeLimit = debugTimeLimit,
startDelay = 1.0f,
endDelay = 1.0f,
infinite = true,
suddenDeath = false
});
}
audioSource = GameObject.FindWithTag("SFX").GetComponent<AudioSource>();
continueButton.gameObject.SetActive(false);
}
public void MakeGlow(int arrowIndex) {
// TODO: implement (make the arrow at ArrowIndex glow)
// use the shader thing
}
void StartTimer() {
startTimestamp = Time.time;
isTicking = true;
MakeGlow(0);
}
void Reset() {
Debug.Log("Reset");
if (isOver)
return;
foreach (ArrowController arrow in arrows) {
Destroy(arrow.gameObject);
}
arrows.Clear();
Init(this.info, false);
isTicking = true;
MakeGlow(0);
}
char GetRank() {
float winRate = numWon * info.numArrows * (1 + resetDelay);
if (winRate > info.timeLimit * 3)
return 'S';
if (winRate > info.timeLimit * 2.5)
return 'A';
if (winRate > info.timeLimit * 2)
return 'B';
if (winRate > info.timeLimit * 1.5)
return 'C';
if (winRate > info.timeLimit * 1)
return 'D';
return 'F';
}
int GetScore(char rank) {
return numWon * 30;
/*
switch (rank) {
case 'S':
return 300;
case 'A':
return 250;
case 'B':
return 200;
case 'C':
return 150;
case 'D':
return 100;
default:
return 0;
}
*/
}
public void GoBack() {
GameData.GLOBAL.IncrementTime();
SceneManager.LoadScene("Manager");
}
void AllowContinue() {
continueButton.gameObject.SetActive(true);
}
void TimesUp() {
Debug.Log("Time's Up!");
isOver = true;
char rank = GetRank();
int score = GetScore(rank);
summaryTMPro.SetText("Time's Up!\nRank: " + rank.ToString() + "\nPay: $" + score.ToString());
GameData.GLOBAL.money += score;
GameData.GLOBAL.workedToday = true;
Invoke("AllowContinue", 1.0f);
}
void TryHit(int key) {
if (isOver)
return;
if (passed < info.numArrows) {
if (arrows[passed].key == key) {
// You hit the right arrow, move to the next one
audioSource.PlayOneShot(hitClip);
arrows[passed].Succeed();
passed += 1;
} else {
arrows[passed].Fail();
if (!info.suddenDeath) {
audioSource.PlayOneShot(missClip);
isTicking = false;
Invoke("Reset", resetDelay);
} else {
// TODO: do a lose thing
audioSource.PlayOneShot(loseClip);
}
}
if (passed == info.numArrows) {
// TODO: do a win thing
audioSource.PlayOneShot(winClip);
numWon += 1;
isTicking = false;
Invoke("Reset", resetDelay);
} else {
MakeGlow(passed);
}
}
}
// Update is called once per frame
void Update() {
if (isOver)
return;
// Process key presses if the delay is over
if (isTicking) {
if (Input.GetKeyDown(KeyCode.LeftArrow)) {
Debug.Log("Left");
TryHit(0);
}
if (Input.GetKeyDown(KeyCode.DownArrow)) {
Debug.Log("Down");
TryHit(1);
}
if (Input.GetKeyDown(KeyCode.UpArrow)) {
Debug.Log("Up");
TryHit(2);
}
if (Input.GetKeyDown(KeyCode.RightArrow)) {
Debug.Log("Right");
TryHit(3);
}
}
clearCountTMPro.SetText(numWon.ToString());
}
void FixedUpdate() {
float time;
if (isTicking) {
time = info.timeLimit - (Time.time - startTimestamp);
if (time <= 0f) {
isTicking = false;
time = 0f;
TimesUp();
}
freezeTimestamp = time;
} else {
time = freezeTimestamp;
}
timeTMPro.SetText(time.ToString("#0.00"));
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: 3afcad898513dc04d80735eb278fa6dc
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: