private void GatherDresses(EnumCharacterDressType type) { List <ItemStack> dresses = new List <ItemStack>(); dresses.Add(null); string stringtype = type.ToString().ToLowerInvariant(); IList <Item> items = capi.World.Items; for (int i = 0; i < items.Count; i++) { Item item = items[i]; if (item == null || item.Code == null || item.Attributes == null) { continue; } string clothcat = item.Attributes["clothescategory"]?.AsString(); bool allow = item.Attributes["inCharacterCreationDialog"]?.AsBool() == true; if (allow && clothcat?.ToLowerInvariant() == stringtype) { dresses.Add(new ItemStack(item)); } } DressesByDressType[type] = dresses.ToArray(); DressPositionByTressType[type] = 0; }
private ItemSlot onNewSlot(int slotId, InventoryGeneric self) { EnumCharacterDressType type = (EnumCharacterDressType)slotId; ItemSlotCharacter slot = new ItemSlotCharacter(type, self); iconByDressType.TryGetValue(type, out slot.BackgroundIcon); return(slot); }
/// <summary> /// Checks to see what dress type the given item is. /// </summary> /// <param name="itemstack"></param> /// <param name="dressType"></param> /// <returns></returns> public static bool IsDressType(IItemStack itemstack, EnumCharacterDressType dressType) { if (itemstack == null || itemstack.Collectible.Attributes == null) { return(false); } string stackDressType = itemstack.Collectible.Attributes["clothescategory"].AsString(); return(stackDressType != null && dressType.ToString().Equals(stackDressType, StringComparison.InvariantCultureIgnoreCase)); }
protected override ItemSlot NewSlot(int slotId) { if (slotId == 15) { return(new ItemSlotSurvival(this)); } EnumCharacterDressType type = (EnumCharacterDressType)slotId; ItemSlotCharacter slot = new ItemSlotCharacter(type, this); iconByDressType.TryGetValue(type, out slot.BackgroundIcon); return(slot); }
public override void OnLoaded(ICoreAPI api) { base.OnLoaded(api); string strdress = Attributes["clothescategory"].AsString(); EnumCharacterDressType dt = EnumCharacterDressType.Unknown; Enum.TryParse(strdress, true, out dt); DressType = dt; JsonObject jsonObj = Attributes?["footStepSound"]; if (jsonObj?.Exists == true) { string soundloc = jsonObj.AsString(null); if (soundloc != null) { AssetLocation loc = AssetLocation.Create(soundloc, Code.Domain).WithPathPrefixOnce("sounds/"); if (soundloc.EndsWith("*")) { loc.Path = loc.Path.TrimEnd('*'); FootStepSounds = api.Assets.GetLocations(loc.Path, loc.Domain).ToArray(); } else { FootStepSounds = new AssetLocation[] { loc }; } } } jsonObj = Attributes?["statModifiers"]; if (jsonObj?.Exists == true) { try { StatModifers = jsonObj.AsObject <StatModifiers>(); } catch (Exception e) { api.World.Logger.Error("Failed loading statModifiers for item/block {0}. Will ignore. Exception: {1}", Code, e); StatModifers = null; } } ProtectionModifiers defMods = null; jsonObj = Attributes?["defaultProtLoss"]; if (jsonObj?.Exists == true) { try { defMods = jsonObj.AsObject <ProtectionModifiers>(); } catch (Exception e) { api.World.Logger.Error("Failed loading defaultProtLoss for item/block {0}. Will ignore. Exception: {1}", Code, e); } } jsonObj = Attributes?["protectionModifiers"]; if (jsonObj?.Exists == true) { try { ProtectionModifiers = jsonObj.AsObject <ProtectionModifiers>(); } catch (Exception e) { api.World.Logger.Error("Failed loading protectionModifiers for item/block {0}. Will ignore. Exception: {1}", Code, e); ProtectionModifiers = null; } } if (ProtectionModifiers != null && ProtectionModifiers.PerTierFlatDamageReductionLoss == null) { ProtectionModifiers.PerTierFlatDamageReductionLoss = defMods?.PerTierFlatDamageReductionLoss; } if (ProtectionModifiers != null && ProtectionModifiers.PerTierRelativeProtectionLoss == null) { ProtectionModifiers.PerTierRelativeProtectionLoss = defMods?.PerTierRelativeProtectionLoss; } }
private float handleDamaged(IPlayer player, float damage, DamageSource dmgSource) { EnumDamageType type = dmgSource.Type; double angleProtectionRange = 120 / 2 * GameMath.DEG2RAD; // Reduce damage if player holds a shield ItemSlot[] shieldSlots = new ItemSlot[] { player.Entity.LeftHandItemSlot, player.Entity.RightHandItemSlot }; foreach (var shieldSlot in shieldSlots) { var attr = shieldSlot.Itemstack?.ItemAttributes?["shield"]; if (attr == null || !attr.Exists) { continue; } string usetype = player.Entity.Controls.Sneak ? "active" : "passive"; float dmgabsorb = attr["damageAbsorption"][usetype].AsFloat(0); float chance = attr["protectionChance"][usetype].AsFloat(0); (player as IServerPlayer)?.SendMessage(GlobalConstants.DamageLogChatGroup, Lang.Get("{0:0.#} of {1:0.#} damage blocked by shield", Math.Min(dmgabsorb, damage), damage), EnumChatType.Notification); double dx; double dz; if (dmgSource.HitPosition != null) { dx = dmgSource.HitPosition.X; dz = dmgSource.HitPosition.Z; } else if (dmgSource.SourceEntity != null) { dx = dmgSource.SourceEntity.Pos.X - player.Entity.Pos.X; dz = dmgSource.SourceEntity.Pos.Z - player.Entity.Pos.Z; } else if (dmgSource.SourcePos != null) { dx = dmgSource.SourcePos.X - player.Entity.Pos.X; dz = dmgSource.SourcePos.Z - player.Entity.Pos.Z; } else { break; } double attackYaw = Math.Atan2((double)dx, (double)dz); double playerYaw = player.Entity.Pos.Yaw + GameMath.PIHALF; bool inProtectionRange = Math.Abs(GameMath.AngleRadDistance((float)playerYaw, (float)attackYaw)) < angleProtectionRange; if (inProtectionRange && api.World.Rand.NextDouble() < chance) { damage = Math.Max(0, damage - dmgabsorb); var loc = shieldSlot.Itemstack.ItemAttributes["blockSound"].AsString("held/shieldblock"); api.World.PlaySoundAt(AssetLocation.Create(loc, shieldSlot.Itemstack.Collectible.Code.Domain).WithPathPrefixOnce("sounds/").WithPathAppendixOnce(".ogg"), player, null); if (api.Side == EnumAppSide.Server) { shieldSlot.Itemstack.Collectible.DamageItem(api.World, dmgSource.SourceEntity, shieldSlot, 1); shieldSlot.MarkDirty(); } } } if (damage <= 0) { return(0); } // The code below only the server needs to execute if (api.Side == EnumAppSide.Client) { return(damage); } // Does not protect against non-attack damages if (type != EnumDamageType.BluntAttack && type != EnumDamageType.PiercingAttack && type != EnumDamageType.SlashingAttack) { return(damage); } if (dmgSource.Source == EnumDamageSource.Internal || dmgSource.Source == EnumDamageSource.Suicide) { return(damage); } ItemSlot armorSlot; IInventory inv = player.InventoryManager.GetOwnInventory(GlobalConstants.characterInvClassName); double rnd = api.World.Rand.NextDouble(); int attackTarget; if ((rnd -= 0.2) < 0) { // Head armorSlot = inv[12]; attackTarget = 0; } else if ((rnd -= 0.5) < 0) { // Body armorSlot = inv[13]; attackTarget = 1; } else { // Legs armorSlot = inv[14]; attackTarget = 2; } // Apply full damage if no armor is in this slot if (armorSlot.Empty || !(armorSlot.Itemstack.Item is ItemWearable)) { EnumCharacterDressType[] dressTargets = clothingDamageTargetsByAttackTacket[attackTarget]; EnumCharacterDressType target = dressTargets[api.World.Rand.Next(dressTargets.Length)]; ItemSlot targetslot = player.Entity.GearInventory[(int)target]; if (!targetslot.Empty) { // Wolf: 10 hp damage = 10% condition loss // Ram: 10 hp damage = 2.5% condition loss // Bronze locust: 10 hp damage = 5% condition loss float mul = 0.25f; if (type == EnumDamageType.SlashingAttack) { mul = 1f; } if (type == EnumDamageType.PiercingAttack) { mul = 0.5f; } float diff = -damage / 100 * mul; if (Math.Abs(diff) > 0.05) { api.World.PlaySoundAt(ripSound, player.Entity); } (targetslot.Itemstack.Collectible as ItemWearable)?.ChangeCondition(targetslot, diff); } return(damage); } ProtectionModifiers protMods = (armorSlot.Itemstack.Item as ItemWearable).ProtectionModifiers; int weaponTier = dmgSource.DamageTier; float flatDmgProt = protMods.FlatDamageReduction; float percentProt = protMods.RelativeProtection; for (int tier = 1; tier <= weaponTier; tier++) { bool aboveTier = tier > protMods.ProtectionTier; float flatLoss = aboveTier ? protMods.PerTierFlatDamageReductionLoss[1] : protMods.PerTierFlatDamageReductionLoss[0]; float percLoss = aboveTier ? protMods.PerTierRelativeProtectionLoss[1] : protMods.PerTierRelativeProtectionLoss[0]; if (aboveTier && protMods.HighDamageTierResistant) { flatLoss /= 2; percLoss /= 2; } flatDmgProt -= flatLoss; percentProt *= 1 - percLoss; } // Durability loss is the one before the damage reductions float durabilityLoss = 0.5f + damage * Math.Max(0.5f, (weaponTier - protMods.ProtectionTier) * 3); int durabilityLossInt = GameMath.RoundRandom(api.World.Rand, durabilityLoss); // Now reduce the damage damage = Math.Max(0, damage - flatDmgProt); damage *= 1 - Math.Max(0, percentProt); armorSlot.Itemstack.Collectible.DamageItem(api.World, player.Entity, armorSlot, durabilityLossInt); if (armorSlot.Empty) { api.World.PlaySoundAt(new AssetLocation("sounds/effect/toolbreak"), player); } return(damage); }
private float handleDamaged(IPlayer player, float damage, DamageSource dmgSource) { // Does not protect against non-attack damages EnumDamageType type = dmgSource.Type; if (type != EnumDamageType.BluntAttack && type != EnumDamageType.PiercingAttack && type != EnumDamageType.SlashingAttack) { return(damage); } if (dmgSource.Source == EnumDamageSource.Internal || dmgSource.Source == EnumDamageSource.Suicide) { return(damage); } ItemSlot armorSlot; IInventory inv = player.InventoryManager.GetOwnInventory(GlobalConstants.characterInvClassName); double rnd = api.World.Rand.NextDouble(); int attackTarget; if ((rnd -= 0.2) < 0) { // Head armorSlot = inv[12]; attackTarget = 0; } else if ((rnd -= 0.5) < 0) { // Body armorSlot = inv[13]; attackTarget = 1; } else { // Legs armorSlot = inv[14]; attackTarget = 2; } // Apply full damage if no armor is in this slot if (armorSlot.Empty || !(armorSlot.Itemstack.Item is ItemWearable)) { EnumCharacterDressType[] dressTargets = clothingDamageTargetsByAttackTacket[attackTarget]; EnumCharacterDressType target = dressTargets[api.World.Rand.Next(dressTargets.Length)]; ItemSlot targetslot = player.Entity.GearInventory[(int)target]; if (!targetslot.Empty) { // Wolf: 10 hp damage = 10% condition loss // Ram: 10 hp damage = 2.5% condition loss // Bronze locust: 10 hp damage = 5% condition loss float mul = 0.25f; if (type == EnumDamageType.SlashingAttack) { mul = 1f; } if (type == EnumDamageType.PiercingAttack) { mul = 0.5f; } float diff = -damage / 100 * mul; if (Math.Abs(diff) > 0.05) { api.World.PlaySoundAt(ripSound, player.Entity); } (targetslot.Itemstack.Collectible as ItemWearable)?.ChangeCondition(targetslot, diff); } return(damage); } ProtectionModifiers protMods = (armorSlot.Itemstack.Item as ItemWearable).ProtectionModifiers; int weaponTier = dmgSource.DamageTier; float flatDmgProt = protMods.FlatDamageReduction; float percentProt = protMods.RelativeProtection; for (int tier = 1; tier <= weaponTier; tier++) { bool aboveTier = tier > protMods.ProtectionTier; float flatLoss = aboveTier ? protMods.PerTierFlatDamageReductionLoss[1] : protMods.PerTierFlatDamageReductionLoss[0]; float percLoss = aboveTier ? protMods.PerTierRelativeProtectionLoss[1] : protMods.PerTierRelativeProtectionLoss[0]; if (aboveTier && protMods.HighDamageTierResistant) { flatLoss /= 2; percLoss /= 2; } flatDmgProt -= flatLoss; percentProt *= 1 - percLoss; } // Durability loss is the one before the damage reductions float durabilityLoss = 0.5f + damage * Math.Max(0.5f, (weaponTier - protMods.ProtectionTier) * 3); int durabilityLossInt = GameMath.RoundRandom(api.World.Rand, durabilityLoss); // Now reduce the damage damage = Math.Max(0, damage - flatDmgProt); damage *= 1 - Math.Max(0, percentProt); armorSlot.Itemstack.Collectible.DamageItem(api.World, player.Entity, armorSlot, durabilityLossInt); if (armorSlot.Empty) { api.World.PlaySoundAt(new AssetLocation("sounds/effect/toolbreak"), player); } return(damage); }
private void SetupDialog() { // title bar ElementBounds bgBounds = ElementStdBounds.DialogBackground(); ElementBounds dialogBounds = ElementStdBounds.AutosizedMainDialog.WithChild(bgBounds); SingleComposer = capi.Gui.CreateCompo("tailoring", dialogBounds) .AddShadedDialogBG(bgBounds) .AddDialogTitleBar("Tailoring", () => TryClose()) .BeginChildElements(bgBounds); ElementBounds titleBarBounds = ElementStdBounds.TitleBar(); bgBounds.WithChild(titleBarBounds); // search text box ElementBounds searchBounds = ElementBounds.FixedSize(200, 30).FixedUnder(titleBarBounds); bgBounds.WithChild(searchBounds); SingleComposer.AddTextInput(searchBounds, (string newText) => { filterSearch = newText; FilterItems(); }, CairoFont.WhiteSmallishText(), "search"); SingleComposer.GetTextInput("search").SetPlaceHolderText("Search..."); // SingleComposer.FocusElement(SingleComposer.GetTextInput("search").TabIndex); // prep for category dropdown string[] characterDressTypeNames = EnumCharacterDressType.GetNames(typeof(EnumCharacterDressType)); List <string> filteredCharacterDressTypeNames = new List <string>(); foreach (var characterDressTypeName in characterDressTypeNames) { if (categoryCount.ContainsKey(characterDressTypeName.ToLowerInvariant())) { filteredCharacterDressTypeNames.Add(characterDressTypeName); } } string[] values = new string[filteredCharacterDressTypeNames.Count + 1]; values[0] = ""; filteredCharacterDressTypeNames.CopyTo(0, values, 1, filteredCharacterDressTypeNames.Count); string[] names = new string[filteredCharacterDressTypeNames.Count + 1]; names[0] = "(Show all)"; filteredCharacterDressTypeNames.CopyTo(0, names, 1, filteredCharacterDressTypeNames.Count); // category dropdown ElementBounds categoryDropdownBounds = ElementBounds.FixedSize(150, 30).FixedUnder(titleBarBounds).FixedRightOf(searchBounds, PADDING); bgBounds.WithChild(categoryDropdownBounds); SingleComposer.AddDropDown(values, names, 0, (value, selected) => { filterCategory = value; FilterItems(); }, categoryDropdownBounds, "category"); // stacklist ElementBounds stacklistBounds = ElementBounds.FixedSize(400, STACKLIST_HEIGHT).FixedUnder(searchBounds, PADDING); bgBounds.WithChild(stacklistBounds); ElementBounds clipBounds = stacklistBounds.ForkBoundingParent(); ElementBounds insetBounds = stacklistBounds.FlatCopy().FixedGrow(6).WithFixedOffset(-3, -3); ElementBounds scrollbarBounds = insetBounds.CopyOffsetedSibling(3 + stacklistBounds.fixedWidth + 7).WithFixedWidth(20); SingleComposer .BeginClip(clipBounds) .AddInset(insetBounds, 3) .AddInteractiveElement(new GuiElementHandbookListWithTooltips(capi, stacklistBounds, (int index) => { OnSelectProduct((shownStacklistItems[index] as GuiHandbookItemStackPage).Stack); }, shownStacklistItems), "stacklist") .EndClip() .AddVerticalScrollbar((float value) => { GuiElementHandbookList stacklist = SingleComposer.GetHandbookStackList("stacklist"); stacklist.insideBounds.fixedY = 3 - value; stacklist.insideBounds.CalcWorldBounds(); }, scrollbarBounds, "scrollbar") ; UpdateStacklistScrollbar(); // costLabel ElementBounds costLabelBounds = ElementBounds.FixedSize(300, 80).FixedUnder(clipBounds, PADDING); bgBounds.WithChild(costLabelBounds); SingleComposer.AddDynamicText("", CairoFont.WhiteSmallText(), EnumTextOrientation.Left, costLabelBounds, "costLabel"); // craftButton ElementBounds craftButtonBounds = ElementBounds .FixedSize(0, 0) .FixedUnder(clipBounds, PADDING) .WithAlignment(EnumDialogArea.RightFixed) .WithFixedPadding(20, 4) .WithFixedAlignmentOffset(-11, 1) ; bgBounds.WithChild(craftButtonBounds); SingleComposer.AddSmallButton("Craft", () => { OnCraftButtonClicked(); return(true); }, craftButtonBounds, EnumButtonStyle.Normal, EnumTextOrientation.Center, "craftButton"); var craftButton = SingleComposer.GetButton("craftButton"); craftButton.Enabled = false; SingleComposer.EndChildElements(); // bgBounds SingleComposer.Compose(); }
public ItemSlotCharacter(EnumCharacterDressType type, InventoryBase inventory) : base(inventory) { this.type = type; }