Initial commit
This commit is contained in:
@@ -74,6 +74,15 @@ public class Building : MonoBehaviour
|
||||
{
|
||||
return buildingState;
|
||||
}
|
||||
public Resource.ResourceType[] GetResourceRequirement()
|
||||
{
|
||||
return constructionResources;
|
||||
}
|
||||
|
||||
public int[] GetConstructionCost()
|
||||
{
|
||||
return constructionCost;
|
||||
}
|
||||
private void SetBuildingModel(BuildingState state)
|
||||
{
|
||||
switch (state)
|
||||
@@ -105,24 +114,27 @@ public class Building : MonoBehaviour
|
||||
break;
|
||||
}
|
||||
}
|
||||
public void StartBuilding()
|
||||
{
|
||||
if (buildingState != BuildingState.Unbuilt)
|
||||
return;
|
||||
public void StartBuilding()
|
||||
{
|
||||
if (buildingState != BuildingState.Unbuilt)
|
||||
return;
|
||||
|
||||
for (int i = 0; i < constructionResources.Length && i < constructionCost.Length; i++)
|
||||
Resource.ResourceType[] resources = GetResourceRequirement();
|
||||
int[] costs = GetConstructionCost();
|
||||
|
||||
for (int i = 0; i < resources.Length && i < costs.Length; i++)
|
||||
{
|
||||
if (GameManager.Instance.GetResource(resources[i]) < costs[i])
|
||||
{
|
||||
if (GameManager.Instance.GetResource(constructionResources[i]) < constructionCost[i])
|
||||
{
|
||||
Debug.Log("Not enough resources");
|
||||
return;
|
||||
}
|
||||
GameManager.Instance.AddResource(constructionResources[i], -constructionCost[i]);
|
||||
Debug.Log("Not enough resources");
|
||||
return;
|
||||
}
|
||||
Debug.Log("Building Started");
|
||||
buildingState = BuildingState.Constructing;
|
||||
SetBuildingModel(buildingState);
|
||||
GameManager.Instance.AddResource(resources[i], -costs[i]);
|
||||
}
|
||||
Debug.Log("Building Started");
|
||||
buildingState = BuildingState.Constructing;
|
||||
SetBuildingModel(buildingState);
|
||||
}
|
||||
public void FinishBuilding()
|
||||
{
|
||||
if (buildingState != BuildingState.Constructing)
|
||||
|
||||
@@ -42,8 +42,17 @@ public class GameManager : MonoBehaviour
|
||||
population += amountToAdd;
|
||||
break;
|
||||
}
|
||||
// If the dictionary doesn't contain this resource yet, initialize it at 0
|
||||
if (!statistics.ContainsKey(resourceToAdd))
|
||||
{
|
||||
statistics.Add(resourceToAdd, 0);
|
||||
}
|
||||
statistics[resourceToAdd] += amountToAdd;
|
||||
UIController.Instance.UpdateStats();
|
||||
// Safety check to prevent a crash on Awake
|
||||
if (UIController.Instance != null)
|
||||
{
|
||||
UIController.Instance.UpdateStats();
|
||||
}
|
||||
}
|
||||
|
||||
public float GetResource(Resource.ResourceType resourceToGet)
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using UnityEngine;
|
||||
using System.Collections.Generic;
|
||||
|
||||
public class JobManager : MonoBehaviour
|
||||
{
|
||||
@@ -28,13 +29,57 @@ public class JobManager : MonoBehaviour
|
||||
private Building GetUnfinishedBuildings()
|
||||
{
|
||||
Building[] buildings = GameManager.Instance.CountBuildings();
|
||||
List<Building> candidates = new List<Building>();
|
||||
|
||||
foreach (Building building in buildings)
|
||||
{
|
||||
if(building.GetBuildingState() == Building.BuildingState.Unbuilt)
|
||||
var state = building.GetBuildingState();
|
||||
if (state == Building.BuildingState.Unbuilt)
|
||||
{
|
||||
return building;
|
||||
if (CanBuildBuilding(building))
|
||||
{
|
||||
candidates.Add(building);
|
||||
}
|
||||
}
|
||||
else if (state == Building.BuildingState.Constructing)
|
||||
{
|
||||
// Allow additional builders to join already-constructing buildings
|
||||
candidates.Add(building);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
||||
if (candidates.Count == 0)
|
||||
return null;
|
||||
|
||||
int idx = Random.Range(0, candidates.Count);
|
||||
return candidates[idx];
|
||||
}
|
||||
|
||||
private bool CanBuildBuilding(Building building)
|
||||
{
|
||||
Resource.ResourceType[] requiredResources = building.GetResourceRequirement();
|
||||
int[] requiredCosts = building.GetConstructionCost();
|
||||
|
||||
if (requiredResources == null || requiredCosts == null)
|
||||
{
|
||||
Debug.LogWarning("Building missing resource or cost arrays");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (requiredResources.Length != requiredCosts.Length)
|
||||
{
|
||||
Debug.LogWarning("Building resource and cost arrays don't match in length");
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < requiredResources.Length; i++)
|
||||
{
|
||||
if (GameManager.Instance.GetResource(requiredResources[i]) < requiredCosts[i])
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ public class NPC : MonoBehaviour
|
||||
|
||||
private Resource.ResourceType resourceToWorkWith, carryingResource;
|
||||
public Dictionary<Resource.ResourceType, int> inventory = new Dictionary<Resource.ResourceType, int>();
|
||||
public Dictionary<Skills.SkillType, Skills> skills = new Dictionary<Skills.SkillType, Skills>();
|
||||
|
||||
[SerializeField] int gatherAmount, inventoryCapacity;
|
||||
[SerializeField] NavMeshAgent navMeshAgent;
|
||||
@@ -74,7 +75,8 @@ public class NPC : MonoBehaviour
|
||||
}
|
||||
else
|
||||
{
|
||||
float distanceToTarget = Vector3.Distance(transform.position, currentTargetResource.transform.position);
|
||||
Vector3 targetPosition = GetResourceTargetPosition();
|
||||
float distanceToTarget = Vector3.Distance(transform.position, targetPosition);
|
||||
|
||||
if (distanceToTarget <= interactionRadius)
|
||||
{
|
||||
@@ -82,11 +84,21 @@ public class NPC : MonoBehaviour
|
||||
}
|
||||
else
|
||||
{
|
||||
MoveToLocation(currentTargetResource.transform.position);
|
||||
MoveToLocation(targetPosition);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Vector3 GetResourceTargetPosition()
|
||||
{
|
||||
if (currentTargetResource != null && job == Job.Miner && currentTargetResource.mineLocation != null)
|
||||
{
|
||||
return currentTargetResource.mineLocation.position;
|
||||
}
|
||||
|
||||
return currentTargetResource != null ? currentTargetResource.transform.position : transform.position;
|
||||
}
|
||||
|
||||
private void HandleDeliveryPhase()
|
||||
{
|
||||
// 1. Find a TownHall if we haven't cached one yet
|
||||
@@ -191,7 +203,7 @@ public class NPC : MonoBehaviour
|
||||
foreach (Resource res in resources)
|
||||
{
|
||||
if (res.resourceType == resourceToWorkWith && res.resourceState == Resource.ResourceState.Full)
|
||||
{
|
||||
{
|
||||
float distance = Vector3.Distance(transform.position, res.transform.position);
|
||||
if (distance < closestDistance)
|
||||
{
|
||||
@@ -204,7 +216,10 @@ public class NPC : MonoBehaviour
|
||||
if (closestResource != null)
|
||||
{
|
||||
currentTargetResource = closestResource;
|
||||
MoveToLocation(currentTargetResource.transform.position);
|
||||
if(this.job == Job.Miner)
|
||||
MoveToLocation(currentTargetResource.mineLocation.transform.position);
|
||||
else
|
||||
MoveToLocation(currentTargetResource.transform.position);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -250,7 +265,40 @@ public class NPC : MonoBehaviour
|
||||
}
|
||||
|
||||
currentTargetResource.RemoveResource(gatherAmount);
|
||||
AddToInventory(resourceToWorkWith, gatherAmount);
|
||||
|
||||
Skills.SkillType currentSkillType = resourceToWorkWith switch
|
||||
{
|
||||
Resource.ResourceType.Wood => Skills.SkillType.Woodcutting,
|
||||
Resource.ResourceType.Stone => Skills.SkillType.Stonecutting,
|
||||
Resource.ResourceType.Metal => Skills.SkillType.Mining,
|
||||
Resource.ResourceType.Food => Skills.SkillType.Farming,
|
||||
_ => Skills.SkillType.Woodcutting
|
||||
};
|
||||
|
||||
int currentSkillLevel = 1;
|
||||
if (skills.TryGetValue(currentSkillType, out Skills currentSkill))
|
||||
{
|
||||
currentSkillLevel = currentSkill.GetLevel(currentSkill.skillType);
|
||||
}
|
||||
|
||||
int bonusHarvest = Mathf.Max(0, currentSkillLevel - 1);
|
||||
AddToInventory(resourceToWorkWith, gatherAmount + bonusHarvest);
|
||||
|
||||
switch (resourceToWorkWith)
|
||||
{
|
||||
case Resource.ResourceType.Wood:
|
||||
GainExperience(Skills.SkillType.Woodcutting, 10);
|
||||
break;
|
||||
case Resource.ResourceType.Stone:
|
||||
GainExperience(Skills.SkillType.Stonecutting, 10);
|
||||
break;
|
||||
case Resource.ResourceType.Metal:
|
||||
GainExperience(Skills.SkillType.Mining, 10);
|
||||
break;
|
||||
case Resource.ResourceType.Food:
|
||||
GainExperience(Skills.SkillType.Farming, 10);
|
||||
break;
|
||||
}
|
||||
|
||||
if (currentTargetResource.GetResourceState() == false)
|
||||
{
|
||||
@@ -350,6 +398,18 @@ public class NPC : MonoBehaviour
|
||||
{
|
||||
return GetTotalInventoryAmount() + amountToAdd <= inventoryCapacity;
|
||||
}
|
||||
private void GainExperience(Skills.SkillType type, int amount)
|
||||
{
|
||||
// 1. Check if the dictionary does NOT contain the skill yet
|
||||
if (!skills.ContainsKey(type))
|
||||
{
|
||||
// The NPC learns the skill for the first time, using our new Constructor
|
||||
skills.Add(type, new Skills(type));
|
||||
}
|
||||
|
||||
// 2. Add the XP to that specific skill in the dictionary
|
||||
skills[type].AddExperience(amount);
|
||||
}
|
||||
|
||||
// Efficiency: Created a helper method so we aren't writing out the dictionary loop constantly
|
||||
private int GetTotalInventoryAmount()
|
||||
|
||||
@@ -22,6 +22,7 @@ public class Resource : MonoBehaviour
|
||||
[SerializeField] int maxResourceQuantity;
|
||||
private int curResourceQuantity;
|
||||
[SerializeField] private GameObject fullModel, depletedModel;
|
||||
public Transform mineLocation;
|
||||
// Start is called once before the first execution of Update after the MonoBehaviour is created
|
||||
void Start()
|
||||
{
|
||||
|
||||
53
Assets/Scripts/Skills.cs
Normal file
53
Assets/Scripts/Skills.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using UnityEngine;
|
||||
|
||||
// System.Serializable makes these show up in the Unity Inspector so you can debug NPC levels!
|
||||
[System.Serializable]
|
||||
public class Skills
|
||||
{
|
||||
public enum SkillType
|
||||
{
|
||||
Woodcutting,
|
||||
Stonecutting,
|
||||
Mining,
|
||||
Building,
|
||||
Farming // Added to match your Farmer job
|
||||
}
|
||||
|
||||
public SkillType skillType;
|
||||
public int skillExp;
|
||||
public int skillLevel;
|
||||
|
||||
// 1. The Constructor: This runs automatically when the NPC learns the skill for the first time
|
||||
public Skills(SkillType type)
|
||||
{
|
||||
skillType = type;
|
||||
skillLevel = 1;
|
||||
skillExp = 0;
|
||||
}
|
||||
|
||||
// 2. The Math: Handles gaining XP and checking for level ups
|
||||
public void AddExperience(int amount)
|
||||
{
|
||||
skillExp += amount;
|
||||
|
||||
// Example leveling formula: Level 1 requires 100xp, Level 2 requires 200xp, etc.
|
||||
int xpRequiredForNextLevel = skillLevel * 100;
|
||||
|
||||
if (skillExp >= xpRequiredForNextLevel)
|
||||
{
|
||||
// Subtract the requirement but keep the rollover XP
|
||||
skillExp -= xpRequiredForNextLevel;
|
||||
skillLevel++;
|
||||
|
||||
Debug.Log($"Leveled up! {skillType} is now Level {skillLevel}");
|
||||
}
|
||||
}
|
||||
public int GetLevel(SkillType type)
|
||||
{
|
||||
if (type == skillType)
|
||||
return skillLevel;
|
||||
|
||||
Debug.LogWarning($"Requested level for {type} but this skill is {skillType}");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/Skills.cs.meta
Normal file
2
Assets/Scripts/Skills.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 073eee246aee481449d8f5619dc58baa
|
||||
13
Assets/Scripts/SpinningWindmill.cs
Normal file
13
Assets/Scripts/SpinningWindmill.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using UnityEngine;
|
||||
|
||||
public class SpinningWindmill : MonoBehaviour
|
||||
{
|
||||
[SerializeField] private float rotationSpeed;
|
||||
[SerializeField] GameObject windmillBlades;
|
||||
|
||||
void Update()
|
||||
{
|
||||
//transform.Rotate(0f, 0f, rotationSpeed * Time.deltaTime);
|
||||
windmillBlades.transform.Rotate(0f, 0f, rotationSpeed * Time.deltaTime);
|
||||
}
|
||||
}
|
||||
2
Assets/Scripts/SpinningWindmill.cs.meta
Normal file
2
Assets/Scripts/SpinningWindmill.cs.meta
Normal file
@@ -0,0 +1,2 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9f8348a8c83d0884f864ffaf4554faa1
|
||||
Reference in New Issue
Block a user