Contract Name:
FARPG_QuestSystemV1
Contract Source Code:
File 1 of 1 : FARPG_QuestSystemV1
// File: @openzeppelin/[email protected]/utils/Context.sol
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)
pragma solidity ^0.8.0;
/**
* @dev Provides information about the current execution context, including the
* sender of the transaction and its data. While these are generally available
* via msg.sender and msg.data, they should not be accessed in such a direct
* manner, since when dealing with meta-transactions the account sending and
* paying for execution may not be the actual sender (as far as an application
* is concerned).
*
* This contract is only required for intermediate, library-like contracts.
*/
abstract contract Context {
function _msgSender() internal view virtual returns (address) {
return msg.sender;
}
function _msgData() internal view virtual returns (bytes calldata) {
return msg.data;
}
}
// File: @openzeppelin/[email protected]/access/Ownable.sol
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module which provides a basic access control mechanism, where
* there is an account (an owner) that can be granted exclusive access to
* specific functions.
*
* By default, the owner account will be the one that deploys the contract. This
* can later be changed with {transferOwnership}.
*
* This module is used through inheritance. It will make available the modifier
* `onlyOwner`, which can be applied to your functions to restrict their use to
* the owner.
*/
abstract contract Ownable is Context {
address private _owner;
event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);
/**
* @dev Initializes the contract setting the deployer as the initial owner.
*/
constructor() {
_transferOwnership(_msgSender());
}
/**
* @dev Throws if called by any account other than the owner.
*/
modifier onlyOwner() {
_checkOwner();
_;
}
/**
* @dev Returns the address of the current owner.
*/
function owner() public view virtual returns (address) {
return _owner;
}
/**
* @dev Throws if the sender is not the owner.
*/
function _checkOwner() internal view virtual {
require(owner() == _msgSender(), "Ownable: caller is not the owner");
}
/**
* @dev Leaves the contract without owner. It will not be possible to call
* `onlyOwner` functions anymore. Can only be called by the current owner.
*
* NOTE: Renouncing ownership will leave the contract without an owner,
* thereby removing any functionality that is only available to the owner.
*/
function renounceOwnership() public virtual onlyOwner {
_transferOwnership(address(0));
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Can only be called by the current owner.
*/
function transferOwnership(address newOwner) public virtual onlyOwner {
require(newOwner != address(0), "Ownable: new owner is the zero address");
_transferOwnership(newOwner);
}
/**
* @dev Transfers ownership of the contract to a new account (`newOwner`).
* Internal function without access restriction.
*/
function _transferOwnership(address newOwner) internal virtual {
address oldOwner = _owner;
_owner = newOwner;
emit OwnershipTransferred(oldOwner, newOwner);
}
}
// File: FINALdeployFA/LIB - Common Structs.sol
pragma solidity ^0.8.9;
library S {
//Pet struct
struct Unit {
uint hp; //unit fainted when hp <= 0
uint attack; //attack - defense = damage on hp
uint defense; //attack - defense = damage on hp
uint speed; //how frequent to take a move
uint intelligence; //how frequent to use skill
uint genestrength; //depends on how many duplicates
uint range; //range skill, id
uint special; //special skill, id
}
struct Status {
uint id; //unit id
uint family; //determine which class of gear it can be wore. record while evolve, since its only has max 2 family, example Dragon+phantom, and 30gene max, so can use *100
uint stage; //1 is rookie, 2 is mature, 3 is perfect
}
struct Time {
uint bond; //how many time you took on this unit , use to evolve
uint stamina; //how much you can train it per day. it should follow saturation graph
uint hunger; //how much you feed it per day. it should follow saturation graph
}
}
// File: FINALdeployFA/LIB - WeatherOutfit.sol
pragma solidity ^0.8.0;
library WO {
function WeatherBuff (S.Unit[6] memory _UnitGroup, uint _weather) external pure returns (S.Unit[6] memory UnitGroup) {
UnitGroup = _UnitGroup;
//--------weather system---------
// WARNING: Cannot have + stats, because empty slot still empty after multiply.
//enum Weather { Sunny, Cloudy, Rainy, Thunderstorm, Snowy, Aurora, BloodMoon, NONE } 0=Sunny and so on 7 or more = none
//0 Sunny day Fire ATK x2, Nature INTx2
//1 Cloudy day has nothing
//2 Rainy day, Water HPx1.5
//3 Thunderstorm day, Electric SPDx2
//4 Snowy day, Ice DEF x2
//5 Aurora day, Light speed x2
//6 Bloodmoon day, Dark HPx2
//****Lings with special type
//Fire = 3, 5, 10, 23, 28, 38, 39, 60, 63, 69, 81, 95
//Nature = 20, 21, 22, 24, 26, 29, 30, 42, 51, 72, 76, 80, 86, 96
//Water = 15, 17, 31, 35, 71, 75, 79, 98
//Electric = 2, 4, 27, 55, 57, 62, 73, 85, 87, 97
//Ice = 12, 14, 16, 25, 43, 46, 47, 61, 64, 82
//Dark = 8, 9, 11, 18, 32, 33, 36, 44, 54, 56, 58, 70, 74, 78, 84, 88
//Light = 6, 34, 40, 48, 77, 89, 99
for (uint i = 0; i < UnitGroup.length; i++) {
if (_weather == 0 && ( UnitGroup[i].special == 3 ||
UnitGroup[i].special == 5 ||
UnitGroup[i].special == 10 ||
UnitGroup[i].special == 23 ||
UnitGroup[i].special == 28 ||
UnitGroup[i].special == 38 ||
UnitGroup[i].special == 39 ||
UnitGroup[i].special == 60 ||
UnitGroup[i].special == 63 ||
UnitGroup[i].special == 69 ||
UnitGroup[i].special == 81 ||
UnitGroup[i].special == 95)) { //Fire
UnitGroup[i].attack = UnitGroup[i].attack*2;
} else if (_weather == 0 && ( UnitGroup[i].special == 20 ||
UnitGroup[i].special == 21 ||
UnitGroup[i].special == 22 ||
UnitGroup[i].special == 24 ||
UnitGroup[i].special == 26 ||
UnitGroup[i].special == 29 ||
UnitGroup[i].special == 30 ||
UnitGroup[i].special == 42 ||
UnitGroup[i].special == 51 ||
UnitGroup[i].special == 72 ||
UnitGroup[i].special == 76 ||
UnitGroup[i].special == 80 ||
UnitGroup[i].special == 86 ||
UnitGroup[i].special == 96)) { //Nature
UnitGroup[i].intelligence = UnitGroup[i].intelligence*2;
} else if (_weather == 2 && ( UnitGroup[i].special == 15 ||
UnitGroup[i].special == 17 ||
UnitGroup[i].special == 31 ||
UnitGroup[i].special == 35 ||
UnitGroup[i].special == 71 ||
UnitGroup[i].special == 75 ||
UnitGroup[i].special == 79 ||
UnitGroup[i].special == 98)) { //Water
UnitGroup[i].hp = (UnitGroup[i].hp*15)/10;
} else if (_weather == 3 && ( UnitGroup[i].special == 2 ||
UnitGroup[i].special == 4 ||
UnitGroup[i].special == 27 ||
UnitGroup[i].special == 55 ||
UnitGroup[i].special == 57 ||
UnitGroup[i].special == 62 ||
UnitGroup[i].special == 73 ||
UnitGroup[i].special == 85 ||
UnitGroup[i].special == 87 ||
UnitGroup[i].special == 97)) { //Electric
UnitGroup[i].speed = UnitGroup[i].speed*2;
} else if (_weather == 4 && ( UnitGroup[i].special == 12 ||
UnitGroup[i].special == 14 ||
UnitGroup[i].special == 16 ||
UnitGroup[i].special == 25 ||
UnitGroup[i].special == 43 ||
UnitGroup[i].special == 46 ||
UnitGroup[i].special == 47 ||
UnitGroup[i].special == 61 ||
UnitGroup[i].special == 64 ||
UnitGroup[i].special == 82)) { //Ice
UnitGroup[i].defense = UnitGroup[i].defense*2;
} else if (_weather == 6 && ( UnitGroup[i].special == 8 ||
UnitGroup[i].special == 9 ||
UnitGroup[i].special == 11 ||
UnitGroup[i].special == 18 ||
UnitGroup[i].special == 32 ||
UnitGroup[i].special == 33 ||
UnitGroup[i].special == 36 ||
UnitGroup[i].special == 44 ||
UnitGroup[i].special == 54 ||
UnitGroup[i].special == 56 ||
UnitGroup[i].special == 58 ||
UnitGroup[i].special == 70 ||
UnitGroup[i].special == 74 ||
UnitGroup[i].special == 78 ||
UnitGroup[i].special == 84 ||
UnitGroup[i].special == 88)) { //Dark
UnitGroup[i].hp = UnitGroup[i].hp*2;
} else if (_weather == 5 && ( UnitGroup[i].special == 6 ||
UnitGroup[i].special == 34 ||
UnitGroup[i].special == 40 ||
UnitGroup[i].special == 48 ||
UnitGroup[i].special == 77 ||
UnitGroup[i].special == 89 ||
UnitGroup[i].special == 99)) { //Light
UnitGroup[i].speed = UnitGroup[i].speed*2;
}
}
}
/* function calibrate() public returns (S.Unit[6] memory UnitGroup) {
S.Unit[6] memory _UnitGroup;
uint[5] memory _outfitsID; uint[5] memory _outfitBalance;
_outfitsID[0] = 3015;
_outfitsID[1] = 6020;
_outfitsID[2] = 1133;
_outfitsID[3] = 1140;
_outfitsID[4] = 1147;
_outfitBalance[0] = 1;
_outfitBalance[1] = 2;
_outfitBalance[2] = 3;
_outfitBalance[3] = 4;
_outfitBalance[4] = 5;
UnitGroup = TrainersOutfitBonus(_UnitGroup, _outfitsID,_outfitBalance);
}*/
function TrainersOutfitBonus (S.Unit[6] memory _UnitGroup, uint[5] memory _outfitsID, uint[5] memory _outfitBalance)
internal pure returns (S.Unit[6] memory UnitGroup) {
//_outfit[0~4] is outfit ID for the trainer ID. (what to wear) ID 0 means wearing nothing
//[0] = Aerobot [1] = headgear [2] = Body [3] = Leggings [4 = Boots
UnitGroup = _UnitGroup;
//convert Outfit balance into Multiplier
for (uint i=0; i<5; i++) {
if (_outfitBalance[i] >= 4096) {
_outfitBalance[i] = 5;
} else if (_outfitBalance[i] >= 512) {
_outfitBalance[i] = 4;
} else if (_outfitBalance[i] >= 64) {
_outfitBalance[i] = 3;
} else if (_outfitBalance[i] >= 8) {
_outfitBalance[i] = 2;
} else if (_outfitBalance[i] >= 1) {
_outfitBalance[i] = 1;
} //otherwise = 0, multiplier =0
}
S.Unit memory Bonus;
//Get Bonus from each outfit
//========== AEROBOT ======================
if (_outfitsID[0] == 3001) { //Bolt (Aerobot) //spd + 6
Bonus.speed += (6 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3002) { //Pixi (Aerobot) //atk + 6
Bonus.attack += (6 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3003) { //Finspark (Aerobot) //SPD + 10
Bonus.speed += (10 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3004) { //Cyanite //ATK + 10
Bonus.attack += (10 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3005) { //Daemon //all (20, 2, 2, 2, 1)
Bonus.hp += (20 * _outfitBalance[0]);
Bonus.attack += (2 * _outfitBalance[0]);
Bonus.defense += (2 * _outfitBalance[0]);
Bonus.speed += (2 * _outfitBalance[0]);
Bonus.intelligence += (1 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3006) { //Skye //Int +4
Bonus.intelligence += (4 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3007) { //Cocoon //int +3
Bonus.intelligence += (3 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3008) { //Orbitron //Spd +8
Bonus.speed += (8 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3009) { //Glide //Atk +8
Bonus.attack += (8 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3010) { //Bolt Mark II //Def + 8
Bonus.defense += (8 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3011) { //Lovey //Hp + 80
Bonus.hp += (80 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3012) { //Zetabot //hp + 60
Bonus.hp += (60 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3013) { //Roxie //def + 6
Bonus.defense += (6 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3014) { //Puzzle //INT + 5
Bonus.intelligence += (5 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3015) { //Aura //all (20, 2, 2, 2, 1)
Bonus.hp += (20 * _outfitBalance[0]);
Bonus.attack += (2 * _outfitBalance[0]);
Bonus.defense += (2 * _outfitBalance[0]);
Bonus.speed += (2 * _outfitBalance[0]);
Bonus.intelligence += (1 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3016) { //Goldon //DEF + 10
Bonus.defense += (10 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3017) { //Meteoron //HP + 100
Bonus.hp += (100 * _outfitBalance[0]);
}
//========== Headgear ======================
if (_outfitsID[1] == 6001) { //headgear 1 //hp+50
Bonus.hp += (50 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6002) { //headgear 2 //atk+3
Bonus.attack += (3 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6003) { //headgear 3 //def+3
Bonus.defense += (3 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6004) { //headgear 4 //spd+3
Bonus.speed += (3 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6005) { //headgear 5 //int+1
Bonus.intelligence += (1 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6006) { //headgear 6 //hp+60
Bonus.hp += (60 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6007) { //headgear 7 //atk+6
Bonus.attack += (6 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6008) { //headgear 8 //def+6
Bonus.defense += (6 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6009) { //headgear 9 //spd+6
Bonus.speed += (6 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6010) { //headgear 10 //int+3
Bonus.intelligence += (3 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6011) { //headgear 11 //hp+80
Bonus.hp += (80 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6012) { //headgear 12 //atk+8
Bonus.attack += (8 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6013) { //headgear 13 //def+8
Bonus.defense += (8 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6014) { //headgear 14 //spd+8
Bonus.speed += (8 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6015) { //headgear 15 //int+4
Bonus.intelligence += (4 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6016) { //headgear 16 //hp+100
Bonus.hp += (100 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6017) { //headgear 17 //atk+10
Bonus.attack += (10 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6018) { //headgear 18 //def+10
Bonus.defense += (10 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6019) { //headgear 19 //spd+10
Bonus.speed += (10 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6020) { //headgear 20 //int+5
Bonus.intelligence += (5 * _outfitBalance[1]);
}
//========== Body ======================
if (_outfitsID[2] == 1001) { //Scholar (Body) //hp 50
Bonus.hp += (50 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1002) { //Scholar (Body) //atk 3
Bonus.attack += (3 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1003) { //Scholar (Body) //def 3
Bonus.defense += (3 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1004) { //Scholar (Body) //spd 3
Bonus.speed += (3 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1005) { //Scholar (Body) //int 1
Bonus.intelligence += (1 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1006 || _outfitsID[2] == 1007) { //Scholar (Body) //all (10,1,1,1,1)
Bonus.hp += (10 * _outfitBalance[2]);
Bonus.attack += (1 * _outfitBalance[2]);
Bonus.defense += (1 * _outfitBalance[2]);
Bonus.speed += (1 * _outfitBalance[2]);
Bonus.intelligence += (1 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1022) { //Love Embrace (Body) //hp 60
Bonus.hp += (60 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1023) { //Love Embrace (Body) //atk 6
Bonus.attack += (6 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1024) { //Love Embrace (Body) //def 6
Bonus.defense += (6 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1025) { //Love Embrace (Body) //spd 6
Bonus.speed += (6 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1026) { //Love Embrace (Body) //int 3
Bonus.intelligence += (3 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1027 || _outfitsID[2] == 1028) { //Love Embrace (Body) //all (12,2,1,1,1)
Bonus.hp += (12 * _outfitBalance[2]);
Bonus.attack += (2 * _outfitBalance[2]);
Bonus.defense += (1 * _outfitBalance[2]);
Bonus.speed += (1 * _outfitBalance[2]);
Bonus.intelligence += (1 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1043) { //Celestial Harmony (Body) //hp 80
Bonus.hp += (80 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1044) { //Celestial Harmony (Body) //atk 8
Bonus.attack += (8 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1045) { //Celestial Harmony (Body) //def 8
Bonus.defense += (8 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1046) { //Celestial Harmony (Body) //spd 8
Bonus.speed += (8 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1047) { //Celestial Harmony (Body) //int 4
Bonus.intelligence += (4 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1048 || _outfitsID[2] == 1049) { //Celestial Harmony (Body) //all (16,2,2,1,1)
Bonus.hp += (16 * _outfitBalance[2]);
Bonus.attack += (2 * _outfitBalance[2]);
Bonus.defense += (2 * _outfitBalance[2]);
Bonus.speed += (1 * _outfitBalance[2]);
Bonus.intelligence += (1 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1064) { //Cyber Strike (Body) //hp 80
Bonus.hp += (80 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1065) { //Cyber Strike (Body) //atk 8
Bonus.attack += (8 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1066) { //Cyber Strike (Body) //def 8
Bonus.defense += (8 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1067) { //Cyber Strike (Body) //spd 8
Bonus.speed += (8 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1068) { //Cyber Strike (Body) //int 4
Bonus.intelligence += (4 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1069 || _outfitsID[2] == 1070) { //Cyber Strike (Body) //all (16,2,2,1,1)
Bonus.hp += (16 * _outfitBalance[2]);
Bonus.attack += (2 * _outfitBalance[2]);
Bonus.defense += (2 * _outfitBalance[2]);
Bonus.speed += (1 * _outfitBalance[2]);
Bonus.intelligence += (1 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1085) { //Serpent Tribe (Body) //hp 50
Bonus.hp += (50 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1086) { //Serpent Tribe (Body) //atk 3
Bonus.attack += (3 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1087) { //Serpent Tribe (Body) //def 3
Bonus.defense += (3 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1088) { //Serpent Tribe (Body) //spd 3
Bonus.speed += (3 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1089) { //Serpent Tribe (Body) //int 1
Bonus.intelligence += (1 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1090 || _outfitsID[2] == 1091) { //Serpent Tribe (Body) //all (10,1,1,1,1)
Bonus.hp += (10 * _outfitBalance[2]);
Bonus.attack += (1 * _outfitBalance[2]);
Bonus.defense += (1 * _outfitBalance[2]);
Bonus.speed += (1 * _outfitBalance[2]);
Bonus.intelligence += (1 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1106) { //Pearl Empress (Body) //hp 60
Bonus.hp += (60 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1107) { //Pearl Empress (Body) //atk 6
Bonus.attack += (6 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1108) { //Pearl Empress (Body) //def 6
Bonus.defense += (6 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1109) { //Pearl Empress (Body) //spd 6
Bonus.speed += (6 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1110) { //Pearl Empress (Body) //int 3
Bonus.intelligence += (3 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1111 || _outfitsID[2] == 1112) { //Pearl Empress (Body) //all (12,2,1,1,1)
Bonus.hp += (12 * _outfitBalance[2]);
Bonus.attack += (2 * _outfitBalance[2]);
Bonus.defense += (1 * _outfitBalance[2]);
Bonus.speed += (1 * _outfitBalance[2]);
Bonus.intelligence += (1 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1127) { //Starlight Diva (Body) //hp 100
Bonus.hp += (100 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1128) { //Starlight Diva (Body) //atk 10
Bonus.attack += (10 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1129) { //Starlight Diva (Body) //def 10
Bonus.defense += (10 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1130) { //Starlight Diva (Body) //spd 10
Bonus.speed += (10 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1131) { //Starlight Diva (Body) //int 5
Bonus.intelligence += (5 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1132 || _outfitsID[2] == 1133) { //Starlight Diva (Body) //all (20,2,2,2,1)
Bonus.hp += (20 * _outfitBalance[2]);
Bonus.attack += (2 * _outfitBalance[2]);
Bonus.defense += (2 * _outfitBalance[2]);
Bonus.speed += (2 * _outfitBalance[2]);
Bonus.intelligence += (1 * _outfitBalance[2]);
}
//========== Leggings======================
if (_outfitsID[3] == 1008) { //Scholar (Leggings) //hp 50
Bonus.hp += (50 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1009) { //Scholar (Leggings) //atk 3
Bonus.attack += (3 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1010) { //Scholar (Leggings) //def 3
Bonus.defense += (3 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1011) { //Scholar (Leggings) //spd 3
Bonus.speed += (3 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1012) { //Scholar (Leggings) //int 1
Bonus.intelligence += (1 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1013 || _outfitsID[3] == 1014) { //Scholar (Leggings) //all (10,1,1,1,1)
Bonus.hp += (10 * _outfitBalance[3]);
Bonus.attack += (1 * _outfitBalance[3]);
Bonus.defense += (1 * _outfitBalance[3]);
Bonus.speed += (1 * _outfitBalance[3]);
Bonus.intelligence += (1 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1029) { //Love Embrace (Leggings) //hp 60
Bonus.hp += (60 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1030) { //Love Embrace (Leggings) //atk 6
Bonus.attack += (6 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1031) { //Love Embrace (Leggings) //def 6
Bonus.defense += (6 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1032) { //Love Embrace (Leggings) //spd 6
Bonus.speed += (6 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1033) { //Love Embrace (Leggings) //int 3
Bonus.intelligence += (3 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1034 || _outfitsID[3] == 1035) { //Love Embrace (Leggings) //all (12,2,1,1,1)
Bonus.hp += (12 * _outfitBalance[3]);
Bonus.attack += (2 * _outfitBalance[3]);
Bonus.defense += (1 * _outfitBalance[3]);
Bonus.speed += (1 * _outfitBalance[3]);
Bonus.intelligence += (1 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1050) { //Celestial Harmony (Leggings) //hp 80
Bonus.hp += (80 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1051) { //Celestial Harmony (Leggings) //atk 8
Bonus.attack += (8 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1052) { //Celestial Harmony (Leggings) //def 8
Bonus.defense += (8 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1053) { //Celestial Harmony (Leggings) //spd 8
Bonus.speed += (8 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1054) { //Celestial Harmony (Leggings) //int 4
Bonus.intelligence += (4 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1055 || _outfitsID[3] == 1056) { //Celestial Harmony (Leggings) //all (16,2,2,1,1)
Bonus.hp += (16 * _outfitBalance[3]);
Bonus.attack += (2 * _outfitBalance[3]);
Bonus.defense += (2 * _outfitBalance[3]);
Bonus.speed += (1 * _outfitBalance[3]);
Bonus.intelligence += (1 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1071) { //Cyber Strike (Leggings) //hp 80
Bonus.hp += (80 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1072) { //Cyber Strike (Leggings) //atk 8
Bonus.attack += (8 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1073) { //Cyber Strike (Leggings) //def 8
Bonus.defense += (8 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1074) { //Cyber Strike (Leggings) //spd 8
Bonus.speed += (8 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1075) { //Cyber Strike (Leggings) //int 4
Bonus.intelligence += (4 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1076 || _outfitsID[3] == 1077) { //Cyber Strike (Leggings) //all (16,2,2,1,1)
Bonus.hp += (16 * _outfitBalance[3]);
Bonus.attack += (2 * _outfitBalance[3]);
Bonus.defense += (2 * _outfitBalance[3]);
Bonus.speed += (1 * _outfitBalance[3]);
Bonus.intelligence += (1 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1092) { //Serpent Tribe (Leggings) //hp 50
Bonus.hp += (50 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1093) { //Serpent Tribe (Leggings) //atk 3
Bonus.attack += (3 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1094) { //Serpent Tribe (Leggings) //def 3
Bonus.defense += (3 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1095) { //Serpent Tribe (Leggings) //spd 3
Bonus.speed += (3 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1096) { //Serpent Tribe (Leggings) //int 1
Bonus.intelligence += (1 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1097 || _outfitsID[3] == 1098) { //Serpent Tribe (Leggings) //all (10,1,1,1,1)
Bonus.hp += (10 * _outfitBalance[3]);
Bonus.attack += (1 * _outfitBalance[3]);
Bonus.defense += (1 * _outfitBalance[3]);
Bonus.speed += (1 * _outfitBalance[3]);
Bonus.intelligence += (1 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1113) { //Pearl Empress (Leggings) //hp 60
Bonus.hp += (60 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1114) { //Pearl Empress (Leggings) //atk 6
Bonus.attack += (6 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1115) { //Pearl Empress (Leggings) //def 6
Bonus.defense += (6 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1116) { //Pearl Empress (Leggings) //spd 6
Bonus.speed += (6 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1117) { //Pearl Empress (Leggings) //int 3
Bonus.intelligence += (3 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1118 || _outfitsID[3] == 1119) { //Pearl Empress (Leggings) //all (12,2,1,1,1)
Bonus.hp += (12 * _outfitBalance[3]);
Bonus.attack += (2 * _outfitBalance[3]);
Bonus.defense += (1 * _outfitBalance[3]);
Bonus.speed += (1 * _outfitBalance[3]);
Bonus.intelligence += (1 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1134) { //Starlight Diva (Leggings) //hp 100
Bonus.hp += (100 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1135) { //Starlight Diva (Leggings) //atk 10
Bonus.attack += (10 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1136) { //Starlight Diva (Leggings) //def 10
Bonus.defense += (10 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1137) { //Starlight Diva (Leggings) //spd 10
Bonus.speed += (10 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1138) { //Starlight Diva (Leggings) //int 5
Bonus.intelligence += (5 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1139 || _outfitsID[3] == 1140) { //Starlight Diva (Leggings) //all (20,2,2,2,1)
Bonus.hp += (20 * _outfitBalance[3]);
Bonus.attack += (2 * _outfitBalance[3]);
Bonus.defense += (2 * _outfitBalance[3]);
Bonus.speed += (2 * _outfitBalance[3]);
Bonus.intelligence += (1 * _outfitBalance[3]);
}
//========== Boots======================
if (_outfitsID[4] == 1015) { //Scholar (Boots) //hp 50
Bonus.hp += (50 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1016) { //Scholar (Boots) //atk 3
Bonus.attack += (3 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1017) { //Scholar (Boots) //def 3
Bonus.defense += (3 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1018) { //Scholar (Boots) //spd 3
Bonus.speed += (3 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1019) { //Scholar (Boots) //int 1
Bonus.intelligence += (1 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1020 || _outfitsID[4] == 1021) { //Scholar (Boots) //all (10,1,1,1,1)
Bonus.hp += (10 * _outfitBalance[4]);
Bonus.attack += (1 * _outfitBalance[4]);
Bonus.defense += (1 * _outfitBalance[4]);
Bonus.speed += (1 * _outfitBalance[4]);
Bonus.intelligence += (1 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1036) { //Love Embrace (Boots) //hp 60
Bonus.hp += (60 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1037) { //Love Embrace (Boots) //atk 6
Bonus.attack += (6 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1038) { //Love Embrace (Boots) //def 6
Bonus.defense += (6 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1039) { //Love Embrace (Boots) //spd 6
Bonus.speed += (6 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1040) { //Love Embrace (Boots) //int 3
Bonus.intelligence += (3 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1041 || _outfitsID[4] == 1042) { //Love Embrace (Boots) //all (12,2,1,1,1)
Bonus.hp += (12 * _outfitBalance[4]);
Bonus.attack += (2 * _outfitBalance[4]);
Bonus.defense += (1 * _outfitBalance[4]);
Bonus.speed += (1 * _outfitBalance[4]);
Bonus.intelligence += (1 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1057) { //Celestial Harmony (Boots) //hp 80
Bonus.hp += (80 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1058) { //Celestial Harmony (Boots) //atk 8
Bonus.attack += (8 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1059) { //Celestial Harmony (Boots) //def 8
Bonus.defense += (8 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1060) { //Celestial Harmony (Boots) //spd 8
Bonus.speed += (8 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1061) { //Celestial Harmony (Boots) //int 4
Bonus.intelligence += (4 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1062 || _outfitsID[4] == 1063) { //Celestial Harmony (Boots) //all (16,2,2,1,1)
Bonus.hp += (16 * _outfitBalance[4]);
Bonus.attack += (2 * _outfitBalance[4]);
Bonus.defense += (2 * _outfitBalance[4]);
Bonus.speed += (1 * _outfitBalance[4]);
Bonus.intelligence += (1 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1078) { //Cyber Strike (Boots) //hp 80
Bonus.hp += (80 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1079) { //Cyber Strike (Boots) //atk 8
Bonus.attack += (8 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1080) { //Cyber Strike (Boots) //def 8
Bonus.defense += (8 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1081) { //Cyber Strike (Boots) //spd 8
Bonus.speed += (8 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1082) { //Cyber Strike (Boots) //int 4
Bonus.intelligence += (4 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1083 || _outfitsID[4] == 1084) { //Cyber Strike (Boots) //all (16,2,2,1,1)
Bonus.hp += (16 * _outfitBalance[4]);
Bonus.attack += (2 * _outfitBalance[4]);
Bonus.defense += (2 * _outfitBalance[4]);
Bonus.speed += (1 * _outfitBalance[4]);
Bonus.intelligence += (1 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1099) { //Serpent Tribe (Boots) //hp 50
Bonus.hp += (50 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1100) { //Serpent Tribe (Boots) //atk 3
Bonus.attack += (3 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1101) { //Serpent Tribe (Boots) //def 3
Bonus.defense += (3 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1102) { //Serpent Tribe (Boots) //spd 3
Bonus.speed += (3 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1103) { //Serpent Tribe (Boots) //int 1
Bonus.intelligence += (1 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1104 || _outfitsID[4] == 1105) { //Serpent Tribe (Boots) //all (10,1,1,1,1)
Bonus.hp += (10 * _outfitBalance[4]);
Bonus.attack += (1 * _outfitBalance[4]);
Bonus.defense += (1 * _outfitBalance[4]);
Bonus.speed += (1 * _outfitBalance[4]);
Bonus.intelligence += (1 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1120) { //Pearl Empress (Boots) //hp 60
Bonus.hp += (60 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1121) { //Pearl Empress (Boots) //atk 6
Bonus.attack += (6 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1122) { //Pearl Empress (Boots) //def 6
Bonus.defense += (6 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1123) { //Pearl Empress (Boots) //spd 6
Bonus.speed += (6 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1124) { //Pearl Empress (Boots) //int 3
Bonus.intelligence += (3 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1125 || _outfitsID[4] == 1126) { //Pearl Empress (Boots) //all (12,2,1,1,1)
Bonus.hp += (12 * _outfitBalance[4]);
Bonus.attack += (2 * _outfitBalance[4]);
Bonus.defense += (1 * _outfitBalance[4]);
Bonus.speed += (1 * _outfitBalance[4]);
Bonus.intelligence += (1 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1141) { //Starlight Diva (Boots) //hp 100
Bonus.hp += (100 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1142) { //Starlight Diva (Boots) //atk 10
Bonus.attack += (10 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1143) { //Starlight Diva (Boots) //def 10
Bonus.defense += (10 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1144) { //Starlight Diva (Boots) //spd 10
Bonus.speed += (10 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1145) { //Starlight Diva (Boots) //int 5
Bonus.intelligence += (5 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1146 || _outfitsID[4] == 1147) { //Starlight Diva (Boots) //all (20,2,2,2,1)
Bonus.hp += (20 * _outfitBalance[4]);
Bonus.attack += (2 * _outfitBalance[4]);
Bonus.defense += (2 * _outfitBalance[4]);
Bonus.speed += (2 * _outfitBalance[4]);
Bonus.intelligence += (1 * _outfitBalance[4]);
}
for (uint i=0; i<3; i++) {
if (UnitGroup[i].hp >0 ) { //not empty slot
UnitGroup[i].hp = _UnitGroup[i].hp += Bonus.hp;
UnitGroup[i].attack = _UnitGroup[i].attack += Bonus.attack;
UnitGroup[i].defense = _UnitGroup[i].defense += Bonus.defense;
UnitGroup[i].speed = _UnitGroup[i].speed += Bonus.speed;
UnitGroup[i].intelligence = _UnitGroup[i].intelligence += Bonus.intelligence;
}
}
}
function readOutfitBonus (uint[5] memory _outfitsID, uint[5] memory _outfitBalance)
internal pure returns (S.Unit memory Bonus) {
//_outfit[0~4] is outfit ID for the trainer ID. (what to wear) ID 0 means wearing nothing
//[0] = Aerobot [1] = headgear [2] = Body [3] = Leggings [4 = Boots
//convert Outfit balance into Multiplier
for (uint i=0; i<5; i++) {
if (_outfitBalance[i] >= 4096) {
_outfitBalance[i] = 5;
} else if (_outfitBalance[i] >= 512) {
_outfitBalance[i] = 4;
} else if (_outfitBalance[i] >= 64) {
_outfitBalance[i] = 3;
} else if (_outfitBalance[i] >= 8) {
_outfitBalance[i] = 2;
} else if (_outfitBalance[i] >= 1) {
_outfitBalance[i] = 1;
} //otherwise = 0, multiplier =0
}
//Get Bonus from each outfit
//========== AEROBOT ======================
if (_outfitsID[0] == 3001) { //Bolt (Aerobot) //spd + 6
Bonus.speed += (6 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3002) { //Pixi (Aerobot) //atk + 6
Bonus.attack += (6 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3003) { //Finspark (Aerobot) //SPD + 10
Bonus.speed += (10 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3004) { //Cyanite //ATK + 10
Bonus.attack += (10 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3005) { //Daemon //all (20, 2, 2, 2, 1)
Bonus.hp += (20 * _outfitBalance[0]);
Bonus.attack += (2 * _outfitBalance[0]);
Bonus.defense += (2 * _outfitBalance[0]);
Bonus.speed += (2 * _outfitBalance[0]);
Bonus.intelligence += (1 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3006) { //Skye //Int +4
Bonus.intelligence += (4 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3007) { //Cocoon //int +3
Bonus.intelligence += (3 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3008) { //Orbitron //Spd +8
Bonus.speed += (8 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3009) { //Glide //Atk +8
Bonus.attack += (8 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3010) { //Bolt Mark II //Def + 8
Bonus.defense += (8 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3011) { //Lovey //Hp + 80
Bonus.hp += (80 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3012) { //Zetabot //hp + 60
Bonus.hp += (60 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3013) { //Roxie //def + 6
Bonus.defense += (6 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3014) { //Puzzle //INT + 5
Bonus.intelligence += (5 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3015) { //Aura //all (20, 2, 2, 2, 1)
Bonus.hp += (20 * _outfitBalance[0]);
Bonus.attack += (2 * _outfitBalance[0]);
Bonus.defense += (2 * _outfitBalance[0]);
Bonus.speed += (2 * _outfitBalance[0]);
Bonus.intelligence += (1 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3016) { //Goldon //DEF + 10
Bonus.defense += (10 * _outfitBalance[0]);
} else if (_outfitsID[0] == 3017) { //Meteoron //HP + 100
Bonus.hp += (100 * _outfitBalance[0]);
}
//========== Headgear ======================
if (_outfitsID[1] == 6001) { //headgear 1 //hp+50
Bonus.hp += (50 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6002) { //headgear 2 //atk+3
Bonus.attack += (3 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6003) { //headgear 3 //def+3
Bonus.defense += (3 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6004) { //headgear 4 //spd+3
Bonus.speed += (3 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6005) { //headgear 5 //int+1
Bonus.intelligence += (1 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6006) { //headgear 6 //hp+60
Bonus.hp += (60 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6007) { //headgear 7 //atk+6
Bonus.attack += (6 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6008) { //headgear 8 //def+6
Bonus.defense += (6 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6009) { //headgear 9 //spd+6
Bonus.speed += (6 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6010) { //headgear 10 //int+3
Bonus.intelligence += (3 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6011) { //headgear 11 //hp+80
Bonus.hp += (80 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6012) { //headgear 12 //atk+8
Bonus.attack += (8 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6013) { //headgear 13 //def+8
Bonus.defense += (8 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6014) { //headgear 14 //spd+8
Bonus.speed += (8 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6015) { //headgear 15 //int+4
Bonus.intelligence += (4 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6016) { //headgear 16 //hp+100
Bonus.hp += (100 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6017) { //headgear 17 //atk+10
Bonus.attack += (10 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6018) { //headgear 18 //def+10
Bonus.defense += (10 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6019) { //headgear 19 //spd+10
Bonus.speed += (10 * _outfitBalance[1]);
} else if (_outfitsID[1] == 6020) { //headgear 20 //int+5
Bonus.intelligence += (5 * _outfitBalance[1]);
}
//========== Body ======================
if (_outfitsID[2] == 1001) { //Scholar (Body) //hp 50
Bonus.hp += (50 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1002) { //Scholar (Body) //atk 3
Bonus.attack += (3 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1003) { //Scholar (Body) //def 3
Bonus.defense += (3 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1004) { //Scholar (Body) //spd 3
Bonus.speed += (3 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1005) { //Scholar (Body) //int 1
Bonus.intelligence += (1 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1006 || _outfitsID[2] == 1007) { //Scholar (Body) //all (10,1,1,1,1)
Bonus.hp += (10 * _outfitBalance[2]);
Bonus.attack += (1 * _outfitBalance[2]);
Bonus.defense += (1 * _outfitBalance[2]);
Bonus.speed += (1 * _outfitBalance[2]);
Bonus.intelligence += (1 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1022) { //Love Embrace (Body) //hp 60
Bonus.hp += (60 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1023) { //Love Embrace (Body) //atk 6
Bonus.attack += (6 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1024) { //Love Embrace (Body) //def 6
Bonus.defense += (6 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1025) { //Love Embrace (Body) //spd 6
Bonus.speed += (6 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1026) { //Love Embrace (Body) //int 3
Bonus.intelligence += (3 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1027 || _outfitsID[2] == 1028) { //Love Embrace (Body) //all (12,2,1,1,1)
Bonus.hp += (12 * _outfitBalance[2]);
Bonus.attack += (2 * _outfitBalance[2]);
Bonus.defense += (1 * _outfitBalance[2]);
Bonus.speed += (1 * _outfitBalance[2]);
Bonus.intelligence += (1 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1043) { //Celestial Harmony (Body) //hp 80
Bonus.hp += (80 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1044) { //Celestial Harmony (Body) //atk 8
Bonus.attack += (8 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1045) { //Celestial Harmony (Body) //def 8
Bonus.defense += (8 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1046) { //Celestial Harmony (Body) //spd 8
Bonus.speed += (8 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1047) { //Celestial Harmony (Body) //int 4
Bonus.intelligence += (4 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1048 || _outfitsID[2] == 1049) { //Celestial Harmony (Body) //all (16,2,2,1,1)
Bonus.hp += (16 * _outfitBalance[2]);
Bonus.attack += (2 * _outfitBalance[2]);
Bonus.defense += (2 * _outfitBalance[2]);
Bonus.speed += (1 * _outfitBalance[2]);
Bonus.intelligence += (1 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1064) { //Cyber Strike (Body) //hp 80
Bonus.hp += (80 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1065) { //Cyber Strike (Body) //atk 8
Bonus.attack += (8 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1066) { //Cyber Strike (Body) //def 8
Bonus.defense += (8 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1067) { //Cyber Strike (Body) //spd 8
Bonus.speed += (8 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1068) { //Cyber Strike (Body) //int 4
Bonus.intelligence += (4 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1069 || _outfitsID[2] == 1070) { //Cyber Strike (Body) //all (16,2,2,1,1)
Bonus.hp += (16 * _outfitBalance[2]);
Bonus.attack += (2 * _outfitBalance[2]);
Bonus.defense += (2 * _outfitBalance[2]);
Bonus.speed += (1 * _outfitBalance[2]);
Bonus.intelligence += (1 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1085) { //Serpent Tribe (Body) //hp 50
Bonus.hp += (50 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1086) { //Serpent Tribe (Body) //atk 3
Bonus.attack += (3 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1087) { //Serpent Tribe (Body) //def 3
Bonus.defense += (3 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1088) { //Serpent Tribe (Body) //spd 3
Bonus.speed += (3 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1089) { //Serpent Tribe (Body) //int 1
Bonus.intelligence += (1 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1090 || _outfitsID[2] == 1091) { //Serpent Tribe (Body) //all (10,1,1,1,1)
Bonus.hp += (10 * _outfitBalance[2]);
Bonus.attack += (1 * _outfitBalance[2]);
Bonus.defense += (1 * _outfitBalance[2]);
Bonus.speed += (1 * _outfitBalance[2]);
Bonus.intelligence += (1 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1106) { //Pearl Empress (Body) //hp 60
Bonus.hp += (60 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1107) { //Pearl Empress (Body) //atk 6
Bonus.attack += (6 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1108) { //Pearl Empress (Body) //def 6
Bonus.defense += (6 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1109) { //Pearl Empress (Body) //spd 6
Bonus.speed += (6 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1110) { //Pearl Empress (Body) //int 3
Bonus.intelligence += (3 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1111 || _outfitsID[2] == 1112) { //Pearl Empress (Body) //all (12,2,1,1,1)
Bonus.hp += (12 * _outfitBalance[2]);
Bonus.attack += (2 * _outfitBalance[2]);
Bonus.defense += (1 * _outfitBalance[2]);
Bonus.speed += (1 * _outfitBalance[2]);
Bonus.intelligence += (1 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1127) { //Starlight Diva (Body) //hp 100
Bonus.hp += (100 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1128) { //Starlight Diva (Body) //atk 10
Bonus.attack += (10 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1129) { //Starlight Diva (Body) //def 10
Bonus.defense += (10 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1130) { //Starlight Diva (Body) //spd 10
Bonus.speed += (10 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1131) { //Starlight Diva (Body) //int 5
Bonus.intelligence += (5 * _outfitBalance[2]);
} else if (_outfitsID[2] == 1132 || _outfitsID[2] == 1133) { //Starlight Diva (Body) //all (20,2,2,2,1)
Bonus.hp += (20 * _outfitBalance[2]);
Bonus.attack += (2 * _outfitBalance[2]);
Bonus.defense += (2 * _outfitBalance[2]);
Bonus.speed += (2 * _outfitBalance[2]);
Bonus.intelligence += (1 * _outfitBalance[2]);
}
//========== Leggings======================
if (_outfitsID[3] == 1008) { //Scholar (Leggings) //hp 50
Bonus.hp += (50 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1009) { //Scholar (Leggings) //atk 3
Bonus.attack += (3 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1010) { //Scholar (Leggings) //def 3
Bonus.defense += (3 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1011) { //Scholar (Leggings) //spd 3
Bonus.speed += (3 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1012) { //Scholar (Leggings) //int 1
Bonus.intelligence += (1 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1013 || _outfitsID[3] == 1014) { //Scholar (Leggings) //all (10,1,1,1,1)
Bonus.hp += (10 * _outfitBalance[3]);
Bonus.attack += (1 * _outfitBalance[3]);
Bonus.defense += (1 * _outfitBalance[3]);
Bonus.speed += (1 * _outfitBalance[3]);
Bonus.intelligence += (1 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1029) { //Love Embrace (Leggings) //hp 60
Bonus.hp += (60 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1030) { //Love Embrace (Leggings) //atk 6
Bonus.attack += (6 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1031) { //Love Embrace (Leggings) //def 6
Bonus.defense += (6 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1032) { //Love Embrace (Leggings) //spd 6
Bonus.speed += (6 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1033) { //Love Embrace (Leggings) //int 3
Bonus.intelligence += (3 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1034 || _outfitsID[3] == 1035) { //Love Embrace (Leggings) //all (12,2,1,1,1)
Bonus.hp += (12 * _outfitBalance[3]);
Bonus.attack += (2 * _outfitBalance[3]);
Bonus.defense += (1 * _outfitBalance[3]);
Bonus.speed += (1 * _outfitBalance[3]);
Bonus.intelligence += (1 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1050) { //Celestial Harmony (Leggings) //hp 80
Bonus.hp += (80 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1051) { //Celestial Harmony (Leggings) //atk 8
Bonus.attack += (8 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1052) { //Celestial Harmony (Leggings) //def 8
Bonus.defense += (8 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1053) { //Celestial Harmony (Leggings) //spd 8
Bonus.speed += (8 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1054) { //Celestial Harmony (Leggings) //int 4
Bonus.intelligence += (4 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1055 || _outfitsID[3] == 1056) { //Celestial Harmony (Leggings) //all (16,2,2,1,1)
Bonus.hp += (16 * _outfitBalance[3]);
Bonus.attack += (2 * _outfitBalance[3]);
Bonus.defense += (2 * _outfitBalance[3]);
Bonus.speed += (1 * _outfitBalance[3]);
Bonus.intelligence += (1 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1071) { //Cyber Strike (Leggings) //hp 80
Bonus.hp += (80 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1072) { //Cyber Strike (Leggings) //atk 8
Bonus.attack += (8 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1073) { //Cyber Strike (Leggings) //def 8
Bonus.defense += (8 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1074) { //Cyber Strike (Leggings) //spd 8
Bonus.speed += (8 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1075) { //Cyber Strike (Leggings) //int 4
Bonus.intelligence += (4 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1076 || _outfitsID[3] == 1077) { //Cyber Strike (Leggings) //all (16,2,2,1,1)
Bonus.hp += (16 * _outfitBalance[3]);
Bonus.attack += (2 * _outfitBalance[3]);
Bonus.defense += (2 * _outfitBalance[3]);
Bonus.speed += (1 * _outfitBalance[3]);
Bonus.intelligence += (1 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1092) { //Serpent Tribe (Leggings) //hp 50
Bonus.hp += (50 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1093) { //Serpent Tribe (Leggings) //atk 3
Bonus.attack += (3 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1094) { //Serpent Tribe (Leggings) //def 3
Bonus.defense += (3 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1095) { //Serpent Tribe (Leggings) //spd 3
Bonus.speed += (3 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1096) { //Serpent Tribe (Leggings) //int 1
Bonus.intelligence += (1 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1097 || _outfitsID[3] == 1098) { //Serpent Tribe (Leggings) //all (10,1,1,1,1)
Bonus.hp += (10 * _outfitBalance[3]);
Bonus.attack += (1 * _outfitBalance[3]);
Bonus.defense += (1 * _outfitBalance[3]);
Bonus.speed += (1 * _outfitBalance[3]);
Bonus.intelligence += (1 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1113) { //Pearl Empress (Leggings) //hp 60
Bonus.hp += (60 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1114) { //Pearl Empress (Leggings) //atk 6
Bonus.attack += (6 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1115) { //Pearl Empress (Leggings) //def 6
Bonus.defense += (6 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1116) { //Pearl Empress (Leggings) //spd 6
Bonus.speed += (6 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1117) { //Pearl Empress (Leggings) //int 3
Bonus.intelligence += (3 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1118 || _outfitsID[3] == 1119) { //Pearl Empress (Leggings) //all (12,2,1,1,1)
Bonus.hp += (12 * _outfitBalance[3]);
Bonus.attack += (2 * _outfitBalance[3]);
Bonus.defense += (1 * _outfitBalance[3]);
Bonus.speed += (1 * _outfitBalance[3]);
Bonus.intelligence += (1 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1134) { //Starlight Diva (Leggings) //hp 100
Bonus.hp += (100 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1135) { //Starlight Diva (Leggings) //atk 10
Bonus.attack += (10 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1136) { //Starlight Diva (Leggings) //def 10
Bonus.defense += (10 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1137) { //Starlight Diva (Leggings) //spd 10
Bonus.speed += (10 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1138) { //Starlight Diva (Leggings) //int 5
Bonus.intelligence += (5 * _outfitBalance[3]);
} else if (_outfitsID[3] == 1139 || _outfitsID[3] == 1140) { //Starlight Diva (Leggings) //all (20,2,2,2,1)
Bonus.hp += (20 * _outfitBalance[3]);
Bonus.attack += (2 * _outfitBalance[3]);
Bonus.defense += (2 * _outfitBalance[3]);
Bonus.speed += (2 * _outfitBalance[3]);
Bonus.intelligence += (1 * _outfitBalance[3]);
}
//========== Boots======================
if (_outfitsID[4] == 1015) { //Scholar (Boots) //hp 50
Bonus.hp += (50 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1016) { //Scholar (Boots) //atk 3
Bonus.attack += (3 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1017) { //Scholar (Boots) //def 3
Bonus.defense += (3 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1018) { //Scholar (Boots) //spd 3
Bonus.speed += (3 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1019) { //Scholar (Boots) //int 1
Bonus.intelligence += (1 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1020 || _outfitsID[4] == 1021) { //Scholar (Boots) //all (10,1,1,1,1)
Bonus.hp += (10 * _outfitBalance[4]);
Bonus.attack += (1 * _outfitBalance[4]);
Bonus.defense += (1 * _outfitBalance[4]);
Bonus.speed += (1 * _outfitBalance[4]);
Bonus.intelligence += (1 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1036) { //Love Embrace (Boots) //hp 60
Bonus.hp += (60 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1037) { //Love Embrace (Boots) //atk 6
Bonus.attack += (6 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1038) { //Love Embrace (Boots) //def 6
Bonus.defense += (6 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1039) { //Love Embrace (Boots) //spd 6
Bonus.speed += (6 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1040) { //Love Embrace (Boots) //int 3
Bonus.intelligence += (3 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1041 || _outfitsID[4] == 1042) { //Love Embrace (Boots) //all (12,2,1,1,1)
Bonus.hp += (12 * _outfitBalance[4]);
Bonus.attack += (2 * _outfitBalance[4]);
Bonus.defense += (1 * _outfitBalance[4]);
Bonus.speed += (1 * _outfitBalance[4]);
Bonus.intelligence += (1 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1057) { //Celestial Harmony (Boots) //hp 80
Bonus.hp += (80 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1058) { //Celestial Harmony (Boots) //atk 8
Bonus.attack += (8 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1059) { //Celestial Harmony (Boots) //def 8
Bonus.defense += (8 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1060) { //Celestial Harmony (Boots) //spd 8
Bonus.speed += (8 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1061) { //Celestial Harmony (Boots) //int 4
Bonus.intelligence += (4 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1062 || _outfitsID[4] == 1063) { //Celestial Harmony (Boots) //all (16,2,2,1,1)
Bonus.hp += (16 * _outfitBalance[4]);
Bonus.attack += (2 * _outfitBalance[4]);
Bonus.defense += (2 * _outfitBalance[4]);
Bonus.speed += (1 * _outfitBalance[4]);
Bonus.intelligence += (1 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1078) { //Cyber Strike (Boots) //hp 80
Bonus.hp += (80 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1079) { //Cyber Strike (Boots) //atk 8
Bonus.attack += (8 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1080) { //Cyber Strike (Boots) //def 8
Bonus.defense += (8 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1081) { //Cyber Strike (Boots) //spd 8
Bonus.speed += (8 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1082) { //Cyber Strike (Boots) //int 4
Bonus.intelligence += (4 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1083 || _outfitsID[4] == 1084) { //Cyber Strike (Boots) //all (16,2,2,1,1)
Bonus.hp += (16 * _outfitBalance[4]);
Bonus.attack += (2 * _outfitBalance[4]);
Bonus.defense += (2 * _outfitBalance[4]);
Bonus.speed += (1 * _outfitBalance[4]);
Bonus.intelligence += (1 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1099) { //Serpent Tribe (Boots) //hp 50
Bonus.hp += (50 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1100) { //Serpent Tribe (Boots) //atk 3
Bonus.attack += (3 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1101) { //Serpent Tribe (Boots) //def 3
Bonus.defense += (3 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1102) { //Serpent Tribe (Boots) //spd 3
Bonus.speed += (3 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1103) { //Serpent Tribe (Boots) //int 1
Bonus.intelligence += (1 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1104 || _outfitsID[4] == 1105) { //Serpent Tribe (Boots) //all (10,1,1,1,1)
Bonus.hp += (10 * _outfitBalance[4]);
Bonus.attack += (1 * _outfitBalance[4]);
Bonus.defense += (1 * _outfitBalance[4]);
Bonus.speed += (1 * _outfitBalance[4]);
Bonus.intelligence += (1 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1120) { //Pearl Empress (Boots) //hp 60
Bonus.hp += (60 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1121) { //Pearl Empress (Boots) //atk 6
Bonus.attack += (6 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1122) { //Pearl Empress (Boots) //def 6
Bonus.defense += (6 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1123) { //Pearl Empress (Boots) //spd 6
Bonus.speed += (6 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1124) { //Pearl Empress (Boots) //int 3
Bonus.intelligence += (3 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1125 || _outfitsID[4] == 1126) { //Pearl Empress (Boots) //all (12,2,1,1,1)
Bonus.hp += (12 * _outfitBalance[4]);
Bonus.attack += (2 * _outfitBalance[4]);
Bonus.defense += (1 * _outfitBalance[4]);
Bonus.speed += (1 * _outfitBalance[4]);
Bonus.intelligence += (1 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1141) { //Starlight Diva (Boots) //hp 100
Bonus.hp += (100 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1142) { //Starlight Diva (Boots) //atk 10
Bonus.attack += (10 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1143) { //Starlight Diva (Boots) //def 10
Bonus.defense += (10 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1144) { //Starlight Diva (Boots) //spd 10
Bonus.speed += (10 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1145) { //Starlight Diva (Boots) //int 5
Bonus.intelligence += (5 * _outfitBalance[4]);
} else if (_outfitsID[4] == 1146 || _outfitsID[4] == 1147) { //Starlight Diva (Boots) //all (20,2,2,2,1)
Bonus.hp += (20 * _outfitBalance[4]);
Bonus.attack += (2 * _outfitBalance[4]);
Bonus.defense += (2 * _outfitBalance[4]);
Bonus.speed += (2 * _outfitBalance[4]);
Bonus.intelligence += (1 * _outfitBalance[4]);
}
}
}
// File: @openzeppelin/contracts/security/ReentrancyGuard.sol
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)
pragma solidity ^0.8.0;
/**
* @dev Contract module that helps prevent reentrant calls to a function.
*
* Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
* available, which can be applied to functions to make sure there are no nested
* (reentrant) calls to them.
*
* Note that because there is a single `nonReentrant` guard, functions marked as
* `nonReentrant` may not call one another. This can be worked around by making
* those functions `private`, and then adding `external` `nonReentrant` entry
* points to them.
*
* TIP: If you would like to learn more about reentrancy and alternative ways
* to protect against it, check out our blog post
* https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
*/
abstract contract ReentrancyGuard {
// Booleans are more expensive than uint256 or any type that takes up a full
// word because each write operation emits an extra SLOAD to first read the
// slot's contents, replace the bits taken up by the boolean, and then write
// back. This is the compiler's defense against contract upgrades and
// pointer aliasing, and it cannot be disabled.
// The values being non-zero value makes deployment a bit more expensive,
// but in exchange the refund on every call to nonReentrant will be lower in
// amount. Since refunds are capped to a percentage of the total
// transaction's gas, it is best to keep them low in cases like this one, to
// increase the likelihood of the full refund coming into effect.
uint256 private constant _NOT_ENTERED = 1;
uint256 private constant _ENTERED = 2;
uint256 private _status;
constructor() {
_status = _NOT_ENTERED;
}
/**
* @dev Prevents a contract from calling itself, directly or indirectly.
* Calling a `nonReentrant` function from another `nonReentrant`
* function is not supported. It is possible to prevent this from happening
* by making the `nonReentrant` function external, and making it call a
* `private` function that does the actual work.
*/
modifier nonReentrant() {
_nonReentrantBefore();
_;
_nonReentrantAfter();
}
function _nonReentrantBefore() private {
// On the first call to nonReentrant, _status will be _NOT_ENTERED
require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
// Any calls to nonReentrant after this point will fail
_status = _ENTERED;
}
function _nonReentrantAfter() private {
// By storing the original value once again, a refund is triggered (see
// https://eips.ethereum.org/EIPS/eip-2200)
_status = _NOT_ENTERED;
}
/**
* @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
* `nonReentrant` function in the call stack.
*/
function _reentrancyGuardEntered() internal view returns (bool) {
return _status == _ENTERED;
}
}
// File: FINALdeployFA/INTERFACE - StorageV2.sol
pragma solidity ^0.8.20;
// Import your custom structs
/**
* @title IFARPG_Storage
* @dev Interface for FARPG_Storage so other contracts can call it
*/
interface IFARPG_Storage {
//-------------------------------------------------------------------------
// Administrative / Master Contract Access
//-------------------------------------------------------------------------
function owner() external view returns (address);
function masterContracts(uint index) external view returns (address);
function masterIndex(address) external view returns (uint);
function addMasterContract(address _address, uint _index) external;
function addMasterContractBatch(address[] memory _addresses, uint[] memory _indices) external;
function removeMasterContract(uint _index) external;
function getAllMasterContracts() external view returns (address[] memory, uint[] memory);
//-------------------------------------------------------------------------
// UID Management
//-------------------------------------------------------------------------
function UIDmain(address) external view returns (uint);
function UID_ownedby(uint) external view returns (address);
function UIDcounter() external view returns (uint);
function getUID(address player) external view returns (uint _UID);
function transferUID(address player, address newplayerwallet) external;
function registerUID(address player) external;
function setUIDmain (address playerAddress, uint UID) external;
function setUID_ownedby (uint UID, address playerAddress) external;
//-------------------------------------------------------------------------
// Quest (setters)
//-------------------------------------------------------------------------
function setMainQuest(address player, uint index, uint8 progress) external;
function setSideQuest(address player, uint index, uint8 progress) external;
function setPremiumScore(address player, uint score) external;
function setPlayerGeneStrength(address player, uint index, uint strength) external;
function setPlayerVitamin(address player, uint index, uint amount) external;
//-------------------------------------------------------------------------
// Quest (getters)
//-------------------------------------------------------------------------
function getMainQuestProgress(address player, uint index) external view returns (uint8);
function getSideQuestProgress(address player, uint index) external view returns (uint8);
function getPremiumScore(address player) external view returns (uint);
function getPlayerQuestAndScore(address player, uint index) external view returns (uint, uint, uint);
function getMainQuestProgressArray(address player) external view returns (uint8[64] memory);
function getSideQuestProgressArray(address player) external view returns (uint8[64] memory);
//-------------------------------------------------------------------------
// Player Stats (setters)
//-------------------------------------------------------------------------
function setPersonalWallet(address player, address personal) external;
function setGiveControlTo(address player, address web2wallet) external;
function setExp(address player, uint experience) external;
function setRankScore(address player, uint score) external;
function setEnergy1(address player, uint energy) external;
function setEnergy2(address player, uint energy) external;
function setEnergy22(address player, uint energy) external;
function setEnergy3(address player, uint energy) external;
function setTeamFormat(address player, uint[60] calldata format) external;
function setUsernameToUID(string memory username, uint _UID) external;
function setUIDToUsername(uint _UID, string memory username) external;
function deleteUsernameToAddress (string memory username) external;
// Points
function setPoint1(address player, uint point) external;
function setPoint2(address player, uint point) external;
function setPoint3(address player, uint point) external;
function setPoint4(address player, uint point) external;
function setPoint5(address player, uint point) external;
function addPoint1(address player, uint point) external;
function addPoint2(address player, uint point) external;
function addPoint3(address player, uint point) external;
function addPoint4(address player, uint point) external;
function addPoint5(address player, uint point) external;
//-------------------------------------------------------------------------
// Player Stats (getters)
//-------------------------------------------------------------------------
function personalwallet(address) external view returns (address);
function givecontrolto(address) external view returns (address);
function getExperience(address player) external view returns (uint);
function getRankingScore(address player) external view returns (uint);
function getEnergy1(address player) external view returns (uint);
function getEnergy2(address player) external view returns (uint);
function getEnergy22(address player) external view returns (uint);
function getEnergy3(address player) external view returns (uint);
function getPlayerStats(address player) external view returns (uint, uint, uint, uint, uint, uint);
function UIDToUsername(uint) external view returns (string memory);
function usernameToUID(string memory) external view returns (uint);
function getPoint1(address player) external view returns (uint);
function getPoint2(address player) external view returns (uint);
function getPoint3(address player) external view returns (uint);
function getPoint4(address player) external view returns (uint);
function getPoint5(address player) external view returns (uint);
function getPlayerPoints(address player) external view returns (uint, uint, uint, uint, uint);
function getPlayergenestrengthArray(address player) external view returns (uint[50] memory);
function getPlayerGeneStrength(address player, uint index) external view returns (uint);
function getPlayervitaminArray(address player) external view returns (uint[50] memory);
function getPlayerVitamin(address player, uint index) external view returns (uint);
//-------------------------------------------------------------------------
// Limits (setters)
//-------------------------------------------------------------------------
function setLimit1(address player, uint limit) external;
function setLimit2(address player, uint limit) external;
function setLimit3(address player, uint limit) external;
function setTimebound1(address player, uint timestamp) external;
function setTimebound2(address player, uint timestamp) external;
function setTimebound3(address player, uint timestamp) external;
//-------------------------------------------------------------------------
// Limits (getters)
//-------------------------------------------------------------------------
function getLimit1(address player) external view returns (uint);
function getLimit2(address player) external view returns (uint);
function getLimit3(address player) external view returns (uint);
function getTimebound1(address player) external view returns (uint);
function getTimebound2(address player) external view returns (uint);
function getTimebound3(address player) external view returns (uint);
function getPlayerLimits(address player) external view returns (uint, uint, uint, uint, uint, uint);
//-------------------------------------------------------------------------
// Numberset (setters)
//-------------------------------------------------------------------------
function setNumberSet1(address player, uint[6] memory number) external;
function setNumberSet2(address player, uint[5] memory number) external;
function setNumberSet3(address player, uint[5] memory number) external;
function setNumberSet4(address player, uint[5] memory number) external;
function setNumberSet5(address player, uint[5] memory number) external;
function setNumberSet6(address player, uint[5] memory number) external;
function setNumberSet7(address player, uint[5] memory number) external;
function setNumberSet8(address player, uint[5] memory number) external;
function setNumberSet9(address player, uint[5] memory number) external;
function setNumberSetA(address player, uint[5] memory number) external;
function setNumberSetB(address player, uint[5] memory number) external;
function setNumberSetC(address player, uint[5] memory number) external;
function setNumberSetD(address player, uint[5] memory number) external;
function setNumberSetE(address player, uint[10] memory number) external;
function setNumberSetF(address player, uint[10] memory number) external;
function setNumberSetG(address player, uint[10] memory number) external;
function setNumberSetH(address player, uint[10] memory number) external;
//-------------------------------------------------------------------------
// Numberset (getters)
//-------------------------------------------------------------------------
function getNumberSet1(address player) external view returns (uint[6] memory);
function getNumberSet2(address player) external view returns (uint[5] memory);
function getNumberSet3(address player) external view returns (uint[5] memory);
function getNumberSet4(address player) external view returns (uint[5] memory);
function getNumberSet5(address player) external view returns (uint[5] memory);
function getNumberSet6(address player) external view returns (uint[5] memory);
function getNumberSet7(address player) external view returns (uint[5] memory);
function getNumberSet8(address player) external view returns (uint[5] memory);
function getNumberSet9(address player) external view returns (uint[5] memory);
function getNumberSetA(address player) external view returns (uint[5] memory);
function getNumberSetB(address player) external view returns (uint[5] memory);
function getNumberSetC(address player) external view returns (uint[5] memory);
function getNumberSetD(address player) external view returns (uint[5] memory);
function getNumberSetE(address player) external view returns (uint[10] memory);
function getNumberSetF(address player) external view returns (uint[10] memory);
function getNumberSetG(address player) external view returns (uint[10] memory);
function getNumberSetH(address player) external view returns (uint[10] memory);
//-------------------------------------------------------------------------
// PVP Ranks
//-------------------------------------------------------------------------
struct Player {
uint256 rankPoints;
uint256 league;
uint256 indexInLeague; // Index of the player within their league array
}
function setPlayers(address player, Player memory rankpointleagueindexinleague) external;
function setReset_Time_Attempts(address player, uint[2] memory resettimeattemps) external;
function setEligible_Opponents(address player, address[5] memory eligibleOppo) external;
function setFaught_Opponents(address player, uint[5] memory faughtOppo) external;
function setDefending_Formation(address player, uint[3] memory defendingslot) external;
function getPlayers(address player) external view returns (Player memory ) ;
function getReset_Time_Attempts(address player ) external view returns (uint[2] memory );
function getEligible_Opponents(address player ) external view returns (address[5] memory);
function getFaught_Opponents(address player ) external view returns(uint[5] memory) ;
function getDefending_Formation(address player) external view returns (uint[3] memory );
//-------------------------------------------------------------------------
// Pet data (setters)
//-------------------------------------------------------------------------
function setPetUnits(address player, uint index, S.Unit memory newUnit) external;
function setPetUnitsMaxVitamined(address player, uint index, S.Unit memory newUnit) external;
function setPetStatuses(address player, uint index, S.Status memory newStatus) external;
function setPetTimes(address player, uint index, S.Time memory newTime) external;
//-------------------------------------------------------------------------
// Pet data (getters)
//-------------------------------------------------------------------------
function getPetUnitsAll(address player) external view returns (S.Unit[500] memory);
function getPetUnits(address player, uint _index) external view returns (S.Unit memory);
function getPetUnitsMaxVitaminedAll(address player) external view returns (S.Unit[500] memory);
function getPetUnitsMaxVitamined(address player, uint _index) external view returns (S.Unit memory);
function getPetStatusesAll(address player) external view returns (S.Status[500] memory);
function getPetStatuses(address player, uint _index) external view returns (S.Status memory);
function getPetTimesAll(address player) external view returns (S.Time[500] memory);
function getPetTimes(address player, uint _index) external view returns (S.Time memory);
//-------------------------------------------------------------------------
// Party / Outfit
//-------------------------------------------------------------------------
function setPartyFormation(address player, uint[30] memory slots) external;
function setTrainerOutfitPosition(address player, uint[150] memory outfitIds) external;
function getPartyFormation(address player) external view returns (uint[30] memory);
function getAllOutfits(address player) external view returns (uint[150] memory);
//-------------------------------------------------------------------------
// Trainer Gene Infusing
//-------------------------------------------------------------------------
function setTrainerGeneInfusingGene(address player, uint index, uint value) external;
function setTrainerGeneInfusingGeneAll(address player, uint[50] memory newData) external;
function setTrainerGeneInfusingTimer(address player, uint index, uint value) external;
function setTrainerGeneInfusingTimerAll(address player, uint[50] memory newData) external;
function getTrainerGeneInfusingGeneAll(address player) external view returns (uint[50] memory) ;
function getTrainerGeneInfusingTimerAll(address player) external view returns (uint[50] memory);
function getTrainerGeneInfusingGene(address player, uint Index)external view returns (uint ) ;
function getTrainerGeneInfusingTimer(address player, uint Index)external view returns (uint );
//-------------------------------------------------------------------------
// Additional Utility
//-------------------------------------------------------------------------
function getBattleUnit3(address player, uint[3] calldata slots)
external
view
returns (S.Unit[3] memory Units3, uint[3] memory UnitIds);
function getSlotUnitMore(address player, uint startindex, uint stopindex)
external
view
returns (S.Unit[] memory Units, uint[] memory UnitIds);
function getTeamFormat(address _addr) external view returns (uint[60] memory);
//-------------------------------------------------------------------------
// Weather System
//-------------------------------------------------------------------------
function getWeatherUnity() external view returns (uint _weather, uint _daylight, uint _blocktime);
function getWeatherBattle(uint _timenow) external view returns (uint _weather);
function setWeatherConstants(uint[12] memory _weatherIndices) external;
function getWeatherIndexConstants() external view returns (uint[] memory);
}
// File: FINALdeployFA/PUBLIC - QuestSystemV1.sol
pragma solidity ^0.8.19;
//_______________________________________________________________
// ___ __ __ _ ___ _ ___ _ __
// | _ )\ \ / / _ | | / _ \ _ | | / _ \ (_)\ \
// | _ \ \ V / | || || (_) || || || (_) | _ | |
// |___/ |_| \__/ \___/ \__/ \___/ ( ) | |
// |/ /_/
//_______________________________________________________________
// Interface for accessing Storage
//-------------------------------------------------------------------
// _____ _ _ _______ ______ _____ ______ _____ ______
// |_ _| \ | |__ __| ____| __ \| ____/\ / ____| ____|
// | | | \| | | | | |__ | |__) | |__ / \ | | | |__
// | | | . ` | | | | __| | _ /| __/ /\ \| | | __|
// _| |_| |\ | | | | |____| | \ \| | / ____ \ |____| |____
// |_____|_| \_| |_| |______|_| \_\_|/_/ \_\_____|______|
//
//-------------------------------------------------------------------
interface BattleV4 {
//enum Weather { Sunny, Cloudy, Rainy, Thunderstorm, Snowy, Aurora, BloodMoon, NONE }
function BattleV4_3v3(S.Unit[6] memory _UnitGroup) external
returns (uint BattleRhythm, uint bit, bool Won, uint randret);
function Calibrate(uint index) external returns (uint, uint, bool, uint);
}
interface FARPG_RAMInterface {
// Read functions
struct TrainerData {
uint gene;
uint[50] genestrength;
uint hashed;
}
function genetoid_mapping(uint trainergene) external pure returns (uint);
function petunitsmax(uint id) external pure returns (S.Unit calldata);
function petunitsevolveid(S.Status calldata _status, S.Unit calldata _Unit, TrainerData calldata _trainerData) external pure returns (S.Status memory , uint );
}
contract FARPG_QuestSystemV1 is Ownable , ReentrancyGuard {
IFARPG_Storage public contractStorage;
FARPG_RAMInterface public contractRAM;
BattleV4 public Battle;
constructor() {
}
event StatChangedResult(S.Unit AfterUnit, S.Status AfterStatus, S.Time AfterTime);
event BattleResultV2(uint BattleRythm, uint bit, bool Won, uint randret, S.Unit[6] unitgroup,uint[3] oponentid, uint[3] attackerid);
//-------------------------------------------------------------------
// _____ _ ____ ____ _ __ __
// / ____| | / __ \| _ \ /\ | | \ \ / /
// | | __| | | | | | |_) | / \ | | \ \ / /
// | | |_ | | | | | | _ < / /\ \ | | \ \/ /
// | |__| | |___| |__| | |_) / ____ \| |____ \ / _
// \_____|______\____/|____/_/ \_\______| \/ (_)
//
//-------------------------------------------------------------------
uint private QuesttoQuestDelay3 = 3 seconds; //prevent a bot to finish the quest too fast
uint private QuesttoQuestDelay10 = 10 seconds; //prevent a bot to finish the quest too fast
mapping (address => uint) private reentrant_time;
uint constant PRICE_TOOPENBOX = 5 ether; //dont have to change, as this will not happened since First quest only run once. Even is, that is attempt to exploit. 5 FTM will prevent that.
uint constant TIME_INITIALSTAMINA = 24 hours; //initial stamina
uint constant TIME_INITIALENDURANCE = 3 hours; //initial endurance/hunger
string constant MESSAGE_STANDARDQUESTCONDITIONUNMATCHED = "Quest requirement unmatched.";
//---------------------------------------------------------
// _____ __ __ _____ _ _
// /\ | __ \| \/ |_ _| \ | |
// / \ | | | | \ / | | | | \| |
// / /\ \ | | | | |\/| | | | | . ` |
// / ____ \| |__| | | | |_| |_| |\ |
// /_/ \_\_____/|_| |_|_____|_| \_|
//
//---------------------------------------------------------
function updateStorageContractAAddress(address _newContractAAddress) external onlyOwner {
require(_newContractAAddress != address(0), "Invalid address");
contractStorage = IFARPG_Storage(_newContractAAddress);
}
function updateRAMContractAAddress(address _newContractAAddress) external onlyOwner {
require(_newContractAAddress != address(0), "Invalid address");
contractRAM = FARPG_RAMInterface(_newContractAAddress);
}
function updateBattleV4Address(address _newContractAAddress) external onlyOwner {
require(_newContractAAddress != address(0), "Invalid address");
Battle = BattleV4(_newContractAAddress);
}
function withdraw() external onlyOwner {
// Function to withdraw all balance from the contract for revenue
require(address(this).balance > 0, "Contract balance is zero");
payable(msg.sender).transfer(address(this).balance);
}
//---------------------------------------------------------
//
// _____ _______ _____ _______
// / ____|__ __|/\ | __ \__ __|
// | (___ | | / \ | |__) | | |
// \___ \ | | / /\ \ | _ / | |
// ____) | | |/ ____ \| | \ \ | |
// |_____/ |_/_/ \_\_| \_\ |_|
//
//---------------------------------------------------------
//--------- sub functions ---------------
function accountAddressToProceed() public view returns (address) {
// Ready for account abstraction
// If the player doesn't provide a personal wallet, all data will be recorded in the trainer wallet
address playerAddress = contractStorage.personalwallet(msg.sender);
if (playerAddress == address(0)) {
return msg.sender;
} else {
return playerAddress;
}
}
modifier onlyEOA() {
require(!isContract(msg.sender), "Smart contracts not allowed");
_;
}
function noneReentrant_time(address player, uint delay) internal {
require(reentrant_time[player] < block.timestamp ,"Spam prevention activated.");
reentrant_time[player] = block.timestamp + delay;
}
function isContract(address _addr) internal view returns (bool) {
uint256 size;
assembly {
size := extcodesize(_addr)
}
return size > 0;
}
function openBoxIn24Hr_paid() public view returns (uint boxOpened, uint remainingTimeReset_s, uint pricePerBox) {
//check the timenow and minted 0th box whether the limit has reset
address playerAddress = accountAddressToProceed();
uint timeElapsed = block.timestamp - contractStorage.getTimebound1(playerAddress);
if (timeElapsed >= 24 hours) { //over the TIME limit for 0th box open
boxOpened = 0;
remainingTimeReset_s = 0;
} else { //still within TIME limit since last 0th box opened
boxOpened = contractStorage.getLimit1(playerAddress);
remainingTimeReset_s = 24 hours - timeElapsed;
pricePerBox = PRICE_TOOPENBOX*boxOpened;
}
}
/////////////////////////////////////// QUEST START //////////////////////////////////////////////////////////////////
function Q1_1JojoTranscended() public nonReentrant {
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
contractStorage.registerUID(playerAddress);
require(contractStorage.getMainQuestProgress(playerAddress,1) == 0,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
uint jojoStrength = contractStorage.getPlayerGeneStrength(playerAddress,0);
contractStorage.setPlayerGeneStrength(playerAddress, 0, jojoStrength+1);
contractStorage.setMainQuest(playerAddress,1,1); //done the quest
}
function Q1_2GetFirstLings(uint slot, uint trainergene) public payable nonReentrant{
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
require(contractStorage.getMainQuestProgress(playerAddress,1) == 1,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
contractStorage.setMainQuest(playerAddress,1,2); //done the quest
uint limit2 = contractStorage.getLimit2(playerAddress); //limit2 is slot limit
uint genestrength = contractStorage.getPlayerGeneStrength(playerAddress,trainergene);
uint _timenow = block.timestamp;
//check to see the chosen slot has occupied or exceed the slotlimit
S.Status memory _petstatus = contractStorage.getPetStatuses(playerAddress, slot);
if (limit2 == 0) {
limit2 = 5;
contractStorage.setLimit2(playerAddress, limit2); //initialize for the limit2 since its a new player
}
require(slot < limit2, "Chosen slot exceeds limit.");
require(_petstatus.id == 0, "Chosen slot is occupied.");
require(trainergene == 0, "must be Jojo."); //prevent exploit to get 1 day 2 limited Lings (Quest and Free)
S.Unit memory _petunit = S.Unit({ hp: 1000, attack: 100, defense: 50, speed: 100, intelligence: 100, genestrength: genestrength, range: 0, special: 0});
_petstatus = S.Status({id: contractRAM.genetoid_mapping(trainergene), family: trainergene + 1 , stage: 1});
S.Time memory _pettime = S.Time({bond: 0, stamina: _timenow - TIME_INITIALSTAMINA, hunger: _timenow + TIME_INITIALENDURANCE});
contractStorage.setPetUnits(playerAddress, slot ,_petunit);
contractStorage.setPetStatuses(playerAddress,slot , _petstatus);
contractStorage.setPetTimes(playerAddress, slot ,_pettime);
contractStorage.setPetUnitsMaxVitamined(playerAddress, slot ,contractRAM.petunitsmax(_petstatus.id));
uint GENEbit = contractStorage.getPoint2(playerAddress);
GENEbit |= (1 << (_petstatus.id%10000)); //DO not minus 1 bit as no shinning check
contractStorage.setPoint2(playerAddress,GENEbit);
emit StatChangedResult(_petunit,_petstatus,_pettime);
}
/////////////// FEED AND TRAIN PET TUTORIAL ///////////////////////
uint constant REENTRANT_TIMELIMIT = 2 seconds; // default 2 seconds. means u cannot run the nonreentrant functions >1 time within 3 seconds.
uint constant PET_STAMINA_MAX = 24 hours; //maximum stamina even rested for so long
uint constant PET_HUNGER_MAX = 24 hours; // if a pet left for very long time. the MAX hunger should be...
uint constant ROOKIETOMATURE_BOND = 35 hours; // if Bond more than this, evolve. BUT it is Stamina + Hunger, thus 48hr per day, open Box gave 24+21= 45 hours
uint constant MATURETOPERFECT_BOND = 81 hours; // on evolved, you gain max stamina and initial hunger again, means 45hours again.
//////////////////////////////// sub functions ///////////////////
struct PetData { //resolve stack too deep
S.Status petstatuses;
S.Unit petunits;
S.Time pettimes;
S.Unit petunitsmax;
}
function UnitUpdateStats(S.Unit memory petunits, S.Unit memory petunitsmax , uint stats_type, uint rate) internal pure returns (S.Unit memory petunitsout){
//************* rate in 100% = 1000 ***********
petunitsout = petunits;
if (stats_type == 0) { //hp
if (petunitsmax.hp > petunits.hp) { //no overflow
petunitsout.hp = petunits.hp + ((petunitsmax.hp - petunits.hp)*rate)/1000;
} else {petunitsout.hp = petunitsmax.hp;}
} else if (stats_type == 1) { // atk
if (petunitsmax.attack > petunits.attack) { //no overflow
petunitsout.attack = petunits.attack + ((petunitsmax.attack - petunits.attack)*rate)/1000;
} else {petunitsout.attack = petunitsmax.attack;}
} else if (stats_type == 2) { // def
if (petunitsmax.defense > petunits.defense) { //no overflow
petunitsout.defense = petunits.defense + ((petunitsmax.defense - petunits.defense)*rate)/1000;
} else {petunitsout.defense = petunitsmax.defense;}
} else if (stats_type == 3) { // spd
if (petunitsmax.speed > petunits.speed) { //no overflow
petunitsout.speed = petunits.speed + ((petunitsmax.speed - petunits.speed)*rate)/1000;
} else {petunitsout.speed = petunitsmax.speed;}
} else if (stats_type == 4) { // int
if (petunitsmax.intelligence > petunits.intelligence) { //no overflow
petunitsout.intelligence = petunits.intelligence + ((petunitsmax.intelligence - petunits.intelligence)*rate)/1000;
} else {petunitsout.intelligence = petunitsmax.intelligence;}
}
}
function feedPet(uint _slot, uint _foodtype, uint _trainergene) internal {
address playerAddress = accountAddressToProceed();
uint genestrength = contractStorage.getPlayerGeneStrength(playerAddress,_trainergene);
require(genestrength > 0, "Don't have the gene.");
//}
PetData memory Lings;
Lings.petstatuses = contractStorage.getPetStatuses(playerAddress,_slot);
Lings.petunits = contractStorage.getPetUnits(playerAddress,_slot);
Lings.pettimes = contractStorage.getPetTimes(playerAddress,_slot);
Lings.petunitsmax = contractStorage.getPetUnitsMaxVitamined(playerAddress,_slot);
uint _exp = contractStorage.getExperience(playerAddress);
uint _full; //determine how full is the food after eaten in time
uint _partialstat; // partial stat gain only. 100% = 10000
uint _timenow = block.timestamp;
require (Lings.petstatuses.id != 0, "empty slot");
require(_foodtype <= 10, "Invalid food type");
if (_foodtype==0){_full = 6 hours;} //backpack food
else if (_foodtype==1){_full = 12 hours; } //shop1
else if (_foodtype==2){_full = 10 hours; }
else if (_foodtype==3){_full = 10 hours; }
else if (_foodtype==4){_full = 11 hours; } //shop1.1
else if (_foodtype==5){_full = 11 hours; }
else if (_foodtype==6){_full = 24 hours; } //shop2
else if (_foodtype==7){_full = 24 hours; }
else if (_foodtype==8){_full = 24 hours; }
else if (_foodtype==9){_full = 24 hours; } //shop2.2
else if (_foodtype==10){_full = 24 hours; }
if (Lings.pettimes.hunger < _timenow) { //super hungry, endurance = 0
Lings.pettimes.bond = Lings.pettimes.bond + _full;
_exp += _full;
Lings.pettimes.hunger = _timenow + _full;
_partialstat= 10; // 100% = 10
} else if (Lings.pettimes.hunger - _timenow + _full> PET_HUNGER_MAX) { //over feed, gain partial stat
uint fullhittingcap = (PET_HUNGER_MAX- (Lings.pettimes.hunger - _timenow));
Lings.pettimes.bond = Lings.pettimes.bond + fullhittingcap;
_exp += fullhittingcap;
_partialstat = (fullhittingcap*10)/ (_full); //100 = 1 = 100% (upscale 2 0)
//this has to run last otherwise alter the hunger variable for above
Lings.pettimes.hunger = _timenow + PET_HUNGER_MAX;
} else { //no over feed. stat gain all
Lings.pettimes.bond = Lings.pettimes.bond + _full;
_exp += _full;
Lings.pettimes.hunger = Lings.pettimes.hunger + _full;
_partialstat= 10; // 100% = 10
}
if (_foodtype==0){} //backpack food
else if (_foodtype==1){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,10*_partialstat);} //hp + 10% //shop1
else if (_foodtype==2){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,5*_partialstat);} //atk + 5%
else if (_foodtype==3){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,5*_partialstat);} //def + 5%
else if (_foodtype==4){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,5*_partialstat);} //spd + 5% //shop1.1
else if (_foodtype==5){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,5*_partialstat);} //int + 5%
else if (_foodtype==6){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,19*_partialstat);} //hp + 19% //shop2
else if (_foodtype==7){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,11*_partialstat);} //atk + 11%
else if (_foodtype==8){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,11*_partialstat);} //def + 11%
else if (_foodtype==9){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,11*_partialstat);} //spd + 11% //shop2.2
else if (_foodtype==10){Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,11*_partialstat);} //int + 11%
//*************** check evolve **************
if ((Lings.petstatuses.stage == 1 && Lings.pettimes.bond > ROOKIETOMATURE_BOND)|| //check if rookie, then to mature
(Lings.petstatuses.stage == 2 && Lings.pettimes.bond > MATURETOPERFECT_BOND)) { // check if mature, then to perfect
//evolve id and maxstats
//this need from RAM as update each patch
FARPG_RAMInterface.TrainerData memory _trainerdata;
_trainerdata.gene = _trainergene;
_trainerdata.genestrength = contractStorage.getPlayergenestrengthArray(playerAddress);
_trainerdata.hashed = uint(keccak256(abi.encodePacked(playerAddress,block.timestamp,block.prevrandao)));
uint compiledGenestrength;
(Lings.petstatuses, compiledGenestrength)= contractRAM.petunitsevolveid(Lings.petstatuses,Lings.petunits, _trainerdata);
contractStorage.setPetStatuses(playerAddress,_slot , Lings.petstatuses); //update: ID, family, stage
Lings.pettimes = S.Time({bond: Lings.pettimes.bond, stamina: _timenow - TIME_INITIALSTAMINA, hunger: _timenow + TIME_INITIALENDURANCE});
contractStorage.setPetTimes(playerAddress, _slot ,Lings.pettimes); //update: bond for evolve, stamina, hunger
Lings.petunitsmax = contractRAM.petunitsmax(Lings.petstatuses.id); //use new id to get max stat, no genestrength and skills yet
contractStorage.setPetUnitsMaxVitamined(playerAddress, _slot, Lings.petunitsmax);
//evolve gain all stats by 30%
Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,300);
Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,300);
Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,300);
Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,300);
Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,300);
//gain new skill, with training stats above
if (Lings.petstatuses.stage == 2) {//evolved into Mature
Lings.petstatuses.id += 1; //add 1 to minus 1 back to retain consistent gas.
if (Lings.petstatuses.id > 10000) { //if its shinning, normalized it first for skill
Lings.petunits.range = Lings.petstatuses.id - 10001;
} else {
Lings.petunits.range = Lings.petstatuses.id - 1;
}
}
if (Lings.petstatuses.stage == 3) {
Lings.petstatuses.id += 1; //add 1 to minus 1 back to retain consistent gas.
if (Lings.petstatuses.id > 10000) { //if its shinning, normalized it first for skill
Lings.petunits.special = Lings.petstatuses.id - 10001;
} else {
Lings.petunits.special = Lings.petstatuses.id - 1;
}
}
contractStorage.setPetUnits(playerAddress, _slot , Lings.petunits); //final write into petUnits (stats, genestrength, skills)
uint GENEbit = contractStorage.getPoint2(playerAddress);
// Set the bit at the position corresponding to ID
GENEbit |= (1 << ((Lings.petstatuses.id-1)%10000));//need to minus 1 bit because of previous add on shinning check
contractStorage.setPoint2(playerAddress,GENEbit);
} else {
contractStorage.setPetUnits(playerAddress, _slot , Lings.petunits);
contractStorage.setPetTimes(playerAddress, _slot ,Lings.pettimes);
}
//************** check evolve end ******************
contractStorage.setExp(playerAddress, _exp);
emit StatChangedResult(Lings.petunits,Lings.petstatuses,Lings.pettimes);
}
/////////////////////////////////////// TRAIN PET //////////////////////////////////////////////////////////////////
function trainPet(uint _slot, uint _traintype, uint _trainergene) internal {
address playerAddress = accountAddressToProceed();
uint _exp = contractStorage.getExperience(playerAddress);
uint genestrength = contractStorage.getPlayerGeneStrength(playerAddress,_trainergene);
//if (_trainergene !=0) { //if the trainer is not default Jojo, then make sure this player has different trainer
require(genestrength > 0, "Don't have the gene.");
//}
PetData memory Lings;
Lings.petstatuses = contractStorage.getPetStatuses(playerAddress,_slot);
Lings.petunits = contractStorage.getPetUnits(playerAddress,_slot);
Lings.pettimes = contractStorage.getPetTimes(playerAddress,_slot);
Lings.petunitsmax = contractStorage.getPetUnitsMaxVitamined(playerAddress,_slot);
uint _effort; //determine how full is the food after eaten in time
uint _timenow = block.timestamp;
require (Lings.petstatuses.id != 0, "empty slot");
require(_traintype <= 24, "Invalid training type");
if (_traintype==0){_effort = 3 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,170); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,100); } //basic 1, 0hp / 1atk / 2def/ 3spd / 4int
else if (_traintype==1){_effort = 3 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,170); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,100); }
else if (_traintype==2){_effort = 3 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,170); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,100); }
else if (_traintype==3){_effort = 3 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,170); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,100); }
else if (_traintype==4){_effort = 3 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,170); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,100); }
else if (_traintype==5){_effort = 6 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,311); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,100); } //upgraded training center 1
else if (_traintype==6){_effort = 6 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,311); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,100); }
else if (_traintype==7){_effort = 6 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,311); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,100); }
else if (_traintype==8){_effort = 6 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,311); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,100); }
else if (_traintype==9){_effort = 6 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,311); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,100); }
else if (_traintype==10){_effort = 12 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,525); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,100); } //upgraded training center 2
else if (_traintype==11){_effort = 12 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,525); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,100); }
else if (_traintype==12){_effort = 12 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,525); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,100); }
else if (_traintype==13){_effort = 12 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,525); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,100); }
else if (_traintype==14){_effort = 12 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,525); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,100); }
else if (_traintype==15){_effort = 18 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,673); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,100); } //upgraded training center 3
else if (_traintype==16){_effort = 18 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,673); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,100); }
else if (_traintype==17){_effort = 18 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,673); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,100); }
else if (_traintype==18){_effort = 18 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,673); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,100); }
else if (_traintype==19){_effort = 18 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,673); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,100); }
else if (_traintype==20){_effort = 24 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,775); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,100); } //upgraded training center 4
else if (_traintype==21){_effort = 24 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,775); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,100); }
else if (_traintype==22){_effort = 24 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,775); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,100); }
else if (_traintype==23){_effort = 24 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,775); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,100); }
else if (_traintype==24){_effort = 24 hours; Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,775); Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,100); }
uint _staminaleft = _timenow - Lings.pettimes.stamina; //staminatime sure lower than timenow. NO WAY staminatime > timenow, really is, then revert
require(_staminaleft >= _effort, "Not enough stamina.");
if (_staminaleft > PET_STAMINA_MAX) {_staminaleft = PET_STAMINA_MAX;} //capping stamina before spending
_staminaleft -= _effort; //remaining stamina
Lings.pettimes.stamina = _timenow - _staminaleft; //timenow always larger than staminaleft.
Lings.pettimes.bond += _effort;
_exp += _effort;
//*************** check evolve **************
if ((Lings.petstatuses.stage == 1 && Lings.pettimes.bond > ROOKIETOMATURE_BOND)|| //check if rookie, then to mature
(Lings.petstatuses.stage == 2 && Lings.pettimes.bond > MATURETOPERFECT_BOND)) { // check if mature, then to perfect
//evolve id and maxstats
//this need from RAM as update each patch
FARPG_RAMInterface.TrainerData memory _trainerdata;
_trainerdata.gene = _trainergene;
_trainerdata.genestrength = contractStorage.getPlayergenestrengthArray(playerAddress);
_trainerdata.hashed = uint(keccak256(abi.encodePacked(playerAddress,block.timestamp,block.prevrandao)));
uint compiledGenestrength;
(Lings.petstatuses, compiledGenestrength)= contractRAM.petunitsevolveid(Lings.petstatuses,Lings.petunits, _trainerdata);
contractStorage.setPetStatuses(playerAddress,_slot , Lings.petstatuses); //update: ID, family, stage
//ONCE evolve you gain Stamina and Endurance
Lings.pettimes = S.Time({bond: Lings.pettimes.bond, stamina: _timenow - TIME_INITIALSTAMINA, hunger: _timenow + TIME_INITIALENDURANCE});
contractStorage.setPetTimes(playerAddress, _slot ,Lings.pettimes); //update: bond for evolve, stamina, hunger
Lings.petunitsmax = contractRAM.petunitsmax(Lings.petstatuses.id); //use new id to get max stat, no genestrength and skills yet
contractStorage.setPetUnitsMaxVitamined(playerAddress, _slot, Lings.petunitsmax);
//evolve gain all stats by 30%
Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,0,300);
Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,1,300);
Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,2,300);
Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,3,300);
Lings.petunits=UnitUpdateStats(Lings.petunits,Lings.petunitsmax,4,300);
if (Lings.petstatuses.stage == 2) {//evolved into Mature
Lings.petstatuses.id += 1; //add 1 to minus 1 back to retain consistent gas.
if (Lings.petstatuses.id > 10000) { //if its shinning, normalized it first for skill
Lings.petunits.range = Lings.petstatuses.id - 10001;
} else {
Lings.petunits.range = Lings.petstatuses.id - 1;
}
}
if (Lings.petstatuses.stage == 3) {
Lings.petstatuses.id += 1; //add 1 to minus 1 back to retain consistent gas.
if (Lings.petstatuses.id > 10000) { //if its shinning, normalized it first for skill
Lings.petunits.special = Lings.petstatuses.id - 10001;
} else {
Lings.petunits.special = Lings.petstatuses.id - 1;
}
}
contractStorage.setPetUnits(playerAddress, _slot , Lings.petunits); //final write into petUnits (stats, genestrength, skills)
uint GENEbit = contractStorage.getPoint2(playerAddress);
// Set the bit at the position corresponding to ID
GENEbit |= (1 << ((Lings.petstatuses.id-1)%10000));//need to minus 1 bit because of previous add on shinning check
contractStorage.setPoint2(playerAddress,GENEbit);
//**//***//////////////////////////////////////////
} else { //if no evolve, follow back the stamina and hunger, only update Units states and time, Status(ID, Family, stage) no change.
contractStorage.setPetUnits(playerAddress, _slot , Lings.petunits);
contractStorage.setPetTimes(playerAddress, _slot ,Lings.pettimes);
}
//************** check evolve end ******************
contractStorage.setExp(playerAddress, _exp);
emit StatChangedResult(Lings.petunits,Lings.petstatuses,Lings.pettimes);
}
function Q1_3FeedPet(uint _slot, uint _foodtype, uint _trainergene) public nonReentrant{
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay10); //prevent spam
require(contractStorage.getMainQuestProgress(playerAddress,1) == 2,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
contractStorage.setMainQuest(playerAddress,1,3); //Fed Pet, set Quest1 to 3, if unsuccessful, revert, so it wont set.
feedPet(_slot, _foodtype, _trainergene);
}
function Q1_4TrainPet(uint _slot, uint _traintype, uint _trainergene) public nonReentrant{
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
require(contractStorage.getMainQuestProgress(playerAddress,1) == 3,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
contractStorage.setMainQuest(playerAddress,1,4); //trainPet, set Quest1 to 4, if unsuccessful, revert, so it wont set.
trainPet(_slot, _traintype, _trainergene);
}
function Q1_5TrainPet(uint _slot, uint _traintype, uint _trainergene) public nonReentrant{
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
require(contractStorage.getMainQuestProgress(playerAddress,1) == 4,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
contractStorage.setMainQuest(playerAddress,1,5); //trainPet, set Quest1 to 5, if unsuccessful, revert, so it wont set.
trainPet(_slot, _traintype, _trainergene);
}
function Q1_6TrainPet(uint _slot, uint _traintype, uint _trainergene) public nonReentrant{
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
require(contractStorage.getMainQuestProgress(playerAddress,1) == 5,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
contractStorage.setMainQuest(playerAddress,1,6); //trainPet, set Quest1 to 6, if unsuccessful, revert, so it wont set.
trainPet(_slot, _traintype, _trainergene);
}
function Q1_7TrainPet(uint _slot, uint _traintype, uint _trainergene) public nonReentrant{
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
require(contractStorage.getMainQuestProgress(playerAddress,1) == 6,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
contractStorage.setMainQuest(playerAddress,1,7); //trainPet, set Quest1 to 7, if unsuccessful, revert, so it wont set.
trainPet(_slot, _traintype, _trainergene);
}
function Q1_8TrainPet(uint _slot, uint _traintype, uint _trainergene) public nonReentrant{
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
require(contractStorage.getMainQuestProgress(playerAddress,1) == 7,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
contractStorage.setMainQuest(playerAddress,1,8); //trainPet, set Quest1 to 8, if unsuccessful, revert, so it wont set.
trainPet(_slot, _traintype, _trainergene);
}
function Q1_9SetPartyTutorial(uint[30] memory partyFormation) public nonReentrant{
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay10); //prevent spam
require(contractStorage.getMainQuestProgress(playerAddress,1) == 8,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
contractStorage.setPartyFormation(playerAddress,partyFormation);
contractStorage.setMainQuest(playerAddress,1,9); //done the quest
}
function Q1_10FirstBattle(uint[3] calldata attackersID) public nonReentrant{
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay10); //prevent spam
require(contractStorage.getMainQuestProgress(playerAddress,1) == 9,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
reentrant_time[playerAddress] = block.timestamp;
bool AttackerWin;
uint BattleRhythm;
uint randret;
S.Unit[3] memory AttackerUnits; //0,1,2 is Attacker, defender on PvPFULLRecords storage
uint[3] memory AttackerIDs; //0,1,2 is Attacker, defender on PvPFULLRecords storage
S.Unit[6] memory UnitGroup; //this is a group that will send to battlecontract
uint bit;
uint[3] memory OpponIDs;
(AttackerUnits,AttackerIDs) = contractStorage.getBattleUnit3(playerAddress,attackersID); //get attacker/player data
require(AttackerUnits[0].hp>0 || AttackerUnits[1].hp>0 || AttackerUnits[2].hp>0,"3 empty slots, cannot battle.");
UnitGroup[0] = AttackerUnits[0];
UnitGroup[1] = AttackerUnits[1];
UnitGroup[2] = AttackerUnits[2];
UnitGroup[3] = S.Unit({ hp: 1300, attack: 110, defense: 12, speed: 311, intelligence: 355, genestrength: 10, range: 15, special: 0 }); //preset opponent, skill decide later.
OpponIDs = [uint256(15), uint256(0), uint256(0)]; // will finalize later after decide the first battle //saved for event emit.
(BattleRhythm, bit, AttackerWin, randret) = Battle.BattleV4_3v3(UnitGroup);
if (AttackerWin == true) {
//give treasure box, need items contract
contractStorage.setMainQuest(playerAddress,1,10); //done the quest 1, set to 10
} else {
//nothing happened... front end make them back to town and say better train more/listen to advice.
}
emit BattleResultV2(BattleRhythm, bit, AttackerWin, randret,UnitGroup,OpponIDs,AttackerIDs);
}
////////////////////////////////////////////Quest 2 3 4 STARTED Parallel/////////////////////////////////////////////////////////////
function Q2_1FightLena(uint[3] calldata attackersID) public payable nonReentrant{
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay10); //prevent spam
require(contractStorage.getMainQuestProgress(playerAddress,1) == 10 &&
contractStorage.getMainQuestProgress(playerAddress,2) == 0,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
bool AttackerWin;
uint BattleRhythm;
uint randret;
S.Unit[3] memory AttackerUnits; //0,1,2 is Attacker, defender on PvPFULLRecords storage
uint[3] memory AttackerIDs; //0,1,2 is Attacker, defender on PvPFULLRecords storage
S.Unit[6] memory UnitGroup; //this is a group that will send to battlecontract
uint bit;
uint[3] memory OpponIDs;
(AttackerUnits,AttackerIDs) = contractStorage.getBattleUnit3(playerAddress,attackersID);
require(AttackerUnits[0].hp>0 || AttackerUnits[1].hp>0 || AttackerUnits[2].hp>0,"3 empty slots, cannot battle.");
//player's Lings
UnitGroup[0] = AttackerUnits[0];
UnitGroup[1] = AttackerUnits[1];
UnitGroup[2] = AttackerUnits[2];
//Lena's Lings Wolf M1 Packer ID 42
UnitGroup[3] = S.Unit({ hp: 3200, attack: 800, defense: 100, speed: 253, intelligence: 455, genestrength: 0, range: 8, special: 0 }); //range suppose ID42, but pending
OpponIDs = [uint(42), uint(0), uint(0)];
(BattleRhythm, bit, AttackerWin, randret) = Battle.BattleV4_3v3(UnitGroup);
if (AttackerWin == true) {
if (contractStorage.getMainQuestProgress(playerAddress,2) == 0) { //<-----prevent exploit to reset quest
contractStorage.setMainQuest(playerAddress,2,1); //WIN LENA, set the quest2 to 1
}
} else {
}
emit BattleResultV2(BattleRhythm, bit, AttackerWin, randret,UnitGroup,OpponIDs,AttackerIDs);
//If WON, she will go to town and Open SHOP
}
function Q2_2ShoppingTutorial() public nonReentrant{
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
require(contractStorage.getMainQuestProgress(playerAddress,2) == 1,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
contractStorage.setMainQuest(playerAddress,2,2); //done the quest
}
///--------------------------
function Q3_1SaveQingYue() public nonReentrant{
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay10); //prevent spam
require(contractStorage.getMainQuestProgress(playerAddress,1) == 10 &&
contractStorage.getMainQuestProgress(playerAddress,3) == 0,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
if (contractStorage.getMainQuestProgress(playerAddress,3) == 0) { //<-----prevent exploit to reset quest
contractStorage.setMainQuest(playerAddress,3,1); //done the quest
}
}
function Q3_2RestaurantTutorial() public nonReentrant{
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
require(contractStorage.getMainQuestProgress(playerAddress,3) == 1,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
contractStorage.setMainQuest(playerAddress,3,2); //done the quest
//can feed 24 hours food.
}
//--------------------------
function Q4_1FightKlue(uint[3] calldata attackersID) public payable nonReentrant{
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay10); //prevent spam
require(contractStorage.getMainQuestProgress(playerAddress,1) == 10,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
bool AttackerWin;
uint BattleRhythm;
uint randret;
S.Unit[3] memory AttackerUnits; //0,1,2 is Attacker, defender on PvPFULLRecords storage
uint[3] memory AttackerIDs; //0,1,2 is Attacker, defender on PvPFULLRecords storage
S.Unit[6] memory UnitGroup; //this is a group that will send to battlecontract
uint bit;
uint[3] memory OpponIDs;
(AttackerUnits,AttackerIDs) = contractStorage.getBattleUnit3(playerAddress,attackersID);
require(AttackerUnits[0].hp>0 || AttackerUnits[1].hp>0 || AttackerUnits[2].hp>0,"3 empty slots, cannot battle.");
//player's Lings
UnitGroup[0] = AttackerUnits[0];
UnitGroup[1] = AttackerUnits[1];
UnitGroup[2] = AttackerUnits[2];
UnitGroup[3] = S.Unit({ hp: 32152, attack: 4500, defense: 3600, speed: 610, intelligence: 355, genestrength: 50, range: 14, special: 16 });
UnitGroup[4] = S.Unit({ hp: 26431, attack: 2300, defense: 1060, speed: 650, intelligence: 355, genestrength: 50, range: 14, special: 0 });
UnitGroup[5] = S.Unit({ hp: 21002, attack: 2800, defense: 730, speed: 820, intelligence: 355, genestrength: 50, range: 15, special: 0 });
OpponIDs = [uint(16), uint(14), uint(15)];
// Call the BattleV4_3v3 function with matching types
(BattleRhythm, bit, AttackerWin, randret) = Battle.BattleV4_3v3(UnitGroup);
//(BattleRhythm, bit, AttackerWin, randret)=Battle.Calibrate(1);
if (contractStorage.getMainQuestProgress(playerAddress,4) == 0) { //<-----prevent exploit to reset quest
contractStorage.setMainQuest(playerAddress,4,1); //lose klue, escaped but pass quest
}
emit BattleResultV2(BattleRhythm, bit, AttackerWin, randret,UnitGroup,OpponIDs,AttackerIDs);
//This suppose to be sure lose battle. but even lose, will complete the quest
}
function Q5_1AndreAskToFindMichael() public nonReentrant{
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
require(contractStorage.getMainQuestProgress(playerAddress,2) > 0 &&
contractStorage.getMainQuestProgress(playerAddress,3) > 0 &&
contractStorage.getMainQuestProgress(playerAddress,4) > 0 &&
contractStorage.getMainQuestProgress(playerAddress,5) == 0 ,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
contractStorage.setMainQuest(playerAddress,5,1); //done the quest
}
function Q5_2MichaelShowBridge() public nonReentrant{
address playerAddress = accountAddressToProceed();
noneReentrant_time(playerAddress,QuesttoQuestDelay3); //prevent spam
require(contractStorage.getMainQuestProgress(playerAddress,5) == 1,MESSAGE_STANDARDQUESTCONDITIONUNMATCHED); //<-----------------QUEST LIMIT ----
contractStorage.setMainQuest(playerAddress,5,2); //done the quest -- UNLOCK Simulated Dungeon
}
}