Files
pgs/Assets/Scripts/NpcController.cs

214 lines
8.8 KiB
C#
Raw Permalink Normal View History

2026-02-21 16:58:22 -08:00
using System.Collections;
using System.Collections.Generic;
using TMPro;
using UnityEditor;
using UnityEngine;
public class NpcController : MonoBehaviour {
public static bool isInCutscene = false;
[SerializeField] private Animator animator;
[SerializeField] private Rigidbody2D rigidBody;
[SerializeField] public GameObject icon;
[SerializeField] public NpcID npcID;
[SerializeField] public float statusCheckTick;
[SerializeField] public UIPanelController uiPanelController;
[SerializeField] public GameObject questPanelObject;
private QuestPanelController questPanelController;
[SerializeField] public GameObject craftingPanelObject;
private GameObject myCraftingPanel;
[SerializeField] public GameObject shopPanelObject;
private GameObject myShopPanel;
[SerializeField] private Collider2D trigger;
// When talking and stopping talk, whether StartTalk and EndTalk should do anything.
[SerializeField] private bool skipTransitions;
public ItemSpriteCollectionController itemSpriteCollectionController;
public float cutsceneStartRange = 1.0f;
private Npc npc;
private PlayerMovement playerMovement;
public List<DialogueStatement> statements;
public int currentInteractionIndex = 0;
private GameAudioController gameAudioController;
public static HashSet<DialogueID> nonInteractDialogue = new HashSet<DialogueID>() {
DialogueID.LYN_ACCEPT_GETTING_THE_GOODS,
};
// Start is called before the first frame update
void Start() {
animator = gameObject.GetComponent<Animator>();
rigidBody = gameObject.GetComponent<Rigidbody2D>();
playerMovement = GameObject.FindGameObjectWithTag("Player").GetComponent<PlayerMovement>();
itemSpriteCollectionController =
GameObject.FindGameObjectWithTag("ItemSpriteCollection").GetComponent<ItemSpriteCollectionController>();
uiPanelController =
GameObject.FindGameObjectWithTag("UnderlayUI").GetComponent<UIPanelController>();
gameAudioController = GameObject.FindGameObjectWithTag("GameAudio")
.GetComponent<GameAudioController>();
if (npcID != NpcID.NONE) {
npc = (Npc)NpcInfo.npcs[npcID];
StartCoroutine("StatusCheckTick", 0.2f);
}
if (skipTransitions) {
animator.SetBool("skipTransition", true);
}
}
private IEnumerator StatusCheckTick() {
NpcQuestProgress questProgress = (NpcQuestProgress)State.state.npcState.npcQuestMap[npcID];
bool hasCompletableQuest = false;
foreach (QuestID questID in questProgress.inProgressQuests) {
if (((QuestProgress)State.state.quests.allQuestProgress[questID]).CheckComplete()) {
hasCompletableQuest = true;
break;
}
}
if (hasCompletableQuest) {
// Quest Complete = sprite 1
icon.GetComponent<SpriteRenderer>().sprite = itemSpriteCollectionController.npcIconSprites[1];
} else {
bool hasAcceptableQuest = false;
foreach (QuestID questID in questProgress.acceptingQuests) {
if (State.state.quests.CheckPrerequisites(questID)) {
hasAcceptableQuest = true;
break;
}
}
if (hasAcceptableQuest) {
// Quest Accept = sprite 0
icon.GetComponent<SpriteRenderer>().sprite = itemSpriteCollectionController.npcIconSprites[0];
} else if ((npc.shop != null || npc.craftingList != null) &&
State.state.quests.CheckNpcShopPrerequisites(npc)) {
// Me fly en shoppen = sprite 2
icon.GetComponent<SpriteRenderer>().sprite = itemSpriteCollectionController.npcIconSprites[2];
} else {
icon.GetComponent<SpriteRenderer>().sprite = null;
}
}
yield return new WaitForSeconds(statusCheckTick);
StartCoroutine(StatusCheckTick());
}
private void Awake() {
}
private bool IsPlayerInRange() {
if (Vector2.Distance(transform.position,
playerMovement.transform.position) <= cutsceneStartRange) {
return true;
}
return false;
}
public void QuestInteract(QuestID questID) {
Destroy(questPanelController.gameObject);
gameAudioController.audioSource.PlayOneShot(
gameAudioController.UI_Quest_Accept);
isInCutscene = true;
NpcInteraction interaction = npc.behavior.QuestInteract(questID);
statements = (List<DialogueStatement>)Dialogue.dialogueMap[interaction.dialogueID];
currentInteractionIndex = 0;
uiPanelController.IterateCutscene(statements[currentInteractionIndex]);
if (!nonInteractDialogue.Contains(interaction.dialogueID)) {
animator.SetBool("isTalking", true);
}
playerMovement.TriggerCollision(trigger);
}
public void Interact() {
Debug.Log("Starting cutscene");
// TODO: Stop the NPC from moving.
// TODO: Face the player.
// TODO: Make the player face the NPC.
NpcQuestProgress quests = (NpcQuestProgress)State.state.npcState.npcQuestMap[npcID];
HashSet<QuestID> acceptingQuests = new HashSet<QuestID>();
foreach (QuestID questID in quests.acceptingQuests) {
if (State.state.quests.CheckPrerequisites(questID)) {
acceptingQuests.Add(questID);
}
}
if (acceptingQuests.Count > 0 || quests.inProgressQuests.Count > 0) {
// Show quest window.
questPanelController = Instantiate(questPanelObject).GetComponent<QuestPanelController>();
questPanelController.transform.SetParent(GameObject.FindGameObjectWithTag("OverlayUI").transform);
questPanelController.transform.localPosition = Vector3.zero;
questPanelController.transform.localScale = Vector3.one;
questPanelController.questMenuController.Setup(acceptingQuests, quests.inProgressQuests, this);
gameAudioController.audioSource.PlayOneShot(
gameAudioController.UI_Quest_Open);
} else {
isInCutscene = true;
NpcInteraction interaction = npc.behavior.Interact();
statements = (List<DialogueStatement>)Dialogue.dialogueMap[interaction.dialogueID];
currentInteractionIndex = 0;
uiPanelController.IterateCutscene(statements[currentInteractionIndex]);
if (!nonInteractDialogue.Contains(interaction.dialogueID)) {
animator.SetBool("isTalking", true);
}
}
}
public void UtilityInteract() {
Debug.Log("Starting utility");
// TODO: Stop the NPC from moving.
// TODO: Face the player.
// TODO: Make the player face the NPC.
if (npc.shop != null) {
myShopPanel = Instantiate(shopPanelObject);
myShopPanel.transform.parent = GameObject.FindGameObjectWithTag("OverlayUI").transform;
myShopPanel.transform.localPosition = Vector3.zero;
myShopPanel.transform.localScale = Vector3.one;
myShopPanel.GetComponent<ShopPanelController>().shopMenuController.SetupBuyMenu(npc);
// TODO: UI_Shop_Open
gameAudioController.audioSource.PlayOneShot(
gameAudioController.UI_Quest_Open);
} else if (npc.craftingList != null) {
myCraftingPanel = Instantiate(craftingPanelObject);
myCraftingPanel.transform.parent = GameObject.FindGameObjectWithTag("OverlayUI").transform;
myCraftingPanel.transform.localPosition = Vector3.zero;
myCraftingPanel.transform.localScale = Vector3.one;
myCraftingPanel.GetComponent<CraftingPanelController>().craftingMenuController.Setup(npc);
// TODO: UI_Craft_Open
gameAudioController.audioSource.PlayOneShot(
gameAudioController.UI_Quest_Open);
}
}
private void Update() {
if (Input.GetButtonDown("Fire1") && isInCutscene && statements != null && statements.Count > 0) {
if (uiPanelController.SkipDialogueTypewriter()) {
Debug.Log("Skipped typing animation");
} else if (++currentInteractionIndex >= statements.Count) {
Debug.Log("Cutscene over");
isInCutscene = false;
statements = null;
currentInteractionIndex = 0;
playerMovement.cutscene = false;
uiPanelController.DeactivateDialoguePanel();
animator.SetBool("isTalking", false);
} else {
Debug.Log("Next!");
uiPanelController.IterateCutscene(statements[currentInteractionIndex]);
}
}
}
}