Farmhouse.cs 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247
  1. using System.Collections.Generic;
  2. using UnityEngine;
  3. public class Farmhouse : MonoBehaviour
  4. {
  5. [Header("Farmhouse Settings")]
  6. public int maxFarmers = 2; // How many farmers can live here
  7. public float fieldBuildRange = 10f; // How far from farmhouse fields can be built
  8. public List<Field> ownedFields = new List<Field>();
  9. public List<Villager> residentFarmers = new List<Villager>();
  10. [Header("Field Construction")]
  11. public GameObject fieldPrefab; // Will be created procedurally if null
  12. public FieldSize nextFieldSize = FieldSize.Small; // Size for next field to be built
  13. private Building buildingComponent;
  14. void Start()
  15. {
  16. buildingComponent = GetComponent<Building>();
  17. Debug.Log($"Farmhouse initialized - Max farmers: {maxFarmers}, Field range: {fieldBuildRange}");
  18. }
  19. void Update()
  20. {
  21. // Check if we need to assign farmers to field construction
  22. CheckFieldConstruction();
  23. // Update field management
  24. ManageFields();
  25. }
  26. public bool CanBuildField(Vector3 position)
  27. {
  28. // Check if position is within building range
  29. float distance = Vector3.Distance(transform.position, position);
  30. if (distance > fieldBuildRange)
  31. {
  32. Debug.Log($"Field position too far from farmhouse ({distance:F1}m > {fieldBuildRange}m)");
  33. return false;
  34. }
  35. // Check if we have farmers available to build
  36. if (GetAvailableFarmer() == null)
  37. {
  38. Debug.Log("No available farmers to build field");
  39. return false;
  40. }
  41. // Check for overlapping fields or other obstacles
  42. Collider[] overlapping = Physics.OverlapSphere(position, (int)nextFieldSize * 0.6f);
  43. foreach (var col in overlapping)
  44. {
  45. if (col.GetComponent<Field>() != null || col.GetComponent<Building>() != null)
  46. {
  47. Debug.Log($"Field position blocked by {col.name}");
  48. return false;
  49. }
  50. }
  51. return true;
  52. }
  53. public Field BuildField(Vector3 position, FieldSize size)
  54. {
  55. if (!CanBuildField(position)) return null;
  56. // Create field GameObject
  57. GameObject fieldObj = CreateFieldObject(position, size);
  58. Field field = fieldObj.GetComponent<Field>();
  59. // Set up field properties
  60. field.fieldSize = size;
  61. field.farmhouse = gameObject;
  62. field.isUnderConstruction = true;
  63. // Assign a farmer to build it
  64. Villager farmer = GetAvailableFarmer();
  65. if (farmer != null)
  66. {
  67. field.assignedFarmer = farmer;
  68. farmer.AssignToFieldConstruction(field);
  69. }
  70. // Add to owned fields
  71. ownedFields.Add(field);
  72. Debug.Log($"Started building {size} field at {position}. Assigned farmer: {farmer?.villagerName}");
  73. return field;
  74. }
  75. GameObject CreateFieldObject(Vector3 position, FieldSize size)
  76. {
  77. GameObject fieldObj;
  78. if (fieldPrefab != null)
  79. {
  80. fieldObj = Instantiate(fieldPrefab, position, Quaternion.identity);
  81. }
  82. else
  83. {
  84. // Create basic field
  85. fieldObj = GameObject.CreatePrimitive(PrimitiveType.Cube);
  86. fieldObj.name = $"Field_{size}";
  87. fieldObj.transform.position = position;
  88. fieldObj.transform.localScale = new Vector3((int)size, 0.1f, (int)size);
  89. // Make it look like a field
  90. Renderer renderer = fieldObj.GetComponent<Renderer>();
  91. renderer.material.color = new Color(0.4f, 0.3f, 0.2f); // Dirt brown initially
  92. }
  93. // Add Field component if not present
  94. if (fieldObj.GetComponent<Field>() == null)
  95. {
  96. fieldObj.AddComponent<Field>();
  97. }
  98. return fieldObj;
  99. }
  100. public Villager GetAvailableFarmer()
  101. {
  102. foreach (var farmer in residentFarmers)
  103. {
  104. if (farmer != null && farmer.currentJob == JobType.Farmer && farmer.state == VillagerState.Idle)
  105. {
  106. return farmer;
  107. }
  108. }
  109. return null;
  110. }
  111. public bool CanHouseFarmer()
  112. {
  113. return residentFarmers.Count < maxFarmers;
  114. }
  115. public bool AddFarmer(Villager farmer)
  116. {
  117. if (!CanHouseFarmer()) return false;
  118. if (!residentFarmers.Contains(farmer))
  119. {
  120. residentFarmers.Add(farmer);
  121. farmer.SetHomeBuilding(gameObject);
  122. Debug.Log($"Farmer {farmer.villagerName} now lives at farmhouse");
  123. return true;
  124. }
  125. return false;
  126. }
  127. public void RemoveFarmer(Villager farmer)
  128. {
  129. if (residentFarmers.Remove(farmer))
  130. {
  131. farmer.SetHomeBuilding(null);
  132. Debug.Log($"Farmer {farmer.villagerName} moved out of farmhouse");
  133. }
  134. }
  135. void CheckFieldConstruction()
  136. {
  137. // Check if any fields need farmers for construction
  138. foreach (var field in ownedFields)
  139. {
  140. if (field != null && field.isUnderConstruction && field.assignedFarmer == null)
  141. {
  142. Villager availableFarmer = GetAvailableFarmer();
  143. if (availableFarmer != null)
  144. {
  145. field.assignedFarmer = availableFarmer;
  146. availableFarmer.AssignToFieldConstruction(field);
  147. Debug.Log($"Assigned {availableFarmer.villagerName} to continue field construction");
  148. }
  149. }
  150. }
  151. }
  152. void ManageFields()
  153. {
  154. // Remove destroyed or null fields from the list
  155. ownedFields.RemoveAll(field => field == null);
  156. // Could add seasonal management, field rotation, etc. here later
  157. }
  158. public int GetTotalFoodProduction()
  159. {
  160. int totalFood = 0;
  161. foreach (var field in ownedFields)
  162. {
  163. if (field != null && !field.isUnderConstruction)
  164. {
  165. totalFood += field.currentFood;
  166. }
  167. }
  168. return totalFood;
  169. }
  170. public string GetFarmhouseInfo()
  171. {
  172. int totalFields = ownedFields.Count;
  173. int constructedFields = 0;
  174. int totalFood = 0;
  175. foreach (var field in ownedFields)
  176. {
  177. if (field != null)
  178. {
  179. if (!field.isUnderConstruction)
  180. {
  181. constructedFields++;
  182. totalFood += field.currentFood;
  183. }
  184. }
  185. }
  186. return $"Farmhouse\nFarmers: {residentFarmers.Count}/{maxFarmers}\nFields: {constructedFields}/{totalFields}\nTotal Food: {totalFood}";
  187. }
  188. // Method to be called by UI for building fields
  189. public void StartFieldConstruction(FieldSize size)
  190. {
  191. nextFieldSize = size;
  192. // The actual field placement will be handled by the building system
  193. // This just prepares the farmhouse for the next field
  194. Debug.Log($"Farmhouse ready to build {size} field");
  195. }
  196. void OnDrawGizmosSelected()
  197. {
  198. // Show field building range
  199. Gizmos.color = Color.green;
  200. Gizmos.DrawWireSphere(transform.position, fieldBuildRange);
  201. // Show connections to owned fields
  202. Gizmos.color = Color.yellow;
  203. foreach (var field in ownedFields)
  204. {
  205. if (field != null)
  206. {
  207. Gizmos.DrawLine(transform.position, field.transform.position);
  208. }
  209. }
  210. }
  211. }