Contract Name:
ItemNFTLibrary
Contract Source Code:
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {Skill, Attire, CombatStyle, CombatStats} from "./misc.sol";
import {GuaranteedReward, RandomReward} from "./rewards.sol";
enum ActionQueueStrategy {
OVERWRITE,
APPEND,
KEEP_LAST_IN_PROGRESS
}
struct QueuedActionInput {
Attire attire;
uint16 actionId;
uint16 regenerateId; // Food (combat), maybe something for non-combat later
uint16 choiceId; // Melee/Ranged/Magic (combat), logs, ore (non-combat)
uint16 rightHandEquipmentTokenId; // Axe/Sword/bow, can be empty
uint16 leftHandEquipmentTokenId; // Shield, can be empty
uint24 timespan; // How long to queue the action for
uint8 combatStyle; // CombatStyle specific style of combat
uint40 petId; // id of the pet (can be empty)
}
struct QueuedAction {
uint16 actionId;
uint16 regenerateId; // Food (combat), maybe something for non-combat later
uint16 choiceId; // Melee/Ranged/Magic (combat), logs, ore (non-combat)
uint16 rightHandEquipmentTokenId; // Axe/Sword/bow, can be empty
uint16 leftHandEquipmentTokenId; // Shield, can be empty
uint24 timespan; // How long to queue the action for
uint24 prevProcessedTime; // How long the action has been processed for previously
uint24 prevProcessedXPTime; // How much XP has been gained for this action so far
uint64 queueId; // id of this queued action
bytes1 packed; // 1st bit is isValid (not used yet), 2nd bit is for hasPet (decides if the 2nd storage slot is read)
uint8 combatStyle;
uint24 reserved;
// Next storage slot
uint40 petId; // id of the pet (can be empty)
}
// This is only used as an input arg (and events)
struct ActionInput {
uint16 actionId;
ActionInfo info;
GuaranteedReward[] guaranteedRewards;
RandomReward[] randomRewards;
CombatStats combatStats;
}
struct ActionInfo {
uint8 skill;
bool actionChoiceRequired; // If true, then the user must choose an action choice
uint24 xpPerHour;
uint32 minXP;
uint24 numSpawned; // Mostly for combat, capped respawn rate for xp/drops. Per hour, base 10000
uint16 handItemTokenIdRangeMin; // Inclusive
uint16 handItemTokenIdRangeMax; // Inclusive
uint8 successPercent; // 0-100
uint8 worldLocation; // 0 is the main starting world
bool isFullModeOnly;
bool isAvailable;
uint16 questPrerequisiteId;
}
uint16 constant ACTIONCHOICE_MELEE_BASIC_SWORD = 1500;
uint16 constant ACTIONCHOICE_MAGIC_SHADOW_BLAST = 2000;
uint16 constant ACTIONCHOICE_RANGED_BASIC_BOW = 3000;
// Allows for 2, 4 or 8 hour respawn time
uint256 constant SPAWN_MUL = 1000;
uint256 constant RATE_MUL = 1000;
uint256 constant GUAR_MUL = 10; // Guaranteeded reward multiplier (1 decimal, allows for 2 hour action times)
uint256 constant MAX_QUEUEABLE_ACTIONS = 3; // Available slots to queue actions
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
enum BoostType {
NONE,
ANY_XP,
COMBAT_XP,
NON_COMBAT_XP,
GATHERING,
ABSENCE,
PASSIVE_SKIP_CHANCE,
// Clan wars
PVP_BLOCK,
PVP_REATTACK,
PVP_SUPER_ATTACK,
// Combat stats
COMBAT_FIXED
}
struct Equipment {
uint16 itemTokenId;
uint24 amount;
}
enum Skill {
NONE,
COMBAT, // This is a helper which incorporates all combat skills, attack <-> magic, defence, health etc
MELEE,
RANGED,
MAGIC,
DEFENCE,
HEALTH,
RESERVED_COMBAT,
MINING,
WOODCUTTING,
FISHING,
SMITHING,
THIEVING,
CRAFTING,
COOKING,
FIREMAKING,
FARMING,
ALCHEMY,
FLETCHING,
FORGING,
RESERVED2,
RESERVED3,
RESERVED4,
RESERVED5,
RESERVED6,
RESERVED7,
RESERVED8,
RESERVED9,
RESERVED10,
RESERVED11,
RESERVED12,
RESERVED13,
RESERVED14,
RESERVED15,
RESERVED16,
RESERVED17,
RESERVED18,
RESERVED19,
RESERVED20,
TRAVELING // Helper Skill for travelling
}
struct Attire {
uint16 head;
uint16 neck;
uint16 body;
uint16 arms;
uint16 legs;
uint16 feet;
uint16 ring;
uint16 reserved1;
}
struct CombatStats {
// From skill points
int16 meleeAttack;
int16 magicAttack;
int16 rangedAttack;
int16 health;
// These include equipment
int16 meleeDefence;
int16 magicDefence;
int16 rangedDefence;
}
enum CombatStyle {
NONE,
ATTACK,
DEFENCE
}
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {QueuedAction} from "./actions.sol";
import {Skill, BoostType, CombatStats, Equipment} from "./misc.sol";
import {PlayerQuest} from "./quests.sol";
// 4 bytes for each level. 0x00000000 is the first level, 0x00000054 is the second, etc.
bytes constant XP_BYTES = hex"0000000000000054000000AE0000010E00000176000001E60000025E000002DE00000368000003FD0000049B00000546000005FC000006C000000792000008730000096400000A6600000B7B00000CA400000DE100000F36000010A200001229000013CB0000158B0000176B0000196E00001B9400001DE20000205A000022FF000025D5000028DD00002C1E00002F99000033540000375200003B9A000040300000451900004A5C00004FFF0000560900005C810000637000006ADD000072D100007B570000847900008E42000098BE0000A3F90000B0020000BCE70000CAB80000D9860000E9630000FA6200010C990001201D0001350600014B6F0001637300017D2E000198C10001B64E0001D5F80001F7E600021C430002433B00026CFD000299BE0002C9B30002FD180003342B00036F320003AE730003F23D00043AE3000488BE0004DC2F0005359B000595700005FC2400066A360006E02D00075E990007E6160008774C000912EB0009B9B4000A6C74000B2C06000BF956000CD561000DC134000EBDF3000FCCD40010EF2400122648001373BF0014D9230016582C0017F2B00019AAA9001B8234001D7B95001F99390021DDBC00244BE60026E6B60029B15F002CAF51002FE43A0033540D00370303003AF5A4003F30CC0043B9B0004895E3004DCB600053609100595C53005FC6030066A585006E034D0075E86C007E5E980087703B0091287D009B935300A6BD8F00B2B4EE00BF882800CD470500DC026F00EBCC8500FCB8B7010EDBD5";
uint256 constant MAX_LEVEL = 140; // Original max level
uint256 constant MAX_LEVEL_1 = 160; // TODO: Update later
uint256 constant MAX_LEVEL_2 = 190; // TODO: Update later
enum EquipPosition {
NONE,
HEAD,
NECK,
BODY,
ARMS,
LEGS,
FEET,
RING,
SPARE2,
LEFT_HAND,
RIGHT_HAND,
BOTH_HANDS,
QUIVER,
MAGIC_BAG,
FOOD,
AUX, // wood, seeds etc..
BOOST_VIAL,
EXTRA_BOOST_VIAL,
GLOBAL_BOOST_VIAL,
CLAN_BOOST_VIAL,
PASSIVE_BOOST_VIAL,
LOCKED_VAULT,
TERRITORY
}
struct Player {
uint40 currentActionStartTimestamp; // The in-progress start time of the first queued action
Skill currentActionProcessedSkill1; // The skill that the queued action has already gained XP in
uint24 currentActionProcessedXPGained1; // The amount of XP that the queued action has already gained
Skill currentActionProcessedSkill2;
uint24 currentActionProcessedXPGained2;
Skill currentActionProcessedSkill3;
uint24 currentActionProcessedXPGained3;
uint16 currentActionProcessedFoodConsumed;
uint16 currentActionProcessedBaseInputItemsConsumedNum; // e.g scrolls, crafting materials etc
Skill skillBoosted1; // The first skill that is boosted
Skill skillBoosted2; // The second skill that is boosted (if applicable)
uint48 totalXP;
uint16 totalLevel; // Doesn't not automatically add new skills to it
bytes1 packedData; // Contains worldLocation in first 6 bits (0 is the main starting randomnessBeacon), and full mode unlocked in the upper most bit
// TODO: Can be up to 7
QueuedAction[] actionQueue;
string name; // Raw name
}
struct Item {
EquipPosition equipPosition;
bytes1 packedData; // 0x1 exists, upper most bit is full mode
uint16 questPrerequisiteId;
// Can it be transferred?
bool isTransferable; // TODO: Move into packedData
// Food
uint16 healthRestored;
// Boost vial
BoostType boostType;
uint16 boostValue; // Varies, could be the % increase
uint24 boostDuration; // How long the effect of the boost last
// Combat stats
int16 meleeAttack;
int16 magicAttack;
int16 rangedAttack;
int16 meleeDefence;
int16 magicDefence;
int16 rangedDefence;
int16 health;
// Minimum requirements in this skill to use this item (can be NONE)
Skill skill;
uint32 minXP;
}
// Used for events
struct BoostInfo {
uint40 startTime;
uint24 duration;
uint16 value;
uint16 itemTokenId; // Get the effect of it
BoostType boostType;
}
struct PlayerBoostInfo {
uint40 startTime;
uint24 duration;
uint16 value;
uint16 itemTokenId; // Get the effect of it
BoostType boostType;
// Another boost slot (for global/clan boosts this is the "last", for users it is the "extra")
uint40 extraOrLastStartTime;
uint24 extraOrLastDuration;
uint16 extraOrLastValue;
uint16 extraOrLastItemTokenId;
BoostType extraOrLastBoostType;
uint40 cooldown; // Just put here for packing
}
// This is effectively a ratio to produce 1 of outputTokenId.
// Available choices that can be undertaken for an action
struct ActionChoiceInput {
uint8 skill; // Skill that this action choice is related to
uint24 rate; // Rate of output produced per hour (base 1000) 3 decimals
uint24 xpPerHour;
uint16[] inputTokenIds;
uint24[] inputAmounts;
uint16 outputTokenId;
uint8 outputAmount;
uint8 successPercent; // 0-100
uint16 handItemTokenIdRangeMin; // Inclusive
uint16 handItemTokenIdRangeMax; // Inclusive
bool isFullModeOnly;
bool isAvailable;
uint16 questPrerequisiteId;
uint8[] skills; // Skills required to do this action choice
uint32[] skillMinXPs; // Min XP in the corresponding skills to be able to do this action choice
int16[] skillDiffs; // How much the skill is increased/decreased by this action choice
}
struct ActionChoice {
uint8 skill; // Skill that this action choice is related to
uint24 rate; // Rate of output produced per hour (base 1000) 3 decimals
uint24 xpPerHour;
uint16 inputTokenId1;
uint24 inputAmount1;
uint16 inputTokenId2;
uint24 inputAmount2;
uint16 inputTokenId3;
uint24 inputAmount3;
uint16 outputTokenId;
uint8 outputAmount;
uint8 successPercent; // 0-100
uint8 skill1; // Skills required to do this action choice, commonly the same as skill
uint32 skillMinXP1; // Min XP in the skill to be able to do this action choice
int16 skillDiff1; // How much the skill is increased/decreased by this action choice
uint8 skill2;
uint32 skillMinXP2;
int16 skillDiff2;
uint8 skill3;
uint32 skillMinXP3;
int16 skillDiff3;
uint16 handItemTokenIdRangeMin; // Inclusive
uint16 handItemTokenIdRangeMax; // Inclusive
uint16 questPrerequisiteId;
// FullMode is last bit, first 6 bits is worldLocation,
// 2nd last bit is if there are other skills in next storage slot to check,
// 3rd last bit if the input amounts should be used
bytes1 packedData;
}
// Must be in the same order as Skill enum
struct PackedXP {
uint40 melee;
uint40 ranged;
uint40 magic;
uint40 defence;
uint40 health;
uint40 reservedCombat;
bytes2 packedDataIsMaxed; // 2 bits per skill to indicate whether the maxed skill is reached. I think this was added in case we added a new max level which a user had already passed so old & new levels are the same and it would not trigger a level up event.
// Next slot
uint40 mining;
uint40 woodcutting;
uint40 fishing;
uint40 smithing;
uint40 thieving;
uint40 crafting;
bytes2 packedDataIsMaxed1; // 2 bits per skill to indicate whether the maxed skill is reached
// Next slot
uint40 cooking;
uint40 firemaking;
uint40 farming;
uint40 alchemy;
uint40 fletching;
uint40 forging;
bytes2 packedDataIsMaxed2; // 2 bits per skill to indicate whether the maxed skill is reached
}
struct AvatarInfo {
string name;
string description;
string imageURI;
Skill[2] startSkills; // Can be NONE
}
struct PastRandomRewardInfo {
uint16 itemTokenId;
uint24 amount;
uint64 queueId;
}
struct PendingQueuedActionEquipmentState {
uint256[] consumedItemTokenIds;
uint256[] consumedAmounts;
uint256[] producedItemTokenIds;
uint256[] producedAmounts;
}
struct PendingQueuedActionMetadata {
uint32 xpGained; // total xp gained
uint32 rolls;
bool died;
uint16 actionId;
uint64 queueId;
uint24 elapsedTime;
uint24 xpElapsedTime;
uint8 checkpoint;
}
struct PendingQueuedActionData {
// The amount of XP that the queued action has already gained
Skill skill1;
uint24 xpGained1;
Skill skill2; // Most likely health
uint24 xpGained2;
Skill skill3; // Could come
uint24 xpGained3;
// How much food is consumed in the current action so far
uint16 foodConsumed;
// How many base consumables are consumed in the current action so far
uint16 baseInputItemsConsumedNum;
}
struct PendingQueuedActionProcessed {
// XP gained during this session
Skill[] skills;
uint32[] xpGainedSkills;
// Data for the current action which has been previously processed, this is used to store on the Player
PendingQueuedActionData currentAction;
}
struct QuestState {
uint256[] consumedItemTokenIds;
uint256[] consumedAmounts;
uint256[] rewardItemTokenIds;
uint256[] rewardAmounts;
PlayerQuest[] activeQuestInfo;
uint256[] questsCompleted;
Skill[] skills; // Skills gained XP in
uint32[] xpGainedSkills; // XP gained in these skills
}
struct LotteryWinnerInfo {
uint16 lotteryId;
uint24 raffleId;
uint16 itemTokenId;
uint16 amount;
bool instantConsume;
uint64 playerId;
}
struct PendingQueuedActionState {
// These 2 are in sync. Separated to reduce gas/deployment costs as these are passed down many layers.
PendingQueuedActionEquipmentState[] equipmentStates;
PendingQueuedActionMetadata[] actionMetadatas;
QueuedAction[] remainingQueuedActions;
PastRandomRewardInfo[] producedPastRandomRewards;
uint256[] xpRewardItemTokenIds;
uint256[] xpRewardAmounts;
uint256[] dailyRewardItemTokenIds;
uint256[] dailyRewardAmounts;
PendingQueuedActionProcessed processedData;
bytes32 dailyRewardMask;
QuestState quests;
uint256 numPastRandomRewardInstancesToRemove;
uint8 worldLocation;
LotteryWinnerInfo lotteryWinner;
}
struct FullAttireBonusInput {
Skill skill;
uint8 bonusXPPercent;
uint8 bonusRewardsPercent; // 3 = 3%
uint16[5] itemTokenIds; // 0 = head, 1 = body, 2 arms, 3 body, 4 = feet
}
// Contains everything you need to create an item
struct ItemInput {
CombatStats combatStats;
uint16 tokenId;
EquipPosition equipPosition;
bool isTransferable;
bool isFullModeOnly;
bool isAvailable;
uint16 questPrerequisiteId;
// Minimum requirements in this skill
Skill skill;
uint32 minXP;
// Food
uint16 healthRestored;
// Boost
BoostType boostType;
uint16 boostValue; // Varies, could be the % increase
uint24 boostDuration; // How long the effect of the boost vial last
// uri
string metadataURI;
string name;
}
/* Order head, neck, body, arms, legs, feet, ring, reserved1,
leftHandEquipment, rightHandEquipment,
Not used yet: input1, input2,input3, regenerate, reserved2, reserved3 */
struct CheckpointEquipments {
uint16[16] itemTokenIds;
uint16[16] balances;
}
struct ActivePlayerInfo {
uint64 playerId;
uint40 checkpoint;
uint24 timespan;
uint24 timespan1;
uint24 timespan2;
}
uint8 constant START_LEVEL = 17; // Needs updating when there is a new skill. Only useful for new heroes.
uint256 constant MAX_UNIQUE_TICKETS = 64;
// Used in a bunch of places
uint256 constant IS_FULL_MODE_BIT = 7;
// Passive/Instant/InstantVRF/Actions/ActionChoices/Item action
uint256 constant IS_AVAILABLE_BIT = 6;
// Passive actions
uint256 constant HAS_RANDOM_REWARDS_BIT = 5;
// The rest use world location for first 4 bits
// Queued action
uint256 constant HAS_PET_BIT = 2;
uint256 constant IS_VALID_BIT = 1;
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {Skill} from "./misc.sol";
struct QuestInput {
uint16 dependentQuestId; // The quest that must be completed before this one can be started
uint16 actionId1; // action to do
uint16 actionNum1; // how many (up to 65535)
uint16 actionId2; // another action to do
uint16 actionNum2; // how many (up to 65535)
uint16 actionChoiceId; // actionChoice to perform
uint16 actionChoiceNum; // how many to do (base number), (up to 65535)
Skill skillReward; // The skill to reward XP to
uint24 skillXPGained; // The amount of XP to give (up to 65535)
uint16 rewardItemTokenId1; // Reward an item
uint16 rewardAmount1; // amount of the reward (up to 65535)
uint16 rewardItemTokenId2; // Reward another item
uint16 rewardAmount2; // amount of the reward (up to 65535)
uint16 burnItemTokenId; // Burn an item
uint16 burnAmount; // amount of the burn (up to 65535)
uint16 questId; // Unique id for this quest
bool isFullModeOnly; // If true this quest requires the user be evolved
uint8 worldLocation; // 0 is the main starting world
}
struct Quest {
uint16 dependentQuestId; // The quest that must be completed before this one can be started
uint16 actionId1; // action to do
uint16 actionNum1; // how many (up to 65535)
uint16 actionId2; // another action to do
uint16 actionNum2; // how many (up to 65535)
uint16 actionChoiceId; // actionChoice to perform
uint16 actionChoiceNum; // how many to do (base number), (up to 65535)
Skill skillReward; // The skill to reward XP to
uint24 skillXPGained; // The amount of XP to give (up to 65535)
uint16 rewardItemTokenId1; // Reward an item
uint16 rewardAmount1; // amount of the reward (up to 65535)
uint16 rewardItemTokenId2; // Reward another item
uint16 rewardAmount2; // amount of the reward (up to 65535)
uint16 burnItemTokenId; // Burn an item
uint16 burnAmount; // amount of the burn (up to 65535)
uint16 reserved; // Reserved for future use (previously was questId and cleared)
bytes1 packedData; // FullMode is last bit, first 6 bits is worldLocation
}
struct PlayerQuest {
uint32 questId;
uint16 actionCompletedNum1;
uint16 actionCompletedNum2;
uint16 actionChoiceCompletedNum;
uint16 burnCompletedAmount;
}
uint256 constant QUEST_PURSE_STRINGS = 5; // MAKE SURE THIS MATCHES definitions
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
import {BoostType, Equipment} from "./misc.sol";
struct GuaranteedReward {
uint16 itemTokenId;
uint16 rate; // num per hour (base 10, 1 decimal) for actions and num per duration for passive actions
}
struct RandomReward {
uint16 itemTokenId;
uint16 chance; // out of 65535
uint8 amount; // out of 255
}
struct PendingRandomReward {
uint16 actionId;
uint40 startTime;
uint24 xpElapsedTime;
uint16 boostItemTokenId;
uint24 elapsedTime;
uint40 boostStartTime; // When the boost was started
uint24 sentinelElapsedTime;
// Full equipment at the time this was generated
uint8 fullAttireBonusRewardsPercent;
uint64 queueId; // TODO: Could reduce this if more stuff is needed
}
struct ActionRewards {
uint16 guaranteedRewardTokenId1;
uint16 guaranteedRewardRate1; // Num per hour base 10 (1 decimal) for actions (Max 6553.5 per hour), num per duration for passive actions
uint16 guaranteedRewardTokenId2;
uint16 guaranteedRewardRate2;
uint16 guaranteedRewardTokenId3;
uint16 guaranteedRewardRate3;
// Random chance rewards
uint16 randomRewardTokenId1;
uint16 randomRewardChance1; // out of 65535
uint8 randomRewardAmount1; // out of 255
uint16 randomRewardTokenId2;
uint16 randomRewardChance2;
uint8 randomRewardAmount2;
uint16 randomRewardTokenId3;
uint16 randomRewardChance3;
uint8 randomRewardAmount3;
uint16 randomRewardTokenId4;
uint16 randomRewardChance4;
uint8 randomRewardAmount4;
// No more room in this storage slot!
}
struct XPThresholdReward {
uint32 xpThreshold;
Equipment[] rewards;
}
enum InstantVRFActionType {
NONE,
GENERIC,
FORGING,
EGG
}
struct InstantVRFActionInput {
uint16 actionId;
uint16[] inputTokenIds;
uint24[] inputAmounts;
bytes data;
InstantVRFActionType actionType;
bool isFullModeOnly;
bool isAvailable;
uint16 questPrerequisiteId;
}
struct InstantVRFRandomReward {
uint16 itemTokenId;
uint16 chance; // out of 65535
uint16 amount; // out of 65535
}
uint256 constant MAX_GUARANTEED_REWARDS_PER_ACTION = 3;
uint256 constant MAX_RANDOM_REWARDS_PER_ACTION = 4;
uint256 constant MAX_REWARDS_PER_ACTION = MAX_GUARANTEED_REWARDS_PER_ACTION + MAX_RANDOM_REWARDS_PER_ACTION;
uint256 constant MAX_CONSUMED_PER_ACTION = 3;
uint256 constant MAX_QUEST_REWARDS = 2;
uint256 constant TIER_1_DAILY_REWARD_START_XP = 0;
uint256 constant TIER_2_DAILY_REWARD_START_XP = 7_650;
uint256 constant TIER_3_DAILY_REWARD_START_XP = 33_913;
uint256 constant TIER_4_DAILY_REWARD_START_XP = 195_864;
uint256 constant TIER_5_DAILY_REWARD_START_XP = 784_726;
uint256 constant TIER_6_DAILY_REWARD_START_XP = 2_219_451;
// 4 bytes for each threshold, starts at 500 xp in decimal
bytes constant XP_THRESHOLD_REWARDS = hex"00000000000001F4000003E8000009C40000138800002710000075300000C350000186A00001D4C0000493E0000557300007A120000927C0000B71B0000DBBA0000F424000124F800016E360001B7740001E8480002625A0002932E0002DC6C0003567E0003D0900004C4B40005B8D80006ACFC0007A1200008954400098968000A7D8C000B71B0000C65D4000D59F8000E4E1C0";
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;
// solhint-disable-next-line no-global-import
import "./globals/players.sol";
// This file contains methods for interacting with the item NFT, used to decrease implementation deployment bytecode code.
library ItemNFTLibrary {
function setItem(ItemInput calldata inputItem, Item storage item) external {
bool hasCombat;
CombatStats calldata combatStats = inputItem.combatStats;
assembly ("memory-safe") {
hasCombat := not(iszero(combatStats))
}
item.equipPosition = inputItem.equipPosition;
item.isTransferable = inputItem.isTransferable;
bytes1 packedData = bytes1(uint8(0x1)); // Exists
packedData = packedData | bytes1(uint8(inputItem.isFullModeOnly ? 1 << IS_FULL_MODE_BIT : 0));
if (inputItem.isAvailable) {
packedData |= bytes1(uint8(1 << IS_AVAILABLE_BIT));
}
item.packedData = packedData;
item.questPrerequisiteId = inputItem.questPrerequisiteId;
if (hasCombat) {
// Combat stats
item.meleeAttack = inputItem.combatStats.meleeAttack;
item.rangedAttack = inputItem.combatStats.rangedAttack;
item.magicAttack = inputItem.combatStats.magicAttack;
item.meleeDefence = inputItem.combatStats.meleeDefence;
item.rangedDefence = inputItem.combatStats.rangedDefence;
item.magicDefence = inputItem.combatStats.magicDefence;
item.health = inputItem.combatStats.health;
}
if (inputItem.healthRestored != 0) {
item.healthRestored = inputItem.healthRestored;
}
if (inputItem.boostType != BoostType.NONE) {
item.boostType = inputItem.boostType;
item.boostValue = inputItem.boostValue;
item.boostDuration = inputItem.boostDuration;
}
item.minXP = inputItem.minXP;
item.skill = inputItem.skill;
}
}