void Update() { Player player = Player.localPlayer; if (player != null) { // hotkey (not while typing in chat, etc.) if (Input.GetKeyDown(hotKey) && !UIUtils.AnyInputActive()) { panel.SetActive(!panel.activeSelf); } // only update the panel if it's active if (panel.activeSelf) { // only show active quests, no completed ones List <Quest> activeQuests = player.quests.Where(q => !q.completed).ToList(); // instantiate/destroy enough slots UIUtils.BalancePrefabs(slotPrefab.gameObject, activeQuests.Count, content); // refresh all for (int i = 0; i < activeQuests.Count; ++i) { UIQuestSlot slot = content.GetChild(i).GetComponent <UIQuestSlot>(); Quest quest = activeQuests[i]; // name button GameObject descriptionPanel = slot.descriptionText.gameObject; string prefix = descriptionPanel.activeSelf ? hidePrefix : expandPrefix; slot.nameButton.GetComponentInChildren <Text>().text = prefix + quest.name; slot.nameButton.onClick.SetListener(() => { descriptionPanel.SetActive(!descriptionPanel.activeSelf); }); // description slot.descriptionText.text = quest.ToolTip(player); } } } else { panel.SetActive(false); } }
void Update() { Player player = Player.localPlayer; // only if trading, otherwise set inactive if (player != null && player.State == "TRADING" && player.Target != null && player.Target is Player) { panel.SetActive(true); Player other = (Player)player.Target; // OTHER /////////////////////////////////////////////////////////// // status text if (other.tradeStatus == TradeStatus.Accepted) { otherStatusText.text = "[ACCEPTED]"; } else if (other.tradeStatus == TradeStatus.Locked) { otherStatusText.text = "[LOCKED]"; } else { otherStatusText.text = ""; } // gold input otherGoldInput.text = other.tradeOfferGold.ToString(); // items UIUtils.BalancePrefabs(slotPrefab.gameObject, other.tradeOfferItems.Count, otherContent); for (int i = 0; i < other.tradeOfferItems.Count; ++i) { UIPlayerTradingSlot slot = otherContent.GetChild(i).GetComponent <UIPlayerTradingSlot>(); int inventoryIndex = other.tradeOfferItems[i]; slot.dragAndDropable.dragable = false; slot.dragAndDropable.dropable = false; if (0 <= inventoryIndex && inventoryIndex < other.inventory.Count && other.inventory[inventoryIndex].amount > 0) { ItemSlot itemSlot = other.inventory[inventoryIndex]; // refresh valid item slot.tooltip.enabled = true; slot.tooltip.text = itemSlot.ToolTip(); slot.image.color = Color.white; slot.image.sprite = itemSlot.item.Image; slot.amountOverlay.SetActive(itemSlot.amount > 1); slot.amountText.text = itemSlot.amount.ToString(); } else { // refresh invalid item slot.tooltip.enabled = false; slot.image.color = Color.clear; slot.image.sprite = null; slot.amountOverlay.SetActive(false); } } // SELF //////////////////////////////////////////////////////////// // status text if (player.tradeStatus == TradeStatus.Accepted) { myStatusText.text = "[ACCEPTED]"; } else if (player.tradeStatus == TradeStatus.Locked) { myStatusText.text = "[LOCKED]"; } else { myStatusText.text = ""; } // gold input if (player.tradeStatus == TradeStatus.Free) { myGoldInput.interactable = true; myGoldInput.onValueChanged.SetListener(val => { long goldOffer = Utility.Utility.Clamp(val.ToLong(), 0, player.Money); myGoldInput.text = goldOffer.ToString(); player.CmdTradeOfferGold(goldOffer); }); } else { myGoldInput.interactable = false; myGoldInput.text = player.tradeOfferGold.ToString(); } // items UIUtils.BalancePrefabs(slotPrefab.gameObject, player.tradeOfferItems.Count, myContent); for (int i = 0; i < player.tradeOfferItems.Count; ++i) { UIPlayerTradingSlot slot = myContent.GetChild(i).GetComponent <UIPlayerTradingSlot>(); slot.dragAndDropable.name = i.ToString(); // drag and drop index int inventoryIndex = player.tradeOfferItems[i]; if (0 <= inventoryIndex && inventoryIndex < player.inventory.Count && player.inventory[inventoryIndex].amount > 0) { ItemSlot itemSlot = player.inventory[inventoryIndex]; // refresh valid item slot.tooltip.enabled = true; slot.tooltip.text = itemSlot.ToolTip(); slot.dragAndDropable.dragable = player.tradeStatus == TradeStatus.Free; slot.image.color = Color.white; slot.image.sprite = itemSlot.item.Image; slot.amountOverlay.SetActive(itemSlot.amount > 1); slot.amountText.text = itemSlot.amount.ToString(); } else { // refresh invalid item slot.tooltip.enabled = false; slot.dragAndDropable.dragable = false; slot.image.color = Color.clear; slot.image.sprite = null; slot.amountOverlay.SetActive(false); } } // buttons ///////////////////////////////////////////////////////// // lock lockButton.interactable = player.tradeStatus == TradeStatus.Free; lockButton.onClick.SetListener(() => { player.CmdTradeOfferLock(); }); // accept (only if both have locked the trade & if not accepted yet) // accept (if not accepted yet & other has locked or accepted) acceptButton.interactable = player.tradeStatus == TradeStatus.Locked && other.tradeStatus != TradeStatus.Free; acceptButton.onClick.SetListener(() => { player.CmdTradeOfferAccept(); }); // cancel cancelButton.onClick.SetListener(() => { player.CmdTradeCancel(); }); } else { panel.SetActive(false); } }
void Update() { Player player = Player.localPlayer; // use collider point(s) to also work with big entities if (player != null && panel.activeSelf && player.Target != null && player.Target.Health == 0 && Utility.Utility.ClosestDistance(player.collider, player.Target.collider) <= player.interactionRange && player.Target is Monster && ((Monster)player.Target).HasLoot()) { // gold slot if (player.Target.Money > 0) { goldSlot.SetActive(true); goldSlot.GetComponentInChildren <Button>().onClick.SetListener(() => { player.CmdTakeLootGold(); }); goldText.text = player.Target.Money.ToString(); } else { goldSlot.SetActive(false); } // instantiate/destroy enough slots // (we only want to show the non-empty slots) List <ItemSlot> items = player.Target.inventory.Where(slot => slot.amount > 0).ToList(); UIUtils.BalancePrefabs(itemSlotPrefab.gameObject, items.Count, content); // refresh all valid items for (int i = 0; i < items.Count; ++i) { UILootSlot slot = content.GetChild(i).GetComponent <UILootSlot>(); slot.dragAndDropable.name = i.ToString(); // drag and drop index int itemIndex = player.Target.inventory.FindIndex( // note: .Equals because name AND dynamic variables matter (petLevel etc.) itemSlot => itemSlot.amount > 0 && itemSlot.item.Equals(items[i].item) ); // refresh slot.button.interactable = player.InventoryCanAdd(items[i].item, items[i].amount); slot.button.onClick.SetListener(() => { player.CmdTakeLootItem(itemIndex); }); slot.tooltip.text = items[i].ToolTip(); slot.image.color = Color.white; slot.image.sprite = items[i].item.Image; slot.nameText.text = items[i].item.Name; slot.amountOverlay.SetActive(items[i].amount > 1); slot.amountText.text = items[i].amount.ToString(); } } else { panel.SetActive(false); // hide } }
void Update() { Player player = Player.localPlayer; if (player != null) { // show nextTarget > target // => feels best in situations where we select another target while // casting a skill on the existing target. // => '.target' doesn't change while casting, but the UI gives the // illusion that we already targeted something else // => this is also great for skills that change the target while casting, // e.g. a buff that is cast on 'self' even though we target an 'npc. // this way the player doesn't see the target switching. // => this is how most MMORPGs do it too. Entity target = player.NextTarget ?? player.Target; if (target != null && target != player) { float distance = Utility.Utility.ClosestDistance(player.collider, target.collider); // name and health panel.SetActive(true); healthSlider.value = target.HealthPercent(); nameText.text = target.name; // target buffs UIUtils.BalancePrefabs(buffSlotPrefab.gameObject, target.buffs.Count, buffsPanel); for (int i = 0; i < target.buffs.Count; ++i) { UIBuffSlot slot = buffsPanel.GetChild(i).GetComponent <UIBuffSlot>(); // refresh slot.image.color = Color.white; slot.image.sprite = target.buffs[i].image; slot.tooltip.text = target.buffs[i].ToolTip(); slot.slider.maxValue = target.buffs[i].buffTime; slot.slider.value = target.buffs[i].BuffTimeRemaining(); } // trade button if (target is Player) { tradeButton.gameObject.SetActive(true); tradeButton.interactable = player.CanStartTradeWith(target); tradeButton.onClick.SetListener(() => { player.CmdTradeRequestSend(); }); } else { tradeButton.gameObject.SetActive(false); } // guild invite button if (target is Player && player.InGuild()) { guildInviteButton.gameObject.SetActive(true); guildInviteButton.interactable = !((Player)target).InGuild() && player.guild.CanInvite(player.name, target.name) && NetworkTime.time >= player.nextRiskyActionTime && distance <= player.interactionRange; guildInviteButton.onClick.SetListener(() => { player.CmdGuildInviteTarget(); }); } else { guildInviteButton.gameObject.SetActive(false); } // party invite button if (target is Player) { partyInviteButton.gameObject.SetActive(true); partyInviteButton.interactable = (!player.InParty() || !player.party.IsFull()) && !((Player)target).InParty() && NetworkTime.time >= player.nextRiskyActionTime && distance <= player.interactionRange; partyInviteButton.onClick.SetListener(() => { player.CmdPartyInvite(target.name); }); } else { partyInviteButton.gameObject.SetActive(false); } } else { panel.SetActive(false); } } else { panel.SetActive(false); } }
void Update() { Player player = Player.localPlayer; // only show and update while there are party members if (player != null && player.InParty()) { panel.SetActive(true); Party party = player.party; // get party members without self. no need to show self in HUD too. List <string> members = player.InParty() ? party.members.Where(m => m != player.name).ToList() : new List <string>(); // instantiate/destroy enough slots UIUtils.BalancePrefabs(slotPrefab.gameObject, members.Count, memberContent); // refresh all members for (int i = 0; i < members.Count; ++i) { UIPartyHUDMemberSlot slot = memberContent.GetChild(i).GetComponent <UIPartyHUDMemberSlot>(); string memberName = members[i]; float distance = Mathf.Infinity; float visRange = player.VisRange(); slot.nameText.text = memberName; slot.masterIndicatorText.gameObject.SetActive(party.master == memberName); // pull health, mana, etc. from observers so that party struct // doesn't have to send all that data around. people will only // see health of party members that are near them, which is the // only time that it's important anyway. if (Player.onlinePlayers.ContainsKey(memberName)) { Player member = Player.onlinePlayers[memberName]; slot.icon.sprite = member.classIcon; slot.healthSlider.value = member.HealthPercent(); slot.manaSlider.value = member.MindPercent(); slot.backgroundButton.onClick.SetListener(() => { // member variable might be null by the time button gets // clicked. can't target null, otherwise we get a // MissingReferenceException. if (member != null) { player.CmdSetTarget(member.netIdentity); } }); // distance color based on visRange ratio distance = Vector2.Distance(player.transform.position, member.transform.position); visRange = member.VisRange(); // visRange is always based on the other guy } // distance overlay alpha based on visRange ratio // (because values are only up to date for members in observer // range) float ratio = visRange > 0 ? distance / visRange : 1f; float alpha = alphaCurve.Evaluate(ratio); // icon alpha Color iconColor = slot.icon.color; iconColor.a = alpha; slot.icon.color = iconColor; // health bar alpha foreach (Image image in slot.healthSlider.GetComponentsInChildren <Image>()) { Color color = image.color; color.a = alpha; image.color = color; } // mana bar alpha foreach (Image image in slot.manaSlider.GetComponentsInChildren <Image>()) { Color color = image.color; color.a = alpha; image.color = color; } } } else { panel.SetActive(false); } }
void Update() { Player player = Player.localPlayer; if (player) { // hotkey (not while typing in chat, etc.) if (Input.GetKeyDown(hotKey) && !UIUtils.AnyInputActive()) { panel.SetActive(!panel.activeSelf); } // only update the panel if it's active if (panel.activeSelf) { // instantiate/destroy enough slots // (we only care about non status skills) UIUtils.BalancePrefabs(slotPrefab.gameObject, player.skills.Count, content); // refresh all for (int i = 0; i < player.skills.Count; ++i) { UISkillSlot slot = content.GetChild(i).GetComponent <UISkillSlot>(); Skill skill = player.skills[i]; bool isPassive = skill.data is PassiveSkill; // set state slot.dragAndDropable.name = i.ToString(); slot.dragAndDropable.dragable = skill.level > 0 && !isPassive; // click event slot.button.interactable = skill.level > 0 && !isPassive && player.CastCheckSelf(skill); // checks mana, cooldown etc. int icopy = i; slot.button.onClick.SetListener(() => { // try use the skill or walk closer if needed player.TryUseSkill(icopy); }); // image if (skill.level > 0) { slot.image.color = Color.white; slot.image.sprite = skill.image; } // description slot.descriptionText.text = skill.ToolTip(showRequirements: skill.level == 0); // learn / upgrade if (skill.level < skill.maxLevel) { slot.upgradeButton.gameObject.SetActive(true); slot.upgradeButton.GetComponentInChildren <Text>().text = skill.level == 0 ? "Learn" : "Upgrade"; slot.upgradeButton.interactable = player.CanUpgradeSkill(skill); slot.upgradeButton.onClick.SetListener(() => { player.CmdUpgradeSkill(icopy); }); } // otherwise no button needed else { slot.upgradeButton.gameObject.SetActive(false); } // cooldown overlay float cooldown = skill.CooldownRemaining(); slot.cooldownOverlay.SetActive(skill.level > 0 && cooldown > 0); slot.cooldownText.text = cooldown.ToString("F0"); slot.cooldownCircle.fillAmount = skill.cooldown > 0 ? cooldown / skill.cooldown : 0; } // skill experience skillExperienceText.text = player.skillExperience.ToString(); } } else { panel.SetActive(false); } }
void Update() { Player player = Player.localPlayer; if (player) { // hotkey (not while typing in chat, etc.) if (Input.GetKeyDown(hotKey) && !UIUtils.AnyInputActive()) { panel.SetActive(!panel.activeSelf); } // only update the panel if it's active if (panel.activeSelf) { // instantiate/destroy enough category slots UIUtils.BalancePrefabs(categorySlotPrefab.gameObject, player.itemMallCategories.Length, categoryContent); // refresh all category buttons for (int i = 0; i < player.itemMallCategories.Length; ++i) { Button button = categoryContent.GetChild(i).GetComponent <Button>(); button.interactable = i != currentCategory; button.GetComponentInChildren <Text>().text = player.itemMallCategories[i].category; int icopy = i; // needed for lambdas, otherwise i is Count button.onClick.SetListener(() => { // set new category and then scroll to the top again currentCategory = icopy; ScrollToBeginning(); }); } if (player.itemMallCategories.Length > 0) { // instantiate/destroy enough item slots for that category ScriptableItem[] items = player.itemMallCategories[currentCategory].items; UIUtils.BalancePrefabs(itemSlotPrefab.gameObject, items.Length, itemContent); // refresh all items in that category for (int i = 0; i < items.Length; ++i) { UIItemMallSlot slot = itemContent.GetChild(i).GetComponent <UIItemMallSlot>(); ScriptableItem item = items[i]; // refresh item slot.tooltip.text = new Item(item).ToolTip(); slot.image.color = Color.white; slot.image.sprite = item.image; slot.nameText.text = item.name; slot.priceText.text = item.itemMallPrice.ToString(); slot.unlockButton.interactable = player.Health > 0 && player.coins >= item.itemMallPrice; int icopy = i; // needed for lambdas, otherwise i is Count slot.unlockButton.onClick.SetListener(() => { player.CmdUnlockItem(currentCategory, icopy); inventoryPanel.SetActive(true); // better feedback }); } } // overview nameText.text = player.name; levelText.text = "Lv. " + player.level; currencyAmountText.text = player.coins.ToString(); buyButton.onClick.SetListener(() => { Application.OpenURL(buyUrl); }); couponInput.interactable = NetworkTime.time >= player.nextRiskyActionTime; couponButton.interactable = NetworkTime.time >= player.nextRiskyActionTime; couponButton.onClick.SetListener(() => { if (!string.IsNullOrWhiteSpace(couponInput.text)) { player.CmdEnterCoupon(couponInput.text); } couponInput.text = ""; }); } } else { panel.SetActive(false); } }
void Update() { Player player = Player.localPlayer; // use collider point(s) to also work with big entities if (player != null && player.Target != null && player.Target is Npc && Utility.Utility.ClosestDistance(player.collider, player.Target.collider) <= player.interactionRange) { Npc npc = (Npc)player.Target; // instantiate/destroy enough slots List <ScriptableQuest> questsAvailable = npc.QuestsVisibleFor(player); UIUtils.BalancePrefabs(slotPrefab.gameObject, questsAvailable.Count, content); // refresh all for (int i = 0; i < questsAvailable.Count; ++i) { UINpcQuestSlot slot = content.GetChild(i).GetComponent <UINpcQuestSlot>(); // find quest index in original npc quest list (unfiltered) int npcIndex = Array.FindIndex(npc.quests, entry => entry.quest.name == questsAvailable[i].name); // find quest index in player quest list int questIndex = player.GetQuestIndexByName(npc.quests[npcIndex].quest.name); if (questIndex != -1) { // running quest: shows description with current progress // instead of static one Quest quest = player.quests[questIndex]; ScriptableItem reward = npc.quests[npcIndex].quest.rewardItem; bool hasSpace = reward == null || player.InventoryCanAdd(new Item(reward), 1); // description + not enough space warning (if needed) slot.descriptionText.text = quest.ToolTip(player); if (!hasSpace) { slot.descriptionText.text += "\n<color=red>Not enough inventory space!</color>"; } slot.actionButton.interactable = player.CanCompleteQuest(quest.name); slot.actionButton.GetComponentInChildren <Text>().text = "Complete"; slot.actionButton.onClick.SetListener(() => { player.CmdCompleteQuest(npcIndex); panel.SetActive(false); }); } else { // new quest slot.descriptionText.text = new Quest(npc.quests[npcIndex].quest).ToolTip(player); slot.actionButton.interactable = true; slot.actionButton.GetComponentInChildren <Text>().text = "Accept"; slot.actionButton.onClick.SetListener(() => { player.CmdAcceptQuest(npcIndex); }); } } } else { panel.SetActive(false); } }
void Update() { Player player = Player.localPlayer; if (player) { // hotkey (not while typing in chat, etc.) if (Input.GetKeyDown(hotKey) && !UIUtils.AnyInputActive()) { panel.SetActive(!panel.activeSelf); } // only update the panel if it's active if (panel.activeSelf) { // instantiate/destroy enough slots UIUtils.BalancePrefabs(ingredientSlotPrefab.gameObject, player.craftingIndices.Count, ingredientContent); // refresh all for (int i = 0; i < player.craftingIndices.Count; ++i) { UICraftingIngredientSlot slot = ingredientContent.GetChild(i).GetComponent <UICraftingIngredientSlot>(); slot.dragAndDropable.name = i.ToString(); // drag and drop index int itemIndex = player.craftingIndices[i]; if (0 <= itemIndex && itemIndex < player.inventory.Count && player.inventory[itemIndex].amount > 0) { ItemSlot itemSlot = player.inventory[itemIndex]; // refresh valid item slot.tooltip.enabled = true; slot.tooltip.text = itemSlot.ToolTip(); slot.dragAndDropable.dragable = true; slot.image.color = Color.white; slot.image.sprite = itemSlot.item.Image; slot.amountOverlay.SetActive(itemSlot.amount > 1); slot.amountText.text = itemSlot.amount.ToString(); } else { // reset the index because it's invalid player.craftingIndices[i] = -1; // refresh invalid item slot.tooltip.enabled = false; slot.dragAndDropable.dragable = false; slot.image.color = Color.clear; slot.image.sprite = null; slot.amountOverlay.SetActive(false); } } // find valid indices => item templates => matching recipe List <int> validIndices = player.craftingIndices.Where( index => 0 <= index && index < player.inventory.Count && player.inventory[index].amount > 0 ).ToList(); List <ItemSlot> items = validIndices.Select(index => player.inventory[index]).ToList(); ScriptableRecipe recipe = ScriptableRecipe.Dictionary.Values.ToList().Find(r => r.CanCraftWith(items)); // good enough for now if (recipe != null) { // refresh valid recipe Item item = new Item(recipe.result); resultSlotToolTip.enabled = true; resultSlotToolTip.text = new ItemSlot(item).ToolTip(); // ItemSlot so that {AMOUNT} is replaced too resultSlotImage.color = Color.white; resultSlotImage.sprite = recipe.result.image; // show progress bar while crafting // (show 100% if craft time = 0 because it's just better feedback) progressSlider.gameObject.SetActive(player.State == "CRAFTING"); double startTime = player.craftingTimeEnd - recipe.craftingTime; double elapsedTime = NetworkTime.time - startTime; progressSlider.value = recipe.craftingTime > 0 ? (float)elapsedTime / recipe.craftingTime : 1; } else { // refresh invalid recipe resultSlotToolTip.enabled = false; resultSlotImage.color = Color.clear; resultSlotImage.sprite = null; progressSlider.gameObject.SetActive(false); } // craft result // (no recipe != null check because it will be null if those were // the last two ingredients in our inventory) if (player.craftingState == CraftingState.Success) { resultText.color = successColor; resultText.text = "Success!"; } else if (player.craftingState == CraftingState.Failed) { resultText.color = failedColor; resultText.text = "Failed :("; } else { resultText.text = ""; } // craft button with 'Try' prefix to let people know that it might fail // (disabled while in progress) craftButton.GetComponentInChildren <Text>().text = recipe != null && recipe.probability < 1 ? "Try Craft" : "Craft"; craftButton.interactable = recipe != null && player.State != "CRAFTING" && player.craftingState != CraftingState.InProgress && player.InventoryCanAdd(new Item(recipe.result), 1); craftButton.onClick.SetListener(() => { player.craftingState = CraftingState.InProgress; // wait for result // pass original array so server can copy it to it's own // craftingIndices. we pass original one and not only the valid // indicies because then in host mode we would make the crafting // indices array smaller by only copying the valid indices, // hence losing crafting slots player.CmdCraft(player.craftingIndices.ToArray()); }); } } else { panel.SetActive(false); } }
void Update() { Player player = Player.localPlayer; if (player) { panel.SetActive(true); // instantiate/destroy enough slots UIUtils.BalancePrefabs(slotPrefab.gameObject, player.skillbar.Length, content); // refresh all for (int i = 0; i < player.skillbar.Length; ++i) { UISkillbarSlot slot = content.GetChild(i).GetComponent <UISkillbarSlot>(); slot.dragAndDropable.name = i.ToString(); // drag and drop index // hotkey overlay (without 'Alpha' etc.) string pretty = player.skillbar[i].hotKey.ToString().Replace("Alpha", ""); slot.hotkeyText.text = pretty; // skill, inventory item or equipment item? int skillIndex = player.GetSkillIndexByName(player.skillbar[i].reference); int inventoryIndex = player.GetInventoryIndexByName(player.skillbar[i].reference); int equipmentIndex = player.GetEquipmentIndexByName(player.skillbar[i].reference); if (skillIndex != -1) { Skill skill = player.skills[skillIndex]; bool canCast = player.CastCheckSelf(skill); // hotkey pressed and not typing in any input right now? if (Input.GetKeyDown(player.skillbar[i].hotKey) && !UIUtils.AnyInputActive() && canCast) // checks mana, cooldowns, etc.) { // try use the skill or walk closer if needed player.TryUseSkill(skillIndex); } // refresh skill slot slot.button.interactable = canCast; // check mana, cooldowns, etc. slot.button.onClick.SetListener(() => { // try use the skill or walk closer if needed player.TryUseSkill(skillIndex); }); slot.tooltip.enabled = true; slot.tooltip.text = skill.ToolTip(); slot.dragAndDropable.dragable = true; slot.image.color = Color.white; slot.image.sprite = skill.image; float cooldown = skill.CooldownRemaining(); slot.cooldownOverlay.SetActive(cooldown > 0); slot.cooldownText.text = cooldown.ToString("F0"); slot.cooldownCircle.fillAmount = skill.cooldown > 0 ? cooldown / skill.cooldown : 0; slot.amountOverlay.SetActive(false); } else if (inventoryIndex != -1) { ItemSlot itemSlot = player.inventory[inventoryIndex]; // hotkey pressed and not typing in any input right now? if (Input.GetKeyDown(player.skillbar[i].hotKey) && !UIUtils.AnyInputActive()) { player.CmdUseInventoryItem(inventoryIndex); } // refresh inventory slot slot.button.onClick.SetListener(() => { player.CmdUseInventoryItem(inventoryIndex); }); slot.tooltip.enabled = true; slot.tooltip.text = itemSlot.ToolTip(); slot.dragAndDropable.dragable = true; slot.image.color = Color.white; slot.image.sprite = itemSlot.item.Image; slot.cooldownOverlay.SetActive(false); slot.cooldownCircle.fillAmount = 0; slot.amountOverlay.SetActive(itemSlot.amount > 1); slot.amountText.text = itemSlot.amount.ToString(); } else if (equipmentIndex != -1) { ItemSlot itemSlot = player.equipment[equipmentIndex]; // refresh equipment slot slot.button.onClick.RemoveAllListeners(); slot.tooltip.enabled = true; slot.tooltip.text = itemSlot.ToolTip(); slot.dragAndDropable.dragable = true; slot.image.color = Color.white; slot.image.sprite = itemSlot.item.Image; slot.cooldownOverlay.SetActive(false); slot.cooldownCircle.fillAmount = 0; slot.amountOverlay.SetActive(itemSlot.amount > 1); slot.amountText.text = itemSlot.amount.ToString(); } else { // clear the outdated reference player.skillbar[i].reference = ""; // refresh empty slot slot.button.onClick.RemoveAllListeners(); slot.tooltip.enabled = false; slot.dragAndDropable.dragable = false; slot.image.color = Color.clear; slot.image.sprite = null; slot.cooldownOverlay.SetActive(false); slot.cooldownCircle.fillAmount = 0; slot.amountOverlay.SetActive(false); } } } else { panel.SetActive(false); } }
void Update() { Player player = Player.localPlayer; if (player) { // hotkey (not while typing in chat, etc.) if (Input.GetKeyDown(hotKey) && !UIUtils.AnyInputActive()) { panel.SetActive(!panel.activeSelf); } // only update the panel if it's active if (panel.activeSelf) { // instantiate/destroy enough slots UIUtils.BalancePrefabs(slotPrefab.gameObject, player.inventory.Count, content); // refresh all items for (int i = 0; i < player.inventory.Count; ++i) { UIInventorySlot slot = content.GetChild(i).GetComponent <UIInventorySlot>(); slot.dragAndDropable.name = i.ToString(); // drag and drop index ItemSlot itemSlot = player.inventory[i]; if (itemSlot.amount > 0) { // refresh valid item int icopy = i; // needed for lambdas, otherwise i is Count slot.button.onClick.SetListener(() => { if (itemSlot.item.Data is UsableItem && ((UsableItem)itemSlot.item.Data).CanUse(player, icopy)) { player.CmdUseInventoryItem(icopy); } }); slot.tooltip.enabled = true; slot.tooltip.text = itemSlot.ToolTip(); slot.dragAndDropable.dragable = true; slot.image.color = Color.white; slot.image.sprite = itemSlot.item.Image; slot.amountOverlay.SetActive(itemSlot.amount > 1); slot.amountText.text = itemSlot.amount.ToString(); } else { // refresh invalid item slot.button.onClick.RemoveAllListeners(); slot.tooltip.enabled = false; slot.dragAndDropable.dragable = false; slot.image.color = Color.clear; slot.image.sprite = null; slot.amountOverlay.SetActive(false); } } // gold goldText.text = player.Money.ToString(); // trash (tooltip always enabled, dropable always true) trash.dragable = player.trash.amount > 0; if (player.trash.amount > 0) { // refresh valid item trashImage.color = Color.white; trashImage.sprite = player.trash.item.Image; trashOverlay.SetActive(player.trash.amount > 1); trashAmountText.text = player.trash.amount.ToString(); } else { // refresh invalid item trashImage.color = Color.clear; trashImage.sprite = null; trashOverlay.SetActive(false); } } } else { panel.SetActive(false); } }
void Update() { Player player = Player.localPlayer; if (player) { // hotkey (not while typing in chat, etc.) if (Input.GetKeyDown(hotKey) && !UIUtils.AnyInputActive()) { panel.SetActive(!panel.activeSelf); } // only update the panel if it's active if (panel.activeSelf) { Guild guild = player.guild; int memberCount = guild.members != null ? guild.members.Length : 0; // guild properties nameText.text = player.guild.name; masterText.text = guild.master; currentCapacityText.text = memberCount.ToString(); maximumCapacityText.text = GuildSystem.Capacity.ToString(); // notice edit button noticeEditButton.interactable = guild.CanNotify(player.name) && !noticeInput.interactable; noticeEditButton.onClick.SetListener(() => { noticeInput.interactable = true; }); // notice set button noticeSetButton.interactable = guild.CanNotify(player.name) && noticeInput.interactable && NetworkTime.time >= player.nextRiskyActionTime; noticeSetButton.onClick.SetListener(() => { noticeInput.interactable = false; if (noticeInput.text.Length > 0 && !string.IsNullOrWhiteSpace(noticeInput.text) && noticeInput.text != guild.notice) { player.CmdSetGuildNotice(noticeInput.text); } }); // notice input: copies notice while not editing it if (!noticeInput.interactable) { noticeInput.text = guild.notice ?? ""; } noticeInput.characterLimit = GuildSystem.NoticeMaxLength; // leave leaveButton.interactable = guild.CanLeave(player.name); leaveButton.onClick.SetListener(() => { player.CmdLeaveGuild(); }); // instantiate/destroy enough slots UIUtils.BalancePrefabs(slotPrefab.gameObject, memberCount, memberContent); // refresh all members for (int i = 0; i < memberCount; ++i) { UIGuildMemberSlot slot = memberContent.GetChild(i).GetComponent <UIGuildMemberSlot>(); GuildMember member = guild.members[i]; slot.onlineStatusImage.color = member.online ? onlineColor : offlineColor; slot.nameText.text = member.name; slot.levelText.text = member.level.ToString(); slot.rankText.text = member.rank.ToString(); slot.promoteButton.interactable = guild.CanPromote(player.name, member.name); slot.promoteButton.onClick.SetListener(() => { player.CmdGuildPromote(member.name); }); slot.demoteButton.interactable = guild.CanDemote(player.name, member.name); slot.demoteButton.onClick.SetListener(() => { player.CmdGuildDemote(member.name); }); slot.kickButton.interactable = guild.CanKick(player.name, member.name); slot.kickButton.onClick.SetListener(() => { player.CmdGuildKick(member.name); }); } } } else { panel.SetActive(false); } }
void Update() { Player player = Player.localPlayer; if (player) { // hotkey (not while typing in chat, etc.) if (Input.GetKeyDown(hotKey) && !UIUtils.AnyInputActive()) { panel.SetActive(!panel.activeSelf); } // only update the panel if it's active if (panel.activeSelf) { Party party = player.party; int memberCount = party.members != null ? party.members.Length : 0; // properties currentCapacityText.text = memberCount.ToString(); maximumCapacityText.text = Party.Capacity.ToString(); // instantiate/destroy enough slots UIUtils.BalancePrefabs(slotPrefab.gameObject, memberCount, memberContent); // refresh all members for (int i = 0; i < memberCount; ++i) { UIPartyMemberSlot slot = memberContent.GetChild(i).GetComponent <UIPartyMemberSlot>(); string memberName = party.members[i]; slot.nameText.text = memberName; slot.masterIndicatorText.gameObject.SetActive(i == 0); // party struct doesn't sync health, mana, level, etc. We find // those from observers instead. Saves bandwidth and is good // enough since another member's health is only really important // to use when we are fighting the same monsters. // => null if member not in observer range, in which case health // bars etc. should be grayed out! // update some data only if around. otherwise keep previous data. // update icon only if around. otherwise keep previous one. if (Player.onlinePlayers.ContainsKey(memberName)) { Player member = Player.onlinePlayers[memberName]; slot.icon.sprite = member.classIcon; slot.levelText.text = member.level.ToString(); slot.guildText.text = member.guild.name; slot.healthSlider.value = member.HealthPercent(); slot.manaSlider.value = member.MindPercent(); } // action button: // dismiss: if i=0 and member=self and master // kick: if i > 0 and player=master // leave: if member=self and not master if (memberName == player.name && i == 0) { slot.actionButton.gameObject.SetActive(true); slot.actionButton.GetComponentInChildren <Text>().text = "Dismiss"; slot.actionButton.onClick.SetListener(() => { player.CmdPartyDismiss(); }); } else if (memberName == player.name && i > 0) { slot.actionButton.gameObject.SetActive(true); slot.actionButton.GetComponentInChildren <Text>().text = "Leave"; slot.actionButton.onClick.SetListener(() => { player.CmdPartyLeave(); }); } else if (party.members[0] == player.name && i > 0) { slot.actionButton.gameObject.SetActive(true); slot.actionButton.GetComponentInChildren <Text>().text = "Kick"; slot.actionButton.onClick.SetListener(() => { player.CmdPartyKick(memberName); }); } else { slot.actionButton.gameObject.SetActive(false); } } // exp share toggle experienceShareToggle.interactable = player.InParty() && party.members[0] == player.name; experienceShareToggle.onValueChanged.SetListener((val) => { }); // avoid callback while setting .isOn via code experienceShareToggle.isOn = party.shareExperience; experienceShareToggle.onValueChanged.SetListener((val) => { player.CmdPartySetExperienceShare(val); }); // gold share toggle goldShareToggle.interactable = player.InParty() && party.members[0] == player.name; goldShareToggle.onValueChanged.SetListener((val) => { }); // avoid callback while setting .isOn via code goldShareToggle.isOn = party.shareGold; goldShareToggle.onValueChanged.SetListener((val) => { player.CmdPartySetGoldShare(val); }); } } else { panel.SetActive(false); } }
void Update() { Player player = Player.localPlayer; // use collider point(s) to also work with big entities if (player != null && player.Target != null && player.Target is Npc && Utility.Utility.ClosestDistance(player.collider, player.Target.collider) <= player.interactionRange) { Npc npc = (Npc)player.Target; // items for sale UIUtils.BalancePrefabs(slotPrefab.gameObject, npc.saleItems.Length, content); for (int i = 0; i < npc.saleItems.Length; ++i) { UINpcTradingSlot slot = content.GetChild(i).GetComponent <UINpcTradingSlot>(); ScriptableItem itemData = npc.saleItems[i]; // show item in UI int icopy = i; slot.button.onClick.SetListener(() => { buyIndex = icopy; }); slot.image.color = Color.white; slot.image.sprite = itemData.image; slot.tooltip.enabled = true; slot.tooltip.text = new ItemSlot(new Item(itemData)).ToolTip(); // with slot for {AMOUNT} } // buy if (buyIndex != -1 && buyIndex < npc.saleItems.Length) { ScriptableItem itemData = npc.saleItems[buyIndex]; // make valid amount, calculate price int amount = buyAmountInput.text.ToInt(); amount = Mathf.Clamp(amount, 1, itemData.maxStack); long price = amount * itemData.buyPrice; // show buy panel with item in UI buyAmountInput.text = amount.ToString(); buySlot.GetComponent <Image>().color = Color.white; buySlot.GetComponent <Image>().sprite = itemData.image; buySlot.GetComponent <UIShowToolTip>().enabled = true; buySlot.GetComponent <UIShowToolTip>().text = new ItemSlot(new Item(itemData)).ToolTip(); // with slot for {AMOUNT} buySlot.dragable = true; buyCostsText.text = price.ToString(); buyButton.interactable = amount > 0 && price <= player.Money && player.InventoryCanAdd(new Item(itemData), amount); buyButton.onClick.SetListener(() => { player.CmdNpcBuyItem(buyIndex, amount); buyIndex = -1; buyAmountInput.text = "1"; }); } else { // show default buy panel in UI buySlot.GetComponent <Image>().color = Color.clear; buySlot.GetComponent <Image>().sprite = null; buySlot.GetComponent <UIShowToolTip>().enabled = false; buySlot.dragable = false; buyCostsText.text = "0"; buyButton.interactable = false; } // sell if (sellIndex != -1 && sellIndex < player.inventory.Count && player.inventory[sellIndex].amount > 0) { ItemSlot itemSlot = player.inventory[sellIndex]; // make valid amount, calculate price int amount = sellAmountInput.text.ToInt(); amount = Mathf.Clamp(amount, 1, itemSlot.amount); long price = amount * itemSlot.item.SellPrice; // show sell panel with item in UI sellAmountInput.text = amount.ToString(); sellSlot.GetComponent <Image>().color = Color.white; sellSlot.GetComponent <Image>().sprite = itemSlot.item.Image; sellSlot.GetComponent <UIShowToolTip>().enabled = true; sellSlot.GetComponent <UIShowToolTip>().text = itemSlot.ToolTip(); sellSlot.dragable = true; sellCostsText.text = price.ToString(); sellButton.interactable = amount > 0; sellButton.onClick.SetListener(() => { player.CmdNpcSellItem(sellIndex, amount); sellIndex = -1; sellAmountInput.text = "1"; }); } else { // show default sell panel in UI sellSlot.GetComponent <Image>().color = Color.clear; sellSlot.GetComponent <Image>().sprite = null; sellSlot.GetComponent <UIShowToolTip>().enabled = false; sellSlot.dragable = false; sellCostsText.text = "0"; sellButton.interactable = false; } } else { panel.SetActive(false); // hide } }