From d329f501bee62d8ccb08892678d50cde11c11b12 Mon Sep 17 00:00:00 2001 From: Dmitry Evdokimov Date: Thu, 4 Jun 2026 23:22:13 +0300 Subject: [PATCH] first commit --- .gitignore | 65 + Assets/Editor.meta | 8 + Assets/Editor/Lab8SceneBuilder.cs | 1389 + Assets/Editor/Lab8SceneBuilder.cs.meta | 11 + Assets/Scenes.meta | 8 + Assets/Scenes/SampleScene.unity | 267 + Assets/Scenes/SampleScene.unity.meta | 7 + Assets/_Data.meta | 8 + Assets/_Data/Abilities.meta | 8 + Assets/_Data/Abilities/Blink.asset | 24 + Assets/_Data/Abilities/Blink.asset.meta | 8 + Assets/_Data/Abilities/Blink_Icon.png | Bin 0 -> 4550 bytes Assets/_Data/Abilities/Blink_Icon.png.meta | 114 + Assets/_Data/Abilities/Fireball.asset | 25 + Assets/_Data/Abilities/Fireball.asset.meta | 8 + Assets/_Data/Abilities/Fireball_Icon.png | Bin 0 -> 4175 bytes Assets/_Data/Abilities/Fireball_Icon.png.meta | 114 + Assets/_Data/Abilities/Heal.asset | 24 + Assets/_Data/Abilities/Heal.asset.meta | 8 + Assets/_Data/Abilities/Heal_Icon.png | Bin 0 -> 4425 bytes Assets/_Data/Abilities/Heal_Icon.png.meta | 114 + Assets/_Data/Dialogue.meta | 8 + .../_Data/Dialogue/Dialogue_Blacksmith.asset | 29 + .../Dialogue/Dialogue_Blacksmith.asset.meta | 8 + Assets/_Data/Dialogue/Dialogue_Elder.asset | 28 + .../_Data/Dialogue/Dialogue_Elder.asset.meta | 8 + Assets/_Data/Dialogue/Dialogue_Guard.asset | 29 + .../_Data/Dialogue/Dialogue_Guard.asset.meta | 8 + Assets/_Data/Dialogue/Dialogue_Mage.asset | 29 + .../_Data/Dialogue/Dialogue_Mage.asset.meta | 8 + Assets/_Data/Items.meta | 8 + Assets/_Data/Items/BasicSword.asset | 21 + Assets/_Data/Items/BasicSword.asset.meta | 8 + Assets/_Data/Items/BasicSword_Icon.png | Bin 0 -> 4534 bytes Assets/_Data/Items/BasicSword_Icon.png.meta | 114 + Assets/_Data/Items/Crystal.asset | 22 + Assets/_Data/Items/Crystal.asset.meta | 8 + Assets/_Data/Items/Crystal_Icon.png | Bin 0 -> 4604 bytes Assets/_Data/Items/Crystal_Icon.png.meta | 114 + Assets/_Data/Items/GoblinFang.asset | 21 + Assets/_Data/Items/GoblinFang.asset.meta | 8 + Assets/_Data/Items/GoblinFang_Icon.png | Bin 0 -> 4487 bytes Assets/_Data/Items/GoblinFang_Icon.png.meta | 114 + Assets/_Data/Items/HealthPotion.asset | 22 + Assets/_Data/Items/HealthPotion.asset.meta | 8 + Assets/_Data/Items/HealthPotion_Icon.png | Bin 0 -> 4428 bytes Assets/_Data/Items/HealthPotion_Icon.png.meta | 114 + Assets/_Data/Items/Herb.asset | 21 + Assets/_Data/Items/Herb.asset.meta | 8 + Assets/_Data/Items/Herb_Icon.png | Bin 0 -> 4131 bytes Assets/_Data/Items/Herb_Icon.png.meta | 114 + Assets/_Data/Items/IronAxe.asset | 22 + Assets/_Data/Items/IronAxe.asset.meta | 8 + Assets/_Data/Items/IronAxe_Icon.png | Bin 0 -> 4441 bytes Assets/_Data/Items/IronAxe_Icon.png.meta | 114 + Assets/_Data/Items/IronOre.asset | 22 + Assets/_Data/Items/IronOre.asset.meta | 8 + Assets/_Data/Items/IronOre_Icon.png | Bin 0 -> 4443 bytes Assets/_Data/Items/IronOre_Icon.png.meta | 114 + Assets/_Data/Items/ManaPotion.asset | 22 + Assets/_Data/Items/ManaPotion.asset.meta | 8 + Assets/_Data/Items/ManaPotion_Icon.png | Bin 0 -> 4221 bytes Assets/_Data/Items/ManaPotion_Icon.png.meta | 114 + Assets/_Data/Items/Stone.asset | 21 + Assets/_Data/Items/Stone.asset.meta | 8 + Assets/_Data/Items/Stone_Icon.png | Bin 0 -> 4334 bytes Assets/_Data/Items/Stone_Icon.png.meta | 114 + Assets/_Data/Items/Wood.asset | 23 + Assets/_Data/Items/Wood.asset.meta | 8 + Assets/_Data/Items/Wood_Icon.png | Bin 0 -> 4065 bytes Assets/_Data/Items/Wood_Icon.png.meta | 114 + Assets/_Data/Quests.meta | 8 + Assets/_Data/Quests/Quest_CraftAxe.asset | 31 + Assets/_Data/Quests/Quest_CraftAxe.asset.meta | 8 + Assets/_Data/Quests/Quest_GatherWood.asset | 30 + .../_Data/Quests/Quest_GatherWood.asset.meta | 8 + Assets/_Data/Quests/Quest_KillGoblins.asset | 31 + .../_Data/Quests/Quest_KillGoblins.asset.meta | 8 + Assets/_Data/Recipes.meta | 8 + .../_Data/Recipes/Recipe_HealthPotion.asset | 25 + .../Recipes/Recipe_HealthPotion.asset.meta | 8 + Assets/_Data/Recipes/Recipe_IronAxe.asset | 28 + .../_Data/Recipes/Recipe_IronAxe.asset.meta | 8 + Assets/_Data/Recipes/Recipe_ManaPotion.asset | 25 + .../Recipes/Recipe_ManaPotion.asset.meta | 8 + Assets/_Data/Talents.meta | 8 + Assets/_Data/Talents/AdvancedStrength.asset | 27 + .../_Data/Talents/AdvancedStrength.asset.meta | 8 + .../_Data/Talents/AdvancedStrength_Icon.png | Bin 0 -> 4340 bytes .../Talents/AdvancedStrength_Icon.png.meta | 114 + Assets/_Data/Talents/Agility.asset | 26 + Assets/_Data/Talents/Agility.asset.meta | 8 + Assets/_Data/Talents/Agility_Icon.png | Bin 0 -> 4340 bytes Assets/_Data/Talents/Agility_Icon.png.meta | 114 + Assets/_Data/Talents/ArcaneFlow.asset | 26 + Assets/_Data/Talents/ArcaneFlow.asset.meta | 8 + Assets/_Data/Talents/ArcaneFlow_Icon.png | Bin 0 -> 4340 bytes Assets/_Data/Talents/ArcaneFlow_Icon.png.meta | 114 + Assets/_Data/Talents/Strength.asset | 26 + Assets/_Data/Talents/Strength.asset.meta | 8 + Assets/_Data/Talents/Strength_Icon.png | Bin 0 -> 4340 bytes Assets/_Data/Talents/Strength_Icon.png.meta | 114 + Assets/_Data/Talents/Toughness.asset | 26 + Assets/_Data/Talents/Toughness.asset.meta | 8 + Assets/_Data/Talents/Toughness_Icon.png | Bin 0 -> 4340 bytes Assets/_Data/Talents/Toughness_Icon.png.meta | 114 + Assets/_Data/Weapons.meta | 8 + Assets/_Data/Weapons/BasicSword.asset | 23 + Assets/_Data/Weapons/BasicSword.asset.meta | 8 + Assets/_Data/Weapons/IronAxe.asset | 24 + Assets/_Data/Weapons/IronAxe.asset.meta | 8 + Assets/_Fonts.meta | 8 + Assets/_Fonts/Ubuntu-Bold.ttf | Bin 0 -> 333612 bytes Assets/_Fonts/Ubuntu-Bold.ttf.meta | 21 + Assets/_Fonts/Ubuntu-Regular.ttf | Bin 0 -> 353824 bytes Assets/_Fonts/Ubuntu-Regular.ttf.meta | 21 + Assets/_Materials.meta | 8 + Assets/_Materials/M_Blacksmith.mat | 83 + Assets/_Materials/M_Blacksmith.mat.meta | 8 + Assets/_Materials/M_Camp.mat | 83 + Assets/_Materials/M_Camp.mat.meta | 8 + Assets/_Materials/M_Crystal.mat | 84 + Assets/_Materials/M_Crystal.mat.meta | 8 + Assets/_Materials/M_Elder.mat | 83 + Assets/_Materials/M_Elder.mat.meta | 8 + Assets/_Materials/M_Fire.mat | 84 + Assets/_Materials/M_Fire.mat.meta | 8 + Assets/_Materials/M_Goblin.mat | 83 + Assets/_Materials/M_Goblin.mat.meta | 8 + Assets/_Materials/M_Ground.mat | 83 + Assets/_Materials/M_Ground.mat.meta | 8 + Assets/_Materials/M_Guard.mat | 83 + Assets/_Materials/M_Guard.mat.meta | 8 + Assets/_Materials/M_Herb.mat | 83 + Assets/_Materials/M_Herb.mat.meta | 8 + Assets/_Materials/M_Iron.mat | 83 + Assets/_Materials/M_Iron.mat.meta | 8 + Assets/_Materials/M_Leaves.mat | 83 + Assets/_Materials/M_Leaves.mat.meta | 8 + Assets/_Materials/M_Mage.mat | 83 + Assets/_Materials/M_Mage.mat.meta | 8 + Assets/_Materials/M_Mana.mat | 84 + Assets/_Materials/M_Mana.mat.meta | 8 + Assets/_Materials/M_Player.mat | 83 + Assets/_Materials/M_Player.mat.meta | 8 + Assets/_Materials/M_Stone.mat | 83 + Assets/_Materials/M_Stone.mat.meta | 8 + Assets/_Materials/M_Village.mat | 83 + Assets/_Materials/M_Village.mat.meta | 8 + Assets/_Materials/M_Wood.mat | 83 + Assets/_Materials/M_Wood.mat.meta | 8 + Assets/_Materials/M_Workbench.mat | 83 + Assets/_Materials/M_Workbench.mat.meta | 8 + Assets/_Prefabs.meta | 8 + Assets/_Prefabs/Characters.meta | 8 + Assets/_Prefabs/Effects.meta | 8 + Assets/_Prefabs/Effects/PF_BlinkEffect.prefab | 50 + .../Effects/PF_BlinkEffect.prefab.meta | 7 + .../_Prefabs/Effects/PF_FireballEffect.prefab | 157 + .../Effects/PF_FireballEffect.prefab.meta | 7 + Assets/_Prefabs/Effects/PF_HealEffect.prefab | 46 + .../Effects/PF_HealEffect.prefab.meta | 7 + Assets/_Prefabs/Items.meta | 8 + Assets/_Prefabs/UI.meta | 8 + Assets/_Scenes.meta | 8 + Assets/_Scenes/Lab08_IntegratedRPG.unity | 20872 ++++++++++++++++ Assets/_Scenes/Lab08_IntegratedRPG.unity.meta | 7 + Assets/_Scripts.meta | 8 + Assets/_Scripts/Abilities.meta | 8 + Assets/_Scripts/Abilities/AbilityData.cs | 36 + Assets/_Scripts/Abilities/AbilityData.cs.meta | 11 + Assets/_Scripts/Abilities/AbilityEffect.cs | 28 + .../_Scripts/Abilities/AbilityEffect.cs.meta | 11 + Assets/_Scripts/Abilities/AbilityManager.cs | 181 + .../_Scripts/Abilities/AbilityManager.cs.meta | 11 + Assets/_Scripts/Abilities/BlinkEffect.cs | 43 + Assets/_Scripts/Abilities/BlinkEffect.cs.meta | 11 + Assets/_Scripts/Abilities/FireballEffect.cs | 81 + .../_Scripts/Abilities/FireballEffect.cs.meta | 11 + Assets/_Scripts/Abilities/HealEffect.cs | 19 + Assets/_Scripts/Abilities/HealEffect.cs.meta | 11 + Assets/_Scripts/Combat.meta | 8 + Assets/_Scripts/Combat/Damageable.cs | 65 + Assets/_Scripts/Combat/Damageable.cs.meta | 11 + Assets/_Scripts/Combat/Enemy.cs | 125 + Assets/_Scripts/Combat/Enemy.cs.meta | 11 + Assets/_Scripts/Combat/FloatingDamage.cs | 55 + Assets/_Scripts/Combat/FloatingDamage.cs.meta | 11 + Assets/_Scripts/Core.meta | 8 + Assets/_Scripts/Core/GameEvents.cs | 44 + Assets/_Scripts/Core/GameEvents.cs.meta | 11 + Assets/_Scripts/Core/GameManager.cs | 114 + Assets/_Scripts/Core/GameManager.cs.meta | 11 + Assets/_Scripts/Crafting.meta | 8 + Assets/_Scripts/Crafting/CraftingSystem.cs | 196 + .../_Scripts/Crafting/CraftingSystem.cs.meta | 11 + Assets/_Scripts/Crafting/CraftingUI.cs | 228 + Assets/_Scripts/Crafting/CraftingUI.cs.meta | 11 + Assets/_Scripts/Crafting/RecipeData.cs | 69 + Assets/_Scripts/Crafting/RecipeData.cs.meta | 11 + Assets/_Scripts/Dialogue.meta | 8 + Assets/_Scripts/Dialogue/DialogueManager.cs | 249 + .../_Scripts/Dialogue/DialogueManager.cs.meta | 11 + Assets/_Scripts/Dialogue/DialogueNode.cs | 35 + Assets/_Scripts/Dialogue/DialogueNode.cs.meta | 11 + Assets/_Scripts/Dialogue/DialogueUI.cs | 141 + Assets/_Scripts/Dialogue/DialogueUI.cs.meta | 11 + Assets/_Scripts/Dialogue/NPCInteract.cs | 50 + Assets/_Scripts/Dialogue/NPCInteract.cs.meta | 11 + Assets/_Scripts/Inventory.meta | 8 + Assets/_Scripts/Inventory/Inventory.cs | 213 + Assets/_Scripts/Inventory/Inventory.cs.meta | 11 + Assets/_Scripts/Inventory/InventorySlot.cs | 35 + .../_Scripts/Inventory/InventorySlot.cs.meta | 11 + Assets/_Scripts/Inventory/InventoryUI.cs | 161 + Assets/_Scripts/Inventory/InventoryUI.cs.meta | 11 + Assets/_Scripts/Items.meta | 8 + Assets/_Scripts/Items/ItemData.cs | 40 + Assets/_Scripts/Items/ItemData.cs.meta | 11 + Assets/_Scripts/Items/ItemPickup.cs | 44 + Assets/_Scripts/Items/ItemPickup.cs.meta | 11 + Assets/_Scripts/Items/ResourceNode.cs | 90 + Assets/_Scripts/Items/ResourceNode.cs.meta | 11 + Assets/_Scripts/Player.meta | 8 + Assets/_Scripts/Player/PlayerController.cs | 139 + .../_Scripts/Player/PlayerController.cs.meta | 11 + Assets/_Scripts/Player/PlayerInteraction.cs | 105 + .../_Scripts/Player/PlayerInteraction.cs.meta | 11 + Assets/_Scripts/Quests.meta | 8 + Assets/_Scripts/Quests/QuestData.cs | 41 + Assets/_Scripts/Quests/QuestData.cs.meta | 11 + Assets/_Scripts/Quests/QuestGoal.cs | 64 + Assets/_Scripts/Quests/QuestGoal.cs.meta | 11 + Assets/_Scripts/Quests/QuestLogUI.cs | 172 + Assets/_Scripts/Quests/QuestLogUI.cs.meta | 11 + Assets/_Scripts/Quests/QuestManager.cs | 498 + Assets/_Scripts/Quests/QuestManager.cs.meta | 11 + Assets/_Scripts/Save.meta | 8 + Assets/_Scripts/Save/GameSaveData.cs | 24 + Assets/_Scripts/Save/GameSaveData.cs.meta | 11 + Assets/_Scripts/Save/SaveSystem.cs | 152 + Assets/_Scripts/Save/SaveSystem.cs.meta | 11 + Assets/_Scripts/Stats.meta | 8 + Assets/_Scripts/Stats/LevelSystem.cs | 85 + Assets/_Scripts/Stats/LevelSystem.cs.meta | 11 + Assets/_Scripts/Stats/ModifierType.cs | 9 + Assets/_Scripts/Stats/ModifierType.cs.meta | 11 + Assets/_Scripts/Stats/PlayerStats.cs | 325 + Assets/_Scripts/Stats/PlayerStats.cs.meta | 11 + Assets/_Scripts/Stats/StatModifier.cs | 21 + Assets/_Scripts/Stats/StatModifier.cs.meta | 11 + Assets/_Scripts/Stats/StatType.cs | 12 + Assets/_Scripts/Stats/StatType.cs.meta | 11 + Assets/_Scripts/Talents.meta | 8 + Assets/_Scripts/Talents/TalentData.cs | 33 + Assets/_Scripts/Talents/TalentData.cs.meta | 11 + Assets/_Scripts/Talents/TalentManager.cs | 268 + Assets/_Scripts/Talents/TalentManager.cs.meta | 11 + Assets/_Scripts/Talents/TalentNodeUI.cs | 110 + Assets/_Scripts/Talents/TalentNodeUI.cs.meta | 11 + Assets/_Scripts/Talents/TalentTooltipUI.cs | 39 + .../_Scripts/Talents/TalentTooltipUI.cs.meta | 11 + Assets/_Scripts/Talents/TalentTreeUI.cs | 231 + Assets/_Scripts/Talents/TalentTreeUI.cs.meta | 11 + Assets/_Scripts/UI.meta | 8 + Assets/_Scripts/UI/HUDController.cs | 171 + Assets/_Scripts/UI/HUDController.cs.meta | 11 + Assets/_Scripts/UI/InteractionPromptUI.cs | 40 + .../_Scripts/UI/InteractionPromptUI.cs.meta | 11 + Assets/_Scripts/UI/NotificationUI.cs | 90 + Assets/_Scripts/UI/NotificationUI.cs.meta | 11 + Assets/_Scripts/UI/TooltipUI.cs | 40 + Assets/_Scripts/UI/TooltipUI.cs.meta | 11 + Assets/_Scripts/UI/UIManager.cs | 242 + Assets/_Scripts/UI/UIManager.cs.meta | 11 + Assets/_Scripts/UI/UITheme.cs | 29 + Assets/_Scripts/UI/UITheme.cs.meta | 11 + Assets/_Scripts/Weapons.meta | 8 + Assets/_Scripts/Weapons/WeaponController.cs | 90 + .../_Scripts/Weapons/WeaponController.cs.meta | 11 + Assets/_Scripts/Weapons/WeaponData.cs | 35 + Assets/_Scripts/Weapons/WeaponData.cs.meta | 11 + Assets/_Scripts/Weapons/WeaponManager.cs | 186 + Assets/_Scripts/Weapons/WeaponManager.cs.meta | 11 + Packages/manifest.json | 41 + Packages/packages-lock.json | 382 + ProjectSettings/AudioManager.asset | 19 + ProjectSettings/ClusterInputManager.asset | 6 + ProjectSettings/DynamicsManager.asset | 34 + ProjectSettings/EditorBuildSettings.asset | 11 + ProjectSettings/EditorSettings.asset | 30 + ProjectSettings/GraphicsSettings.asset | 63 + ProjectSettings/InputManager.asset | 295 + ProjectSettings/MemorySettings.asset | 35 + ProjectSettings/NavMeshAreas.asset | 91 + ProjectSettings/PackageManagerSettings.asset | 35 + .../Settings.json | 5 + ProjectSettings/Physics2DSettings.asset | 56 + ProjectSettings/PresetManager.asset | 7 + ProjectSettings/ProjectSettings.asset | 772 + ProjectSettings/ProjectVersion.txt | 2 + ProjectSettings/QualitySettings.asset | 234 + ProjectSettings/SceneTemplateSettings.json | 121 + ProjectSettings/TagManager.asset | 43 + ProjectSettings/TimeManager.asset | 9 + ProjectSettings/UnityConnectSettings.asset | 36 + ProjectSettings/VFXManager.asset | 12 + ProjectSettings/VersionControlSettings.asset | 8 + ProjectSettings/XRSettings.asset | 10 + ЛР8_Интеграция_наработок_ОТГ.docx | Bin 0 -> 88580 bytes 310 files changed, 36395 insertions(+) create mode 100644 .gitignore create mode 100644 Assets/Editor.meta create mode 100644 Assets/Editor/Lab8SceneBuilder.cs create mode 100644 Assets/Editor/Lab8SceneBuilder.cs.meta create mode 100644 Assets/Scenes.meta create mode 100644 Assets/Scenes/SampleScene.unity create mode 100644 Assets/Scenes/SampleScene.unity.meta create mode 100644 Assets/_Data.meta create mode 100644 Assets/_Data/Abilities.meta create mode 100644 Assets/_Data/Abilities/Blink.asset create mode 100644 Assets/_Data/Abilities/Blink.asset.meta create mode 100644 Assets/_Data/Abilities/Blink_Icon.png create mode 100644 Assets/_Data/Abilities/Blink_Icon.png.meta create mode 100644 Assets/_Data/Abilities/Fireball.asset create mode 100644 Assets/_Data/Abilities/Fireball.asset.meta create mode 100644 Assets/_Data/Abilities/Fireball_Icon.png create mode 100644 Assets/_Data/Abilities/Fireball_Icon.png.meta create mode 100644 Assets/_Data/Abilities/Heal.asset create mode 100644 Assets/_Data/Abilities/Heal.asset.meta create mode 100644 Assets/_Data/Abilities/Heal_Icon.png create mode 100644 Assets/_Data/Abilities/Heal_Icon.png.meta create mode 100644 Assets/_Data/Dialogue.meta create mode 100644 Assets/_Data/Dialogue/Dialogue_Blacksmith.asset create mode 100644 Assets/_Data/Dialogue/Dialogue_Blacksmith.asset.meta create mode 100644 Assets/_Data/Dialogue/Dialogue_Elder.asset create mode 100644 Assets/_Data/Dialogue/Dialogue_Elder.asset.meta create mode 100644 Assets/_Data/Dialogue/Dialogue_Guard.asset create mode 100644 Assets/_Data/Dialogue/Dialogue_Guard.asset.meta create mode 100644 Assets/_Data/Dialogue/Dialogue_Mage.asset create mode 100644 Assets/_Data/Dialogue/Dialogue_Mage.asset.meta create mode 100644 Assets/_Data/Items.meta create mode 100644 Assets/_Data/Items/BasicSword.asset create mode 100644 Assets/_Data/Items/BasicSword.asset.meta create mode 100644 Assets/_Data/Items/BasicSword_Icon.png create mode 100644 Assets/_Data/Items/BasicSword_Icon.png.meta create mode 100644 Assets/_Data/Items/Crystal.asset create mode 100644 Assets/_Data/Items/Crystal.asset.meta create mode 100644 Assets/_Data/Items/Crystal_Icon.png create mode 100644 Assets/_Data/Items/Crystal_Icon.png.meta create mode 100644 Assets/_Data/Items/GoblinFang.asset create mode 100644 Assets/_Data/Items/GoblinFang.asset.meta create mode 100644 Assets/_Data/Items/GoblinFang_Icon.png create mode 100644 Assets/_Data/Items/GoblinFang_Icon.png.meta create mode 100644 Assets/_Data/Items/HealthPotion.asset create mode 100644 Assets/_Data/Items/HealthPotion.asset.meta create mode 100644 Assets/_Data/Items/HealthPotion_Icon.png create mode 100644 Assets/_Data/Items/HealthPotion_Icon.png.meta create mode 100644 Assets/_Data/Items/Herb.asset create mode 100644 Assets/_Data/Items/Herb.asset.meta create mode 100644 Assets/_Data/Items/Herb_Icon.png create mode 100644 Assets/_Data/Items/Herb_Icon.png.meta create mode 100644 Assets/_Data/Items/IronAxe.asset create mode 100644 Assets/_Data/Items/IronAxe.asset.meta create mode 100644 Assets/_Data/Items/IronAxe_Icon.png create mode 100644 Assets/_Data/Items/IronAxe_Icon.png.meta create mode 100644 Assets/_Data/Items/IronOre.asset create mode 100644 Assets/_Data/Items/IronOre.asset.meta create mode 100644 Assets/_Data/Items/IronOre_Icon.png create mode 100644 Assets/_Data/Items/IronOre_Icon.png.meta create mode 100644 Assets/_Data/Items/ManaPotion.asset create mode 100644 Assets/_Data/Items/ManaPotion.asset.meta create mode 100644 Assets/_Data/Items/ManaPotion_Icon.png create mode 100644 Assets/_Data/Items/ManaPotion_Icon.png.meta create mode 100644 Assets/_Data/Items/Stone.asset create mode 100644 Assets/_Data/Items/Stone.asset.meta create mode 100644 Assets/_Data/Items/Stone_Icon.png create mode 100644 Assets/_Data/Items/Stone_Icon.png.meta create mode 100644 Assets/_Data/Items/Wood.asset create mode 100644 Assets/_Data/Items/Wood.asset.meta create mode 100644 Assets/_Data/Items/Wood_Icon.png create mode 100644 Assets/_Data/Items/Wood_Icon.png.meta create mode 100644 Assets/_Data/Quests.meta create mode 100644 Assets/_Data/Quests/Quest_CraftAxe.asset create mode 100644 Assets/_Data/Quests/Quest_CraftAxe.asset.meta create mode 100644 Assets/_Data/Quests/Quest_GatherWood.asset create mode 100644 Assets/_Data/Quests/Quest_GatherWood.asset.meta create mode 100644 Assets/_Data/Quests/Quest_KillGoblins.asset create mode 100644 Assets/_Data/Quests/Quest_KillGoblins.asset.meta create mode 100644 Assets/_Data/Recipes.meta create mode 100644 Assets/_Data/Recipes/Recipe_HealthPotion.asset create mode 100644 Assets/_Data/Recipes/Recipe_HealthPotion.asset.meta create mode 100644 Assets/_Data/Recipes/Recipe_IronAxe.asset create mode 100644 Assets/_Data/Recipes/Recipe_IronAxe.asset.meta create mode 100644 Assets/_Data/Recipes/Recipe_ManaPotion.asset create mode 100644 Assets/_Data/Recipes/Recipe_ManaPotion.asset.meta create mode 100644 Assets/_Data/Talents.meta create mode 100644 Assets/_Data/Talents/AdvancedStrength.asset create mode 100644 Assets/_Data/Talents/AdvancedStrength.asset.meta create mode 100644 Assets/_Data/Talents/AdvancedStrength_Icon.png create mode 100644 Assets/_Data/Talents/AdvancedStrength_Icon.png.meta create mode 100644 Assets/_Data/Talents/Agility.asset create mode 100644 Assets/_Data/Talents/Agility.asset.meta create mode 100644 Assets/_Data/Talents/Agility_Icon.png create mode 100644 Assets/_Data/Talents/Agility_Icon.png.meta create mode 100644 Assets/_Data/Talents/ArcaneFlow.asset create mode 100644 Assets/_Data/Talents/ArcaneFlow.asset.meta create mode 100644 Assets/_Data/Talents/ArcaneFlow_Icon.png create mode 100644 Assets/_Data/Talents/ArcaneFlow_Icon.png.meta create mode 100644 Assets/_Data/Talents/Strength.asset create mode 100644 Assets/_Data/Talents/Strength.asset.meta create mode 100644 Assets/_Data/Talents/Strength_Icon.png create mode 100644 Assets/_Data/Talents/Strength_Icon.png.meta create mode 100644 Assets/_Data/Talents/Toughness.asset create mode 100644 Assets/_Data/Talents/Toughness.asset.meta create mode 100644 Assets/_Data/Talents/Toughness_Icon.png create mode 100644 Assets/_Data/Talents/Toughness_Icon.png.meta create mode 100644 Assets/_Data/Weapons.meta create mode 100644 Assets/_Data/Weapons/BasicSword.asset create mode 100644 Assets/_Data/Weapons/BasicSword.asset.meta create mode 100644 Assets/_Data/Weapons/IronAxe.asset create mode 100644 Assets/_Data/Weapons/IronAxe.asset.meta create mode 100644 Assets/_Fonts.meta create mode 100644 Assets/_Fonts/Ubuntu-Bold.ttf create mode 100644 Assets/_Fonts/Ubuntu-Bold.ttf.meta create mode 100644 Assets/_Fonts/Ubuntu-Regular.ttf create mode 100644 Assets/_Fonts/Ubuntu-Regular.ttf.meta create mode 100644 Assets/_Materials.meta create mode 100644 Assets/_Materials/M_Blacksmith.mat create mode 100644 Assets/_Materials/M_Blacksmith.mat.meta create mode 100644 Assets/_Materials/M_Camp.mat create mode 100644 Assets/_Materials/M_Camp.mat.meta create mode 100644 Assets/_Materials/M_Crystal.mat create mode 100644 Assets/_Materials/M_Crystal.mat.meta create mode 100644 Assets/_Materials/M_Elder.mat create mode 100644 Assets/_Materials/M_Elder.mat.meta create mode 100644 Assets/_Materials/M_Fire.mat create mode 100644 Assets/_Materials/M_Fire.mat.meta create mode 100644 Assets/_Materials/M_Goblin.mat create mode 100644 Assets/_Materials/M_Goblin.mat.meta create mode 100644 Assets/_Materials/M_Ground.mat create mode 100644 Assets/_Materials/M_Ground.mat.meta create mode 100644 Assets/_Materials/M_Guard.mat create mode 100644 Assets/_Materials/M_Guard.mat.meta create mode 100644 Assets/_Materials/M_Herb.mat create mode 100644 Assets/_Materials/M_Herb.mat.meta create mode 100644 Assets/_Materials/M_Iron.mat create mode 100644 Assets/_Materials/M_Iron.mat.meta create mode 100644 Assets/_Materials/M_Leaves.mat create mode 100644 Assets/_Materials/M_Leaves.mat.meta create mode 100644 Assets/_Materials/M_Mage.mat create mode 100644 Assets/_Materials/M_Mage.mat.meta create mode 100644 Assets/_Materials/M_Mana.mat create mode 100644 Assets/_Materials/M_Mana.mat.meta create mode 100644 Assets/_Materials/M_Player.mat create mode 100644 Assets/_Materials/M_Player.mat.meta create mode 100644 Assets/_Materials/M_Stone.mat create mode 100644 Assets/_Materials/M_Stone.mat.meta create mode 100644 Assets/_Materials/M_Village.mat create mode 100644 Assets/_Materials/M_Village.mat.meta create mode 100644 Assets/_Materials/M_Wood.mat create mode 100644 Assets/_Materials/M_Wood.mat.meta create mode 100644 Assets/_Materials/M_Workbench.mat create mode 100644 Assets/_Materials/M_Workbench.mat.meta create mode 100644 Assets/_Prefabs.meta create mode 100644 Assets/_Prefabs/Characters.meta create mode 100644 Assets/_Prefabs/Effects.meta create mode 100644 Assets/_Prefabs/Effects/PF_BlinkEffect.prefab create mode 100644 Assets/_Prefabs/Effects/PF_BlinkEffect.prefab.meta create mode 100644 Assets/_Prefabs/Effects/PF_FireballEffect.prefab create mode 100644 Assets/_Prefabs/Effects/PF_FireballEffect.prefab.meta create mode 100644 Assets/_Prefabs/Effects/PF_HealEffect.prefab create mode 100644 Assets/_Prefabs/Effects/PF_HealEffect.prefab.meta create mode 100644 Assets/_Prefabs/Items.meta create mode 100644 Assets/_Prefabs/UI.meta create mode 100644 Assets/_Scenes.meta create mode 100644 Assets/_Scenes/Lab08_IntegratedRPG.unity create mode 100644 Assets/_Scenes/Lab08_IntegratedRPG.unity.meta create mode 100644 Assets/_Scripts.meta create mode 100644 Assets/_Scripts/Abilities.meta create mode 100644 Assets/_Scripts/Abilities/AbilityData.cs create mode 100644 Assets/_Scripts/Abilities/AbilityData.cs.meta create mode 100644 Assets/_Scripts/Abilities/AbilityEffect.cs create mode 100644 Assets/_Scripts/Abilities/AbilityEffect.cs.meta create mode 100644 Assets/_Scripts/Abilities/AbilityManager.cs create mode 100644 Assets/_Scripts/Abilities/AbilityManager.cs.meta create mode 100644 Assets/_Scripts/Abilities/BlinkEffect.cs create mode 100644 Assets/_Scripts/Abilities/BlinkEffect.cs.meta create mode 100644 Assets/_Scripts/Abilities/FireballEffect.cs create mode 100644 Assets/_Scripts/Abilities/FireballEffect.cs.meta create mode 100644 Assets/_Scripts/Abilities/HealEffect.cs create mode 100644 Assets/_Scripts/Abilities/HealEffect.cs.meta create mode 100644 Assets/_Scripts/Combat.meta create mode 100644 Assets/_Scripts/Combat/Damageable.cs create mode 100644 Assets/_Scripts/Combat/Damageable.cs.meta create mode 100644 Assets/_Scripts/Combat/Enemy.cs create mode 100644 Assets/_Scripts/Combat/Enemy.cs.meta create mode 100644 Assets/_Scripts/Combat/FloatingDamage.cs create mode 100644 Assets/_Scripts/Combat/FloatingDamage.cs.meta create mode 100644 Assets/_Scripts/Core.meta create mode 100644 Assets/_Scripts/Core/GameEvents.cs create mode 100644 Assets/_Scripts/Core/GameEvents.cs.meta create mode 100644 Assets/_Scripts/Core/GameManager.cs create mode 100644 Assets/_Scripts/Core/GameManager.cs.meta create mode 100644 Assets/_Scripts/Crafting.meta create mode 100644 Assets/_Scripts/Crafting/CraftingSystem.cs create mode 100644 Assets/_Scripts/Crafting/CraftingSystem.cs.meta create mode 100644 Assets/_Scripts/Crafting/CraftingUI.cs create mode 100644 Assets/_Scripts/Crafting/CraftingUI.cs.meta create mode 100644 Assets/_Scripts/Crafting/RecipeData.cs create mode 100644 Assets/_Scripts/Crafting/RecipeData.cs.meta create mode 100644 Assets/_Scripts/Dialogue.meta create mode 100644 Assets/_Scripts/Dialogue/DialogueManager.cs create mode 100644 Assets/_Scripts/Dialogue/DialogueManager.cs.meta create mode 100644 Assets/_Scripts/Dialogue/DialogueNode.cs create mode 100644 Assets/_Scripts/Dialogue/DialogueNode.cs.meta create mode 100644 Assets/_Scripts/Dialogue/DialogueUI.cs create mode 100644 Assets/_Scripts/Dialogue/DialogueUI.cs.meta create mode 100644 Assets/_Scripts/Dialogue/NPCInteract.cs create mode 100644 Assets/_Scripts/Dialogue/NPCInteract.cs.meta create mode 100644 Assets/_Scripts/Inventory.meta create mode 100644 Assets/_Scripts/Inventory/Inventory.cs create mode 100644 Assets/_Scripts/Inventory/Inventory.cs.meta create mode 100644 Assets/_Scripts/Inventory/InventorySlot.cs create mode 100644 Assets/_Scripts/Inventory/InventorySlot.cs.meta create mode 100644 Assets/_Scripts/Inventory/InventoryUI.cs create mode 100644 Assets/_Scripts/Inventory/InventoryUI.cs.meta create mode 100644 Assets/_Scripts/Items.meta create mode 100644 Assets/_Scripts/Items/ItemData.cs create mode 100644 Assets/_Scripts/Items/ItemData.cs.meta create mode 100644 Assets/_Scripts/Items/ItemPickup.cs create mode 100644 Assets/_Scripts/Items/ItemPickup.cs.meta create mode 100644 Assets/_Scripts/Items/ResourceNode.cs create mode 100644 Assets/_Scripts/Items/ResourceNode.cs.meta create mode 100644 Assets/_Scripts/Player.meta create mode 100644 Assets/_Scripts/Player/PlayerController.cs create mode 100644 Assets/_Scripts/Player/PlayerController.cs.meta create mode 100644 Assets/_Scripts/Player/PlayerInteraction.cs create mode 100644 Assets/_Scripts/Player/PlayerInteraction.cs.meta create mode 100644 Assets/_Scripts/Quests.meta create mode 100644 Assets/_Scripts/Quests/QuestData.cs create mode 100644 Assets/_Scripts/Quests/QuestData.cs.meta create mode 100644 Assets/_Scripts/Quests/QuestGoal.cs create mode 100644 Assets/_Scripts/Quests/QuestGoal.cs.meta create mode 100644 Assets/_Scripts/Quests/QuestLogUI.cs create mode 100644 Assets/_Scripts/Quests/QuestLogUI.cs.meta create mode 100644 Assets/_Scripts/Quests/QuestManager.cs create mode 100644 Assets/_Scripts/Quests/QuestManager.cs.meta create mode 100644 Assets/_Scripts/Save.meta create mode 100644 Assets/_Scripts/Save/GameSaveData.cs create mode 100644 Assets/_Scripts/Save/GameSaveData.cs.meta create mode 100644 Assets/_Scripts/Save/SaveSystem.cs create mode 100644 Assets/_Scripts/Save/SaveSystem.cs.meta create mode 100644 Assets/_Scripts/Stats.meta create mode 100644 Assets/_Scripts/Stats/LevelSystem.cs create mode 100644 Assets/_Scripts/Stats/LevelSystem.cs.meta create mode 100644 Assets/_Scripts/Stats/ModifierType.cs create mode 100644 Assets/_Scripts/Stats/ModifierType.cs.meta create mode 100644 Assets/_Scripts/Stats/PlayerStats.cs create mode 100644 Assets/_Scripts/Stats/PlayerStats.cs.meta create mode 100644 Assets/_Scripts/Stats/StatModifier.cs create mode 100644 Assets/_Scripts/Stats/StatModifier.cs.meta create mode 100644 Assets/_Scripts/Stats/StatType.cs create mode 100644 Assets/_Scripts/Stats/StatType.cs.meta create mode 100644 Assets/_Scripts/Talents.meta create mode 100644 Assets/_Scripts/Talents/TalentData.cs create mode 100644 Assets/_Scripts/Talents/TalentData.cs.meta create mode 100644 Assets/_Scripts/Talents/TalentManager.cs create mode 100644 Assets/_Scripts/Talents/TalentManager.cs.meta create mode 100644 Assets/_Scripts/Talents/TalentNodeUI.cs create mode 100644 Assets/_Scripts/Talents/TalentNodeUI.cs.meta create mode 100644 Assets/_Scripts/Talents/TalentTooltipUI.cs create mode 100644 Assets/_Scripts/Talents/TalentTooltipUI.cs.meta create mode 100644 Assets/_Scripts/Talents/TalentTreeUI.cs create mode 100644 Assets/_Scripts/Talents/TalentTreeUI.cs.meta create mode 100644 Assets/_Scripts/UI.meta create mode 100644 Assets/_Scripts/UI/HUDController.cs create mode 100644 Assets/_Scripts/UI/HUDController.cs.meta create mode 100644 Assets/_Scripts/UI/InteractionPromptUI.cs create mode 100644 Assets/_Scripts/UI/InteractionPromptUI.cs.meta create mode 100644 Assets/_Scripts/UI/NotificationUI.cs create mode 100644 Assets/_Scripts/UI/NotificationUI.cs.meta create mode 100644 Assets/_Scripts/UI/TooltipUI.cs create mode 100644 Assets/_Scripts/UI/TooltipUI.cs.meta create mode 100644 Assets/_Scripts/UI/UIManager.cs create mode 100644 Assets/_Scripts/UI/UIManager.cs.meta create mode 100644 Assets/_Scripts/UI/UITheme.cs create mode 100644 Assets/_Scripts/UI/UITheme.cs.meta create mode 100644 Assets/_Scripts/Weapons.meta create mode 100644 Assets/_Scripts/Weapons/WeaponController.cs create mode 100644 Assets/_Scripts/Weapons/WeaponController.cs.meta create mode 100644 Assets/_Scripts/Weapons/WeaponData.cs create mode 100644 Assets/_Scripts/Weapons/WeaponData.cs.meta create mode 100644 Assets/_Scripts/Weapons/WeaponManager.cs create mode 100644 Assets/_Scripts/Weapons/WeaponManager.cs.meta create mode 100644 Packages/manifest.json create mode 100644 Packages/packages-lock.json create mode 100644 ProjectSettings/AudioManager.asset create mode 100644 ProjectSettings/ClusterInputManager.asset create mode 100644 ProjectSettings/DynamicsManager.asset create mode 100644 ProjectSettings/EditorBuildSettings.asset create mode 100644 ProjectSettings/EditorSettings.asset create mode 100644 ProjectSettings/GraphicsSettings.asset create mode 100644 ProjectSettings/InputManager.asset create mode 100644 ProjectSettings/MemorySettings.asset create mode 100644 ProjectSettings/NavMeshAreas.asset create mode 100644 ProjectSettings/PackageManagerSettings.asset create mode 100644 ProjectSettings/Packages/com.unity.testtools.codecoverage/Settings.json create mode 100644 ProjectSettings/Physics2DSettings.asset create mode 100644 ProjectSettings/PresetManager.asset create mode 100644 ProjectSettings/ProjectSettings.asset create mode 100644 ProjectSettings/ProjectVersion.txt create mode 100644 ProjectSettings/QualitySettings.asset create mode 100644 ProjectSettings/SceneTemplateSettings.json create mode 100644 ProjectSettings/TagManager.asset create mode 100644 ProjectSettings/TimeManager.asset create mode 100644 ProjectSettings/UnityConnectSettings.asset create mode 100644 ProjectSettings/VFXManager.asset create mode 100644 ProjectSettings/VersionControlSettings.asset create mode 100644 ProjectSettings/XRSettings.asset create mode 100644 ЛР8_Интеграция_наработок_ОТГ.docx diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f4b15e7 --- /dev/null +++ b/.gitignore @@ -0,0 +1,65 @@ +# Unity generated folders +[Ll]ibrary/ +[Tt]emp/ +[Oo]bj/ +[Bb]uild/ +[Bb]uilds/ +[Ll]ogs/ +[Uu]ser[Ss]ettings/ + +# Unity cache and local state +[Mm]emoryCaptures/ +[Rr]ecordings/ +[Aa]ssets/AssetStoreTools* +sysinfo.txt + +# Autogenerated Unity project files +*.csproj +*.unityproj +*.sln +*.suo +*.tmp +*.user +*.userprefs +*.pidb +*.booproj +*.svd +*.pdb +*.mdb +*.opendb +*.VC.db +*.pidb.meta + +# IDE folders +.vs/ +.vscode/ +.idea/ +*.swp +*.swo + +# OS files +.DS_Store +.DS_Store? +._* +.Spotlight-V100 +.Trashes +ehthumbs.db +Thumbs.db +Desktop.ini + +# Unity build outputs +*.apk +*.aab +*.unitypackage +*.app +*.exe +*.x86 +*.x86_64 +*.bundle + +# Crash and profiler output +[Cc]rash[Rr]eports/ +*.stackdump + +# Package manager local cache +.upmconfig.toml diff --git a/Assets/Editor.meta b/Assets/Editor.meta new file mode 100644 index 0000000..0ac6aa5 --- /dev/null +++ b/Assets/Editor.meta @@ -0,0 +1,8 @@ +fileFormatVersion: 2 +guid: a59f5c31b8b3935b9857d9eb66702638 +folderAsset: yes +DefaultImporter: + externalObjects: {} + userData: + assetBundleName: + assetBundleVariant: diff --git a/Assets/Editor/Lab8SceneBuilder.cs b/Assets/Editor/Lab8SceneBuilder.cs new file mode 100644 index 0000000..b97db89 --- /dev/null +++ b/Assets/Editor/Lab8SceneBuilder.cs @@ -0,0 +1,1389 @@ +using System.Collections.Generic; +using System.IO; +using OTGIntegrated.Abilities; +using OTGIntegrated.Combat; +using OTGIntegrated.Core; +using OTGIntegrated.Crafting; +using OTGIntegrated.Dialogue; +using OTGIntegrated.Items; +using OTGIntegrated.Player; +using OTGIntegrated.Quests; +using OTGIntegrated.Save; +using OTGIntegrated.Stats; +using OTGIntegrated.Talents; +using OTGIntegrated.UI; +using OTGIntegrated.Weapons; +using UnityEditor; +using UnityEditor.SceneManagement; +using UnityEngine; +using UnityEngine.EventSystems; +using UnityEngine.SceneManagement; +using UnityEngine.UI; +using PlayerInventory = OTGIntegrated.Inventory.Inventory; +using InventoryUI = OTGIntegrated.Inventory.InventoryUI; + +public static class Lab8SceneBuilder +{ + private const string ScenePath = "Assets/_Scenes/Lab08_IntegratedRPG.unity"; + + private static Font regularFont; + private static Font boldFont; + private static Dictionary materials; + + [MenuItem("Tools/Technical Game Design/Lab8/Create Integrated RPG Scene")] + public static void CreateIntegratedRPGScene() + { + EnsureProjectFolders(); + regularFont = InstallUbuntuFont("Ubuntu-Regular.ttf", false); + boldFont = InstallUbuntuFont("Ubuntu-Bold.ttf", true); + if (boldFont == null) + { + boldFont = regularFont; + } + + materials = CreateMaterials(); + DataSet data = CreateData(); + + Scene scene = EditorSceneManager.NewScene(NewSceneSetup.EmptyScene, NewSceneMode.Single); + scene.name = "Lab08_IntegratedRPG"; + + CreateLighting(); + CreateGroundAndZones(); + Camera mainCamera = CreateCamera(); + PlayerBundle player = CreatePlayer(mainCamera, data); + CraftingSystem craftingSystem = CreateVillage(data); + QuestManager questManager = CreateQuestManager(data); + DialogueManager dialogueManager = CreateDialogueManager(); + SaveSystem saveSystem = CreateSaveSystem(data); + CreateResources(data); + CreateGoblinCamp(data); + CreateMagicCircle(); + UIManager uiManager = CreateUI(player, questManager, craftingSystem, dialogueManager, saveSystem); + GameManager gameManager = CreateGameManager(player, questManager, dialogueManager, craftingSystem, uiManager, saveSystem); + + EditorUtility.SetDirty(gameManager); + EditorUtility.SetDirty(uiManager); + EditorSceneManager.SaveScene(scene, ScenePath); + AddSceneToBuildSettings(ScenePath); + AssetDatabase.SaveAssets(); + AssetDatabase.Refresh(); + + Debug.Log($"Lab08 integrated RPG scene created: {ScenePath}"); + } + + [MenuItem("Tools/Technical Game Design/Lab8/Validate Integrated RPG Scene")] + public static void ValidateIntegratedRPGScene() + { + if (!File.Exists(ToSystemPath(ScenePath))) + { + throw new System.Exception($"Scene is missing: {ScenePath}"); + } + + Scene scene = EditorSceneManager.OpenScene(ScenePath, OpenSceneMode.Single); + int missingScripts = CountMissingScripts(scene); + if (missingScripts > 0) + { + throw new System.Exception($"Missing scripts found: {missingScripts}"); + } + + Require(Object.FindObjectOfType() != null, "GameManager missing"); + Require(Object.FindObjectOfType() != null, "PlayerController missing"); + Require(Object.FindObjectOfType() != null, "Inventory missing"); + Require(Object.FindObjectOfType() != null, "PlayerStats missing"); + Require(Object.FindObjectOfType() != null, "QuestManager missing"); + Require(Object.FindObjectOfType() != null, "DialogueManager missing"); + Require(Object.FindObjectOfType() != null, "UIManager missing"); + Require(Object.FindObjectOfType() != null, "SaveSystem missing"); + Require(Object.FindObjectsOfType().Length >= 5, "Goblin enemies missing"); + Require(Object.FindObjectsOfType().Length >= 10, "Resource nodes missing"); + Require(Object.FindObjectOfType() != null, "EventSystem missing"); + + Font expectedFont = AssetDatabase.LoadAssetAtPath("Assets/_Fonts/Ubuntu-Regular.ttf"); + if (expectedFont != null) + { + foreach (Text text in Resources.FindObjectsOfTypeAll()) + { + if (text.gameObject.scene == scene) + { + Require(text.font == expectedFont || text.font == AssetDatabase.LoadAssetAtPath("Assets/_Fonts/Ubuntu-Bold.ttf"), $"Text does not use Ubuntu font: {text.name}"); + } + } + } + + Debug.Log("Lab08 validation passed: core scene objects, systems, enemies, resources, UI and fonts are present."); + } + + private sealed class DataSet + { + public readonly List allItems = new List(); + public ItemData wood; + public ItemData stone; + public ItemData ironOre; + public ItemData herb; + public ItemData crystal; + public ItemData goblinFang; + public ItemData basicSwordItem; + public ItemData ironAxeItem; + public ItemData healthPotion; + public ItemData manaPotion; + + public WeaponData basicSwordWeapon; + public WeaponData ironAxeWeapon; + public RecipeData recipeIronAxe; + public RecipeData recipeHealthPotion; + public RecipeData recipeManaPotion; + public QuestData questGatherWood; + public QuestData questKillGoblins; + public QuestData questCraftAxe; + public DialogueNode elderDialogue; + public DialogueNode guardDialogue; + public DialogueNode blacksmithDialogue; + public DialogueNode mageDialogue; + public AbilityData fireball; + public AbilityData heal; + public AbilityData blink; + public TalentData toughness; + public TalentData strength; + public TalentData agility; + public TalentData arcaneFlow; + public TalentData advancedStrength; + } + + private sealed class PlayerBundle + { + public GameObject root; + public PlayerController controller; + public PlayerStats stats; + public PlayerInventory inventory; + public LevelSystem levelSystem; + public WeaponController weaponController; + public WeaponManager weaponManager; + public AbilityManager abilityManager; + public TalentManager talentManager; + public PlayerInteraction interaction; + } + + private static void EnsureProjectFolders() + { + string[] folders = + { + "Assets/_Scenes", + "Assets/_Scripts", + "Assets/_Scripts/Core", + "Assets/_Scripts/Player", + "Assets/_Scripts/Stats", + "Assets/_Scripts/Inventory", + "Assets/_Scripts/Items", + "Assets/_Scripts/Crafting", + "Assets/_Scripts/Dialogue", + "Assets/_Scripts/Quests", + "Assets/_Scripts/Combat", + "Assets/_Scripts/Weapons", + "Assets/_Scripts/Abilities", + "Assets/_Scripts/Talents", + "Assets/_Scripts/UI", + "Assets/_Scripts/Save", + "Assets/_Data", + "Assets/_Data/Items", + "Assets/_Data/Recipes", + "Assets/_Data/Quests", + "Assets/_Data/Dialogue", + "Assets/_Data/Abilities", + "Assets/_Data/Talents", + "Assets/_Data/Weapons", + "Assets/_Prefabs", + "Assets/_Prefabs/UI", + "Assets/_Prefabs/Characters", + "Assets/_Prefabs/Items", + "Assets/_Prefabs/Effects", + "Assets/_Materials", + "Assets/_Fonts", + "Assets/Editor" + }; + + for (int i = 0; i < folders.Length; i++) + { + Directory.CreateDirectory(folders[i]); + } + + AssetDatabase.Refresh(); + } + + private static Font InstallUbuntuFont(string destinationName, bool bold) + { + string destination = "Assets/_Fonts/" + destinationName; + string[] candidates = bold + ? new[] + { + "/usr/share/fonts/truetype/ubuntu/Ubuntu-B.ttf", + "/usr/share/fonts/truetype/ubuntu/Ubuntu-Bold.ttf", + "/usr/share/fonts/TTF/Ubuntu-B.ttf", + "/usr/share/fonts/TTF/Ubuntu-Bold.ttf" + } + : new[] + { + "/usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf", + "/usr/share/fonts/truetype/ubuntu/Ubuntu-Regular.ttf", + "/usr/share/fonts/TTF/Ubuntu-R.ttf", + "/usr/share/fonts/TTF/Ubuntu-Regular.ttf" + }; + + string source = FindExistingFile(candidates); + if (string.IsNullOrEmpty(source)) + { + source = FindFontRecursive(bold ? new[] { "Ubuntu-B.ttf", "Ubuntu-Bold.ttf" } : new[] { "Ubuntu-R.ttf", "Ubuntu-Regular.ttf" }); + } + + if (string.IsNullOrEmpty(source)) + { + Debug.LogWarning("Ubuntu Font was not found. Arial fallback will be used."); + return Resources.GetBuiltinResource("Arial.ttf"); + } + + File.Copy(source, destination, true); + AssetDatabase.ImportAsset(destination, ImportAssetOptions.ForceUpdate); + Font font = AssetDatabase.LoadAssetAtPath(destination); + return font != null ? font : Resources.GetBuiltinResource("Arial.ttf"); + } + + private static string FindExistingFile(string[] candidates) + { + for (int i = 0; i < candidates.Length; i++) + { + if (File.Exists(candidates[i])) + { + return candidates[i]; + } + } + + return null; + } + + private static string FindFontRecursive(string[] fileNames) + { + string[] roots = { "/usr/share/fonts", "/usr/share/fonts/truetype/ubuntu", "/usr/share/fonts/TTF" }; + for (int r = 0; r < roots.Length; r++) + { + if (!Directory.Exists(roots[r])) + { + continue; + } + + for (int f = 0; f < fileNames.Length; f++) + { + string[] matches = Directory.GetFiles(roots[r], fileNames[f], SearchOption.AllDirectories); + if (matches.Length > 0) + { + return matches[0]; + } + } + } + + return null; + } + + private static Dictionary CreateMaterials() + { + return new Dictionary + { + ["Ground"] = CreateMaterial("Ground", new Color(0.28f, 0.46f, 0.25f, 1f)), + ["Village"] = CreateMaterial("Village", new Color(0.54f, 0.48f, 0.38f, 1f)), + ["Wood"] = CreateMaterial("Wood", new Color(0.45f, 0.28f, 0.13f, 1f)), + ["Leaves"] = CreateMaterial("Leaves", new Color(0.18f, 0.48f, 0.18f, 1f)), + ["Stone"] = CreateMaterial("Stone", new Color(0.42f, 0.43f, 0.45f, 1f)), + ["Iron"] = CreateMaterial("Iron", new Color(0.42f, 0.48f, 0.52f, 1f)), + ["Herb"] = CreateMaterial("Herb", new Color(0.1f, 0.62f, 0.24f, 1f)), + ["Crystal"] = CreateMaterial("Crystal", new Color(0.18f, 0.84f, 0.95f, 1f), true), + ["Player"] = CreateMaterial("Player", new Color(0.16f, 0.36f, 0.84f, 1f)), + ["Elder"] = CreateMaterial("Elder", new Color(0.78f, 0.62f, 0.34f, 1f)), + ["Guard"] = CreateMaterial("Guard", new Color(0.2f, 0.36f, 0.62f, 1f)), + ["Blacksmith"] = CreateMaterial("Blacksmith", new Color(0.5f, 0.2f, 0.16f, 1f)), + ["Mage"] = CreateMaterial("Mage", new Color(0.35f, 0.22f, 0.72f, 1f)), + ["Goblin"] = CreateMaterial("Goblin", new Color(0.24f, 0.55f, 0.18f, 1f)), + ["Camp"] = CreateMaterial("Camp", new Color(0.45f, 0.16f, 0.12f, 1f)), + ["Fire"] = CreateMaterial("Fire", new Color(1f, 0.32f, 0.05f, 1f), true), + ["Mana"] = CreateMaterial("Mana", new Color(0.36f, 0.25f, 0.95f, 1f), true), + ["Workbench"] = CreateMaterial("Workbench", new Color(0.35f, 0.22f, 0.12f, 1f)) + }; + } + + private static Material CreateMaterial(string name, Color color, bool emission = false) + { + string path = $"Assets/_Materials/M_{name}.mat"; + Material material = AssetDatabase.LoadAssetAtPath(path); + if (material == null) + { + material = new Material(Shader.Find("Standard")); + AssetDatabase.CreateAsset(material, path); + } + + material.color = color; + material.SetFloat("_Glossiness", emission ? 0.35f : 0.08f); + if (emission) + { + material.EnableKeyword("_EMISSION"); + material.SetColor("_EmissionColor", color * 1.5f); + } + else + { + material.DisableKeyword("_EMISSION"); + } + + EditorUtility.SetDirty(material); + return material; + } + + private static DataSet CreateData() + { + DataSet data = new DataSet(); + + data.wood = CreateItem("Wood", "Wood", "Древесина для строительства и крафта.", 20, ItemType.Resource, new Color(0.55f, 0.33f, 0.16f, 1f)); + data.stone = CreateItem("Stone", "Stone", "Камень из каменоломни.", 20, ItemType.Resource, new Color(0.52f, 0.53f, 0.55f, 1f)); + data.ironOre = CreateItem("IronOre", "Iron Ore", "Руда для кузнечных рецептов.", 10, ItemType.Resource, new Color(0.42f, 0.48f, 0.52f, 1f)); + data.herb = CreateItem("Herb", "Herb", "Лечебная трава.", 20, ItemType.Resource, new Color(0.1f, 0.65f, 0.28f, 1f)); + data.crystal = CreateItem("Crystal", "Crystal", "Кристалл с магической энергией.", 10, ItemType.Resource, new Color(0.2f, 0.9f, 1f, 1f)); + data.goblinFang = CreateItem("GoblinFang", "Goblin Fang", "Трофей с гоблина.", 20, ItemType.Quest, new Color(0.75f, 0.72f, 0.54f, 1f)); + data.basicSwordItem = CreateItem("BasicSword", "Basic Sword", "Простой меч героя.", 1, ItemType.Weapon, new Color(0.72f, 0.78f, 0.84f, 1f)); + data.ironAxeItem = CreateItem("IronAxe", "Iron Axe", "Тяжёлый железный топор.", 1, ItemType.Weapon, new Color(0.68f, 0.7f, 0.74f, 1f)); + data.healthPotion = CreateItem("HealthPotion", "Health Potion", "Зелье восстановления здоровья.", 5, ItemType.Consumable, new Color(0.86f, 0.16f, 0.2f, 1f)); + data.manaPotion = CreateItem("ManaPotion", "Mana Potion", "Зелье восстановления маны.", 5, ItemType.Consumable, new Color(0.16f, 0.32f, 0.9f, 1f)); + + data.allItems.AddRange(new[] + { + data.wood, data.stone, data.ironOre, data.herb, data.crystal, data.goblinFang, + data.basicSwordItem, data.ironAxeItem, data.healthPotion, data.manaPotion + }); + + data.basicSwordWeapon = CreateWeapon("BasicSword", "Basic Sword", 10f, 0.75f, 2.2f, false, 0f, "Базовое оружие ближнего боя."); + data.ironAxeWeapon = CreateWeapon("IronAxe", "Iron Axe", 18f, 0.95f, 2.4f, false, 0f, "Скрафченный топор с повышенным уроном."); + + data.recipeIronAxe = CreateRecipe("Recipe_IronAxe", "Iron Axe", "Соберите рукоять и металлическую голову топора.", data.ironAxeItem, 1, + IngredientOf(data.wood, 2), IngredientOf(data.stone, 2), IngredientOf(data.ironOre, 1)); + data.recipeHealthPotion = CreateRecipe("Recipe_HealthPotion", "Health Potion", "Простое лечебное зелье.", data.healthPotion, 1, + IngredientOf(data.herb, 2), IngredientOf(data.crystal, 1)); + data.recipeManaPotion = CreateRecipe("Recipe_ManaPotion", "Mana Potion", "Зелье для восстановления магической энергии.", data.manaPotion, 1, + IngredientOf(data.crystal, 2), IngredientOf(data.herb, 1)); + + data.questGatherWood = CreateQuest("Quest_GatherWood", "Помощь старосте", "Соберите 5 древесины для укрепления деревни.", "Elder", "Elder", 50, 1, + new QuestGoal { goalType = QuestGoalType.CollectItem, targetItem = data.wood, requiredAmount = 5 }); + data.questKillGoblins = CreateQuest("Quest_KillGoblins", "Очистка лагеря", "Уничтожьте 3 гоблинов возле деревни.", "Guard", "Guard", 100, 0, + new QuestGoal { goalType = QuestGoalType.KillEnemy, enemyId = "Goblin", requiredAmount = 3 }); + data.questKillGoblins.rewardItems = new List { new QuestRewardItem { item = data.ironOre, amount = 2 } }; + EditorUtility.SetDirty(data.questKillGoblins); + + data.questCraftAxe = CreateQuest("Quest_CraftAxe", "Работа кузнеца", "Скрафтите железный топор.", "Blacksmith", "Blacksmith", 50, 0, + new QuestGoal { goalType = QuestGoalType.CraftItem, targetItem = data.ironAxeItem, requiredAmount = 1 }); + data.questCraftAxe.rewardItems = new List { new QuestRewardItem { item = data.healthPotion, amount = 1 } }; + EditorUtility.SetDirty(data.questCraftAxe); + + data.elderDialogue = CreateDialogue("Dialogue_Elder", "Староста", "Деревня держится, но нам нужна древесина для укрепления стен. Поможешь?"); + data.guardDialogue = CreateDialogue("Dialogue_Guard", "Стражник", "Гоблины снова заняли лагерь у дороги. Разберись с ними, когда будешь готов."); + data.blacksmithDialogue = CreateDialogue("Dialogue_Blacksmith", "Кузнец", "Верстак рядом. Если принесёшь материалы, сможешь сделать железный топор."); + data.mageDialogue = CreateDialogue("Dialogue_Mage", "Маг", "Способности привязаны к клавишам 1, 2 и 3. Таланты открываются на K и усиливают твои характеристики."); + + GameObject fireballPrefab = CreateFireballPrefab(); + GameObject healPrefab = CreateHealPrefab(); + GameObject blinkPrefab = CreateBlinkPrefab(); + data.fireball = CreateAbility("Fireball", "Fireball", "Летящий огненный снаряд, наносящий 25 + Damage.", 15f, 2f, 25f, 14f, fireballPrefab, new Color(0.95f, 0.22f, 0.08f, 1f)); + data.heal = CreateAbility("Heal", "Heal", "Восстанавливает 30 HP.", 20f, 5f, 30f, 0f, healPrefab, new Color(0.22f, 0.9f, 0.36f, 1f)); + data.blink = CreateAbility("Blink", "Blink", "Телепорт вперёд с проверкой препятствий.", 20f, 6f, 0f, 7f, blinkPrefab, new Color(0.48f, 0.38f, 1f, 1f)); + + data.toughness = CreateTalent("Toughness", "Toughness", "MaxHealth +20", new Vector2(-330f, 130f), new[] { new StatModifier(StatType.MaxHealth, ModifierType.FlatAdd, 20f) }, null); + data.strength = CreateTalent("Strength", "Strength", "Damage +5", new Vector2(-110f, 130f), new[] { new StatModifier(StatType.Damage, ModifierType.FlatAdd, 5f) }, null); + data.agility = CreateTalent("Agility", "Agility", "MoveSpeed +1", new Vector2(110f, 130f), new[] { new StatModifier(StatType.MoveSpeed, ModifierType.FlatAdd, 1f) }, null); + data.arcaneFlow = CreateTalent("ArcaneFlow", "Arcane Flow", "MaxMana +25", new Vector2(330f, 130f), new[] { new StatModifier(StatType.MaxMana, ModifierType.FlatAdd, 25f) }, null); + data.advancedStrength = CreateTalent("AdvancedStrength", "Advanced Strength", "Damage +10%", new Vector2(-110f, -80f), new[] { new StatModifier(StatType.Damage, ModifierType.PercentAdd, 0.1f) }, new[] { data.strength }); + + return data; + } + + private static ItemData CreateItem(string id, string displayName, string description, int maxStack, ItemType type, Color color) + { + ItemData item = LoadOrCreate($"Assets/_Data/Items/{id}.asset"); + item.itemId = id; + item.displayName = displayName; + item.description = description; + item.maxStack = maxStack; + item.itemType = type; + item.itemColor = color; + item.icon = CreateIcon("Assets/_Data/Items", id + "_Icon", color); + EditorUtility.SetDirty(item); + return item; + } + + private static WeaponData CreateWeapon(string id, string displayName, float damage, float rate, float range, bool ranged, float manaCost, string description) + { + WeaponData weapon = LoadOrCreate($"Assets/_Data/Weapons/{id}.asset"); + weapon.weaponId = id; + weapon.displayName = displayName; + weapon.damage = damage; + weapon.attackRate = rate; + weapon.range = range; + weapon.isRanged = ranged; + weapon.manaCost = manaCost; + weapon.description = description; + EditorUtility.SetDirty(weapon); + return weapon; + } + + private static Ingredient IngredientOf(ItemData item, int amount) + { + return new Ingredient { item = item, amount = amount }; + } + + private static RecipeData CreateRecipe(string id, string displayName, string description, ItemData result, int resultAmount, params Ingredient[] ingredients) + { + RecipeData recipe = LoadOrCreate($"Assets/_Data/Recipes/{id}.asset"); + recipe.recipeId = id; + recipe.displayName = displayName; + recipe.description = description; + recipe.resultItem = result; + recipe.resultAmount = resultAmount; + recipe.ingredients = ingredients; + EditorUtility.SetDirty(recipe); + return recipe; + } + + private static QuestData CreateQuest(string id, string displayName, string description, string giverNpcId, string turnInNpcId, int rewardExp, int rewardTalentPoints, QuestGoal goal) + { + QuestData quest = LoadOrCreate($"Assets/_Data/Quests/{id}.asset"); + quest.questId = id; + quest.displayName = displayName; + quest.description = description; + quest.giverNpcId = giverNpcId; + quest.turnInNpcId = turnInNpcId; + quest.rewardExperience = rewardExp; + quest.rewardTalentPoints = rewardTalentPoints; + quest.goals = new List { goal }; + quest.rewardItems = quest.rewardItems ?? new List(); + EditorUtility.SetDirty(quest); + return quest; + } + + private static DialogueNode CreateDialogue(string id, string speaker, string line) + { + DialogueNode node = LoadOrCreate($"Assets/_Data/Dialogue/{id}.asset"); + node.nodeId = id; + node.speakerName = speaker; + node.npcLine = line; + node.responses = new[] + { + new DialogueResponse { responseText = "Расскажи подробнее", endsDialogue = false } + }; + EditorUtility.SetDirty(node); + return node; + } + + private static AbilityData CreateAbility(string id, string displayName, string description, float mana, float cooldown, float damage, float range, GameObject effectPrefab, Color color) + { + AbilityData ability = LoadOrCreate($"Assets/_Data/Abilities/{id}.asset"); + ability.abilityId = id; + ability.displayName = displayName; + ability.description = description; + ability.manaCost = mana; + ability.cooldown = cooldown; + ability.damage = damage; + ability.range = range; + ability.effectPrefab = effectPrefab; + ability.icon = CreateIcon("Assets/_Data/Abilities", id + "_Icon", color); + EditorUtility.SetDirty(ability); + return ability; + } + + private static TalentData CreateTalent(string id, string displayName, string description, Vector2 position, StatModifier[] modifiers, TalentData[] prerequisites) + { + TalentData talent = LoadOrCreate($"Assets/_Data/Talents/{id}.asset"); + talent.talentId = id; + talent.displayName = displayName; + talent.description = description; + talent.cost = 1; + talent.treePosition = position; + talent.modifiers = modifiers; + talent.prerequisites = prerequisites; + talent.icon = CreateIcon("Assets/_Data/Talents", id + "_Icon", new Color(0.82f, 0.64f, 0.22f, 1f)); + EditorUtility.SetDirty(talent); + return talent; + } + + private static T LoadOrCreate(string path) where T : ScriptableObject + { + T asset = AssetDatabase.LoadAssetAtPath(path); + if (asset == null) + { + asset = ScriptableObject.CreateInstance(); + AssetDatabase.CreateAsset(asset, path); + } + + return asset; + } + + private static Sprite CreateIcon(string folder, string name, Color color) + { + Directory.CreateDirectory(folder); + string path = $"{folder}/{name}.png"; + Texture2D texture = new Texture2D(64, 64, TextureFormat.RGBA32, false); + Color dark = Color.Lerp(Color.black, color, 0.3f); + for (int y = 0; y < 64; y++) + { + for (int x = 0; x < 64; x++) + { + Vector2 p = new Vector2(x - 31.5f, y - 31.5f); + float t = Mathf.Clamp01(1f - p.magnitude / 38f); + Color pixel = Color.Lerp(dark, color, t); + if (Mathf.Abs(p.x) < 4f || Mathf.Abs(p.y) < 4f) + { + pixel = Color.Lerp(pixel, Color.white, 0.3f); + } + + texture.SetPixel(x, y, pixel); + } + } + + texture.Apply(); + File.WriteAllBytes(path, texture.EncodeToPNG()); + Object.DestroyImmediate(texture); + AssetDatabase.ImportAsset(path, ImportAssetOptions.ForceUpdate); + TextureImporter importer = AssetImporter.GetAtPath(path) as TextureImporter; + if (importer != null) + { + importer.textureType = TextureImporterType.Sprite; + importer.mipmapEnabled = false; + importer.spritePixelsPerUnit = 64f; + importer.SaveAndReimport(); + } + + return AssetDatabase.LoadAssetAtPath(path); + } + + private static GameObject CreateFireballPrefab() + { + GameObject root = new GameObject("PF_FireballEffect"); + SphereCollider collider = root.AddComponent(); + collider.radius = 0.35f; + collider.isTrigger = true; + root.AddComponent(); + GameObject visual = GameObject.CreatePrimitive(PrimitiveType.Sphere); + visual.name = "Visual"; + visual.transform.SetParent(root.transform, false); + visual.transform.localScale = Vector3.one * 0.65f; + Object.DestroyImmediate(visual.GetComponent()); + visual.GetComponent().sharedMaterial = materials["Fire"]; + return SavePrefab(root, "Assets/_Prefabs/Effects/PF_FireballEffect.prefab"); + } + + private static GameObject CreateHealPrefab() + { + GameObject root = new GameObject("PF_HealEffect"); + root.AddComponent(); + return SavePrefab(root, "Assets/_Prefabs/Effects/PF_HealEffect.prefab"); + } + + private static GameObject CreateBlinkPrefab() + { + GameObject root = new GameObject("PF_BlinkEffect"); + root.AddComponent(); + return SavePrefab(root, "Assets/_Prefabs/Effects/PF_BlinkEffect.prefab"); + } + + private static GameObject SavePrefab(GameObject root, string path) + { + GameObject prefab = PrefabUtility.SaveAsPrefabAsset(root, path); + Object.DestroyImmediate(root); + return prefab; + } + + private static void CreateLighting() + { + RenderSettings.ambientLight = new Color(0.55f, 0.58f, 0.62f, 1f); + GameObject lightObject = new GameObject("Directional Light"); + Light light = lightObject.AddComponent(); + light.type = LightType.Directional; + light.intensity = 1.05f; + lightObject.transform.rotation = Quaternion.Euler(50f, -35f, 0f); + } + + private static void CreateGroundAndZones() + { + GameObject ground = GameObject.CreatePrimitive(PrimitiveType.Plane); + ground.name = "Integrated RPG Village Ground"; + ground.transform.localScale = new Vector3(8.5f, 1f, 8.5f); + ground.GetComponent().sharedMaterial = materials["Ground"]; + + CreateZoneMarker("Central Village", new Vector3(0f, 0.03f, 0f), new Vector3(20f, 0.04f, 20f), materials["Village"]); + CreateZoneMarker("Forest", new Vector3(-28f, 0.04f, 18f), new Vector3(24f, 0.04f, 24f), materials["Leaves"]); + CreateZoneMarker("Quarry", new Vector3(28f, 0.04f, 18f), new Vector3(24f, 0.04f, 24f), materials["Stone"]); + CreateZoneMarker("Goblin Camp", new Vector3(27f, 0.04f, -27f), new Vector3(24f, 0.04f, 24f), materials["Camp"]); + CreateZoneMarker("Magic Circle", new Vector3(-28f, 0.04f, -26f), new Vector3(24f, 0.04f, 24f), materials["Mana"]); + + CreateSign("Forest", new Vector3(-11f, 0.1f, 8f)); + CreateSign("Quarry", new Vector3(11f, 0.1f, 8f)); + CreateSign("Goblin Camp", new Vector3(14f, 0.1f, -10f)); + CreateSign("Magic Circle", new Vector3(-14f, 0.1f, -10f)); + } + + private static void CreateZoneMarker(string name, Vector3 position, Vector3 scale, Material material) + { + GameObject marker = GameObject.CreatePrimitive(PrimitiveType.Cube); + marker.name = name + " Zone Tint"; + marker.transform.position = position; + marker.transform.localScale = scale; + marker.GetComponent().sharedMaterial = material; + Object.DestroyImmediate(marker.GetComponent()); + } + + private static Camera CreateCamera() + { + GameObject cameraObject = new GameObject("Main Camera"); + Camera camera = cameraObject.AddComponent(); + camera.tag = "MainCamera"; + camera.fieldOfView = 48f; + camera.transform.position = new Vector3(0f, 14f, -14f); + camera.transform.rotation = Quaternion.Euler(55f, 0f, 0f); + return camera; + } + + private static PlayerBundle CreatePlayer(Camera camera, DataSet data) + { + PlayerBundle bundle = new PlayerBundle(); + GameObject player = GameObject.CreatePrimitive(PrimitiveType.Capsule); + player.name = "Player"; + player.tag = "Player"; + player.transform.position = new Vector3(0f, 1f, -2f); + player.GetComponent().sharedMaterial = materials["Player"]; + + CharacterController characterController = player.AddComponent(); + characterController.height = 2f; + characterController.radius = 0.42f; + characterController.center = Vector3.zero; + Object.DestroyImmediate(player.GetComponent()); + + bundle.root = player; + bundle.stats = player.AddComponent(); + bundle.inventory = player.AddComponent(); + bundle.levelSystem = player.AddComponent(); + bundle.weaponController = null; + WeaponController weaponController = player.AddComponent(); + bundle.weaponManager = player.AddComponent(); + bundle.abilityManager = player.AddComponent(); + bundle.talentManager = player.AddComponent(); + bundle.controller = player.AddComponent(); + bundle.interaction = player.AddComponent(); + + GameObject attackOrigin = new GameObject("AttackOrigin"); + attackOrigin.transform.SetParent(player.transform, false); + attackOrigin.transform.localPosition = new Vector3(0f, 0.6f, 0.85f); + weaponController.attackOrigin = attackOrigin.transform; + bundle.weaponController = weaponController; + + GameObject castOrigin = new GameObject("CastOrigin"); + castOrigin.transform.SetParent(player.transform, false); + castOrigin.transform.localPosition = new Vector3(0f, 1.25f, 0.75f); + bundle.abilityManager.castOrigin = castOrigin.transform; + bundle.abilityManager.learnedAbilities = new List { data.fireball, data.heal, data.blink }; + + GameObject cameraRoot = new GameObject("PlayerCameraRoot"); + bundle.controller.cameraRoot = cameraRoot.transform; + bundle.controller.playerCamera = camera; + + bundle.weaponManager.weaponController = weaponController; + bundle.weaponManager.startingWeapon = data.basicSwordWeapon; + bundle.weaponManager.availableWeapons = new List { data.basicSwordWeapon, data.ironAxeWeapon }; + bundle.weaponManager.itemUnlocks = new List + { + new WeaponUnlock { item = data.ironAxeItem, weapon = data.ironAxeWeapon } + }; + + bundle.talentManager.allTalents = new List + { + data.toughness, data.strength, data.agility, data.arcaneFlow, data.advancedStrength + }; + bundle.talentManager.availableTalentPoints = 0; + + return bundle; + } + + private static CraftingSystem CreateVillage(DataSet data) + { + CreateNpc("NPC_Starosta", "Elder", "Староста", data.elderDialogue, data.questGatherWood, data.questGatherWood, false, new Vector3(-3f, 1f, 3f), materials["Elder"]); + CreateNpc("NPC_Guard", "Guard", "Стражник", data.guardDialogue, data.questKillGoblins, data.questKillGoblins, false, new Vector3(3f, 1f, 3f), materials["Guard"]); + CreateNpc("NPC_Blacksmith", "Blacksmith", "Кузнец", data.blacksmithDialogue, data.questCraftAxe, data.questCraftAxe, true, new Vector3(6f, 1f, -2f), materials["Blacksmith"]); + CreateNpc("NPC_Mage", "Mage", "Маг", data.mageDialogue, null, null, false, new Vector3(-6f, 1f, -2f), materials["Mage"]); + + CreateBuilding("Elder House", new Vector3(-6f, 1f, 7f), new Vector3(4f, 2f, 3f)); + CreateBuilding("Guard Tower", new Vector3(6f, 1.4f, 7f), new Vector3(2.8f, 2.8f, 2.8f)); + CreateBuilding("Blacksmith Shed", new Vector3(9f, 1f, -5f), new Vector3(4f, 2f, 3f)); + + GameObject workbench = GameObject.CreatePrimitive(PrimitiveType.Cube); + workbench.name = "Workbench"; + workbench.transform.position = new Vector3(7f, 0.55f, -4f); + workbench.transform.localScale = new Vector3(2.2f, 0.7f, 1.1f); + workbench.GetComponent().sharedMaterial = materials["Workbench"]; + CraftingSystem crafting = workbench.AddComponent(); + crafting.availableRecipes = new List { data.recipeIronAxe, data.recipeHealthPotion, data.recipeManaPotion }; + return crafting; + } + + private static void CreateNpc(string objectName, string npcId, string displayName, DialogueNode dialogue, QuestData offered, QuestData completion, bool crafting, Vector3 position, Material material) + { + GameObject npc = GameObject.CreatePrimitive(PrimitiveType.Capsule); + npc.name = objectName; + npc.transform.position = position; + npc.GetComponent().sharedMaterial = material; + NPCInteract interact = npc.AddComponent(); + interact.npcId = npcId; + interact.displayName = displayName; + interact.startNode = dialogue; + interact.offeredQuest = offered; + interact.completionQuest = completion; + interact.canOpenCrafting = crafting; + CreateNameplate(npc.transform, displayName, new Color(1f, 0.84f, 0.35f, 1f)); + } + + private static void CreateBuilding(string name, Vector3 position, Vector3 scale) + { + GameObject building = GameObject.CreatePrimitive(PrimitiveType.Cube); + building.name = name; + building.transform.position = position; + building.transform.localScale = scale; + building.GetComponent().sharedMaterial = materials["Village"]; + } + + private static QuestManager CreateQuestManager(DataSet data) + { + GameObject root = new GameObject("QuestManager"); + QuestManager manager = root.AddComponent(); + manager.allQuests = new List { data.questGatherWood, data.questKillGoblins, data.questCraftAxe }; + return manager; + } + + private static DialogueManager CreateDialogueManager() + { + GameObject root = new GameObject("DialogueManager"); + return root.AddComponent(); + } + + private static SaveSystem CreateSaveSystem(DataSet data) + { + GameObject root = new GameObject("SaveSystem"); + SaveSystem saveSystem = root.AddComponent(); + saveSystem.itemCatalog = data.allItems; + return saveSystem; + } + + private static void CreateResources(DataSet data) + { + for (int i = 0; i < 7; i++) + { + Vector3 pos = new Vector3(-34f + i * 2.5f, 0.55f, 15f + (i % 3) * 3f); + CreateResource("Wood_Node_" + i, PrimitiveType.Cylinder, pos, new Vector3(0.8f, 0.7f, 0.8f), materials["Wood"], data.wood); + CreateTree(new Vector3(pos.x + 1.2f, 0f, pos.z + 1.4f)); + } + + for (int i = 0; i < 5; i++) + { + CreateResource("Stone_Node_" + i, PrimitiveType.Sphere, new Vector3(24f + i * 2.4f, 0.55f, 17f + (i % 2) * 3f), Vector3.one * 1.1f, materials["Stone"], data.stone); + } + + for (int i = 0; i < 4; i++) + { + CreateResource("IronOre_Node_" + i, PrimitiveType.Cube, new Vector3(29f + i * 2.2f, 0.55f, 25f), Vector3.one * 1f, materials["Iron"], data.ironOre); + } + + for (int i = 0; i < 5; i++) + { + CreateResource("Herb_Node_" + i, PrimitiveType.Capsule, new Vector3(-35f + i * 3f, 0.45f, 28f), new Vector3(0.45f, 0.45f, 0.45f), materials["Herb"], data.herb); + } + + for (int i = 0; i < 5; i++) + { + CreateResource("Crystal_Node_" + i, PrimitiveType.Cylinder, new Vector3(-34f + i * 3f, 0.75f, -29f), new Vector3(0.6f, 1.2f, 0.6f), materials["Crystal"], data.crystal); + } + + for (int i = 0; i < 9; i++) + { + CreatePrimitive("Quarry Rock " + i, PrimitiveType.Cube, new Vector3(22f + (i % 3) * 4f, 0.5f, 21f + (i / 3) * 3f), new Vector3(2f, 1f, 1.4f), materials["Stone"]); + } + } + + private static void CreateResource(string name, PrimitiveType primitive, Vector3 position, Vector3 scale, Material material, ItemData item) + { + GameObject resource = GameObject.CreatePrimitive(primitive); + resource.name = name; + resource.transform.position = position; + resource.transform.localScale = scale; + resource.GetComponent().sharedMaterial = material; + ResourceNode node = resource.AddComponent(); + node.itemData = item; + node.amount = 1; + node.respawnCooldown = 0f; + } + + private static void CreateGoblinCamp(DataSet data) + { + Vector3[] positions = + { + new Vector3(22f, 1f, -24f), + new Vector3(28f, 1f, -23f), + new Vector3(33f, 1f, -28f), + new Vector3(24f, 1f, -32f), + new Vector3(31f, 1f, -34f) + }; + + for (int i = 0; i < positions.Length; i++) + { + GameObject goblin = GameObject.CreatePrimitive(PrimitiveType.Capsule); + goblin.name = "Goblin_" + (i + 1); + goblin.transform.position = positions[i]; + goblin.GetComponent().sharedMaterial = materials["Goblin"]; + Enemy enemy = goblin.AddComponent(); + enemy.enemyId = "Goblin"; + enemy.displayName = "Goblin"; + enemy.maxHealth = 50f; + enemy.damage = 5f; + enemy.expReward = 20; + enemy.dropItems = new List { new EnemyDrop { item = data.goblinFang, amount = 1 } }; + CreateNameplate(goblin.transform, "Goblin", new Color(1f, 0.25f, 0.22f, 1f)); + } + + CreatePrimitive("Campfire", PrimitiveType.Cylinder, new Vector3(28f, 0.25f, -29f), new Vector3(1.2f, 0.3f, 1.2f), materials["Fire"]); + for (int i = 0; i < 6; i++) + { + CreatePrimitive("Camp Crate " + i, PrimitiveType.Cube, new Vector3(20f + i * 2.4f, 0.45f, -36f), Vector3.one * 0.9f, materials["Wood"]); + } + } + + private static void CreateMagicCircle() + { + GameObject circle = GameObject.CreatePrimitive(PrimitiveType.Cylinder); + circle.name = "Magic Circle"; + circle.transform.position = new Vector3(-28f, 0.08f, -26f); + circle.transform.localScale = new Vector3(5.5f, 0.08f, 5.5f); + circle.GetComponent().sharedMaterial = materials["Mana"]; + Object.DestroyImmediate(circle.GetComponent()); + + for (int i = 0; i < 6; i++) + { + float angle = i * Mathf.PI * 2f / 6f; + Vector3 pos = new Vector3(-28f + Mathf.Cos(angle) * 5f, 0.75f, -26f + Mathf.Sin(angle) * 5f); + CreatePrimitive("Mana Crystal " + i, PrimitiveType.Cylinder, pos, new Vector3(0.5f, 1.3f, 0.5f), materials["Crystal"]); + } + + for (int i = 0; i < 3; i++) + { + GameObject dummy = GameObject.CreatePrimitive(PrimitiveType.Capsule); + dummy.name = "Training Dummy " + (i + 1); + dummy.transform.position = new Vector3(-34f + i * 5f, 1f, -19f); + dummy.GetComponent().sharedMaterial = materials["Wood"]; + Damageable damageable = dummy.AddComponent(); + damageable.displayName = "Training Dummy"; + damageable.maxHealth = 100f; + } + } + + private static UIManager CreateUI(PlayerBundle player, QuestManager questManager, CraftingSystem craftingSystem, DialogueManager dialogueManager, SaveSystem saveSystem) + { + GameObject canvasObject = new GameObject("HUDCanvas", typeof(Canvas), typeof(CanvasScaler), typeof(GraphicRaycaster)); + Canvas canvas = canvasObject.GetComponent(); + canvas.renderMode = RenderMode.ScreenSpaceOverlay; + CanvasScaler scaler = canvasObject.GetComponent(); + scaler.uiScaleMode = CanvasScaler.ScaleMode.ScaleWithScreenSize; + scaler.referenceResolution = new Vector2(1920f, 1080f); + scaler.screenMatchMode = CanvasScaler.ScreenMatchMode.MatchWidthOrHeight; + scaler.matchWidthOrHeight = 0.5f; + + EnsureEventSystem(); + + UIManager uiManager = canvasObject.AddComponent(); + NotificationUI notificationUI = CreateNotificationStack(canvasObject.transform); + InteractionPromptUI promptUI = CreateInteractionPrompt(canvasObject.transform); + player.interaction.promptUI = promptUI; + + HUDController hud = CreateHud(canvasObject.transform); + InventoryUI inventoryUI = CreateInventoryPanel(canvasObject.transform, out GameObject inventoryPanel); + CraftingUI craftingUI = CreateCraftingPanel(canvasObject.transform, out GameObject craftingPanel); + QuestLogUI questLogUI = CreateQuestLogPanel(canvasObject.transform, out GameObject questPanel); + TalentTreeUI talentTreeUI = CreateTalentTreePanel(canvasObject.transform, out GameObject talentPanel); + DialogueUI dialogueUI = CreateDialoguePanel(canvasObject.transform, out GameObject dialoguePanel); + GameObject pausePanel = CreatePausePanel(canvasObject.transform, out Button resume, out Button saveButton, out Button loadButton, out Button resetButton); + + uiManager.inventoryPanel = inventoryPanel; + uiManager.craftingPanel = craftingPanel; + uiManager.questLogPanel = questPanel; + uiManager.talentTreePanel = talentPanel; + uiManager.dialoguePanel = dialoguePanel; + uiManager.pausePanel = pausePanel; + uiManager.inventoryUI = inventoryUI; + uiManager.craftingUI = craftingUI; + uiManager.questLogUI = questLogUI; + uiManager.talentTreeUI = talentTreeUI; + uiManager.hudController = hud; + uiManager.resumeButton = resume; + uiManager.saveButton = saveButton; + uiManager.loadButton = loadButton; + uiManager.resetSaveButton = resetButton; + + dialogueManager.dialogueUI = dialogueUI; + inventoryPanel.SetActive(false); + craftingPanel.SetActive(false); + questPanel.SetActive(false); + talentPanel.SetActive(false); + dialoguePanel.SetActive(false); + pausePanel.SetActive(false); + return uiManager; + } + + private static HUDController CreateHud(Transform canvas) + { + GameObject hudObject = new GameObject("HUDController"); + hudObject.transform.SetParent(canvas, false); + HUDController hud = hudObject.AddComponent(); + + GameObject status = CreatePanel(canvas, "Player Status Panel", new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(0f, 0f), new Vector2(24f, 24f), new Vector2(320f, 130f), UITheme.Panel); + hud.hpFill = CreateBar(status.transform, "HP", new Vector2(18f, 78f), new Color(0.8f, 0.15f, 0.14f, 1f), out hud.hpText); + hud.manaFill = CreateBar(status.transform, "Mana", new Vector2(18f, 44f), new Color(0.15f, 0.35f, 0.88f, 1f), out hud.manaText); + hud.expFill = CreateBar(status.transform, "EXP", new Vector2(18f, 10f), new Color(0.86f, 0.58f, 0.24f, 1f), out hud.expText); + hud.levelText = CreateText(status.transform, "LevelText", "Level 1", 16, TextAnchor.MiddleLeft, new Vector2(18f, 104f), new Vector2(130f, 22f), boldFont); + + GameObject tracker = CreatePanel(canvas, "Quest Tracker", new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(0f, 1f), new Vector2(24f, -24f), new Vector2(420f, 140f), UITheme.Panel); + hud.questTitleText = CreateText(tracker.transform, "QuestTitle", "Активная цель", 20, TextAnchor.UpperLeft, new Vector2(18f, -14f), new Vector2(380f, 28f), boldFont); + hud.questBodyText = CreateText(tracker.transform, "QuestBody", "Нет активных квестов", 16, TextAnchor.UpperLeft, new Vector2(18f, -48f), new Vector2(380f, 82f), regularFont); + + GameObject abilityBar = CreatePanel(canvas, "Ability Bar", new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 24f), new Vector2(340f, 95f), UITheme.Panel); + hud.abilitySlots = new AbilityHudSlot[3]; + for (int i = 0; i < 3; i++) + { + hud.abilitySlots[i] = CreateAbilitySlot(abilityBar.transform, i, new Vector2(-108f + i * 108f, 8f)); + } + + GameObject weaponPanel = CreatePanel(canvas, "Weapon Panel", new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-24f, 24f), new Vector2(260f, 90f), UITheme.Panel); + hud.weaponNameText = CreateText(weaponPanel.transform, "WeaponName", "Weapon: -", 16, TextAnchor.UpperLeft, new Vector2(16f, -12f), new Vector2(230f, 24f), boldFont); + hud.weaponDamageText = CreateText(weaponPanel.transform, "WeaponDamage", "Damage: -", 16, TextAnchor.UpperLeft, new Vector2(16f, -38f), new Vector2(230f, 22f), regularFont); + hud.weaponHintText = CreateText(weaponPanel.transform, "WeaponHint", "LMB — Attack", 14, TextAnchor.UpperLeft, new Vector2(16f, -62f), new Vector2(230f, 20f), regularFont); + + return hud; + } + + private static Image CreateBar(Transform parent, string name, Vector2 anchored, Color fillColor, out Text valueText) + { + GameObject root = new GameObject(name + "Bar", typeof(RectTransform), typeof(Image)); + root.transform.SetParent(parent, false); + RectTransform rect = root.GetComponent(); + rect.anchorMin = new Vector2(0f, 0f); + rect.anchorMax = new Vector2(0f, 0f); + rect.pivot = new Vector2(0f, 0f); + rect.anchoredPosition = anchored; + rect.sizeDelta = new Vector2(284f, 22f); + root.GetComponent().color = new Color(0.03f, 0.035f, 0.045f, 0.9f); + + GameObject fillObject = new GameObject("Fill", typeof(RectTransform), typeof(Image)); + fillObject.transform.SetParent(root.transform, false); + RectTransform fillRect = fillObject.GetComponent(); + fillRect.anchorMin = Vector2.zero; + fillRect.anchorMax = Vector2.one; + fillRect.offsetMin = Vector2.zero; + fillRect.offsetMax = Vector2.zero; + Image fill = fillObject.GetComponent(); + fill.color = fillColor; + fill.type = Image.Type.Filled; + fill.fillMethod = Image.FillMethod.Horizontal; + fill.fillOrigin = 0; + fill.fillAmount = 1f; + + valueText = CreateText(root.transform, name + "Text", name, 14, TextAnchor.MiddleCenter, Vector2.zero, new Vector2(284f, 22f), regularFont); + valueText.rectTransform.anchorMin = Vector2.zero; + valueText.rectTransform.anchorMax = Vector2.one; + valueText.rectTransform.offsetMin = Vector2.zero; + valueText.rectTransform.offsetMax = Vector2.zero; + return fill; + } + + private static AbilityHudSlot CreateAbilitySlot(Transform parent, int index, Vector2 anchored) + { + GameObject root = CreatePanel(parent, "AbilitySlot_" + (index + 1), new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), anchored, new Vector2(82f, 78f), new Color(0.08f, 0.09f, 0.12f, 0.92f)); + AbilityHudSlot slot = new AbilityHudSlot(); + slot.iconImage = root.GetComponent(); + slot.keyText = CreateText(root.transform, "Key", (index + 1).ToString(), 14, TextAnchor.UpperLeft, new Vector2(7f, -4f), new Vector2(24f, 22f), boldFont); + slot.nameText = CreateText(root.transform, "Name", "-", 13, TextAnchor.LowerCenter, new Vector2(0f, 2f), new Vector2(78f, 22f), regularFont); + slot.manaText = CreateText(root.transform, "Mana", "-", 13, TextAnchor.UpperRight, new Vector2(-7f, -4f), new Vector2(34f, 22f), regularFont); + GameObject overlayObject = new GameObject("CooldownOverlay", typeof(RectTransform), typeof(Image)); + overlayObject.transform.SetParent(root.transform, false); + RectTransform overlayRect = overlayObject.GetComponent(); + overlayRect.anchorMin = Vector2.zero; + overlayRect.anchorMax = Vector2.one; + overlayRect.offsetMin = Vector2.zero; + overlayRect.offsetMax = Vector2.zero; + slot.cooldownOverlay = overlayObject.GetComponent(); + slot.cooldownOverlay.color = new Color(0f, 0f, 0f, 0.58f); + slot.cooldownOverlay.type = Image.Type.Filled; + slot.cooldownOverlay.fillMethod = Image.FillMethod.Radial360; + slot.cooldownOverlay.fillAmount = 0f; + slot.cooldownText = CreateText(root.transform, "CooldownText", string.Empty, 18, TextAnchor.MiddleCenter, Vector2.zero, new Vector2(82f, 78f), boldFont); + slot.cooldownText.rectTransform.anchorMin = Vector2.zero; + slot.cooldownText.rectTransform.anchorMax = Vector2.one; + slot.cooldownText.rectTransform.offsetMin = Vector2.zero; + slot.cooldownText.rectTransform.offsetMax = Vector2.zero; + return slot; + } + + private static NotificationUI CreateNotificationStack(Transform canvas) + { + GameObject root = new GameObject("Notification Stack", typeof(RectTransform), typeof(VerticalLayoutGroup)); + root.transform.SetParent(canvas, false); + RectTransform rect = root.GetComponent(); + rect.anchorMin = new Vector2(0.5f, 1f); + rect.anchorMax = new Vector2(0.5f, 1f); + rect.pivot = new Vector2(0.5f, 1f); + rect.anchoredPosition = new Vector2(0f, -28f); + rect.sizeDelta = new Vector2(540f, 260f); + VerticalLayoutGroup layout = root.GetComponent(); + layout.spacing = 8f; + layout.childAlignment = TextAnchor.UpperCenter; + layout.childControlWidth = false; + layout.childControlHeight = false; + NotificationUI notificationUI = root.AddComponent(); + notificationUI.stackRoot = rect; + notificationUI.uiFont = regularFont; + return notificationUI; + } + + private static InteractionPromptUI CreateInteractionPrompt(Transform canvas) + { + GameObject root = CreatePanel(canvas, "Interaction Prompt", new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 136f), new Vector2(520f, 42f), new Color(0.03f, 0.04f, 0.06f, 0.86f)); + Text text = CreateText(root.transform, "PromptText", "E — взаимодействие", 17, TextAnchor.MiddleCenter, Vector2.zero, new Vector2(520f, 42f), boldFont); + text.rectTransform.anchorMin = Vector2.zero; + text.rectTransform.anchorMax = Vector2.one; + text.rectTransform.offsetMin = Vector2.zero; + text.rectTransform.offsetMax = Vector2.zero; + InteractionPromptUI prompt = root.AddComponent(); + prompt.root = root; + prompt.promptText = text; + root.SetActive(false); + return prompt; + } + + private static InventoryUI CreateInventoryPanel(Transform canvas, out GameObject panel) + { + panel = CreatePanel(canvas, "InventoryPanel", new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(900f, 620f), UITheme.Panel); + InventoryUI ui = panel.AddComponent(); + ui.panelRoot = panel; + ui.uiFont = regularFont; + ui.titleText = CreateText(panel.transform, "Title", "Инвентарь", 30, TextAnchor.UpperLeft, new Vector2(28f, -22f), new Vector2(280f, 42f), boldFont); + GameObject grid = new GameObject("SlotGrid", typeof(RectTransform), typeof(GridLayoutGroup)); + grid.transform.SetParent(panel.transform, false); + RectTransform gridRect = grid.GetComponent(); + gridRect.anchorMin = new Vector2(0f, 1f); + gridRect.anchorMax = new Vector2(0f, 1f); + gridRect.pivot = new Vector2(0f, 1f); + gridRect.anchoredPosition = new Vector2(30f, -92f); + gridRect.sizeDelta = new Vector2(500f, 390f); + GridLayoutGroup layout = grid.GetComponent(); + layout.cellSize = new Vector2(90f, 90f); + layout.spacing = new Vector2(10f, 10f); + layout.constraint = GridLayoutGroup.Constraint.FixedColumnCount; + layout.constraintCount = 5; + ui.slotGrid = grid.transform; + ui.descriptionText = CreateText(panel.transform, "Description", "Выберите предмет.", 17, TextAnchor.UpperLeft, new Vector2(560f, -96f), new Vector2(300f, 360f), regularFont); + ui.hintText = CreateText(panel.transform, "Hint", "I — закрыть", 15, TextAnchor.LowerLeft, new Vector2(30f, 22f), new Vector2(500f, 28f), regularFont); + ui.closeButton = CreateButton(panel.transform, "CloseButton", "Закрыть", new Vector2(760f, -560f), new Vector2(110f, 38f)); + return ui; + } + + private static CraftingUI CreateCraftingPanel(Transform canvas, out GameObject panel) + { + panel = CreatePanel(canvas, "CraftingPanel", new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(1050f, 650f), UITheme.Panel); + CraftingUI ui = panel.AddComponent(); + ui.panelRoot = panel; + ui.uiFont = regularFont; + CreateText(panel.transform, "Title", "Крафт", 30, TextAnchor.UpperLeft, new Vector2(28f, -22f), new Vector2(280f, 42f), boldFont); + ui.recipeListRoot = CreateVerticalList(panel.transform, "RecipeList", new Vector2(30f, -88f), new Vector2(320f, 470f)); + ui.ingredientsText = CreateText(panel.transform, "Ingredients", "Ингредиенты", 18, TextAnchor.UpperLeft, new Vector2(390f, -90f), new Vector2(280f, 300f), regularFont); + ui.resultText = CreateText(panel.transform, "Result", "Результат", 20, TextAnchor.UpperLeft, new Vector2(720f, -90f), new Vector2(280f, 120f), boldFont); + ui.descriptionText = CreateText(panel.transform, "Description", string.Empty, 17, TextAnchor.UpperLeft, new Vector2(720f, -230f), new Vector2(280f, 180f), regularFont); + ui.messageText = CreateText(panel.transform, "Message", string.Empty, 16, TextAnchor.LowerLeft, new Vector2(390f, 42f), new Vector2(360f, 42f), regularFont); + ui.craftButton = CreateButton(panel.transform, "CraftButton", "Создать", new Vector2(822f, -555f), new Vector2(150f, 42f)); + ui.closeButton = CreateButton(panel.transform, "CloseButton", "Закрыть", new Vector2(32f, -585f), new Vector2(120f, 38f)); + return ui; + } + + private static QuestLogUI CreateQuestLogPanel(Transform canvas, out GameObject panel) + { + panel = CreatePanel(canvas, "QuestLogPanel", new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(1050f, 650f), UITheme.Panel); + QuestLogUI ui = panel.AddComponent(); + ui.panelRoot = panel; + ui.uiFont = regularFont; + ui.titleText = CreateText(panel.transform, "Title", "Журнал квестов", 30, TextAnchor.UpperLeft, new Vector2(28f, -22f), new Vector2(360f, 42f), boldFont); + CreateText(panel.transform, "ActiveHeader", "Активные", 20, TextAnchor.UpperLeft, new Vector2(32f, -78f), new Vector2(180f, 30f), boldFont); + ui.activeListRoot = CreateVerticalList(panel.transform, "ActiveList", new Vector2(30f, -115f), new Vector2(340f, 230f)); + CreateText(panel.transform, "CompletedHeader", "Завершённые", 20, TextAnchor.UpperLeft, new Vector2(32f, -365f), new Vector2(220f, 30f), boldFont); + ui.completedListRoot = CreateVerticalList(panel.transform, "CompletedList", new Vector2(30f, -402f), new Vector2(340f, 160f)); + ui.detailText = CreateText(panel.transform, "Details", "Нет выбранного квеста.", 17, TextAnchor.UpperLeft, new Vector2(420f, -92f), new Vector2(570f, 480f), regularFont); + ui.closeButton = CreateButton(panel.transform, "CloseButton", "Закрыть", new Vector2(32f, -585f), new Vector2(120f, 38f)); + return ui; + } + + private static TalentTreeUI CreateTalentTreePanel(Transform canvas, out GameObject panel) + { + panel = CreatePanel(canvas, "TalentTreePanel", new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(1150f, 720f), UITheme.Panel); + TalentTreeUI ui = panel.AddComponent(); + ui.panelRoot = panel; + ui.uiFont = regularFont; + ui.titleText = CreateText(panel.transform, "Title", "Дерево талантов", 30, TextAnchor.UpperLeft, new Vector2(28f, -22f), new Vector2(360f, 42f), boldFont); + ui.pointsText = CreateText(panel.transform, "Points", "Очки талантов: 0", 20, TextAnchor.UpperRight, new Vector2(760f, -24f), new Vector2(340f, 36f), boldFont); + GameObject lineRoot = new GameObject("LineRoot", typeof(RectTransform)); + lineRoot.transform.SetParent(panel.transform, false); + ui.lineRoot = lineRoot.GetComponent(); + StretchRect(ui.lineRoot, new Vector2(40f, 80f), new Vector2(-340f, -110f)); + GameObject nodesRoot = new GameObject("NodesRoot", typeof(RectTransform)); + nodesRoot.transform.SetParent(panel.transform, false); + ui.nodesRoot = nodesRoot.GetComponent(); + StretchRect(ui.nodesRoot, new Vector2(40f, 80f), new Vector2(-340f, -110f)); + ui.statsText = CreateText(panel.transform, "Stats", "Характеристики", 17, TextAnchor.UpperLeft, new Vector2(840f, -100f), new Vector2(270f, 360f), regularFont); + ui.saveButton = CreateButton(panel.transform, "SaveButton", "Save", new Vector2(50f, -660f), new Vector2(110f, 38f)); + ui.loadButton = CreateButton(panel.transform, "LoadButton", "Load", new Vector2(180f, -660f), new Vector2(110f, 38f)); + ui.resetButton = CreateButton(panel.transform, "ResetButton", "Reset", new Vector2(310f, -660f), new Vector2(110f, 38f)); + ui.closeButton = CreateButton(panel.transform, "CloseButton", "Закрыть", new Vector2(980f, -660f), new Vector2(120f, 38f)); + + GameObject tooltipRoot = CreatePanel(panel.transform, "TalentTooltip", new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-28f, 34f), new Vector2(310f, 160f), new Color(0.03f, 0.04f, 0.055f, 0.96f)); + Text tooltipText = CreateText(tooltipRoot.transform, "Text", string.Empty, 15, TextAnchor.UpperLeft, new Vector2(14f, -12f), new Vector2(282f, 136f), regularFont); + TalentTooltipUI tooltip = tooltipRoot.AddComponent(); + tooltip.panelRoot = tooltipRoot; + tooltip.contentText = tooltipText; + ui.tooltip = tooltip; + tooltipRoot.SetActive(false); + return ui; + } + + private static DialogueUI CreateDialoguePanel(Transform canvas, out GameObject panel) + { + panel = CreatePanel(canvas, "DialoguePanel", new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 170f), new Vector2(1100f, 300f), new Color(0.04f, 0.05f, 0.07f, 0.94f)); + DialogueUI ui = panel.AddComponent(); + ui.panelRoot = panel; + ui.uiFont = regularFont; + ui.speakerText = CreateText(panel.transform, "Speaker", "NPC", 24, TextAnchor.UpperLeft, new Vector2(28f, -22f), new Vector2(360f, 36f), boldFont); + ui.lineText = CreateText(panel.transform, "Line", string.Empty, 20, TextAnchor.UpperLeft, new Vector2(28f, -68f), new Vector2(680f, 150f), regularFont); + ui.responseRoot = CreateVerticalList(panel.transform, "Responses", new Vector2(720f, -48f), new Vector2(340f, 210f)); + ui.closeButton = CreateButton(panel.transform, "CloseButton", "Закрыть", new Vector2(962f, -250f), new Vector2(110f, 36f)); + return ui; + } + + private static GameObject CreatePausePanel(Transform canvas, out Button resume, out Button save, out Button load, out Button reset) + { + GameObject panel = CreatePanel(canvas, "PausePanel", new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, new Vector2(420f, 340f), UITheme.Panel); + CreateText(panel.transform, "Title", "Пауза", 30, TextAnchor.UpperCenter, new Vector2(0f, -24f), new Vector2(420f, 44f), boldFont).rectTransform.anchorMin = new Vector2(0f, 1f); + resume = CreateButton(panel.transform, "Resume", "Продолжить", new Vector2(100f, -92f), new Vector2(220f, 42f)); + save = CreateButton(panel.transform, "Save", "Сохранить", new Vector2(100f, -146f), new Vector2(220f, 42f)); + load = CreateButton(panel.transform, "Load", "Загрузить", new Vector2(100f, -200f), new Vector2(220f, 42f)); + reset = CreateButton(panel.transform, "Reset", "Сбросить сохранение", new Vector2(100f, -254f), new Vector2(220f, 42f)); + return panel; + } + + private static GameManager CreateGameManager(PlayerBundle player, QuestManager questManager, DialogueManager dialogueManager, CraftingSystem craftingSystem, UIManager uiManager, SaveSystem saveSystem) + { + GameObject root = new GameObject("GameManager"); + GameManager manager = root.AddComponent(); + manager.playerController = player.controller; + manager.playerStats = player.stats; + manager.inventory = player.inventory; + manager.levelSystem = player.levelSystem; + manager.weaponManager = player.weaponManager; + manager.abilityManager = player.abilityManager; + manager.talentManager = player.talentManager; + manager.questManager = questManager; + manager.dialogueManager = dialogueManager; + manager.craftingSystem = craftingSystem; + manager.uiManager = uiManager; + manager.saveSystem = saveSystem; + return manager; + } + + private static void CreateTree(Vector3 position) + { + GameObject trunk = CreatePrimitive("Tree Trunk", PrimitiveType.Cylinder, position + Vector3.up * 0.8f, new Vector3(0.55f, 1.6f, 0.55f), materials["Wood"]); + GameObject leaves = CreatePrimitive("Tree Leaves", PrimitiveType.Sphere, position + Vector3.up * 2.45f, new Vector3(2.1f, 1.7f, 2.1f), materials["Leaves"]); + leaves.transform.SetParent(trunk.transform, true); + } + + private static GameObject CreatePrimitive(string name, PrimitiveType primitive, Vector3 position, Vector3 scale, Material material) + { + GameObject obj = GameObject.CreatePrimitive(primitive); + obj.name = name; + obj.transform.position = position; + obj.transform.localScale = scale; + Renderer renderer = obj.GetComponent(); + if (renderer != null) + { + renderer.sharedMaterial = material; + } + + return obj; + } + + private static void CreateNameplate(Transform parent, string text, Color color) + { + GameObject nameObject = new GameObject("Nameplate"); + nameObject.transform.SetParent(parent, false); + nameObject.transform.localPosition = new Vector3(0f, 1.55f, 0f); + TextMesh mesh = nameObject.AddComponent(); + mesh.text = text; + mesh.anchor = TextAnchor.MiddleCenter; + mesh.alignment = TextAlignment.Center; + mesh.characterSize = 0.22f; + mesh.fontSize = 42; + mesh.color = color; + if (regularFont != null) + { + mesh.font = regularFont; + mesh.GetComponent().sharedMaterial = regularFont.material; + } + } + + private static void CreateSign(string text, Vector3 position) + { + GameObject sign = CreatePrimitive("Sign " + text, PrimitiveType.Cube, position + Vector3.up * 0.8f, new Vector3(1.8f, 0.9f, 0.12f), materials["Wood"]); + CreateNameplate(sign.transform, text, Color.white); + } + + private static GameObject CreatePanel(Transform parent, string name, Vector2 anchorMin, Vector2 anchorMax, Vector2 pivot, Vector2 anchoredPosition, Vector2 size, Color color) + { + GameObject panel = new GameObject(name, typeof(RectTransform), typeof(Image)); + panel.transform.SetParent(parent, false); + RectTransform rect = panel.GetComponent(); + rect.anchorMin = anchorMin; + rect.anchorMax = anchorMax; + rect.pivot = pivot; + rect.anchoredPosition = anchoredPosition; + rect.sizeDelta = size; + panel.GetComponent().color = color; + return panel; + } + + private static Text CreateText(Transform parent, string name, string value, int fontSize, TextAnchor anchor, Vector2 anchoredPosition, Vector2 size, Font font) + { + GameObject textObject = new GameObject(name, typeof(RectTransform), typeof(Text)); + textObject.transform.SetParent(parent, false); + RectTransform rect = textObject.GetComponent(); + rect.anchorMin = new Vector2(0f, 1f); + rect.anchorMax = new Vector2(0f, 1f); + rect.pivot = new Vector2(0f, 1f); + rect.anchoredPosition = anchoredPosition; + rect.sizeDelta = size; + Text text = textObject.GetComponent(); + text.text = value; + text.font = font != null ? font : regularFont != null ? regularFont : Resources.GetBuiltinResource("Arial.ttf"); + text.fontSize = fontSize; + text.alignment = anchor; + text.color = UITheme.Text; + text.supportRichText = true; + return text; + } + + private static Button CreateButton(Transform parent, string name, string label, Vector2 anchoredPosition, Vector2 size) + { + GameObject buttonObject = new GameObject(name, typeof(RectTransform), typeof(Image), typeof(Button)); + buttonObject.transform.SetParent(parent, false); + RectTransform rect = buttonObject.GetComponent(); + rect.anchorMin = new Vector2(0f, 1f); + rect.anchorMax = new Vector2(0f, 1f); + rect.pivot = new Vector2(0f, 1f); + rect.anchoredPosition = anchoredPosition; + rect.sizeDelta = size; + buttonObject.GetComponent().color = new Color(0.13f, 0.18f, 0.24f, 0.96f); + Text text = CreateText(buttonObject.transform, "Text", label, 16, TextAnchor.MiddleCenter, Vector2.zero, size, regularFont); + text.rectTransform.anchorMin = Vector2.zero; + text.rectTransform.anchorMax = Vector2.one; + text.rectTransform.pivot = new Vector2(0.5f, 0.5f); + text.rectTransform.anchoredPosition = Vector2.zero; + text.rectTransform.offsetMin = Vector2.zero; + text.rectTransform.offsetMax = Vector2.zero; + return buttonObject.GetComponent