| 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263 |
- using UnityEngine;
- using UnityEngine.UIElements; // Make sure you have this using directive
- using UnityEngine.SceneManagement; // Added for scene management
- using System.Collections.Generic; // Needed for List<>
- using System.Linq; // Needed for LINQ operations
- using System.Collections; // Needed for coroutines
- public class MainTeamSelectScript : MonoBehaviour
- {
- private UIDocument uiDocument;
- private TeamCharacter currentCharacter;
- private List<Button> characterSlotButtons = new List<Button>();
- private List<Button> createNewCharacterButtons = new List<Button>();
- // Character slot management
- private TeamCharacter[] characterSlots = new TeamCharacter[4]; // 4 character slots
- private int currentSlotIndex = -1; // -1 means no slot selected
- // UI elements
- private TextField characterNameField;
- private Button randomizeNameButton;
- private DropdownField genderDropdown;
- private IntegerField strengthField, dexterityField, constitutionField, wisdomField, perceptionField;
- private IntegerField initField, damageField, spellCastingField, movementSpeedField, hpField, acField;
- // Attribute management UI
- private Button randomizeAttributesButton;
- private Button resetToPointBuyButton;
- private Label availablePointsLabel;
- private Label creationModeLabel;
- // Inventory/Shop UI elements
- private Button addWeaponButton;
- private Button addArmorButton;
- private Button addMiscButton;
- private IntegerField goldField;
- private IntegerField silverField;
- private IntegerField copperField;
- private VisualElement weaponsList;
- private VisualElement armorList;
- private VisualElement miscList;
- // Shop reference
- private ItemShopManager shopManager;
- // Navigation buttons
- private Button backToTitleButton;
- private Button proceedToBattleButton;
- void Awake()
- {
- uiDocument = GetComponent<UIDocument>();
- if (uiDocument == null)
- {
- Debug.LogError("UIDocument component not found on this GameObject.", this);
- return; // Exit if no UIDocument is found
- }
- // Initialize character slots array
- characterSlots = new TeamCharacter[4];
- // Clear all existing character equipment to ensure shop-only acquisition
- ClearAllCharacterEquipment();
- // Start with no character selected (empty character sheet)
- currentCharacter = null;
- currentSlotIndex = -1;
- // Check if team has been finalized (proceeded to map)
- bool teamFinalized = IsTeamFinalized();
- // Load saved team if available
- LoadSavedTeamData();
- // Get UI element references
- GetUIElementReferences();
- // Set up event listeners
- SetupEventListeners();
- // Try to find missing UI elements one more time after everything is set up
- ValidateUIElements();
- // If team is finalized, disable editing and show message
- if (teamFinalized)
- {
- SetTeamFinalizedMode();
- }
- // Initialize UI with character data
- UpdateCharacterUI();
- UpdateSlotVisualStates();
- UpdateNavigationButtons();
- }
- private void ValidateUIElements()
- {
- // Final attempt to find critical UI elements that might have been missed
- if (proceedToBattleButton == null && uiDocument != null)
- {
- var root = uiDocument.rootVisualElement;
- Debug.LogWarning("Final attempt to find proceedToBattleButton...");
- // Try searching with different approaches
- proceedToBattleButton = root.Q<Button>("ProceedToBattleButton") ??
- root.Q<Button>("ProceedButton") ??
- root.Q<Button>("StartButton") ??
- root.Q<Button>(className: "proceed-button");
- // If still not found, search through all buttons for text matches
- if (proceedToBattleButton == null)
- {
- var allButtons = root.Query<Button>().ToList();
- foreach (var button in allButtons)
- {
- if (button.text.ToLower().Contains("proceed") ||
- button.text.ToLower().Contains("start") ||
- button.text.ToLower().Contains("battle"))
- {
- proceedToBattleButton = button;
- break;
- }
- }
- }
- if (proceedToBattleButton != null)
- {
- // Set up the event listener since we found it late
- proceedToBattleButton.clicked += OnProceedToBattleClicked;
- }
- else
- {
- Debug.LogError("CRITICAL: Could not find proceed button in UI! Please check the UI Document.");
- }
- }
- }
- private void GetUIElementReferences()
- {
- var root = uiDocument.rootVisualElement;
- // Character info fields
- characterNameField = root.Q<TextField>("CharacterNameField");
- randomizeNameButton = root.Q<Button>("RandomizeNameButton");
- genderDropdown = root.Q<DropdownField>("GenderDropdown");
- // Stat fields
- strengthField = root.Q<IntegerField>("StrengthValue");
- dexterityField = root.Q<IntegerField>("DexterityValue");
- constitutionField = root.Q<IntegerField>("ConstitutionValue");
- wisdomField = root.Q<IntegerField>("WisdomValue");
- perceptionField = root.Q<IntegerField>("PerceptionValue");
- // Derived stat fields
- initField = root.Q<IntegerField>("InitValue");
- damageField = root.Q<IntegerField>("DamageValue");
- spellCastingField = root.Q<IntegerField>("SpellCastingValue");
- movementSpeedField = root.Q<IntegerField>("MovementSpeedValue");
- hpField = root.Q<IntegerField>("HPValue");
- acField = root.Q<IntegerField>("ACValue");
- // Attribute management UI
- randomizeAttributesButton = root.Q<Button>("RandomizeAttributesButton");
- resetToPointBuyButton = root.Q<Button>("ResetToPointBuyButton");
- availablePointsLabel = root.Q<Label>("AvailablePointsLabel");
- creationModeLabel = root.Q<Label>("CreationModeLabel");
- // Find all buttons with the name "CreateNewCharacterButton"
- createNewCharacterButtons = uiDocument.rootVisualElement.Query<Button>("CreateNewCharacterButton").ToList();
- // Find all ViewCharacterButton buttons
- characterSlotButtons = uiDocument.rootVisualElement.Query<Button>("ViewCharacterButton").ToList();
- // Inventory/Shop UI elements
- addWeaponButton = root.Q<Button>("AddWeaponButton");
- addArmorButton = root.Q<Button>("AddArmourButton");
- addMiscButton = root.Q<Button>("AddMiscButton");
- goldField = root.Q<IntegerField>("GoldValue");
- silverField = root.Q<IntegerField>("SilverValue");
- copperField = root.Q<IntegerField>("CopperValue");
- weaponsList = root.Q<VisualElement>("WeaponsList");
- armorList = root.Q<VisualElement>("ArmourList");
- miscList = root.Q<VisualElement>("MiscList");
- // Navigation buttons
- backToTitleButton = root.Q<Button>("BackToTitleButton");
- proceedToBattleButton = root.Q<Button>("ProceedToBattleButton");
- // Debug and fallback for Back to Title button
- if (backToTitleButton == null)
- {
- Debug.LogWarning("BackToTitleButton not found! Creating fallback button...");
- // Create a simple fallback button
- backToTitleButton = new Button();
- backToTitleButton.text = "Back to Title";
- backToTitleButton.name = "BackToTitleButton_Fallback";
- backToTitleButton.style.position = Position.Absolute;
- backToTitleButton.style.top = 10;
- backToTitleButton.style.left = 10;
- backToTitleButton.style.width = 120;
- backToTitleButton.style.height = 30;
- root.Add(backToTitleButton);
- }
- // Find shop manager in scene
- shopManager = FindFirstObjectByType<ItemShopManager>();
- if (shopManager == null)
- {
- Debug.LogWarning("No ItemShopManager found in scene. Shop functionality will be limited.");
- Debug.LogWarning("Trying to refresh shop manager reference...");
- // Try again after a short delay to allow for potential late initialization
- StartCoroutine(RefreshShopManagerReference());
- }
- else
- {
- SetupShopManagerCallbacks();
- }
- // Check if any buttons were found
- if (createNewCharacterButtons.Count == 0)
- {
- Debug.LogWarning("No buttons with the name 'CreateNewCharacterButton' found in the UI Document.");
- }
- else
- {
- // Add a click listener to each button found
- foreach (Button button in createNewCharacterButtons)
- {
- // Example of passing data (requires adjusting the handler method):
- int characterIndex = createNewCharacterButtons.IndexOf(button); // Example data
- button.clicked += () => OnCreateNewCharacterButtonClicked(characterIndex);
- }
- }
- // Add click listeners to ViewCharacterButton buttons
- for (int i = 0; i < characterSlotButtons.Count; i++)
- {
- int index = i; // Capture the index for the closure
- characterSlotButtons[i].clicked += () => OnViewCharacterButtonClicked(index);
- }
- }
- private void SetupEventListeners()
- {
- // Name randomization
- if (randomizeNameButton != null)
- {
- randomizeNameButton.clicked += OnRandomizeNameClicked;
- }
- // Character name change
- if (characterNameField != null)
- {
- characterNameField.RegisterValueChangedCallback(OnCharacterNameChanged);
- }
- // Gender change
- if (genderDropdown != null)
- {
- genderDropdown.RegisterValueChangedCallback(OnGenderChanged);
- }
- // Stat changes
- if (strengthField != null)
- strengthField.RegisterValueChangedCallback(evt => OnStatChanged());
- if (dexterityField != null)
- dexterityField.RegisterValueChangedCallback(evt => OnStatChanged());
- if (constitutionField != null)
- constitutionField.RegisterValueChangedCallback(evt => OnStatChanged());
- if (wisdomField != null)
- wisdomField.RegisterValueChangedCallback(evt => OnStatChanged());
- if (perceptionField != null)
- perceptionField.RegisterValueChangedCallback(evt => OnStatChanged());
- // Attribute management
- if (randomizeAttributesButton != null)
- randomizeAttributesButton.clicked += OnRandomizeAttributesClicked;
- if (resetToPointBuyButton != null)
- resetToPointBuyButton.clicked += OnResetToPointBuyClicked;
- // Inventory/Shop management
- if (addWeaponButton != null)
- addWeaponButton.clicked += OnAddWeaponClicked;
- if (addArmorButton != null)
- addArmorButton.clicked += OnAddArmorClicked;
- if (addMiscButton != null)
- addMiscButton.clicked += OnAddMiscClicked;
- // Bank field changes
- if (goldField != null)
- goldField.RegisterValueChangedCallback(evt => OnBankChanged());
- if (silverField != null)
- silverField.RegisterValueChangedCallback(evt => OnBankChanged());
- if (copperField != null)
- copperField.RegisterValueChangedCallback(evt => OnBankChanged());
- // Navigation buttons
- if (backToTitleButton != null)
- backToTitleButton.clicked += OnBackToTitleClicked;
- if (proceedToBattleButton != null)
- proceedToBattleButton.clicked += OnProceedToBattleClicked;
- else
- Debug.LogWarning("proceedToBattleButton is null during SetupEventListeners - will try to set up event listener later");
- }
- private void OnRandomizeNameClicked()
- {
- if (currentCharacter == null) return;
- currentCharacter.GenerateRandomName();
- characterNameField.value = currentCharacter.name;
- // Update the slot button and save to slot
- UpdateCurrentSlotButton();
- SaveCurrentCharacterToSlot();
- }
- private void OnCharacterNameChanged(ChangeEvent<string> evt)
- {
- if (currentCharacter == null) return;
- currentCharacter.name = evt.newValue;
- // Update the slot button and save to slot
- UpdateCurrentSlotButton();
- SaveCurrentCharacterToSlot();
- // Update the character card if we have a current slot
- if (currentSlotIndex >= 0)
- {
- UpdateCharacterCard(currentSlotIndex, currentCharacter);
- }
- }
- private void OnGenderChanged(ChangeEvent<string> evt)
- {
- if (currentCharacter == null) return;
- currentCharacter.SetGender(evt.newValue == "Male");
- // Optionally regenerate name when gender changes
- // You can remove this if you don't want automatic name regeneration
- currentCharacter.GenerateRandomName();
- characterNameField.value = currentCharacter.name;
- // Update the slot button and save to slot
- UpdateCurrentSlotButton();
- SaveCurrentCharacterToSlot();
- // Update the character card if we have a current slot
- if (currentSlotIndex >= 0)
- {
- UpdateCharacterCard(currentSlotIndex, currentCharacter);
- }
- }
- private void OnStatChanged()
- {
- if (currentCharacter == null) return;
- // Validate point-buy constraints
- int newStr = strengthField?.value ?? currentCharacter.strength;
- int newDex = dexterityField?.value ?? currentCharacter.dexterity;
- int newCon = constitutionField?.value ?? currentCharacter.constitution;
- int newWis = wisdomField?.value ?? currentCharacter.wisdom;
- int newPer = perceptionField?.value ?? currentCharacter.perception;
- // Clamp values to valid range (4-18)
- newStr = Mathf.Clamp(newStr, 4, 18);
- newDex = Mathf.Clamp(newDex, 4, 18);
- newCon = Mathf.Clamp(newCon, 4, 18);
- newWis = Mathf.Clamp(newWis, 4, 18);
- newPer = Mathf.Clamp(newPer, 4, 18);
- // Check if the new combination is affordable
- int totalCost = TeamCharacter.GetStatCost(newStr) + TeamCharacter.GetStatCost(newDex) +
- TeamCharacter.GetStatCost(newCon) + TeamCharacter.GetStatCost(newWis) + TeamCharacter.GetStatCost(newPer);
- if (totalCost <= 22) // Changed from 18 to 22 for 5-stat system
- {
- // Update character stats from UI
- currentCharacter.strength = newStr;
- currentCharacter.dexterity = newDex;
- currentCharacter.constitution = newCon;
- currentCharacter.wisdom = newWis;
- currentCharacter.perception = newPer;
- currentCharacter.UpdateAvailablePoints();
- }
- else
- {
- // Reset to previous valid values
- if (strengthField != null) strengthField.value = currentCharacter.strength;
- if (dexterityField != null) dexterityField.value = currentCharacter.dexterity;
- if (constitutionField != null) constitutionField.value = currentCharacter.constitution;
- if (wisdomField != null) wisdomField.value = currentCharacter.wisdom;
- if (perceptionField != null) perceptionField.value = currentCharacter.perception;
- }
- // Update derived stats and point display
- UpdateDerivedStats();
- UpdateAttributeUI();
- SaveCurrentCharacterToSlot();
- UpdateNavigationButtons();
- // Update the character card if we have a current slot
- if (currentSlotIndex >= 0)
- {
- UpdateCharacterCard(currentSlotIndex, currentCharacter);
- }
- }
- private void OnRandomizeAttributesClicked()
- {
- if (currentCharacter == null) return;
- currentCharacter.RandomizeAttributes();
- UpdateCharacterUI();
- UpdateAttributeUI();
- SaveCurrentCharacterToSlot();
- UpdateNavigationButtons();
- // Update the character card if we have a current slot
- if (currentSlotIndex >= 0)
- {
- UpdateCharacterCard(currentSlotIndex, currentCharacter);
- }
- }
- private void OnResetToPointBuyClicked()
- {
- if (currentCharacter == null) return;
- currentCharacter.ResetToPointBuy();
- UpdateCharacterUI();
- UpdateAttributeUI();
- SaveCurrentCharacterToSlot();
- UpdateNavigationButtons();
- // Update the character card if we have a current slot
- if (currentSlotIndex >= 0)
- {
- UpdateCharacterCard(currentSlotIndex, currentCharacter);
- }
- }
- private void OnAddWeaponClicked()
- {
- if (currentCharacter == null)
- {
- Debug.LogWarning("OnAddWeaponClicked: No current character selected");
- return;
- }
- // Open weapon shop for this character
- OpenWeaponShop();
- }
- private void OpenWeaponShop()
- {
- if (shopManager != null)
- {
- shopManager.OpenShop(currentCharacter);
- }
- else
- {
- Debug.LogWarning("No shop manager found - cannot open shop");
- }
- }
- private void AddWeaponToCharacter(string weaponType)
- {
- // Add weapon to character's inventory (would integrate with real shop/inventory system)
- if (currentCharacter.weapons == null)
- {
- currentCharacter.weapons = new System.Collections.Generic.List<string>();
- }
- currentCharacter.weapons.Add(weaponType);
- // If this is the first weapon, equip it automatically
- if (string.IsNullOrEmpty(currentCharacter.equippedWeapon))
- {
- currentCharacter.equippedWeapon = weaponType;
- }
- SaveCurrentCharacterToSlot();
- }
- private void OnAddArmorClicked()
- {
- if (currentCharacter == null) return;
- if (shopManager != null)
- {
- shopManager.OpenShop(currentCharacter);
- }
- else
- {
- Debug.LogWarning("No shop manager found - cannot open shop");
- }
- }
- private void OnAddMiscClicked()
- {
- if (currentCharacter == null) return;
- if (shopManager != null)
- {
- shopManager.OpenShop(currentCharacter);
- }
- else
- {
- Debug.LogWarning("No shop manager found - cannot open shop");
- }
- }
- private void AddArmorToCharacter(string armorType)
- {
- if (currentCharacter.armor == null)
- {
- currentCharacter.armor = new System.Collections.Generic.List<string>();
- }
- currentCharacter.armor.Add(armorType);
- SaveCurrentCharacterToSlot();
- UpdateInventoryUI();
- }
- private void AddMiscItemToCharacter(string itemType)
- {
- if (currentCharacter.miscItems == null)
- {
- currentCharacter.miscItems = new System.Collections.Generic.List<string>();
- }
- currentCharacter.miscItems.Add(itemType);
- SaveCurrentCharacterToSlot();
- UpdateInventoryUI();
- }
- private void OnBankChanged()
- {
- if (currentCharacter == null) return;
- currentCharacter.gold = goldField?.value ?? currentCharacter.gold;
- currentCharacter.silver = silverField?.value ?? currentCharacter.silver;
- currentCharacter.copper = copperField?.value ?? currentCharacter.copper;
- SaveCurrentCharacterToSlot();
- }
- private void UpdateInventoryUI()
- {
- if (currentCharacter == null) return;
- // Update bank fields
- if (goldField != null) goldField.value = currentCharacter.gold;
- if (silverField != null) silverField.value = currentCharacter.silver;
- if (copperField != null) copperField.value = currentCharacter.copper;
- // Update weapon list with equip status
- UpdateWeaponListWithEquipStatus(weaponsList, currentCharacter.weapons, currentCharacter.equippedWeapon);
- // Update armor list
- UpdateItemList(armorList, currentCharacter.armor, "ArmorItemRow", OnRemoveArmor);
- // Update misc list
- UpdateItemList(miscList, currentCharacter.miscItems, "MiscItemRow", OnRemoveMisc);
- }
- private void UpdateWeaponListWithEquipStatus(VisualElement container, System.Collections.Generic.List<string> weapons, string equippedWeapon)
- {
- if (container == null || weapons == null) return;
- // Clear existing items (except example rows)
- var itemsToRemove = container.Query<VisualElement>(className: "inventory-item-row").ToList()
- .Where(item => !item.name.Contains("Example")).ToList();
- foreach (var item in itemsToRemove)
- {
- container.Remove(item);
- }
- // Add current weapons with equip status
- foreach (var weaponName in weapons)
- {
- var itemRow = new VisualElement();
- itemRow.AddToClassList("inventory-item-row");
- itemRow.AddToClassList("WeaponItemRow");
- bool isEquipped = weaponName == equippedWeapon;
- var nameLabel = new Label(isEquipped ? $"[EQUIPPED] {weaponName}" : weaponName);
- nameLabel.AddToClassList("item-name-label");
- if (isEquipped)
- {
- nameLabel.style.color = UnityEngine.Color.green;
- nameLabel.style.unityFontStyleAndWeight = UnityEngine.FontStyle.Bold;
- }
- itemRow.Add(nameLabel);
- // Equip button (only show if not already equipped)
- if (!isEquipped)
- {
- var equipButton = new Button(() => OnEquipWeapon(weaponName));
- equipButton.text = "Equip";
- equipButton.AddToClassList("equip-item-button");
- itemRow.Add(equipButton);
- }
- var removeButton = new Button(() => OnRemoveWeapon(weaponName));
- removeButton.text = "Remove (Refund)";
- removeButton.AddToClassList("remove-item-button");
- // Add tooltip for refund information
- string refundInfo = GetRefundInfo(weaponName, "weapon");
- if (!string.IsNullOrEmpty(refundInfo))
- {
- removeButton.tooltip = $"Remove and refund: {refundInfo}";
- }
- itemRow.Add(removeButton);
- container.Add(itemRow);
- }
- }
- private void OnEquipWeapon(string weaponName)
- {
- if (currentCharacter != null && currentCharacter.weapons.Contains(weaponName))
- {
- currentCharacter.equippedWeapon = weaponName;
- SaveCurrentCharacterToSlot();
- UpdateInventoryUI();
- }
- }
- private void UpdateItemList(VisualElement container, System.Collections.Generic.List<string> items, string rowClassName, System.Action<string> removeAction)
- {
- if (container == null || items == null) return;
- // Clear existing items (except example rows)
- var itemsToRemove = container.Query<VisualElement>(className: "inventory-item-row").ToList()
- .Where(item => !item.name.Contains("Example")).ToList();
- foreach (var item in itemsToRemove)
- {
- container.Remove(item);
- }
- // Add current items
- foreach (var itemName in items)
- {
- var itemRow = new VisualElement();
- itemRow.AddToClassList("inventory-item-row");
- itemRow.AddToClassList(rowClassName);
- var nameLabel = new Label(itemName);
- nameLabel.AddToClassList("item-name-label");
- itemRow.Add(nameLabel);
- var removeButton = new Button(() => removeAction(itemName));
- removeButton.text = "Remove (Refund)";
- removeButton.AddToClassList("remove-item-button");
- // Add tooltip or title to show refund information
- string itemType = GetItemTypeFromClassName(rowClassName);
- string refundInfo = GetRefundInfo(itemName, itemType);
- if (!string.IsNullOrEmpty(refundInfo))
- {
- removeButton.tooltip = $"Remove and refund: {refundInfo}";
- }
- itemRow.Add(removeButton);
- container.Add(itemRow);
- }
- }
- private string GetItemTypeFromClassName(string className)
- {
- if (className.Contains("Weapon")) return "weapon";
- if (className.Contains("Armor")) return "armor";
- if (className.Contains("Misc")) return "misc";
- return "";
- }
- private string GetRefundInfo(string itemName, string itemType)
- {
- if (shopManager == null) return "";
- List<Item> itemList = null;
- switch (itemType.ToLower())
- {
- case "weapon":
- itemList = shopManager.GetWeapons();
- break;
- case "armor":
- itemList = shopManager.GetArmor();
- break;
- case "misc":
- itemList = shopManager.GetMiscItems();
- break;
- }
- if (itemList != null)
- {
- var shopItem = itemList.Find(item => item.itemName == itemName);
- if (shopItem != null)
- {
- return shopItem.GetCostString();
- }
- }
- return "";
- }
- private void RefundItemPrice(string itemName, string itemType)
- {
- if (shopManager == null || currentCharacter == null)
- {
- Debug.LogWarning($"Cannot refund {itemName}: shop manager or current character is null");
- return;
- }
- // Find the item price from the shop manager
- int goldRefund = 0;
- int silverRefund = 0;
- int copperRefund = 0;
- // Check the appropriate list based on item type
- List<Item> itemList = null;
- switch (itemType.ToLower())
- {
- case "weapon":
- itemList = shopManager.GetWeapons();
- break;
- case "armor":
- itemList = shopManager.GetArmor();
- break;
- case "misc":
- itemList = shopManager.GetMiscItems();
- break;
- }
- if (itemList != null)
- {
- // Find the item in the shop list
- var shopItem = itemList.Find(item => item.itemName == itemName);
- if (shopItem != null)
- {
- goldRefund = shopItem.goldCost;
- silverRefund = shopItem.silverCost;
- copperRefund = shopItem.copperCost;
- // Add the refund to the character's money
- currentCharacter.gold += goldRefund;
- currentCharacter.silver += silverRefund;
- currentCharacter.copper += copperRefund;
- }
- else
- {
- Debug.LogWarning($"Could not find {itemName} in shop {itemType} list for refund");
- }
- }
- else
- {
- Debug.LogWarning($"Could not access shop {itemType} list for refund");
- }
- }
- private void OnRemoveWeapon(string weaponName)
- {
- if (currentCharacter?.weapons != null)
- {
- currentCharacter.weapons.Remove(weaponName);
- // If this was the equipped weapon, unequip it and equip the first remaining weapon if any
- if (currentCharacter.equippedWeapon == weaponName)
- {
- if (currentCharacter.weapons.Count > 0)
- {
- currentCharacter.equippedWeapon = currentCharacter.weapons[0];
- }
- else
- {
- currentCharacter.equippedWeapon = "";
- }
- }
- // Refund the weapon price
- RefundItemPrice(weaponName, "weapon");
- SaveCurrentCharacterToSlot();
- UpdateInventoryUI();
- }
- }
- private void OnRemoveArmor(string armorName)
- {
- if (currentCharacter?.armor != null)
- {
- currentCharacter.armor.Remove(armorName);
- // Refund the armor price
- RefundItemPrice(armorName, "armor");
- SaveCurrentCharacterToSlot();
- UpdateInventoryUI();
- }
- }
- private void OnRemoveMisc(string itemName)
- {
- if (currentCharacter?.miscItems != null)
- {
- currentCharacter.miscItems.Remove(itemName);
- // Refund the misc item price
- RefundItemPrice(itemName, "misc");
- SaveCurrentCharacterToSlot();
- UpdateInventoryUI();
- }
- }
- private void UpdateCharacterUI()
- {
- if (currentCharacter == null)
- {
- // Clear the UI when no character is selected
- if (characterNameField != null) characterNameField.value = "";
- if (genderDropdown != null) genderDropdown.value = "Male";
- if (strengthField != null) strengthField.value = 10;
- if (dexterityField != null) dexterityField.value = 10;
- if (constitutionField != null) constitutionField.value = 10;
- if (wisdomField != null) wisdomField.value = 10;
- // Clear derived stats
- if (initField != null) initField.value = 0;
- if (damageField != null) damageField.value = 0;
- if (spellCastingField != null) spellCastingField.value = 0;
- if (movementSpeedField != null) movementSpeedField.value = 30;
- if (hpField != null) hpField.value = 10;
- if (acField != null) acField.value = 0;
- // Clear attribute UI
- if (creationModeLabel != null) creationModeLabel.text = "Mode: None";
- if (availablePointsLabel != null) availablePointsLabel.text = "Available Points: 0";
- return;
- }
- // Update UI with current character data
- if (characterNameField != null)
- characterNameField.value = currentCharacter.name;
- if (genderDropdown != null)
- genderDropdown.value = currentCharacter.isMale ? "Male" : "Female";
- if (strengthField != null) strengthField.value = currentCharacter.strength;
- if (dexterityField != null) dexterityField.value = currentCharacter.dexterity;
- if (constitutionField != null) constitutionField.value = currentCharacter.constitution;
- if (wisdomField != null) wisdomField.value = currentCharacter.wisdom;
- if (perceptionField != null) perceptionField.value = currentCharacter.perception;
- // Recalculate equipment bonuses from inventory
- currentCharacter.RecalculateEquipmentBonuses();
- UpdateDerivedStats();
- UpdateAttributeUI();
- UpdateInventoryUI();
- }
- private void UpdateAttributeUI()
- {
- if (currentCharacter == null) return;
- // Update creation mode display
- if (creationModeLabel != null)
- {
- creationModeLabel.text = "Mode: Point Buy";
- }
- // Update available points display
- if (availablePointsLabel != null)
- {
- availablePointsLabel.text = $"Available Points: {currentCharacter.availablePoints}";
- }
- // All stat fields are always editable in the new system
- if (strengthField != null) strengthField.SetEnabled(true);
- if (dexterityField != null) dexterityField.SetEnabled(true);
- if (constitutionField != null) constitutionField.SetEnabled(true);
- if (wisdomField != null) wisdomField.SetEnabled(true);
- if (perceptionField != null) perceptionField.SetEnabled(true);
- }
- private void UpdateDerivedStats()
- {
- if (currentCharacter == null) return;
- // Update the read-only derived stats (uses final stats including equipment modifiers)
- if (initField != null) initField.value = currentCharacter.Initiative;
- if (damageField != null) damageField.value = currentCharacter.DamageBonus;
- if (spellCastingField != null) spellCastingField.value = currentCharacter.SpellAC;
- if (movementSpeedField != null) movementSpeedField.value = currentCharacter.MovementSpeed;
- if (hpField != null) hpField.value = currentCharacter.HitPoints;
- if (acField != null) acField.value = currentCharacter.ArmorClass;
- }
- private void UpdateCurrentSlotButton()
- {
- // Update the character card information if we have a current slot selected
- if (currentSlotIndex >= 0 && currentSlotIndex < characterSlotButtons.Count && currentCharacter != null)
- {
- UpdateCharacterCard(currentSlotIndex, currentCharacter);
- }
- }
- private void UpdateCharacterCard(int slotIndex, TeamCharacter character)
- {
- if (slotIndex < 0 || slotIndex >= 4 || character == null) return;
- var root = uiDocument.rootVisualElement;
- // Find the character slot instance based on index
- string[] slotNames = { "Character1", "Character2", "Character3", "Character4" };
- var characterSlot = root.Q<VisualElement>(slotNames[slotIndex]);
- if (characterSlot == null) return;
- // Find the character card button within this slot
- var characterCard = characterSlot.Q<Button>("ViewCharacterButton");
- if (characterCard == null) return;
- // Update character name
- var nameLabel = characterCard.Q<Label>("CharacterNameLabel");
- if (nameLabel != null)
- {
- nameLabel.text = character.name;
- }
- // Update stats
- var strengthLabel = characterCard.Q<Label>("StrengthLabel");
- if (strengthLabel != null) strengthLabel.text = character.strength.ToString();
- var dexterityLabel = characterCard.Q<Label>("DexterityLabel");
- if (dexterityLabel != null) dexterityLabel.text = character.dexterity.ToString();
- var constitutionLabel = characterCard.Q<Label>("ConstitutionLabel");
- if (constitutionLabel != null) constitutionLabel.text = character.constitution.ToString();
- var wisdomLabel = characterCard.Q<Label>("WisdomLabel");
- if (wisdomLabel != null) wisdomLabel.text = character.wisdom.ToString();
- var perceptionLabel = characterCard.Q<Label>("PerceptionLabel");
- if (perceptionLabel != null) perceptionLabel.text = character.perception.ToString();
- // Update HP and AC
- var hpLabel = characterCard.Q<Label>("HPLabel");
- if (hpLabel != null) hpLabel.text = $"HP: {character.HitPoints}";
- var acLabel = characterCard.Q<Label>("ACLabel");
- if (acLabel != null) acLabel.text = $"AC: {character.ArmorClass}";
- // Show the character card and hide the create button
- var createButton = characterSlot.Q<Button>("CreateNewCharacterButton");
- if (createButton != null)
- {
- createButton.style.display = DisplayStyle.None;
- }
- characterCard.RemoveFromClassList("disabled-card");
- characterCard.style.display = DisplayStyle.Flex;
- characterCard.SetEnabled(true);
- }
- private void SaveCurrentCharacterToSlot()
- {
- // Save the current character data back to its slot
- if (currentSlotIndex >= 0 && currentSlotIndex < characterSlots.Length && currentCharacter != null)
- {
- characterSlots[currentSlotIndex] = currentCharacter.CreateCopy();
- }
- }
- private void UpdateSlotVisualStates()
- {
- var root = uiDocument.rootVisualElement;
- string[] slotNames = { "Character1", "Character2", "Character3", "Character4" };
- // Update visual states of all character slots
- for (int i = 0; i < slotNames.Length; i++)
- {
- var characterSlot = root.Q<VisualElement>(slotNames[i]);
- if (characterSlot == null) continue;
- // Remove all visual state classes first
- characterSlot.RemoveFromClassList("selected-slot");
- // Add selected state if this is the current slot
- if (i == currentSlotIndex)
- {
- characterSlot.AddToClassList("selected-slot");
- }
- // Update character card visibility and data
- if (characterSlots[i] != null)
- {
- // Character exists in this slot
- UpdateCharacterCard(i, characterSlots[i]);
- }
- else
- {
- // No character in this slot - show create button
- var createButton = characterSlot.Q<Button>("CreateNewCharacterButton");
- var characterCard = characterSlot.Q<Button>("ViewCharacterButton");
- if (createButton != null)
- {
- createButton.style.display = DisplayStyle.Flex;
- }
- if (characterCard != null)
- {
- characterCard.style.display = DisplayStyle.None;
- characterCard.AddToClassList("disabled-card");
- characterCard.SetEnabled(false);
- }
- }
- }
- }
- // Example handler if you need to pass data (like an index)
- private void OnCreateNewCharacterButtonClicked(int index)
- {
- // Create a new character with random name
- currentCharacter = new TeamCharacter();
- // Generate name after construction to avoid serialization issues
- currentCharacter.GenerateRandomName();
- // Save character to the slot (create a proper copy)
- characterSlots[index] = currentCharacter.CreateCopy();
- currentSlotIndex = index;
- UpdateCharacterUI();
- UpdateSlotVisualStates();
- // Update navigation buttons immediately after character creation
- UpdateNavigationButtons();
- // Update the character card for this slot
- UpdateCharacterCard(index, currentCharacter);
- // Call UpdateNavigationButtons again after UI updates
- UpdateNavigationButtons();
- }
- private void OnViewCharacterButtonClicked(int index)
- {
- // Check if there's a character in this slot
- if (characterSlots[index] != null)
- {
- // Create a working copy of the character from the slot
- currentCharacter = characterSlots[index].CreateCopy();
- currentSlotIndex = index;
- UpdateCharacterUI();
- UpdateSlotVisualStates();
- UpdateNavigationButtons();
- }
- else
- {
- // Slot is empty, save current character to this slot if we have one
- if (currentCharacter != null)
- {
- // Create a proper copy of the current character data
- characterSlots[index] = currentCharacter.CreateCopy();
- currentSlotIndex = index;
- // Update the character card for this slot
- UpdateCharacterCard(index, currentCharacter);
- UpdateSlotVisualStates();
- UpdateNavigationButtons();
- }
- }
- }
- // Start is called once before the first execution of Update after the MonoBehaviour is created
- void Start()
- {
- // You can keep Start if needed for other initialization
- }
- // Update is called once per frame
- void Update()
- {
- // Debug keys for testing
- if (Input.GetKeyDown(KeyCode.F5))
- {
- DebugCurrentCharacterSlots();
- }
- if (Input.GetKeyDown(KeyCode.F6))
- {
- SaveTeamToGameState();
- }
- if (Input.GetKeyDown(KeyCode.F7))
- {
- TestPlayerPrefsData();
- }
- }
- private void DebugCurrentCharacterSlots()
- {
- for (int i = 0; i < characterSlots.Length; i++)
- {
- if (characterSlots[i] != null)
- {
- var character = characterSlots[i];
- }
- else
- {
- }
- }
- }
- private void TestPlayerPrefsData()
- {
- for (int i = 0; i < 4; i++)
- {
- string existsKey = $"Character{i}_Exists";
- if (PlayerPrefs.HasKey(existsKey))
- {
- int exists = PlayerPrefs.GetInt(existsKey);
- if (exists == 1)
- {
- string prefix = $"Character{i}_";
- string name = PlayerPrefs.GetString(prefix + "Name", "UNKNOWN");
- int str = PlayerPrefs.GetInt(prefix + "Strength", 0);
- int dex = PlayerPrefs.GetInt(prefix + "Dexterity", 0);
- int con = PlayerPrefs.GetInt(prefix + "Constitution", 0);
- int wis = PlayerPrefs.GetInt(prefix + "Wisdom", 0);
- }
- }
- else
- {
- }
- }
- }
- void OnDestroy()
- {
- // Clean up shop manager callbacks to prevent memory leaks
- if (shopManager != null)
- {
- shopManager.OnCharacterDataChanged -= OnShopCharacterDataChanged;
- }
- }
- #region Navigation Methods
- private void OnBackToTitleClicked()
- {
- // Check if team is finalized and this is acting as "New Game" button
- if (IsTeamFinalized())
- {
- // Show confirmation dialog for starting new game
- #if UNITY_EDITOR
- bool confirmed = UnityEditor.EditorUtility.DisplayDialog(
- "Start New Game",
- "This will start a completely new game and overwrite your current progress.\n\nAre you sure you want to continue?",
- "Start New Game",
- "Cancel"
- );
- if (confirmed)
- {
- StartNewGame();
- }
- #else
- // In builds, we'll assume user confirms for now
- // In a real game, implement a proper UI dialog system
- Debug.LogWarning("Starting new game - implement proper dialog for builds");
- StartNewGame();
- #endif
- }
- else
- {
- // Normal back to title behavior
- SceneManager.LoadScene("TitleScreenScene");
- }
- }
- private void StartNewGame()
- {
- // Initialize GameStateManager for new game
- if (GameStateManager.Instance != null)
- {
- GameStateManager.Instance.StartNewGame();
- }
- // Clear all save data
- ClearAllSaveData();
- // Reload the scene to start fresh
- SceneManager.LoadScene("MainTeamSelectScene");
- }
- private void ClearAllSaveData()
- {
- // Clear GameStateManager data
- if (GameStateManager.Instance != null)
- {
- GameStateManager.Instance.teamSetupComplete = false;
- GameStateManager.Instance.hasGeneratedMap = false;
- }
- // Clear PlayerPrefs data
- for (int i = 0; i < 4; i++)
- {
- string prefix = $"Character{i}_";
- PlayerPrefs.DeleteKey($"Character{i}_Exists");
- PlayerPrefs.DeleteKey(prefix + "Name");
- PlayerPrefs.DeleteKey(prefix + "IsMale");
- PlayerPrefs.DeleteKey(prefix + "Strength");
- PlayerPrefs.DeleteKey(prefix + "Dexterity");
- PlayerPrefs.DeleteKey(prefix + "Constitution");
- PlayerPrefs.DeleteKey(prefix + "Wisdom");
- PlayerPrefs.DeleteKey(prefix + "Gold");
- PlayerPrefs.DeleteKey(prefix + "Silver");
- PlayerPrefs.DeleteKey(prefix + "Copper");
- }
- // Clear map data
- PlayerPrefs.DeleteKey("HasGeneratedMap");
- PlayerPrefs.DeleteKey("MapSeed");
- PlayerPrefs.DeleteKey("TeamSize");
- PlayerPrefs.DeleteKey("TeamSetupComplete");
- PlayerPrefs.DeleteKey("GameSaved");
- PlayerPrefs.Save();
- }
- private void OnProceedToBattleClicked()
- {
- // Check if team is already finalized
- if (IsTeamFinalized())
- {
- // Team is finalized, return to MapScene2
- SceneManager.LoadScene("MapScene2");
- return;
- }
- // Check if we have at least one character
- if (!HasAtLeastOneCharacter())
- {
- Debug.LogWarning("Need at least one character to proceed to battle!");
- // TODO: Show message to user
- return;
- }
- // Save all configured characters before proceeding
- SaveTeamToGameState();
- // Mark that the team has proceeded to the map (finalized)
- // Save to both GameStateManager and PlayerPrefs for redundancy
- if (GameStateManager.Instance != null)
- {
- GameStateManager.Instance.teamSetupComplete = true;
- GameStateManager.Instance.SaveGame();
- }
- // Also save to PlayerPrefs as backup
- PlayerPrefs.SetInt("TeamSetupComplete", 1);
- PlayerPrefs.Save();
- SceneManager.LoadScene("MapScene2");
- }
- private void SaveTeamToGameState()
- {
- // Save team data to GameStateManager for persistence
- List<TeamCharacter> configuredCharacters = new List<TeamCharacter>();
- for (int i = 0; i < characterSlots.Length; i++)
- {
- if (characterSlots[i] != null)
- {
- configuredCharacters.Add(characterSlots[i]);
- // Save individual character data
- SaveCharacterToPlayerPrefs(characterSlots[i], i);
- // Verify the save immediately
- PlayerPrefs.SetInt($"Character{i}_Exists", 1);
- string testName = PlayerPrefs.GetString($"Character{i}_Name", "NOT_FOUND");
- }
- else
- {
- // Clear any existing character data for empty slots
- PlayerPrefs.DeleteKey($"Character{i}_Exists");
- }
- }
- // Save team composition info
- PlayerPrefs.SetInt("TeamSize", configuredCharacters.Count);
- // Update GameStateManager if available
- if (GameStateManager.Instance != null)
- {
- // Copy our team to the GameStateManager
- for (int i = 0; i < characterSlots.Length; i++)
- {
- if (characterSlots[i] != null)
- {
- GameStateManager.Instance.savedTeam[i] = characterSlots[i].CreateCopy();
- }
- else
- {
- GameStateManager.Instance.savedTeam[i] = null;
- }
- }
- GameStateManager.Instance.teamSetupComplete = true;
- GameStateManager.Instance.SaveGame();
- }
- else
- {
- Debug.LogWarning("GameStateManager.Instance is null!");
- }
- // Log configured team for MapScene
- foreach (var character in configuredCharacters)
- {
- }
- PlayerPrefs.Save(); // Ensure data is written to disk
- }
- public List<TeamCharacter> GetConfiguredCharacters()
- {
- // Public method to get all configured characters (useful for other scripts)
- List<TeamCharacter> configuredCharacters = new List<TeamCharacter>();
- for (int i = 0; i < characterSlots.Length; i++)
- {
- if (characterSlots[i] != null)
- {
- configuredCharacters.Add(characterSlots[i]);
- }
- }
- return configuredCharacters;
- }
- private void UpdateNavigationButtons()
- {
- // Enable/disable proceed button based on team status
- if (proceedToBattleButton != null)
- {
- bool canProceed = HasAtLeastOneCharacter();
- proceedToBattleButton.SetEnabled(canProceed);
- // Also remove/add visual disabled state
- if (!canProceed)
- {
- proceedToBattleButton.AddToClassList("disabled-button");
- proceedToBattleButton.tooltip = "Create at least one character to proceed";
- }
- else
- {
- proceedToBattleButton.RemoveFromClassList("disabled-button");
- proceedToBattleButton.tooltip = "Start adventure with your team";
- // Force remove any disabled classes that might be interfering
- proceedToBattleButton.RemoveFromClassList("unity-disabled");
- }
- }
- else
- {
- Debug.LogWarning("UpdateNavigationButtons: proceedToBattleButton is null! The button name in the UI might be different than expected.");
- Debug.LogWarning("Please check that a button with name 'ProceedToBattleButton' exists in your UI Document.");
- // Try to find the button again with common alternative names
- var root = uiDocument?.rootVisualElement;
- if (root != null)
- {
- proceedToBattleButton = root.Q<Button>("ProceedButton") ??
- root.Q<Button>("StartButton") ??
- root.Q<Button>("BattleButton") ??
- root.Q<Button>("ProceedToBattleButton");
- if (proceedToBattleButton != null)
- {
- // Recursively call this method now that we found the button
- UpdateNavigationButtons();
- }
- }
- }
- }
- private bool HasAtLeastOneCharacter()
- {
- int characterCount = 0;
- for (int i = 0; i < characterSlots.Length; i++)
- {
- if (characterSlots[i] != null)
- {
- characterCount++;
- }
- else
- {
- }
- }
- bool hasCharacters = characterCount > 0;
- return hasCharacters;
- }
- #endregion
- #region Save/Load Team Data
- private void LoadSavedTeamData()
- {
- // Try to load from GameStateManager first (if available and has data)
- if (GameStateManager.Instance != null && GameStateManager.Instance.savedTeam != null)
- {
- for (int i = 0; i < characterSlots.Length && i < GameStateManager.Instance.savedTeam.Length; i++)
- {
- if (GameStateManager.Instance.savedTeam[i] != null)
- {
- characterSlots[i] = GameStateManager.Instance.savedTeam[i].CreateCopy();
- // Update the slot button
- if (i < characterSlotButtons.Count)
- {
- characterSlotButtons[i].text = characterSlots[i].name;
- characterSlotButtons[i].SetEnabled(true);
- characterSlotButtons[i].RemoveFromClassList("unity-disabled");
- characterSlotButtons[i].RemoveFromClassList("DisabledCharacterCard");
- // Hide the create button
- if (i < createNewCharacterButtons.Count)
- {
- createNewCharacterButtons[i].style.display = DisplayStyle.None;
- }
- }
- }
- }
- }
- // Always also try to load from PlayerPrefs (either as backup or primary)
- for (int i = 0; i < characterSlots.Length; i++)
- {
- // If we haven't loaded this slot from GameStateManager, try PlayerPrefs
- if (characterSlots[i] == null && PlayerPrefs.HasKey($"Character{i}_Exists") && PlayerPrefs.GetInt($"Character{i}_Exists") == 1)
- {
- // Load character data from PlayerPrefs
- characterSlots[i] = LoadCharacterFromPlayerPrefs(i);
- // Update the slot button
- if (i < characterSlotButtons.Count)
- {
- characterSlotButtons[i].text = characterSlots[i].name;
- characterSlotButtons[i].SetEnabled(true);
- characterSlotButtons[i].RemoveFromClassList("unity-disabled");
- characterSlotButtons[i].RemoveFromClassList("DisabledCharacterCard");
- // Hide the create button
- if (i < createNewCharacterButtons.Count)
- {
- createNewCharacterButtons[i].style.display = DisplayStyle.None;
- }
- }
- }
- }
- // Count loaded characters
- int loadedCount = 0;
- for (int i = 0; i < characterSlots.Length; i++)
- {
- if (characterSlots[i] != null) loadedCount++;
- }
- }
- private void SaveCurrentTeamToGameState()
- {
- // Save the current team using PlayerPrefs for now
- for (int i = 0; i < characterSlots.Length; i++)
- {
- if (characterSlots[i] != null)
- {
- SaveCharacterToPlayerPrefs(characterSlots[i], i);
- PlayerPrefs.SetInt($"Character{i}_Exists", 1);
- }
- else
- {
- PlayerPrefs.SetInt($"Character{i}_Exists", 0);
- }
- }
- PlayerPrefs.Save();
- }
- private TeamCharacter LoadCharacterFromPlayerPrefs(int index)
- {
- string prefix = $"Character{index}_";
- var character = new TeamCharacter();
- character.name = PlayerPrefs.GetString(prefix + "Name", "");
- character.isMale = PlayerPrefs.GetInt(prefix + "IsMale", 1) == 1;
- character.strength = PlayerPrefs.GetInt(prefix + "Strength", 10);
- character.dexterity = PlayerPrefs.GetInt(prefix + "Dexterity", 10);
- character.constitution = PlayerPrefs.GetInt(prefix + "Constitution", 10);
- character.wisdom = PlayerPrefs.GetInt(prefix + "Wisdom", 10);
- character.perception = PlayerPrefs.GetInt(prefix + "Perception", 10);
- character.gold = PlayerPrefs.GetInt(prefix + "Gold", 25);
- character.silver = PlayerPrefs.GetInt(prefix + "Silver", 0);
- character.copper = PlayerPrefs.GetInt(prefix + "Copper", 0);
- // Load equipped weapon
- character.equippedWeapon = PlayerPrefs.GetString(prefix + "EquippedWeapon", "");
- // Load weapon list
- int weaponCount = PlayerPrefs.GetInt(prefix + "WeaponCount", 0);
- character.weapons = new System.Collections.Generic.List<string>();
- for (int i = 0; i < weaponCount; i++)
- {
- string weapon = PlayerPrefs.GetString(prefix + $"Weapon{i}", "");
- if (!string.IsNullOrEmpty(weapon))
- {
- character.weapons.Add(weapon);
- }
- }
- // Load armor list
- int armorCount = PlayerPrefs.GetInt(prefix + "ArmorCount", 0);
- character.armor = new System.Collections.Generic.List<string>();
- for (int i = 0; i < armorCount; i++)
- {
- string armor = PlayerPrefs.GetString(prefix + $"Armor{i}", "");
- if (!string.IsNullOrEmpty(armor))
- {
- character.armor.Add(armor);
- }
- }
- // Load misc items
- int miscCount = PlayerPrefs.GetInt(prefix + "MiscCount", 0);
- character.miscItems = new System.Collections.Generic.List<string>();
- for (int i = 0; i < miscCount; i++)
- {
- string misc = PlayerPrefs.GetString(prefix + $"Misc{i}", "");
- if (!string.IsNullOrEmpty(misc))
- {
- character.miscItems.Add(misc);
- }
- }
- // Load equipped armor
- character.equippedArmor = PlayerPrefs.GetString(prefix + "EquippedArmor", "");
- // If no equipped weapon but has weapons, equip the first one
- if (string.IsNullOrEmpty(character.equippedWeapon) && character.weapons.Count > 0)
- {
- character.equippedWeapon = character.weapons[0];
- }
- // Recalculate equipment bonuses from inventory after loading
- character.RecalculateEquipmentBonuses();
- return character;
- }
- private void SaveCharacterToPlayerPrefs(TeamCharacter character, int index)
- {
- string prefix = $"Character{index}_";
- PlayerPrefs.SetString(prefix + "Name", character.name);
- PlayerPrefs.SetInt(prefix + "IsMale", character.isMale ? 1 : 0);
- PlayerPrefs.SetInt(prefix + "Strength", character.strength);
- PlayerPrefs.SetInt(prefix + "Dexterity", character.dexterity);
- PlayerPrefs.SetInt(prefix + "Constitution", character.constitution);
- PlayerPrefs.SetInt(prefix + "Wisdom", character.wisdom);
- PlayerPrefs.SetInt(prefix + "Perception", character.perception);
- PlayerPrefs.SetInt(prefix + "Gold", character.gold);
- PlayerPrefs.SetInt(prefix + "Silver", character.silver);
- PlayerPrefs.SetInt(prefix + "Copper", character.copper);
- // Save equipped weapon
- PlayerPrefs.SetString(prefix + "EquippedWeapon", character.equippedWeapon ?? "");
- // Save weapon list
- if (character.weapons != null)
- {
- PlayerPrefs.SetInt(prefix + "WeaponCount", character.weapons.Count);
- for (int i = 0; i < character.weapons.Count; i++)
- {
- PlayerPrefs.SetString(prefix + $"Weapon{i}", character.weapons[i]);
- }
- }
- else
- {
- PlayerPrefs.SetInt(prefix + "WeaponCount", 0);
- }
- // Save armor list
- if (character.armor != null)
- {
- PlayerPrefs.SetInt(prefix + "ArmorCount", character.armor.Count);
- for (int i = 0; i < character.armor.Count; i++)
- {
- PlayerPrefs.SetString(prefix + $"Armor{i}", character.armor[i]);
- }
- }
- else
- {
- PlayerPrefs.SetInt(prefix + "ArmorCount", 0);
- }
- // Save misc items
- if (character.miscItems != null)
- {
- PlayerPrefs.SetInt(prefix + "MiscCount", character.miscItems.Count);
- for (int i = 0; i < character.miscItems.Count; i++)
- {
- PlayerPrefs.SetString(prefix + $"Misc{i}", character.miscItems[i]);
- }
- }
- else
- {
- PlayerPrefs.SetInt(prefix + "MiscCount", 0);
- }
- // Save equipped armor
- PlayerPrefs.SetString(prefix + "EquippedArmor", character.equippedArmor ?? "");
- // Immediately verify what was saved
- string savedName = PlayerPrefs.GetString(prefix + "Name", "FAILED_TO_SAVE");
- int savedStr = PlayerPrefs.GetInt(prefix + "Strength", -1);
- string savedWeapon = PlayerPrefs.GetString(prefix + "EquippedWeapon", "FAILED_TO_SAVE");
- if (savedName != character.name)
- {
- Debug.LogError($" ERROR: Name save failed! Expected '{character.name}', got '{savedName}'");
- }
- }
- #endregion
- #region Team Finalization
- private bool IsTeamFinalized()
- {
- // Check if the team has been finalized (player clicked "Proceed to Battle" and went to MapScene)
- // This is indicated by TeamSetupComplete being true or HasGeneratedMap being true
- bool hasGeneratedMap = PlayerPrefs.HasKey("HasGeneratedMap") && PlayerPrefs.GetInt("HasGeneratedMap") == 1;
- bool teamSetupCompletePrefs = PlayerPrefs.HasKey("TeamSetupComplete") && PlayerPrefs.GetInt("TeamSetupComplete") == 1;
- bool teamSetupCompleteGameState = false;
- if (GameStateManager.Instance != null)
- {
- teamSetupCompleteGameState = GameStateManager.Instance.teamSetupComplete;
- }
- bool finalized = hasGeneratedMap || teamSetupCompletePrefs || teamSetupCompleteGameState;
- return finalized;
- }
- private void SetTeamFinalizedMode()
- {
- // Disable all character creation and editing
- foreach (var button in createNewCharacterButtons)
- {
- button.SetEnabled(false);
- button.style.opacity = 0.5f;
- button.tooltip = "Team has been finalized - cannot create new characters";
- }
- // Disable character editing fields
- DisableCharacterEditingFields();
- // Change the proceed button to "Return to Adventure"
- if (proceedToBattleButton != null)
- {
- proceedToBattleButton.text = "Return to Adventure";
- proceedToBattleButton.tooltip = "Return to your ongoing adventure";
- }
- // Change the back button to offer new game option
- if (backToTitleButton != null)
- {
- backToTitleButton.text = "New Game";
- backToTitleButton.tooltip = "Start a completely new game (will overwrite current save)";
- }
- // Show a message that team is finalized
- }
- private void DisableCharacterEditingFields()
- {
- // Disable name editing
- if (characterNameField != null)
- {
- characterNameField.SetEnabled(false);
- characterNameField.style.opacity = 0.7f;
- }
- if (randomizeNameButton != null)
- {
- randomizeNameButton.SetEnabled(false);
- randomizeNameButton.style.opacity = 0.5f;
- }
- if (genderDropdown != null)
- {
- genderDropdown.SetEnabled(false);
- genderDropdown.style.opacity = 0.7f;
- }
- // Disable stat editing
- if (strengthField != null) strengthField.SetEnabled(false);
- if (dexterityField != null) dexterityField.SetEnabled(false);
- if (constitutionField != null) constitutionField.SetEnabled(false);
- if (wisdomField != null) wisdomField.SetEnabled(false);
- // Disable attribute buttons
- if (randomizeAttributesButton != null)
- {
- randomizeAttributesButton.SetEnabled(false);
- randomizeAttributesButton.style.opacity = 0.5f;
- }
- if (resetToPointBuyButton != null)
- {
- resetToPointBuyButton.SetEnabled(false);
- resetToPointBuyButton.style.opacity = 0.5f;
- }
- // Disable inventory management
- if (addWeaponButton != null)
- {
- addWeaponButton.SetEnabled(false);
- addWeaponButton.style.opacity = 0.5f;
- }
- if (addArmorButton != null)
- {
- addArmorButton.SetEnabled(false);
- addArmorButton.style.opacity = 0.5f;
- }
- if (addMiscButton != null)
- {
- addMiscButton.SetEnabled(false);
- addMiscButton.style.opacity = 0.5f;
- }
- // Disable bank editing
- if (goldField != null) goldField.SetEnabled(false);
- if (silverField != null) silverField.SetEnabled(false);
- if (copperField != null) copperField.SetEnabled(false);
- }
- #endregion
- private System.Collections.IEnumerator RefreshShopManagerReference()
- {
- // Wait for a short delay to allow for potential late initialization
- yield return new WaitForSeconds(0.1f);
- // Try to find the shop manager again
- var newShopManager = FindFirstObjectByType<ItemShopManager>();
- if (newShopManager != null)
- {
- shopManager = newShopManager;
- SetupShopManagerCallbacks();
- }
- else
- {
- Debug.LogWarning("Still no ItemShopManager found after delay. You may need to create one manually using the ShopSystemSetup component.");
- }
- }
- private void SetupShopManagerCallbacks()
- {
- if (shopManager != null)
- {
- // Subscribe to character data changes from the shop
- shopManager.OnCharacterDataChanged += OnShopCharacterDataChanged;
- }
- }
- private void OnShopCharacterDataChanged(TeamCharacter updatedCharacter)
- {
- if (updatedCharacter == null || currentCharacter == null)
- {
- Debug.LogWarning("OnShopCharacterDataChanged: updatedCharacter or currentCharacter is null");
- return;
- }
- // Copy the updated data back to the current character
- // This ensures the character object reference remains the same but data is updated
- currentCharacter.gold = updatedCharacter.gold;
- currentCharacter.silver = updatedCharacter.silver;
- currentCharacter.copper = updatedCharacter.copper;
- // Update inventory lists (create new lists to avoid reference issues)
- currentCharacter.weapons = new System.Collections.Generic.List<string>(updatedCharacter.weapons);
- currentCharacter.armor = new System.Collections.Generic.List<string>(updatedCharacter.armor);
- currentCharacter.miscItems = new System.Collections.Generic.List<string>(updatedCharacter.miscItems);
- // Update the UI to reflect the changes
- UpdateInventoryUI();
- // Save the updated character to the slot
- SaveCurrentCharacterToSlot();
- }
- // Clear all equipment from existing characters to ensure shop-only acquisition
- private void ClearAllCharacterEquipment()
- {
- // Clear equipment from any existing characters in slots
- for (int i = 0; i < characterSlots.Length; i++)
- {
- if (characterSlots[i] != null)
- {
- characterSlots[i].weapons.Clear();
- characterSlots[i].armor.Clear();
- characterSlots[i].miscItems.Clear();
- characterSlots[i].equippedWeapon = "";
- characterSlots[i].equippedArmor = "";
- }
- }
- // Also clear equipment from current character if it exists
- if (currentCharacter != null)
- {
- currentCharacter.weapons.Clear();
- currentCharacter.armor.Clear();
- currentCharacter.miscItems.Clear();
- currentCharacter.equippedWeapon = "";
- currentCharacter.equippedArmor = "";
- }
- }
- }
- [System.Serializable]
- public class TeamCharacter
- {
- public string name = "";
- public bool isMale = true;
- // Base attributes (can be modified by equipment in the future)
- public int strength = 10;
- public int dexterity = 10;
- public int constitution = 10;
- public int wisdom = 10;
- public int perception = 10;
- // Character creation mode
- public bool isRandomized = false; // Track if stats were randomized
- public int availablePoints = 22; // Point-buy system (adjusted for 5 stats instead of 4)
- // Equipment modifiers (for future use)
- public int strengthModifier = 0;
- public int dexterityModifier = 0;
- public int constitutionModifier = 0;
- public int wisdomModifier = 0;
- public int perceptionModifier = 0;
- public int acModifier = 0; // Direct AC bonuses from equipment
- // Currency
- public int gold = 25; // Reduced starting money to make shop purchases more strategic
- public int silver = 0;
- public int copper = 0;
- // Equipment/Inventory (simple string-based for now)
- public System.Collections.Generic.List<string> weapons = new System.Collections.Generic.List<string>();
- public System.Collections.Generic.List<string> armor = new System.Collections.Generic.List<string>();
- public System.Collections.Generic.List<string> miscItems = new System.Collections.Generic.List<string>();
- public string equippedWeapon = "";
- public string equippedArmor = "";
- // Final attributes (base + equipment modifiers)
- public int FinalStrength => strength + strengthModifier;
- public int FinalDexterity => dexterity + dexterityModifier;
- public int FinalConstitution => constitution + constitutionModifier;
- public int FinalWisdom => wisdom + wisdomModifier;
- public int FinalPerception => perception + perceptionModifier;
- // Derived stats (calculated from final stats)
- public int Initiative => FinalDexterity - 10;
- public int DamageBonus => (FinalStrength - 10) / 2;
- public int SpellAC => FinalWisdom - 10; // Renamed from SpellCastingBonus
- public int MovementSpeed => 30 + (int)(Mathf.Ceil((FinalDexterity - 10) / 5.0f) * 5); // Rounded to closest 5 above
- public int HitPoints => Mathf.Max(10, 10 + (FinalConstitution - 10) * 2 + (FinalStrength - 10) + (FinalDexterity - 10) / 2);
- public int ArmorClass => 10 + (FinalDexterity - 10) / 2 + (FinalConstitution - 10) / 3 + acModifier; // Base 10 + DEX bonus + small CON bonus + equipment AC
- public TeamCharacter()
- {
- // Don't generate random name in constructor to avoid serialization issues
- // Name will be generated explicitly when needed
- }
- public TeamCharacter(string characterName, bool male = true)
- {
- name = characterName;
- isMale = male;
- }
- public void GenerateRandomName()
- {
- // Only generate names when the application is playing to avoid serialization issues
- if (Application.isPlaying)
- {
- name = FantasyNameGenerator.GenerateCharacterName(isMale);
- }
- else
- {
- // Fallback name for serialization/design time
- name = isMale ? "New Male Character" : "New Female Character";
- }
- }
- public void SetGender(bool male)
- {
- isMale = male;
- }
- // Randomize all attributes using point-buy system (22 points)
- public void RandomizeAttributes()
- {
- if (Application.isPlaying)
- {
- // Start with random base values (4-12 range for variety)
- int[] stats = new int[5];
- for (int i = 0; i < 5; i++)
- {
- stats[i] = UnityEngine.Random.Range(4, 13); // Random start between 4-12
- }
- // Calculate how many points we've spent so far
- int pointsSpent = 0;
- for (int i = 0; i < 5; i++)
- {
- pointsSpent += GetStatCost(stats[i]);
- }
- int pointsRemaining = 22 - pointsSpent; // Changed from 18 to 22 for 5 stats
- // If we're over budget, reduce some stats
- while (pointsRemaining < 0)
- {
- int randomStat = UnityEngine.Random.Range(0, 5);
- if (stats[randomStat] > 4) // Don't go below 4
- {
- int oldCost = GetStatCost(stats[randomStat]);
- stats[randomStat]--;
- int newCost = GetStatCost(stats[randomStat]);
- pointsRemaining += (oldCost - newCost);
- }
- }
- // Now spend remaining points randomly
- while (pointsRemaining > 0)
- {
- // Pick a random stat to increase
- int randomStat = UnityEngine.Random.Range(0, 5);
- // Check if we can afford to increase this stat
- int currentValue = stats[randomStat];
- if (currentValue >= 18) continue; // Can't go higher than 18
- int currentCost = GetStatCost(currentValue);
- int newCost = GetStatCost(currentValue + 1);
- int costDifference = newCost - currentCost;
- if (pointsRemaining >= costDifference)
- {
- stats[randomStat]++;
- pointsRemaining -= costDifference;
- }
- else
- {
- // If we can't afford any increases, try to find a stat we can afford
- bool foundAffordable = false;
- for (int i = 0; i < 5; i++)
- {
- if (stats[i] < 18)
- {
- int testCurrentCost = GetStatCost(stats[i]);
- int testNewCost = GetStatCost(stats[i] + 1);
- int testCostDiff = testNewCost - testCurrentCost;
- if (pointsRemaining >= testCostDiff)
- {
- foundAffordable = true;
- break;
- }
- }
- }
- // If no affordable increases, break out
- if (!foundAffordable) break;
- }
- }
- // Assign back to properties
- strength = stats[0];
- dexterity = stats[1];
- constitution = stats[2];
- wisdom = stats[3];
- perception = stats[4];
- // Set as point-buy mode (not locked like true random)
- isRandomized = false;
- UpdateAvailablePoints();
- }
- } // Alternative: Truly random stats (2-18, locked from editing)
- public void RandomizeAttributesWild()
- {
- if (Application.isPlaying)
- {
- strength = UnityEngine.Random.Range(2, 19); // 2-18 inclusive
- dexterity = UnityEngine.Random.Range(2, 19);
- constitution = UnityEngine.Random.Range(2, 19);
- wisdom = UnityEngine.Random.Range(2, 19);
- perception = UnityEngine.Random.Range(2, 19);
- isRandomized = true;
- availablePoints = 0; // No points available when randomized
- }
- }
- // Reset attributes to default for point-buy
- public void ResetToPointBuy()
- {
- strength = 10;
- dexterity = 10;
- constitution = 10;
- wisdom = 10;
- perception = 10;
- isRandomized = false;
- availablePoints = 22; // Reset to full point pool (adjusted for 5 stats)
- }
- // Calculate point cost for a stat value (point-buy system)
- public static int GetStatCost(int statValue)
- {
- // Point-buy costs: 4=-4pts, 5=-2pts, 6=-1pts, 7=-1pts, 8=0pts, 9=1pt, 10=2pts, 11=3pts, 12=4pts, 13=5pts, 14=7pts, 15=9pts, 16=12pts, 17=16pts, 18=21pts
- switch (statValue)
- {
- case 4: return -4;
- case 5: return -2;
- case 6: return -1;
- case 7: return -1;
- case 8: return 0;
- case 9: return 1;
- case 10: return 2;
- case 11: return 3;
- case 12: return 4;
- case 13: return 5;
- case 14: return 7;
- case 15: return 9;
- case 16: return 12;
- case 17: return 16;
- case 18: return 21;
- default: return statValue < 4 ? -4 : 25; // Invalid values
- }
- }
- // Calculate total points spent
- public int GetTotalPointsSpent()
- {
- return GetStatCost(strength) + GetStatCost(dexterity) + GetStatCost(constitution) + GetStatCost(wisdom) + GetStatCost(perception);
- }
- // Update available points based on current stats
- public void UpdateAvailablePoints()
- {
- if (!isRandomized)
- {
- availablePoints = 22 - GetTotalPointsSpent(); // Changed from 18 to 22 for 5 stats
- }
- }
- // Check if we can afford to increase a stat
- public bool CanIncreaseStat(int currentValue)
- {
- if (isRandomized) return false; // Can't change randomized stats
- if (currentValue >= 18) return false; // Max value
- int currentCost = GetStatCost(currentValue);
- int newCost = GetStatCost(currentValue + 1);
- int costDifference = newCost - currentCost;
- return availablePoints >= costDifference;
- }
- // Create a deep copy of this character
- public TeamCharacter CreateCopy()
- {
- var copy = new TeamCharacter(name, isMale)
- {
- strength = this.strength,
- dexterity = this.dexterity,
- constitution = this.constitution,
- wisdom = this.wisdom,
- perception = this.perception,
- isRandomized = this.isRandomized,
- availablePoints = this.availablePoints,
- gold = this.gold,
- silver = this.silver,
- copper = this.copper,
- equippedWeapon = this.equippedWeapon,
- equippedArmor = this.equippedArmor
- };
- // Deep copy the lists
- copy.weapons = new System.Collections.Generic.List<string>(this.weapons);
- copy.armor = new System.Collections.Generic.List<string>(this.armor);
- copy.miscItems = new System.Collections.Generic.List<string>(this.miscItems);
- return copy;
- }
- // Recalculate all equipment modifiers from items in inventory (temporary solution)
- public void RecalculateEquipmentBonuses()
- {
- // Reset all modifiers to zero
- strengthModifier = 0;
- dexterityModifier = 0;
- constitutionModifier = 0;
- wisdomModifier = 0;
- perceptionModifier = 0;
- acModifier = 0;
- // Get reference to the shop manager to access item definitions
- var shopManager = UnityEngine.Object.FindFirstObjectByType<ItemShopManager>();
- if (shopManager == null) return;
- // Apply bonuses from all items in inventory
- ApplyBonusesFromItemList(shopManager.GetWeapons(), weapons);
- ApplyBonusesFromItemList(shopManager.GetArmor(), armor);
- ApplyBonusesFromItemList(shopManager.GetMiscItems(), miscItems);
- }
- private void ApplyBonusesFromItemList(System.Collections.Generic.List<Item> shopItems, System.Collections.Generic.List<string> ownedItems)
- {
- foreach (string itemName in ownedItems)
- {
- var shopItem = shopItems.Find(item => item.itemName == itemName);
- if (shopItem != null)
- {
- // Apply bonuses based on item type
- if (shopItem is WeaponItem weapon)
- {
- // Weapons might provide damage bonuses, but character stats are typically different
- // For now, we'll focus on armor and misc items for stat bonuses
- }
- else if (shopItem is ArmorItem armor)
- {
- strengthModifier += armor.strengthModifier;
- dexterityModifier += armor.dexterityModifier;
- constitutionModifier += armor.constitutionModifier;
- wisdomModifier += armor.wisdomModifier;
- acModifier += armor.armorClass;
- }
- else if (shopItem is MiscellaneousItem misc)
- {
- // Miscellaneous items might provide stat bonuses if they're permanent equipment
- // For consumables, bonuses would typically be applied when used, not while owned
- if (!misc.isConsumable)
- {
- // Add any permanent stat bonuses from misc items here
- // This would need to be extended based on your specific misc item properties
- }
- }
- }
- }
- }
- // Copy data from another character into this one
- public void CopyFrom(TeamCharacter other)
- {
- if (other == null) return;
- name = other.name;
- isMale = other.isMale;
- strength = other.strength;
- dexterity = other.dexterity;
- constitution = other.constitution;
- wisdom = other.wisdom;
- }
- }
|