use of net.silentchaos512.gems.api.ITool in project SilentGems by SilentChaos512.
the class ToolHelper method constructTool.
public static ItemStack constructTool(Item item, ItemStack rod, ItemStack... materials) {
if (materials.length == 1) {
ItemStack[] newMats = new ItemStack[3];
for (int i = 0; i < newMats.length; ++i) newMats[i] = materials[0];
materials = newMats;
}
ItemStack result = new ItemStack(item);
result.setTagCompound(new NBTTagCompound());
result.getTagCompound().setTag(NBT_TEMP_PARTLIST, new NBTTagCompound());
// Set construction materials
ToolPart part;
// Head
for (int i = 0; i < materials.length; ++i) {
if (StackHelper.isEmpty(materials[i])) {
String str = "ToolHelper.constructTool: empty part! ";
for (ItemStack stack : materials) str += stack + ", ";
throw new IllegalArgumentException(str);
}
part = ToolPartRegistry.fromStack(materials[i]);
EnumMaterialGrade grade = EnumMaterialGrade.fromStack(materials[i]);
setTagPart(result, ToolPartPosition.HEAD.getKey(i), part, grade);
// Write part list for client-side name generation.
result.getTagCompound().getCompoundTag(NBT_TEMP_PARTLIST).setTag("part" + i, materials[i].writeToNBT(new NBTTagCompound()));
}
// Rod
part = ToolPartRegistry.fromStack(rod);
if (part == null) {
return StackHelper.empty();
}
setTagPart(result, ToolPartPosition.ROD.getKey(0), part, EnumMaterialGrade.NONE);
// Create name
String displayName = createToolName(item, materials);
result.setStackDisplayName(displayName);
recalculateStats(result);
// Is this tier valid for this tool class?
EnumMaterialTier toolTier = getToolTier(result);
if (item instanceof ITool && !((ITool) item).getValidTiers().contains(toolTier)) {
return StackHelper.empty();
}
return result;
}
use of net.silentchaos512.gems.api.ITool in project SilentGems by SilentChaos512.
the class SoulSkill method selectSkillToLearn.
public static SoulSkill selectSkillToLearn(ToolSoul soul, ItemStack tool) {
// if (soul.getLevel() == 5) {
// return SUPER_SKILL;
// }
Map<SoulSkill, Double> candidates = new LinkedHashMap<>();
// Create list of candidates
for (SoulSkill skill : SKILL_LIST.values()) {
if (skill.canLearn(soul, tool)) {
boolean favorsElement = false;
// Select a weight based on favored elements.
double weight = skill.favoredElements.length < 1 ? 20 : 7;
for (EnumSoulElement elem : skill.favoredElements) {
if (elem == soul.getPrimaryElement()) {
weight = 20;
favorsElement = true;
break;
} else if (elem == soul.getSecondaryElement()) {
weight = 15;
favorsElement = true;
break;
}
}
// Favors certain tool types?
if (skill.favoredType != EnumToolType.NONE) {
EnumToolType toolType = tool.getItem() instanceof ITool ? ((ITool) tool.getItem()).getToolType() : tool.getItem() instanceof IArmor ? ((IArmor) tool.getItem()).getToolType() : EnumToolType.NONE;
if (toolType == skill.favoredType) {
weight += 5;
}
}
// If skill has a median level, apply that to the weight.
if (skill.medianXpLevel > 0) {
int diff = Math.abs(soul.level - skill.medianXpLevel);
if (diff > 6) {
diff = 6;
}
weight -= 0.75 * diff;
}
// If a lower level of the skill is already known, reduce the weight.
if (soul.skills.containsKey(skill)) {
weight -= 2.5 * soul.skills.get(skill);
}
// Base weight diff, favors multiplier
weight += skill.weightDiff;
if (favorsElement) {
weight *= skill.favorWeightMulti;
}
// Make sure weight is at least 1.
if (weight < 1) {
weight = 1;
}
candidates.put(skill, weight);
}
}
// Seed based on soul elements, level, and tool UUID.
Random rand = new Random(soul.getPrimaryElement().ordinal() + (soul.getSecondaryElement().ordinal() << 4) + (soul.getLevel() << 8) + (ToolHelper.getUUID(tool).getLeastSignificantBits() << 16));
// Weighted random selection.
SoulSkill selected = null;
double bestValue = Double.MIN_VALUE;
for (SoulSkill skill : candidates.keySet()) {
double value = -Math.log(rand.nextFloat() / candidates.get(skill));
SilentGems.logHelper.debug(skill.id, candidates.get(skill), value, bestValue);
if (value > bestValue) {
bestValue = value;
selected = skill;
}
}
return selected;
}
use of net.silentchaos512.gems.api.ITool in project SilentGems by SilentChaos512.
the class ToolStats method calculate.
public ToolStats calculate() {
if (parts.length == 0)
return this;
Map<ItemStat, List<ItemStatModifier>> mods = new HashMap<>();
for (ItemStat stat : ItemStat.ALL_STATS) {
mods.put(stat, new ArrayList<>());
}
Set<ToolPart> uniqueParts = Sets.newConcurrentHashSet();
// Head (main) parts
for (int i = 0; i < parts.length; ++i) {
ToolPart part = parts[i];
EnumMaterialGrade grade = grades[i];
for (ItemStat stat : ItemStat.ALL_STATS) {
ItemStatModifier statModifier = part.getStatModifier(stat, grade);
if (statModifier != null) {
mods.get(stat).add(statModifier);
}
}
// float multi = (100 + grade.bonusPercent) / 100f;
// durability += part.getDurability() * multi;
// harvestSpeed += part.getHarvestSpeed() * multi;
// meleeDamage += part.getMeleeDamage() * multi;
// magicDamage += part.getMagicDamage() * multi;
// meleeSpeed += part.getMeleeSpeed() * multi;
// enchantability += part.getEnchantability() * multi;
// chargeSpeed += part.getChargeSpeed() * multi;
// protection += part.getProtection() * multi;
// harvestLevel = Math.max(harvestLevel, part.getHarvestLevel());
uniqueParts.add(part);
}
// Variety bonus
int variety = MathHelper.clamp(uniqueParts.size(), 1, GemsConfig.VARIETY_CAP);
float bonus = 1.0f + GemsConfig.VARIETY_BONUS * (variety - 1);
mods.get(CommonItemStats.DURABILITY).add(new ItemStatModifier(ID_VARIETY_BONUS, bonus, Operation.MULTIPLY));
mods.get(CommonItemStats.HARVEST_SPEED).add(new ItemStatModifier(ID_VARIETY_BONUS, bonus, Operation.MULTIPLY));
mods.get(CommonItemStats.MELEE_DAMAGE).add(new ItemStatModifier(ID_VARIETY_BONUS, bonus, Operation.MULTIPLY));
mods.get(CommonItemStats.MAGIC_DAMAGE).add(new ItemStatModifier(ID_VARIETY_BONUS, bonus, Operation.MULTIPLY));
mods.get(CommonItemStats.ATTACK_SPEED).add(new ItemStatModifier(ID_VARIETY_BONUS, bonus, Operation.MULTIPLY));
mods.get(CommonItemStats.CHARGE_SPEED).add(new ItemStatModifier(ID_VARIETY_BONUS, bonus, Operation.MULTIPLY));
mods.get(CommonItemStats.ENCHANTABILITY).add(new ItemStatModifier(ID_VARIETY_BONUS, bonus, Operation.MULTIPLY));
mods.get(CommonItemStats.ARMOR).add(new ItemStatModifier(ID_VARIETY_BONUS, bonus, Operation.MULTIPLY));
mods.get(CommonItemStats.MAGIC_ARMOR).add(new ItemStatModifier(ID_VARIETY_BONUS, bonus, Operation.MULTIPLY));
// Tool class multipliers
if (tool.getItem() instanceof ITool) {
ITool itool = (ITool) tool.getItem();
durability *= itool.getDurabilityMultiplier();
harvestSpeed *= itool.getHarvestSpeedMultiplier();
}
// Rod, tip, grip, frame
ToolPart partRod = ToolHelper.getConstructionRod(tool);
ToolPart partTip = ToolHelper.getConstructionTip(tool);
ToolPart partGrip = ToolHelper.getPart(tool, ToolPartPosition.ROD_GRIP);
ToolPart partFrame = ArmorHelper.getPart(tool, ArmorPartPosition.FRAME);
for (ToolPart part : Lists.newArrayList(partRod, partTip, partGrip, partFrame)) {
if (part != null) {
for (ItemStat stat : ItemStat.ALL_STATS) {
ItemStatModifier statModifier = part.getStatModifier(stat, EnumMaterialGrade.NONE);
if (statModifier != null) {
mods.get(stat).add(statModifier);
}
}
}
}
durability = calcStat(CommonItemStats.DURABILITY, mods);
harvestSpeed = calcStat(CommonItemStats.HARVEST_SPEED, mods);
meleeDamage = calcStat(CommonItemStats.MELEE_DAMAGE, mods);
magicDamage = calcStat(CommonItemStats.MAGIC_DAMAGE, mods);
meleeSpeed = calcStat(CommonItemStats.ATTACK_SPEED, mods);
chargeSpeed = calcStat(CommonItemStats.CHARGE_SPEED, mods);
enchantability = calcStat(CommonItemStats.ENCHANTABILITY, mods);
protection = calcStat(CommonItemStats.ARMOR, mods);
harvestLevel = (int) calcStat(CommonItemStats.HARVEST_LEVEL, mods);
return this;
}
use of net.silentchaos512.gems.api.ITool in project SilentGems by SilentChaos512.
the class ItemSkillOrb method clOnItemRightClick.
@Override
protected ActionResult<ItemStack> clOnItemRightClick(World world, EntityPlayer player, EnumHand hand) {
ItemStack offhand = player.getHeldItemOffhand();
// Orb in main hand, tool/armor in offhand.
if (hand != EnumHand.MAIN_HAND || StackHelper.isEmpty(offhand) || !(offhand.getItem() instanceof ITool || offhand.getItem() instanceof IArmor)) {
return new ActionResult<ItemStack>(EnumActionResult.PASS, player.getHeldItem(hand));
}
ItemStack orb = player.getHeldItemMainhand();
// Check for tool soul.
ToolSoul soul = SoulManager.getSoul(offhand);
if (soul == null) {
if (!world.isRemote) {
ChatHelper.sendMessage(player, SilentGems.localizationHelper.getItemSubText(Names.SKILL_ORB, "no_soul"));
}
return new ActionResult<ItemStack>(EnumActionResult.PASS, orb);
}
// Check skill on orb.
SoulSkill skill = getSkill(orb);
if (skill == null) {
if (!world.isRemote) {
ChatHelper.sendMessage(player, SilentGems.localizationHelper.getItemSubText(Names.SKILL_ORB, "no_skill"));
}
return new ActionResult<ItemStack>(EnumActionResult.PASS, orb);
}
if (world.isRemote) {
return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, player.getHeldItem(hand));
}
// Try to add or level up the skill.
if (soul.addOrLevelSkill(skill, offhand, player)) {
ToolHelper.recalculateStats(offhand);
StackHelper.shrink(orb, 1);
return new ActionResult<ItemStack>(EnumActionResult.SUCCESS, orb);
} else {
ChatHelper.sendMessage(player, SilentGems.localizationHelper.getItemSubText(Names.SKILL_ORB, "max_level"));
return new ActionResult<ItemStack>(EnumActionResult.PASS, player.getHeldItem(hand));
}
}
use of net.silentchaos512.gems.api.ITool in project SilentGems by SilentChaos512.
the class RecipeDecorateTool method getCraftingResult.
@Override
public ItemStack getCraftingResult(InventoryCrafting inv) {
int i;
int toolRow = 0;
int toolCol = 0;
ItemStack stack;
ItemStack tool = StackHelper.empty();
int repairValue = 0;
int ammoValue = 0;
// Find tool position
for (int row = 0; row < inv.getWidth(); ++row) {
for (int col = 0; col < inv.getHeight(); ++col) {
stack = inv.getStackInRowAndColumn(row, col);
if (StackHelper.isValid(stack) && stack.getItem() instanceof ITool) {
tool = stack;
toolRow = row;
toolCol = col;
}
}
}
// Found a tool?
if (StackHelper.isEmpty(tool)) {
return StackHelper.empty();
}
// Check adjacent materials
ItemStack west = inv.getStackInRowAndColumn(toolRow - 1, toolCol);
ItemStack north = inv.getStackInRowAndColumn(toolRow, toolCol - 1);
ItemStack east = inv.getStackInRowAndColumn(toolRow + 1, toolCol);
ItemStack south = inv.getStackInRowAndColumn(toolRow, toolCol + 1);
if (!checkIsDecorationMaterial(west) || !checkIsDecorationMaterial(north) || !checkIsDecorationMaterial(east) || !checkIsDecorationMaterial(south)) {
return StackHelper.empty();
}
// Check other materials and get all repair values.
List<ItemStack> otherMats = Lists.newArrayList();
EnumMaterialTier toolTier = ToolHelper.getToolTier(tool);
for (i = 0; i < inv.getSizeInventory(); ++i) {
stack = inv.getStackInSlot(i);
if (StackHelper.isValid(stack) && !(stack.getItem() instanceof ITool)) {
ToolPart part = ToolPartRegistry.fromDecoStack(stack);
// Invalid part or not a part?
if (part == null) {
return StackHelper.empty();
}
// Valid for tool tier?
if (!part.validForToolOfTier(toolTier) && !(part instanceof ToolPartMain)) {
return StackHelper.empty();
}
int repairAmount = part.getRepairAmount(tool, stack);
if (repairAmount > 0) {
repairValue += repairAmount;
++ammoValue;
}
otherMats.add(stack);
}
}
if (otherMats.isEmpty()) {
return StackHelper.empty();
}
ItemStack result = StackHelper.safeCopy(tool);
result = ToolHelper.decorateTool(tool, west, north, east, south);
boolean lockedStats = result.getTagCompound().getBoolean(ToolHelper.NBT_LOCK_STATS);
// Other materials
for (ItemStack other : otherMats) {
ToolPart part = ToolPartRegistry.fromDecoStack(other);
EnumMaterialGrade grade = EnumMaterialGrade.fromStack(other);
if (StackHelper.isValid(result) && part instanceof ToolPartRod) {
ToolHelper.setRenderPart(result, part, grade, ToolPartPosition.ROD);
} else if (part instanceof ToolPartTip) {
if (lockedStats) {
// Tips change stats, so using them with locked tools is not allowed.
return StackHelper.empty();
}
ToolHelper.setConstructionTip(result, part);
}
}
if (repairValue > 0) {
// Makes odd repair values line up better (2 polished stone on pickaxe makes a full repair, etc.)
repairValue += 1;
}
// Tool repair multiplier
repairValue *= ((ITool) tool.getItem()).getRepairMultiplier();
// Repair.
ItemHelper.attemptDamageItem(result, -repairValue, SilentGems.instance.random);
// Restore ammo.
if (result.getItem() instanceof IAmmoTool && ammoValue > 0) {
IAmmoTool ammoTool = (IAmmoTool) result.getItem();
ammoTool.addAmmo(result, ammoValue * GemsConfig.TOMAHAWK_AMMO_PER_MAT);
}
// Recalculate stats.
ToolHelper.recalculateStats(result);
ToolHelper.incrementStatRedecorated(result, 1);
// Change the UUID so that rendering cache updates immediately for recipe output.
result.getTagCompound().removeTag(ToolHelper.NBT_UUID + "Most");
result.getTagCompound().removeTag(ToolHelper.NBT_UUID + "Least");
ToolHelper.getUUID(result);
return result;
}
Aggregations