Working on Chapter 2, draft of Chapter 1 is completed

This commit is contained in:
2026-07-17 15:09:17 +01:00
parent 6cf1f7d8f3
commit 01ce568c47
1292 changed files with 294021 additions and 101198 deletions

View File

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

View File

@@ -1,14 +1,20 @@
using UnityEngine;
using UnityEngine.InputSystem;
using EasyTalk.Controller;
public class GameManager : MonoBehaviour
{
private Player player;
private DialogueController dialogueController;
void Awake()
{
player = GetComponent<Player>();
}
// Start is called once before the first execution of Update after the MonoBehaviour is created
void Start()
{
dialogueController = FindFirstObjectByType<DialogueController>();
if(dialogueController == null)
if (dialogueController == null)
Debug.LogError("DialogueController not found in the scene.");
else
dialogueController.PlayDialogue();
@@ -17,6 +23,26 @@ public class GameManager : MonoBehaviour
// Update is called once per frame
void Update()
{
}
public void ShowPlayerSkills(InputAction.CallbackContext ctx)
{
if (!ctx.performed) return;
player.GetSkills(out var skills);
foreach (var skill in skills)
{
Debug.Log($"Skill: {skill.Key}, Level: {skill.Value.level}, Description: {skill.Value.Description}");
}
}
public void SkillCheck(string skillName, int requiredLevel, out bool hasSkill)
{
if (player.skills.TryGetValue(skillName, out Skill skill))
{
hasSkill = skill.level >= requiredLevel;
}
else
{
hasSkill = false;
}
}
}

331
Assets/Scripts/Inventory.cs Normal file
View File

@@ -0,0 +1,331 @@
using UnityEngine;
using System.Collections.Generic;
[CreateAssetMenu(fileName = "NewItem", menuName = "Inventory/Item")]
public class Item : ScriptableObject
{
public string itemName;
public string itemDescription;
public int itemID;
public int maxStackSize = 1;
public bool isStackable;
public enum ItemType { Weapon, Armor, Consumable, QuestItem, Miscellaneous }
public ItemType itemType;
public Sprite itemIcon;
}
[System.Serializable]
public class InventorySlot
{
public Item item;
public int quantity;
public InventorySlot(Item newItem, int qty)
{
item = newItem;
quantity = qty;
}
}
public class Inventory : MonoBehaviour
{
[SerializeField] private GameObject inventoryUI;
[SerializeField] private int maxCapacity = 20;
[SerializeField] private List<Item> allItems = new List<Item>(); // All available items in game
private List<InventorySlot> inventorySlots = new List<InventorySlot>();
// Equipment slots
private Item equippedWeapon;
private Item equippedArmor;
private Item FindItemByName(string itemName)
{
return allItems.Find(i => i.itemName == itemName);
}
private Item FindItemByID(int itemID)
{
return allItems.Find(i => i.itemID == itemID);
}
public bool AddItem(string itemName, int quantity = 1)
{
Item item = FindItemByName(itemName);
if (item == null)
{
Debug.LogWarning($"Item '{itemName}' not found.");
return false;
}
return AddItemInternal(item, quantity);
}
public bool AddItem(int itemID, int quantity = 1)
{
Item item = FindItemByID(itemID);
if (item == null)
{
Debug.LogWarning($"Item with ID {itemID} not found.");
return false;
}
return AddItemInternal(item, quantity);
}
private bool AddItemInternal(Item item, int quantity = 1)
{
if (item == null)
{
Debug.LogWarning("Tried to add null item to inventory.");
return false;
}
// Try to add to existing stack if stackable
if (item.isStackable)
{
foreach (var slot in inventorySlots)
{
if (slot.item == item && slot.quantity < item.maxStackSize)
{
int spaceAvailable = item.maxStackSize - slot.quantity;
int amountToAdd = Mathf.Min(quantity, spaceAvailable);
slot.quantity += amountToAdd;
Debug.Log($"Added {amountToAdd} {item.itemName} to existing stack. Stack size: {slot.quantity}");
if (amountToAdd < quantity)
{
// Recursively add remaining items
return AddItemInternal(item, quantity - amountToAdd);
}
return true;
}
}
}
// Add new slot if space available
if (inventorySlots.Count < maxCapacity)
{
inventorySlots.Add(new InventorySlot(item, quantity));
Debug.Log($"Added {quantity} {item.itemName} to inventory. Slots used: {inventorySlots.Count}/{maxCapacity}");
return true;
}
Debug.Log("Inventory is full!");
return false;
}
public bool RemoveItem(string itemName, int quantity = 1)
{
Item item = FindItemByName(itemName);
if (item == null)
{
Debug.LogWarning($"Item '{itemName}' not found.");
return false;
}
return RemoveItemInternal(item, quantity);
}
public bool RemoveItem(int itemID, int quantity = 1)
{
Item item = FindItemByID(itemID);
if (item == null)
{
Debug.LogWarning($"Item with ID {itemID} not found.");
return false;
}
return RemoveItemInternal(item, quantity);
}
private bool RemoveItemInternal(Item item, int quantity = 1)
{
if (item == null)
{
Debug.LogWarning("Tried to remove null item from inventory.");
return false;
}
foreach (var slot in inventorySlots)
{
if (slot.item == item)
{
if (slot.quantity >= quantity)
{
slot.quantity -= quantity;
Debug.Log($"Removed {quantity} {item.itemName} from inventory.");
// Remove slot if empty
if (slot.quantity <= 0)
{
inventorySlots.Remove(slot);
}
return true;
}
else
{
Debug.LogWarning($"Not enough {item.itemName} in inventory. Have: {slot.quantity}, Need: {quantity}");
return false;
}
}
}
Debug.LogWarning($"{item.itemName} not found in inventory.");
return false;
}
public int GetItemQuantity(string itemName)
{
Item item = FindItemByName(itemName);
if (item == null) return 0;
return GetItemQuantityInternal(item);
}
public int GetItemQuantity(int itemID)
{
Item item = FindItemByID(itemID);
if (item == null) return 0;
return GetItemQuantityInternal(item);
}
private int GetItemQuantityInternal(Item item)
{
foreach (var slot in inventorySlots)
{
if (slot.item == item)
return slot.quantity;
}
return 0;
}
public List<InventorySlot> GetInventorySlots()
{
return new List<InventorySlot>(inventorySlots);
}
public int GetAvailableSlots()
{
return maxCapacity - inventorySlots.Count;
}
public void ClearInventory()
{
inventorySlots.Clear();
Debug.Log("Inventory cleared.");
}
public bool EquipItem(string itemName)
{
Item item = FindItemByName(itemName);
if (item == null)
{
Debug.LogWarning($"Item '{itemName}' not found.");
return false;
}
return EquipItemInternal(item);
}
public bool EquipItem(int itemID)
{
Item item = FindItemByID(itemID);
if (item == null)
{
Debug.LogWarning($"Item with ID {itemID} not found.");
return false;
}
return EquipItemInternal(item);
}
private bool EquipItemInternal(Item item)
{
if (item == null) return false;
if (item.itemType == Item.ItemType.Weapon)
{
if (equippedWeapon != null)
AddItemInternal(equippedWeapon);
equippedWeapon = item;
RemoveItemInternal(item, 1);
Debug.Log($"Equipped weapon: {item.itemName}");
return true;
}
else if (item.itemType == Item.ItemType.Armor)
{
if (equippedArmor != null)
AddItemInternal(equippedArmor);
equippedArmor = item;
RemoveItemInternal(item, 1);
Debug.Log($"Equipped armor: {item.itemName}");
return true;
}
return false;
}
public Item GetEquippedItem(Item.ItemType type)
{
return type == Item.ItemType.Weapon ? equippedWeapon :
type == Item.ItemType.Armor ? equippedArmor : null;
}
public bool UseItem(string itemName)
{
Item item = FindItemByName(itemName);
if (item == null)
{
Debug.LogWarning($"Item '{itemName}' not found.");
return false;
}
return UseItemInternal(item);
}
public bool UseItem(int itemID)
{
Item item = FindItemByID(itemID);
if (item == null)
{
Debug.LogWarning($"Item with ID {itemID} not found.");
return false;
}
return UseItemInternal(item);
}
private bool UseItemInternal(Item item)
{
if (item.itemType == Item.ItemType.Consumable)
{
Debug.Log($"Used {item.itemName}");
RemoveItemInternal(item, 1);
return true;
}
return false;
}
public bool DropItem(string itemName, int quantity = 1)
{
Item item = FindItemByName(itemName);
if (item == null)
{
Debug.LogWarning($"Item '{itemName}' not found.");
return false;
}
return DropItemInternal(item, quantity);
}
public bool DropItem(int itemID, int quantity = 1)
{
Item item = FindItemByID(itemID);
if (item == null)
{
Debug.LogWarning($"Item with ID {itemID} not found.");
return false;
}
return DropItemInternal(item, quantity);
}
private bool DropItemInternal(Item item, int quantity = 1)
{
if (RemoveItemInternal(item, quantity))
{
Debug.Log($"Dropped {quantity} {item.itemName}");
// TODO: Instantiate item drop in world
return true;
}
return false;
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 1c696bcbb1e2bba4489d42a102676ca1

View File

@@ -0,0 +1,67 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
public class InventoryItemUI : MonoBehaviour, IBeginDragHandler, IDragHandler, IEndDragHandler, IPointerClickHandler
{
private Item item;
private int quantity;
private InventoryUI inventoryUI;
private Image itemImage;
private Text quantityText;
private Canvas canvas;
private GraphicRaycaster raycaster;
private CanvasGroup canvasGroup;
public void Initialize(Item newItem, int qty, InventoryUI ui)
{
item = newItem;
quantity = qty;
inventoryUI = ui;
itemImage = GetComponent<Image>();
quantityText = GetComponentInChildren<Text>();
canvas = GetComponentInParent<Canvas>();
canvasGroup = GetComponent<CanvasGroup>();
if (itemImage != null && item.itemIcon != null)
itemImage.sprite = item.itemIcon;
if (quantityText != null)
quantityText.text = quantity > 1 ? quantity.ToString() : "";
// Make draggable
if (canvasGroup == null)
canvasGroup = gameObject.AddComponent<CanvasGroup>();
GetComponent<RectTransform>().sizeDelta = new Vector2(64, 64);
}
public void OnBeginDrag(PointerEventData eventData)
{
canvasGroup.alpha = 0.6f;
canvasGroup.blocksRaycasts = false;
}
public void OnDrag(PointerEventData eventData)
{
GetComponent<RectTransform>().anchoredPosition += eventData.delta / canvas.scaleFactor;
}
public void OnEndDrag(PointerEventData eventData)
{
canvasGroup.alpha = 1f;
canvasGroup.blocksRaycasts = true;
// Reset position on drop (TODO: check if dropped on equip slot)
GetComponent<RectTransform>().anchoredPosition = Vector2.zero;
}
public void OnPointerClick(PointerEventData eventData)
{
if (eventData.button == PointerEventData.InputButton.Right)
{
inventoryUI.ShowContextMenu(this, item);
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 29fa03381fdd17e4d952a4ea6ea898e1

View File

@@ -0,0 +1,176 @@
using UnityEngine;
using UnityEngine.UI;
using UnityEngine.EventSystems;
using System.Collections.Generic;
public class InventoryUI : MonoBehaviour
{
[SerializeField] private Transform inventoryContent; // Panel > ScrollView > Viewport > Content
[SerializeField] private GameObject inventoryItemPrefab;
[SerializeField] private Transform weaponSlot;
[SerializeField] private Transform armorSlot;
[SerializeField] private Inventory inventory;
private Canvas canvas;
private GameObject contextMenu;
private InventoryItemUI selectedItem;
void Start()
{
canvas = GetComponentInParent<Canvas>();
if (inventory == null)
inventory = FindObjectOfType<Inventory>();
RefreshInventoryUI();
}
public void RefreshInventoryUI()
{
// Clear existing items
foreach (Transform child in inventoryContent)
Destroy(child.gameObject);
// Populate inventory slots
var slots = inventory.GetInventorySlots();
foreach (var slot in slots)
{
CreateInventoryItemUI(slot.item, slot.quantity);
}
// Update equipment slots
UpdateEquipmentSlots();
}
private void CreateInventoryItemUI(Item item, int quantity)
{
GameObject itemUI = Instantiate(inventoryItemPrefab, inventoryContent);
InventoryItemUI itemScript = itemUI.GetComponent<InventoryItemUI>();
itemScript.Initialize(item, quantity, this);
}
private void UpdateEquipmentSlots()
{
Item equippedWeapon = inventory.GetEquippedItem(Item.ItemType.Weapon);
Item equippedArmor = inventory.GetEquippedItem(Item.ItemType.Armor);
UpdateEquipSlot(weaponSlot, equippedWeapon);
UpdateEquipSlot(armorSlot, equippedArmor);
}
private void UpdateEquipSlot(Transform slot, Item item)
{
Image slotImage = slot.GetComponent<Image>();
if (item != null && item.itemIcon != null)
{
slotImage.sprite = item.itemIcon;
slotImage.color = Color.white;
}
else
{
slotImage.sprite = null;
slotImage.color = new Color(1, 1, 1, 0.3f);
}
}
public void ShowContextMenu(InventoryItemUI itemUI, Item item)
{
selectedItem = itemUI;
if (contextMenu != null)
Destroy(contextMenu);
contextMenu = new GameObject("ContextMenu");
contextMenu.transform.SetParent(canvas.transform, false);
VerticalLayoutGroup layout = contextMenu.AddComponent<VerticalLayoutGroup>();
layout.childForceExpandHeight = false;
layout.childForceExpandWidth = false;
layout.spacing = 2;
LayoutElement layoutElement = contextMenu.AddComponent<LayoutElement>();
layoutElement.preferredWidth = 120;
layoutElement.preferredHeight = 140;
RectTransform rectTransform = contextMenu.GetComponent<RectTransform>();
rectTransform.sizeDelta = new Vector2(120, 140);
rectTransform.anchoredPosition = Input.mousePosition / canvas.scaleFactor;
Image bgImage = contextMenu.AddComponent<Image>();
bgImage.color = new Color(0.1f, 0.1f, 0.1f, 0.9f);
// Add menu options based on item type
if (item.itemType == Item.ItemType.Weapon || item.itemType == Item.ItemType.Armor)
AddMenuButton(contextMenu, "Equip", () => OnEquip(item));
if (item.itemType == Item.ItemType.Consumable)
AddMenuButton(contextMenu, "Use", () => OnUse(item));
AddMenuButton(contextMenu, "Info", () => OnInfo(item));
AddMenuButton(contextMenu, "Drop", () => OnDrop(item));
// Close menu on click elsewhere
StartCoroutine(WaitForClickOutside());
}
private void AddMenuButton(GameObject parent, string label, UnityEngine.Events.UnityAction onClick)
{
GameObject buttonObj = new GameObject(label);
buttonObj.transform.SetParent(parent.transform, false);
Button button = buttonObj.AddComponent<Button>();
Text text = buttonObj.AddComponent<Text>();
text.text = label;
text.font = Resources.GetBuiltinResource<Font>("Arial.ttf");
text.alignment = TextAnchor.MiddleCenter;
text.color = Color.white;
text.fontSize = 12;
RectTransform rect = buttonObj.GetComponent<RectTransform>();
rect.sizeDelta = new Vector2(100, 30);
LayoutElement layoutElement = buttonObj.AddComponent<LayoutElement>();
layoutElement.preferredWidth = 100;
layoutElement.preferredHeight = 30;
button.onClick.AddListener(onClick);
button.onClick.AddListener(() => Destroy(contextMenu));
}
private void OnEquip(Item item)
{
inventory.EquipItem(item.itemName);
RefreshInventoryUI();
}
private void OnUse(Item item)
{
inventory.UseItem(item.itemName);
RefreshInventoryUI();
}
private void OnInfo(Item item)
{
Debug.Log($"--- {item.itemName} ---\n{item.itemDescription}\nType: {item.itemType}\nID: {item.itemID}");
// TODO: Show item info panel
}
private void OnDrop(Item item)
{
inventory.DropItem(item.itemName, 1);
RefreshInventoryUI();
}
private System.Collections.IEnumerator WaitForClickOutside()
{
while (true)
{
if (Input.GetMouseButtonDown(0) && contextMenu != null)
{
// Destroy menu when clicking anywhere (simplified approach)
Destroy(contextMenu);
yield break;
}
yield return null;
}
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: fbb322e4f92cd9a40ac342f7d34a81d5

99
Assets/Scripts/Player.cs Normal file
View File

@@ -0,0 +1,99 @@
using UnityEngine;
using System.Collections.Generic;
using System.Linq;
[System.Serializable]
public class Skill // class, not struct
{
public enum SkillType { Swordsmanship, Archer, Magic, Unarmed, Stealth, Alchemy, Blacksmithing, Cooking, Speech, Perception, Lockpicking, Pickpocketing, Persuasion, Bartering, Leadership, Tactics, Strategy, Healing, Enchanting, Summoning, Necromancy, ElementalMagic, IllusionMagic, RestorationMagic, ConjurationMagic, DestructionMagic }
public SkillType skillType;
public enum SkillTier { Novice, Apprentice, Journeyman, Expert, Master }
public SkillTier skillTier;
public int level;
private static readonly Dictionary<SkillType, string> Descriptions = new Dictionary<SkillType, string>
{
{ SkillType.Swordsmanship, "Mastery of the sword." },
{ SkillType.Archer, "Mastery of the bow." },
{ SkillType.Magic, "Mastery of arcane arts." },
{ SkillType.Unarmed, "Mastery of hand-to-hand combat." },
{ SkillType.Stealth, "Mastery of moving unseen." },
{ SkillType.Alchemy, "Mastery of potion making and chemical reactions." },
{ SkillType.Blacksmithing, "Mastery of forging weapons and armor." },
{ SkillType.Cooking, "Mastery of preparing food and potions." },
{ SkillType.Speech, "Mastery of persuasion and communication." },
{ SkillType.Perception, "Mastery of noticing details and hidden objects." },
{ SkillType.Lockpicking, "Mastery of opening locks without a key." },
{ SkillType.Pickpocketing, "Mastery of stealing undetected." },
{ SkillType.Persuasion, "Mastery of convincing others." },
{ SkillType.Bartering, "Mastery of trading and negotiation." },
{ SkillType.Leadership, "Mastery of commanding others." },
{ SkillType.Tactics, "Mastery of battlefield planning." },
{ SkillType.Strategy, "Mastery of long-term planning and warfare." },
{ SkillType.Healing, "Mastery of mending wounds and ailments." },
{ SkillType.Enchanting, "Mastery of imbuing items with magic." },
{ SkillType.Summoning, "Mastery of calling forth creatures." },
{ SkillType.Necromancy, "Mastery of death and undead magic." },
{ SkillType.ElementalMagic, "Mastery of fire, ice, and lightning." },
{ SkillType.IllusionMagic, "Mastery of deceiving the senses." },
{ SkillType.RestorationMagic, "Mastery of healing and ward magic." },
{ SkillType.ConjurationMagic, "Mastery of summoning and binding." },
{ SkillType.DestructionMagic, "Mastery of destructive spells." },
};
public string Description => Descriptions.TryGetValue(skillType, out var desc) ? desc : string.Empty;
}
public class Player : MonoBehaviour
{
[Header("Player Stats")]
[SerializeField] private int maxHealth, maxStamina, maxMana;
private int curHealth, curStamina, curMana;
[Header("Player Skills")]
[SerializeField] private List<Skill> skillList = new List<Skill>(); // serializable
public Dictionary<string, Skill> skills; // runtime lookup
void Start()
{
skills = skillList.ToDictionary(s => s.skillType.ToString(), s => s); // convert list to dictionary for runtime lookup
// Initialize player stats
curHealth = maxHealth;
curStamina = maxStamina;
curMana = maxMana;
}
public void GetStats(out int health, out int stamina, out int mana)
{
health = curHealth;
stamina = curStamina;
mana = curMana;
}
public void GetSkills(out Dictionary<string, Skill> playerSkills)
{
playerSkills = new Dictionary<string, Skill>(skills);
}
public int GetSkillLevel(string skillName)
{
if (skills.TryGetValue(skillName, out Skill skill))
{
return skill.level;
}
else
{
Debug.LogWarning($"Skill '{skillName}' not found for player.");
return -1; // or throw an exception, or return a default value
}
}
public void TakeDamage(int damage)
{
curHealth -= damage;
if (curHealth <= 0)
{
Die();
}
}
private void Die()
{
Debug.Log("Player has died.");
// Handle player death (e.g., respawn, game over, etc.)
}
}

View File

@@ -0,0 +1,2 @@
fileFormatVersion: 2
guid: 03d6b15fc412de94cb7824b32753e73b

View File

@@ -1,114 +1,209 @@
using UnityEngine;
using System.Collections.Generic;
[System.Serializable]
public class Quest
{
public string questName;
public string questDescription;
public int requiredLevel;
public int rewardGold;
public int rewardExperience;
public int requiredQuantity;
public string[] prerequisiteNames; // Store quest names instead of direct references
}
public class Quests : MonoBehaviour
{
private string questName;
private string questDescription;
private int requiredLevel;
private int rewardGold;
private int rewardExperience;
private int requiredQuantity;
private Quests[] prerequisites;
private List<Quests> completedQuests = new List<Quests>();
private List<Quests> activeQuests = new List<Quests>();
private List<Quests> availableQuests = new List<Quests>();
// Start is called before the first frame update
[SerializeField] private List<Quest> completedQuests = new List<Quest>();
[SerializeField] private List<Quest> activeQuests = new List<Quest>();
[SerializeField] private List<Quest> availableQuests = new List<Quest>();
[SerializeField] private List<Quest> allQuests = new List<Quest>(); // All quests in the game
void Start()
{
RefreshAvailableQuests();
}
// Update is called once per frame
void Update()
{
}
public Quests(string name, string description, int level, int gold, int experience, int quantity, Quests[] prerequisites)
public void StartQuest(Quest quest)
{
this.questName = name;
this.questDescription = description;
this.requiredLevel = level;
this.rewardGold = gold;
this.rewardExperience = experience;
this.requiredQuantity = quantity;
this.prerequisites = prerequisites;
}
public void StartQuest()
{
// Logic to start the quest
activeQuests.Add(this);
}
public void CompleteQuest()
{
// Logic to complete the quest
activeQuests.Remove(this);
completedQuests.Add(this);
}
public void AbandonQuest()
{
// Logic to abandon the quest
activeQuests.Remove(this);
}
public void FailQuest()
{
// Logic to fail the quest
activeQuests.Remove(this);
}
public Quests[] GetPrerequisites()
{
return prerequisites;
}
public void GetQuestDetails()
{
// Logic to get quest details
Debug.Log($"Quest Name: {questName}");
Debug.Log($"Description: {questDescription}");
Debug.Log($"Required Level: {requiredLevel}");
Debug.Log($"Reward Gold: {rewardGold}");
Debug.Log($"Reward Experience: {rewardExperience}");
Debug.Log($"Required Quantity: {requiredQuantity}");
}
public void CheckQuestStatus()
{
// Logic to check the status of the quest
if (activeQuests.Contains(this))
if (availableQuests.Contains(quest) && !activeQuests.Contains(quest))
{
Debug.Log($"Quest '{questName}' is currently active.");
}
else if (completedQuests.Contains(this))
{
Debug.Log($"Quest '{questName}' has been completed.");
}
else
{
Debug.Log($"Quest '{questName}' is not active or completed.");
}
}
public void GetAvailableQuests()
{
// Logic to get available quests based on prerequisites and player level
// This is a placeholder implementation; you would typically check the player's level and completed quests
availableQuests.Clear();
if (prerequisites == null || prerequisites.Length == 0)
{
availableQuests.Add(this);
}
else
{
bool allPrerequisitesCompleted = true;
foreach (var prerequisite in prerequisites)
{
if (!completedQuests.Contains(prerequisite))
{
allPrerequisitesCompleted = false;
break;
}
}
if (allPrerequisitesCompleted)
{
availableQuests.Add(this);
}
activeQuests.Add(quest);
availableQuests.Remove(quest);
Debug.Log($"Quest '{quest.questName}' started.");
}
}
public void StartQuest(string questName)
{
Quest quest = allQuests.Find(q => q.questName == questName);
if (quest != null)
StartQuest(quest);
else
Debug.LogWarning($"Quest '{questName}' not found.");
}
public void CompleteQuest(Quest quest)
{
if (activeQuests.Contains(quest))
{
activeQuests.Remove(quest);
completedQuests.Add(quest);
Debug.Log($"Quest '{quest.questName}' completed.");
RefreshAvailableQuests(); // Unlock new quests
}
}
public void CompleteQuest(string questName)
{
Quest quest = allQuests.Find(q => q.questName == questName);
if (quest != null)
CompleteQuest(quest);
else
Debug.LogWarning($"Quest '{questName}' not found.");
}
public void AbandonQuest(Quest quest)
{
if (activeQuests.Contains(quest))
{
activeQuests.Remove(quest);
Debug.Log($"Quest '{quest.questName}' abandoned.");
}
}
public void AbandonQuest(string questName)
{
Quest quest = allQuests.Find(q => q.questName == questName);
if (quest != null)
AbandonQuest(quest);
else
Debug.LogWarning($"Quest '{questName}' not found.");
}
public void FailQuest(Quest quest)
{
if (activeQuests.Contains(quest))
{
activeQuests.Remove(quest);
Debug.Log($"Quest '{quest.questName}' failed.");
}
}
public void FailQuest(string questName)
{
Quest quest = allQuests.Find(q => q.questName == questName);
if (quest != null)
FailQuest(quest);
else
Debug.LogWarning($"Quest '{questName}' not found.");
}
public string[] GetPrerequisites(Quest quest)
{
return quest.prerequisiteNames;
}
private bool ArePrerequisitesMet(Quest quest)
{
if (quest.prerequisiteNames == null || quest.prerequisiteNames.Length == 0)
return true;
foreach (var prereqName in quest.prerequisiteNames)
{
Quest prereqQuest = allQuests.Find(q => q.questName == prereqName);
if (prereqQuest == null || !completedQuests.Contains(prereqQuest))
{
return false;
}
}
return true;
}
public void GetQuestDetails(Quest quest)
{
Debug.Log($"Quest Name: {quest.questName}");
Debug.Log($"Description: {quest.questDescription}");
Debug.Log($"Required Level: {quest.requiredLevel}");
Debug.Log($"Reward Gold: {quest.rewardGold}");
Debug.Log($"Reward Experience: {quest.rewardExperience}");
Debug.Log($"Required Quantity: {quest.requiredQuantity}");
}
public void GetQuestDetails(string questName)
{
Quest quest = allQuests.Find(q => q.questName == questName);
if (quest != null)
GetQuestDetails(quest);
else
Debug.LogWarning($"Quest '{questName}' not found.");
}
public void CheckQuestStatus(Quest quest)
{
if (activeQuests.Contains(quest))
{
Debug.Log($"Quest '{quest.questName}' is currently active.");
}
else if (completedQuests.Contains(quest))
{
Debug.Log($"Quest '{quest.questName}' has been completed.");
}
else if (availableQuests.Contains(quest))
{
Debug.Log($"Quest '{quest.questName}' is available.");
}
else
{
Debug.Log($"Quest '{quest.questName}' is not available.");
}
}
public void CheckQuestStatus(string questName)
{
Quest quest = allQuests.Find(q => q.questName == questName);
if (quest != null)
CheckQuestStatus(quest);
else
Debug.LogWarning($"Quest '{questName}' not found.");
}
public List<Quest> GetAvailableQuests()
{
return new List<Quest>(availableQuests);
}
public List<Quest> GetActiveQuests()
{
return new List<Quest>(activeQuests);
}
public List<Quest> GetCompletedQuests()
{
return new List<Quest>(completedQuests);
}
private void RefreshAvailableQuests()
{
availableQuests.Clear();
foreach (var quest in allQuests)
{
// Skip if already active or completed
if (activeQuests.Contains(quest) || completedQuests.Contains(quest))
continue;
// Check if prerequisites are met
if (ArePrerequisitesMet(quest))
{
availableQuests.Add(quest);
}
}
}
}