Transaction Hash:
Block:
6983503 at Dec-31-2018 03:09:12 AM +UTC
Transaction Fee:
0.001009865 ETH
$2.12
Gas Used:
201,973 Gas / 5 Gwei
Emitted Events:
| 98 |
EtheremonAdventureItem.Transfer( _from=0x00000000...000000000, _to=[Sender] 0x06f175e6ebeb0982b61c1c17ab43c30a8e6ac29a, _tokenId=17400 )
|
| 99 |
EtheremonAdventure.ClaimExplore( from=[Sender] 0x06f175e6ebeb0982b61c1c17ab43c30a8e6ac29a, exploreId=22202, itemType=1, itemClass=321, itemId=17400 )
|
Account State Difference:
| Address | Before | After | State Difference | ||
|---|---|---|---|---|---|
| 0x06f175E6...A8E6aC29A |
0.972335859 Eth
Nonce: 574
|
0.966325994 Eth
Nonce: 575
| 0.006009865 | ||
|
0xb2930B35...e543a0347
Miner
| (MiningPoolHub: Old Address) | 15,222.300085289708326618 Eth | 15,222.301095154708326618 Eth | 0.001009865 | |
| 0xBfdE6246...d2B60393C | |||||
| 0xcdF7CfC9...87fC878e1 | (Etheremon: Adventure 2) | 66.335 Eth | 66.34 Eth | 0.005 | |
| 0xf3bB445b...51C902B00 |
Execution Trace
ETH 0.005
EtheremonAdventure.claimExploreItem( _exploreId=22202 )
-
EtheremonAdventureData.getExploreData( _exploreId=22202 ) => ( _sender=0x06f175E6EBEB0982b61c1C17Ab43c30A8E6aC29A, _typeId=0, _monsterId=46795, _siteId=15, _itemSeed=0, _startAt=6983496 ) -
EtheremonAdventureSetting.getSiteItem( _siteId=15, _seed=26092 ) => ( _monsterClassId=0, _tokenClassId=321, _value=0 ) -
EtheremonAdventureData.removePendingExplore( _exploreId=22202, _itemSeed=26092 ) -
EtheremonAdventureItem.spawnItem( _classId=321, _value=0, _owner=0x06f175E6EBEB0982b61c1C17Ab43c30A8E6aC29A ) => ( 17400 )
claimExploreItem[EtheremonAdventure (ln:356)]
getExploreData[EtheremonAdventure (ln:359)]revert[EtheremonAdventure (ln:362)]revert[EtheremonAdventure (ln:366)]getRandom[EtheremonAdventure (ln:368)]blockhash[EtheremonAdventure (ln:325)]
revert[EtheremonAdventure (ln:371)]getSiteItem[EtheremonAdventure (ln:375)]removePendingExplore[EtheremonAdventure (ln:377)]mintMonster[EtheremonAdventure (ln:381)]ClaimExplore[EtheremonAdventure (ln:382)]spawnItem[EtheremonAdventure (ln:386)]ClaimExplore[EtheremonAdventure (ln:387)]transfer[EtheremonAdventure (ln:391)]ClaimExplore[EtheremonAdventure (ln:392)]revert[EtheremonAdventure (ln:394)]
File 1 of 4: EtheremonAdventure
File 2 of 4: EtheremonAdventureItem
File 3 of 4: EtheremonAdventureData
File 4 of 4: EtheremonAdventureSetting
pragma solidity ^0.4.16;
library AddressUtils {
function isContract(address addr) internal view returns (bool) {
uint256 size;
assembly { size := extcodesize(addr) }
return size > 0;
}
}
contract BasicAccessControl {
address public owner;
// address[] public moderators;
uint16 public totalModerators = 0;
mapping (address => bool) public moderators;
bool public isMaintaining = false;
function BasicAccessControl() public {
owner = msg.sender;
}
modifier onlyOwner {
require(msg.sender == owner);
_;
}
modifier onlyModerators() {
require(msg.sender == owner || moderators[msg.sender] == true);
_;
}
modifier isActive {
require(!isMaintaining);
_;
}
function ChangeOwner(address _newOwner) onlyOwner public {
if (_newOwner != address(0)) {
owner = _newOwner;
}
}
function AddModerator(address _newModerator) onlyOwner public {
if (moderators[_newModerator] == false) {
moderators[_newModerator] = true;
totalModerators += 1;
}
}
function RemoveModerator(address _oldModerator) onlyOwner public {
if (moderators[_oldModerator] == true) {
moderators[_oldModerator] = false;
totalModerators -= 1;
}
}
function UpdateMaintaining(bool _isMaintaining) onlyOwner public {
isMaintaining = _isMaintaining;
}
}
contract EtheremonEnum {
enum ResultCode {
SUCCESS,
ERROR_CLASS_NOT_FOUND,
ERROR_LOW_BALANCE,
ERROR_SEND_FAIL,
ERROR_NOT_TRAINER,
ERROR_NOT_ENOUGH_MONEY,
ERROR_INVALID_AMOUNT
}
enum ArrayType {
CLASS_TYPE,
STAT_STEP,
STAT_START,
STAT_BASE,
OBJ_SKILL
}
enum PropertyType {
ANCESTOR,
XFACTOR
}
}
interface EtheremonDataBase {
// read
function getMonsterClass(uint32 _classId) constant external returns(uint32 classId, uint256 price, uint256 returnPrice, uint32 total, bool catchable);
function getMonsterObj(uint64 _objId) constant external returns(uint64 objId, uint32 classId, address trainer, uint32 exp, uint32 createIndex, uint32 lastClaimIndex, uint createTime);
function getElementInArrayType(EtheremonEnum.ArrayType _type, uint64 _id, uint _index) constant external returns(uint8);
function addMonsterObj(uint32 _classId, address _trainer, string _name) external returns(uint64);
function addElementToArrayType(EtheremonEnum.ArrayType _type, uint64 _id, uint8 _value) external returns(uint);
}
contract ERC20Interface {
function totalSupply() public constant returns (uint);
function balanceOf(address tokenOwner) public constant returns (uint balance);
function allowance(address tokenOwner, address spender) public constant returns (uint remaining);
function transfer(address to, uint tokens) public returns (bool success);
function approve(address spender, uint tokens) public returns (bool success);
function transferFrom(address from, address to, uint tokens) public returns (bool success);
}
interface ERC721Interface {
function ownerOf(uint256 _tokenId) external view returns (address owner);
}
interface EtheremonAdventureItem {
function ownerOf(uint256 _tokenId) external view returns (address);
function getItemInfo(uint _tokenId) constant external returns(uint classId, uint value);
function spawnItem(uint _classId, uint _value, address _owner) external returns(uint);
}
interface EtheremonAdventureSetting {
function getSiteItem(uint _siteId, uint _seed) constant external returns(uint _monsterClassId, uint _tokenClassId, uint _value);
function getSiteId(uint _classId, uint _seed) constant external returns(uint);
}
interface EtheremonMonsterNFT {
function mintMonster(uint32 _classId, address _trainer, string _name) external returns(uint);
}
contract EtheremonAdventureData {
function addLandRevenue(uint _siteId, uint _emontAmount, uint _etherAmount) external;
function addTokenClaim(uint _tokenId, uint _emontAmount, uint _etherAmount) external;
function addExploreData(address _sender, uint _typeId, uint _monsterId, uint _siteId, uint _startAt, uint _emontAmount, uint _etherAmount) external returns(uint);
function removePendingExplore(uint _exploreId, uint _itemSeed) external;
// public function
function getLandRevenue(uint _classId) constant public returns(uint _emontAmount, uint _etherAmount);
function getTokenClaim(uint _tokenId) constant public returns(uint _emontAmount, uint _etherAmount);
function getExploreData(uint _exploreId) constant public returns(address _sender, uint _typeId, uint _monsterId, uint _siteId, uint _itemSeed, uint _startAt);
function getPendingExplore(address _player) constant public returns(uint);
function getPendingExploreData(address _player) constant public returns(uint _exploreId, uint _typeId, uint _monsterId, uint _siteId, uint _itemSeed, uint _startAt);
}
contract EtheremonAdventure is EtheremonEnum, BasicAccessControl {
using AddressUtils for address;
uint8 constant public STAT_COUNT = 6;
uint8 constant public STAT_MAX = 32;
struct MonsterObjAcc {
uint64 monsterId;
uint32 classId;
address trainer;
string name;
uint32 exp;
uint32 createIndex;
uint32 lastClaimIndex;
uint createTime;
}
struct ExploreData {
address sender;
uint monsterType;
uint monsterId;
uint siteId;
uint itemSeed;
uint startAt; // blocknumber
}
struct ExploreReward {
uint monsterClassId;
uint itemClassId;
uint value;
uint temp;
}
address public dataContract;
address public monsterNFT;
address public adventureDataContract;
address public adventureSettingContract;
address public adventureItemContract;
address public tokenContract;
address public kittiesContract;
uint public exploreETHFee = 0.01 ether;
uint public exploreEMONTFee = 1500000000;
uint public exploreFastenETHFee = 0.005 ether;
uint public exploreFastenEMONTFee = 750000000;
uint public minBlockGap = 240;
uint public totalSite = 54;
uint seed = 0;
event SendExplore(address indexed from, uint monsterType, uint monsterId, uint exploreId);
event ClaimExplore(address indexed from, uint exploreId, uint itemType, uint itemClass, uint itemId);
modifier requireDataContract {
require(dataContract != address(0));
_;
}
modifier requireAdventureDataContract {
require(adventureDataContract != address(0));
_;
}
modifier requireAdventureSettingContract {
require(adventureSettingContract != address(0));
_;
}
modifier requireTokenContract {
require(tokenContract != address(0));
_;
}
modifier requireKittiesContract {
require(kittiesContract != address(0));
_;
}
function setContract(address _dataContract, address _monsterNFT, address _adventureDataContract, address _adventureSettingContract, address _adventureItemContract, address _tokenContract, address _kittiesContract) onlyOwner public {
dataContract = _dataContract;
monsterNFT = _monsterNFT;
adventureDataContract = _adventureDataContract;
adventureSettingContract = _adventureSettingContract;
adventureItemContract = _adventureItemContract;
tokenContract = _tokenContract;
kittiesContract = _kittiesContract;
}
function setFeeConfig(uint _exploreETHFee, uint _exploreEMONTFee, uint _exploreFastenETHFee, uint _exploreFastenEMONTFee) onlyOwner public {
exploreETHFee = _exploreETHFee;
exploreEMONTFee = _exploreEMONTFee;
exploreFastenEMONTFee = _exploreFastenEMONTFee;
exploreFastenETHFee = _exploreFastenETHFee;
}
function setConfig( uint _minBlockGap, uint _totalSite) onlyOwner public {
minBlockGap = _minBlockGap;
totalSite = _totalSite;
}
function withdrawEther(address _sendTo, uint _amount) onlyOwner public {
// it is used in case we need to upgrade the smartcontract
if (_amount > address(this).balance) {
revert();
}
_sendTo.transfer(_amount);
}
function withdrawToken(address _sendTo, uint _amount) onlyOwner requireTokenContract external {
ERC20Interface token = ERC20Interface(tokenContract);
if (_amount > token.balanceOf(address(this))) {
revert();
}
token.transfer(_sendTo, _amount);
}
function adventureByToken(address _player, uint _token, uint _param1, uint _param2, uint64 _param3, uint64 _param4) isActive onlyModerators external {
// param1 = 1 -> explore, param1 = 2 -> claim
if (_param1 == 1) {
_exploreUsingEmont(_player, _param2, _param3, _token);
} else {
_claimExploreItemUsingEMont(_param2, _token);
}
}
function _exploreUsingEmont(address _sender, uint _monsterType, uint _monsterId, uint _token) internal {
if (_token < exploreEMONTFee) revert();
seed = getRandom(_sender, block.number - 1, seed, _monsterId);
uint siteId = getTargetSite(_sender, _monsterType, _monsterId, seed);
if (siteId == 0) revert();
EtheremonAdventureData adventureData = EtheremonAdventureData(adventureDataContract);
uint exploreId = adventureData.addExploreData(_sender, _monsterType, _monsterId, siteId, block.number, _token, 0);
SendExplore(_sender, _monsterType, _monsterId, exploreId);
}
function _claimExploreItemUsingEMont(uint _exploreId, uint _token) internal {
if (_token < exploreFastenEMONTFee) revert();
EtheremonAdventureData adventureData = EtheremonAdventureData(adventureDataContract);
ExploreData memory exploreData;
(exploreData.sender, exploreData.monsterType, exploreData.monsterId, exploreData.siteId, exploreData.itemSeed, exploreData.startAt) = adventureData.getExploreData(_exploreId);
if (exploreData.itemSeed != 0)
revert();
// min 2 blocks
if (block.number < exploreData.startAt + 2)
revert();
exploreData.itemSeed = getRandom(exploreData.sender, exploreData.startAt + 1, exploreData.monsterId, _exploreId) % 100000;
ExploreReward memory reward;
(reward.monsterClassId, reward.itemClassId, reward.value) = EtheremonAdventureSetting(adventureSettingContract).getSiteItem(exploreData.siteId, exploreData.itemSeed);
adventureData.removePendingExplore(_exploreId, exploreData.itemSeed);
if (reward.monsterClassId > 0) {
EtheremonMonsterNFT monsterContract = EtheremonMonsterNFT(monsterNFT);
reward.temp = monsterContract.mintMonster(uint32(reward.monsterClassId), exploreData.sender, "..name me..");
ClaimExplore(exploreData.sender, _exploreId, 0, reward.monsterClassId, reward.temp);
} else if (reward.itemClassId > 0) {
// give new adventure item
EtheremonAdventureItem item = EtheremonAdventureItem(adventureItemContract);
reward.temp = item.spawnItem(reward.itemClassId, reward.value, exploreData.sender);
ClaimExplore(exploreData.sender, _exploreId, 1, reward.itemClassId, reward.temp);
} else if (reward.value > 0) {
// send token contract
ERC20Interface token = ERC20Interface(tokenContract);
token.transfer(exploreData.sender, reward.value);
ClaimExplore(exploreData.sender, _exploreId, 2, 0, reward.value);
} else {
revert();
}
}
// public
function getRandom(address _player, uint _block, uint _seed, uint _count) constant public returns(uint) {
return uint(keccak256(block.blockhash(_block), _player, _seed, _count));
}
function getTargetSite(address _sender, uint _monsterType, uint _monsterId, uint _seed) constant public returns(uint) {
if (_monsterType == 0) {
// Etheremon
MonsterObjAcc memory obj;
(obj.monsterId, obj.classId, obj.trainer, obj.exp, obj.createIndex, obj.lastClaimIndex, obj.createTime) = EtheremonDataBase(dataContract).getMonsterObj(uint64(_monsterId));
if (obj.trainer != _sender) revert();
return EtheremonAdventureSetting(adventureSettingContract).getSiteId(obj.classId, _seed);
} else if (_monsterType == 1) {
// Cryptokitties
if (_sender != ERC721Interface(kittiesContract).ownerOf(_monsterId)) revert();
return EtheremonAdventureSetting(adventureSettingContract).getSiteId(_seed % totalSite, _seed);
}
return 0;
}
function exploreUsingETH(uint _monsterType, uint _monsterId) isActive public payable {
// not allow contract to make txn
if (msg.sender.isContract()) revert();
if (msg.value < exploreETHFee) revert();
seed = getRandom(msg.sender, block.number - 1, seed, _monsterId);
uint siteId = getTargetSite(msg.sender, _monsterType, _monsterId, seed);
if (siteId == 0) revert();
EtheremonAdventureData adventureData = EtheremonAdventureData(adventureDataContract);
uint exploreId = adventureData.addExploreData(msg.sender, _monsterType, _monsterId, siteId, block.number, 0, msg.value);
SendExplore(msg.sender, _monsterType, _monsterId, exploreId);
}
function claimExploreItem(uint _exploreId) isActive public payable {
EtheremonAdventureData adventureData = EtheremonAdventureData(adventureDataContract);
ExploreData memory exploreData;
(exploreData.sender, exploreData.monsterType, exploreData.monsterId, exploreData.siteId, exploreData.itemSeed, exploreData.startAt) = adventureData.getExploreData(_exploreId);
if (exploreData.itemSeed != 0)
revert();
// min 2 blocks
if (block.number < exploreData.startAt + 2)
revert();
exploreData.itemSeed = getRandom(exploreData.sender, exploreData.startAt + 1, exploreData.monsterId, _exploreId) % 100000;
if (msg.value < exploreFastenETHFee) {
if (block.number < exploreData.startAt + minBlockGap + exploreData.startAt % minBlockGap)
revert();
}
ExploreReward memory reward;
(reward.monsterClassId, reward.itemClassId, reward.value) = EtheremonAdventureSetting(adventureSettingContract).getSiteItem(exploreData.siteId, exploreData.itemSeed);
adventureData.removePendingExplore(_exploreId, exploreData.itemSeed);
if (reward.monsterClassId > 0) {
EtheremonMonsterNFT monsterContract = EtheremonMonsterNFT(monsterNFT);
reward.temp = monsterContract.mintMonster(uint32(reward.monsterClassId), exploreData.sender, "..name me..");
ClaimExplore(exploreData.sender, _exploreId, 0, reward.monsterClassId, reward.temp);
} else if (reward.itemClassId > 0) {
// give new adventure item
EtheremonAdventureItem item = EtheremonAdventureItem(adventureItemContract);
reward.temp = item.spawnItem(reward.itemClassId, reward.value, exploreData.sender);
ClaimExplore(exploreData.sender, _exploreId, 1, reward.itemClassId, reward.temp);
} else if (reward.value > 0) {
// send token contract
ERC20Interface token = ERC20Interface(tokenContract);
token.transfer(exploreData.sender, reward.value);
ClaimExplore(exploreData.sender, _exploreId, 2, 0, reward.value);
} else {
revert();
}
}
// public
function predictExploreReward(uint _exploreId) constant external returns(uint itemSeed, uint rewardMonsterClass, uint rewardItemCLass, uint rewardValue) {
EtheremonAdventureData adventureData = EtheremonAdventureData(adventureDataContract);
ExploreData memory exploreData;
(exploreData.sender, exploreData.monsterType, exploreData.monsterId, exploreData.siteId, exploreData.itemSeed, exploreData.startAt) = adventureData.getExploreData(_exploreId);
if (exploreData.itemSeed != 0) {
itemSeed = exploreData.itemSeed;
} else {
if (block.number < exploreData.startAt + 2)
return (0, 0, 0, 0);
itemSeed = getRandom(exploreData.sender, exploreData.startAt + 1, exploreData.monsterId, _exploreId) % 100000;
}
(rewardMonsterClass, rewardItemCLass, rewardValue) = EtheremonAdventureSetting(adventureSettingContract).getSiteItem(exploreData.siteId, itemSeed);
}
function getExploreItem(uint _exploreId) constant external returns(address trainer, uint monsterType, uint monsterId, uint siteId, uint startBlock, uint rewardMonsterClass, uint rewardItemClass, uint rewardValue) {
EtheremonAdventureData adventureData = EtheremonAdventureData(adventureDataContract);
(trainer, monsterType, monsterId, siteId, rewardMonsterClass, startBlock) = adventureData.getExploreData(_exploreId);
if (rewardMonsterClass > 0) {
(rewardMonsterClass, rewardItemClass, rewardValue) = EtheremonAdventureSetting(adventureSettingContract).getSiteItem(siteId, rewardMonsterClass);
}
}
function getPendingExploreItem(address _trainer) constant external returns(uint exploreId, uint monsterType, uint monsterId, uint siteId, uint startBlock, uint endBlock) {
EtheremonAdventureData adventureData = EtheremonAdventureData(adventureDataContract);
(exploreId, monsterType, monsterId, siteId, endBlock, startBlock) = adventureData.getPendingExploreData(_trainer);
if (exploreId > 0) {
endBlock = startBlock + minBlockGap + startBlock % minBlockGap;
}
}
}File 2 of 4: EtheremonAdventureItem
pragma solidity ^0.4.23;
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
library SafeMath {
/**
* @dev Multiplies two numbers, throws on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
if (a == 0) {
return 0;
}
c = a * b;
assert(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers, truncating the quotient.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
// uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return a / b;
}
/**
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
/**
* @dev Adds two numbers, throws on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
c = a + b;
assert(c >= a);
return c;
}
}
/**
* Utility library of inline functions on addresses
*/
library AddressUtils {
/**
* Returns whether the target address is a contract
* @dev This function will return false if invoked during the constructor of a contract,
* as the code is not actually created until after the constructor finishes.
* @param addr address to check
* @return whether the target address is a contract
*/
function isContract(address addr) internal view returns (bool) {
uint256 size;
// XXX Currently there is no better way to check if there is a contract in an address
// than to check the size of the code at that address.
// See https://ethereum.stackexchange.com/a/14016/36603
// for more details about how this works.
// TODO Check this again before the Serenity release, because all addresses will be
// contracts then.
// solium-disable-next-line security/no-inline-assembly
assembly { size := extcodesize(addr) }
return size > 0;
}
}
interface ERC165 {
function supportsInterface(bytes4 _interfaceID) external view returns (bool);
}
contract SupportsInterface is ERC165 {
mapping(bytes4 => bool) internal supportedInterfaces;
constructor() public {
supportedInterfaces[0x01ffc9a7] = true; // ERC165
}
function supportsInterface(bytes4 _interfaceID) external view returns (bool) {
return supportedInterfaces[_interfaceID];
}
}
interface ERC721 {
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
function balanceOf(address _owner) external view returns (uint256);
function ownerOf(uint256 _tokenId) external view returns (address);
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes _data) external;
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external;
function transferFrom(address _from, address _to, uint256 _tokenId) external;
function transfer(address _to, uint256 _tokenId) external;
function approve(address _approved, uint256 _tokenId) external;
function setApprovalForAll(address _operator, bool _approved) external;
function getApproved(uint256 _tokenId) external view returns (address);
function isApprovedForAll(address _owner, address _operator) external view returns (bool);
}
interface ERC721Enumerable {
function totalSupply() external view returns (uint256);
function tokenByIndex(uint256 _index) external view returns (uint256);
function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256);
}
interface ERC721Metadata {
function name() external view returns (string _name);
function symbol() external view returns (string _symbol);
function tokenURI(uint256 _tokenId) external view returns (string);
}
interface ERC721TokenReceiver {
function onERC721Received(address _operator, address _from, uint256 _tokenId, bytes _data) external returns(bytes4);
}
contract NFToken is ERC721, SupportsInterface {
using SafeMath for uint256;
using AddressUtils for address;
// A mapping from NFT ID to the address that owns it.
mapping (uint256 => address) internal idToOwner;
// Mapping from NFT ID to approved address.
mapping (uint256 => address) internal idToApprovals;
// Mapping from owner address to count of his tokens.
mapping (address => uint256) internal ownerToNFTokenCount;
// Mapping from owner address to mapping of operator addresses.
mapping (address => mapping (address => bool)) internal ownerToOperators;
/**
* @dev Magic value of a smart contract that can recieve NFT.
* Equal to: bytes4(keccak256("onERC721Received(address,address,uint256,bytes)")).
*/
bytes4 constant MAGIC_ON_ERC721_RECEIVED = 0x150b7a02;
event Transfer(address indexed _from, address indexed _to, uint256 indexed _tokenId);
event Approval(address indexed _owner, address indexed _approved, uint256 indexed _tokenId);
event ApprovalForAll(address indexed _owner, address indexed _operator, bool _approved);
modifier canOperate(uint256 _tokenId) {
address tokenOwner = idToOwner[_tokenId];
require(tokenOwner == msg.sender || ownerToOperators[tokenOwner][msg.sender]);
_;
}
modifier canTransfer(uint256 _tokenId) {
address tokenOwner = idToOwner[_tokenId];
require(tokenOwner == msg.sender || getApproved(_tokenId) == msg.sender || ownerToOperators[tokenOwner][msg.sender]);
_;
}
modifier validNFToken(uint256 _tokenId) {
require(idToOwner[_tokenId] != address(0));
_;
}
constructor() public {
supportedInterfaces[0x80ac58cd] = true; // ERC721
}
function balanceOf(address _owner) external view returns (uint256) {
require(_owner != address(0));
return ownerToNFTokenCount[_owner];
}
function ownerOf(uint256 _tokenId) external view returns (address _owner) {
_owner = idToOwner[_tokenId];
require(_owner != address(0));
}
function safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes _data) external {
_safeTransferFrom(_from, _to, _tokenId, _data);
}
function safeTransferFrom(address _from, address _to, uint256 _tokenId) external {
_safeTransferFrom(_from, _to, _tokenId, "");
}
function transferFrom(address _from, address _to, uint256 _tokenId) external canTransfer(_tokenId) validNFToken(_tokenId) {
address tokenOwner = idToOwner[_tokenId];
require(tokenOwner == _from);
require(_to != address(0));
_transfer(_to, _tokenId);
}
function transfer(address _to, uint256 _tokenId) external canTransfer(_tokenId) validNFToken(_tokenId) {
address tokenOwner = idToOwner[_tokenId];
require(tokenOwner == msg.sender);
require(_to != address(0));
_transfer(_to, _tokenId);
}
function approve(address _approved, uint256 _tokenId) external canOperate(_tokenId) validNFToken(_tokenId) {
address tokenOwner = idToOwner[_tokenId];
require(_approved != tokenOwner);
idToApprovals[_tokenId] = _approved;
emit Approval(tokenOwner, _approved, _tokenId);
}
function setApprovalForAll(address _operator, bool _approved) external {
require(_operator != address(0));
ownerToOperators[msg.sender][_operator] = _approved;
emit ApprovalForAll(msg.sender, _operator, _approved);
}
function getApproved(uint256 _tokenId) public view validNFToken(_tokenId) returns (address) {
return idToApprovals[_tokenId];
}
function isApprovedForAll(address _owner, address _operator) external view returns (bool) {
require(_owner != address(0));
require(_operator != address(0));
return ownerToOperators[_owner][_operator];
}
function _safeTransferFrom(address _from, address _to, uint256 _tokenId, bytes _data) internal canTransfer(_tokenId) validNFToken(_tokenId) {
address tokenOwner = idToOwner[_tokenId];
require(tokenOwner == _from);
require(_to != address(0));
_transfer(_to, _tokenId);
if (_to.isContract()) {
bytes4 retval = ERC721TokenReceiver(_to).onERC721Received(msg.sender, _from, _tokenId, _data);
require(retval == MAGIC_ON_ERC721_RECEIVED);
}
}
function _transfer(address _to, uint256 _tokenId) private {
address from = idToOwner[_tokenId];
clearApproval(_tokenId);
removeNFToken(from, _tokenId);
addNFToken(_to, _tokenId);
emit Transfer(from, _to, _tokenId);
}
function _mint(address _to, uint256 _tokenId) internal {
require(_to != address(0));
require(_tokenId != 0);
require(idToOwner[_tokenId] == address(0));
addNFToken(_to, _tokenId);
emit Transfer(address(0), _to, _tokenId);
}
function _burn(address _owner, uint256 _tokenId) validNFToken(_tokenId) internal {
clearApproval(_tokenId);
removeNFToken(_owner, _tokenId);
emit Transfer(_owner, address(0), _tokenId);
}
function clearApproval(uint256 _tokenId) private {
if(idToApprovals[_tokenId] != 0) {
delete idToApprovals[_tokenId];
}
}
function removeNFToken(address _from, uint256 _tokenId) internal {
require(idToOwner[_tokenId] == _from);
assert(ownerToNFTokenCount[_from] > 0);
ownerToNFTokenCount[_from] = ownerToNFTokenCount[_from] - 1;
delete idToOwner[_tokenId];
}
function addNFToken(address _to, uint256 _tokenId) internal {
require(idToOwner[_tokenId] == address(0));
idToOwner[_tokenId] = _to;
ownerToNFTokenCount[_to] = ownerToNFTokenCount[_to].add(1);
}
}
contract NFTokenEnumerable is NFToken, ERC721Enumerable {
// Array of all NFT IDs.
uint256[] internal tokens;
// Mapping from token ID its index in global tokens array.
mapping(uint256 => uint256) internal idToIndex;
// Mapping from owner to list of owned NFT IDs.
mapping(address => uint256[]) internal ownerToIds;
// Mapping from NFT ID to its index in the owner tokens list.
mapping(uint256 => uint256) internal idToOwnerIndex;
constructor() public {
supportedInterfaces[0x780e9d63] = true; // ERC721Enumerable
}
function _mint(address _to, uint256 _tokenId) internal {
super._mint(_to, _tokenId);
uint256 length = tokens.push(_tokenId);
idToIndex[_tokenId] = length - 1;
}
function _burn(address _owner, uint256 _tokenId) internal {
super._burn(_owner, _tokenId);
assert(tokens.length > 0);
uint256 tokenIndex = idToIndex[_tokenId];
// Sanity check. This could be removed in the future.
assert(tokens[tokenIndex] == _tokenId);
uint256 lastTokenIndex = tokens.length - 1;
uint256 lastToken = tokens[lastTokenIndex];
tokens[tokenIndex] = lastToken;
tokens.length--;
// Consider adding a conditional check for the last token in order to save GAS.
idToIndex[lastToken] = tokenIndex;
idToIndex[_tokenId] = 0;
}
function removeNFToken(address _from, uint256 _tokenId) internal
{
super.removeNFToken(_from, _tokenId);
assert(ownerToIds[_from].length > 0);
uint256 tokenToRemoveIndex = idToOwnerIndex[_tokenId];
uint256 lastTokenIndex = ownerToIds[_from].length - 1;
uint256 lastToken = ownerToIds[_from][lastTokenIndex];
ownerToIds[_from][tokenToRemoveIndex] = lastToken;
ownerToIds[_from].length--;
// Consider adding a conditional check for the last token in order to save GAS.
idToOwnerIndex[lastToken] = tokenToRemoveIndex;
idToOwnerIndex[_tokenId] = 0;
}
function addNFToken(address _to, uint256 _tokenId) internal {
super.addNFToken(_to, _tokenId);
uint256 length = ownerToIds[_to].push(_tokenId);
idToOwnerIndex[_tokenId] = length - 1;
}
function totalSupply() external view returns (uint256) {
return tokens.length;
}
function tokenByIndex(uint256 _index) external view returns (uint256) {
require(_index < tokens.length);
// Sanity check. This could be removed in the future.
assert(idToIndex[tokens[_index]] == _index);
return tokens[_index];
}
function tokenOfOwnerByIndex(address _owner, uint256 _index) external view returns (uint256) {
require(_index < ownerToIds[_owner].length);
return ownerToIds[_owner][_index];
}
}
contract NFTStandard is NFTokenEnumerable, ERC721Metadata {
string internal nftName;
string internal nftSymbol;
mapping (uint256 => string) internal idToUri;
constructor(string _name, string _symbol) public {
nftName = _name;
nftSymbol = _symbol;
supportedInterfaces[0x5b5e139f] = true; // ERC721Metadata
}
function _burn(address _owner, uint256 _tokenId) internal {
super._burn(_owner, _tokenId);
if (bytes(idToUri[_tokenId]).length != 0) {
delete idToUri[_tokenId];
}
}
function _setTokenUri(uint256 _tokenId, string _uri) validNFToken(_tokenId) internal {
idToUri[_tokenId] = _uri;
}
function name() external view returns (string _name) {
_name = nftName;
}
function symbol() external view returns (string _symbol) {
_symbol = nftSymbol;
}
function tokenURI(uint256 _tokenId) validNFToken(_tokenId) external view returns (string) {
return idToUri[_tokenId];
}
}
contract BasicAccessControl {
address public owner;
// address[] public moderators;
uint16 public totalModerators = 0;
mapping (address => bool) public moderators;
bool public isMaintaining = false;
constructor() public {
owner = msg.sender;
}
modifier onlyOwner {
require(msg.sender == owner);
_;
}
modifier onlyModerators() {
require(msg.sender == owner || moderators[msg.sender] == true);
_;
}
modifier isActive {
require(!isMaintaining);
_;
}
function ChangeOwner(address _newOwner) onlyOwner public {
if (_newOwner != address(0)) {
owner = _newOwner;
}
}
function AddModerator(address _newModerator) onlyOwner public {
if (moderators[_newModerator] == false) {
moderators[_newModerator] = true;
totalModerators += 1;
}
}
function RemoveModerator(address _oldModerator) onlyOwner public {
if (moderators[_oldModerator] == true) {
moderators[_oldModerator] = false;
totalModerators -= 1;
}
}
function UpdateMaintaining(bool _isMaintaining) onlyOwner public {
isMaintaining = _isMaintaining;
}
}
interface EtheremonAdventureHandler {
function handleSingleItem(address _sender, uint _classId, uint _value, uint _target, uint _param) external;
function handleMultipleItems(address _sender, uint _classId1, uint _classId2, uint _classId3, uint _target, uint _param) external;
}
contract EtheremonAdventureItem is NFTStandard("EtheremonAdventure", "EMOND"), BasicAccessControl {
uint constant public MAX_OWNER_PERS_SITE = 10;
uint constant public MAX_SITE_ID = 108;
uint constant public MAX_SITE_TOKEN_ID = 1080;
// smartcontract
address public adventureHandler;
// class sites: 1 -> 108
// shard: 109 - 126
// level, exp
struct Item {
uint classId;
uint value;
}
uint public totalItem = MAX_SITE_TOKEN_ID;
mapping (uint => Item) public items; // token id => info
modifier requireAdventureHandler {
require(adventureHandler != address(0));
_;
}
function setAdventureHandler(address _adventureHandler) onlyModerators external {
adventureHandler = _adventureHandler;
}
function setTokenURI(uint256 _tokenId, string _uri) onlyModerators external {
_setTokenUri(_tokenId, _uri);
}
function spawnSite(uint _classId, uint _tokenId, address _owner) onlyModerators external {
if (_owner == address(0)) revert();
if (_classId > MAX_SITE_ID || _classId == 0 || _tokenId > MAX_SITE_TOKEN_ID || _tokenId == 0) revert();
Item storage item = items[_tokenId];
if (item.classId != 0) revert(); // token existed
item.classId = _classId;
_mint(_owner, _tokenId);
}
function spawnItem(uint _classId, uint _value, address _owner) onlyModerators external returns(uint) {
if (_owner == address(0)) revert();
if (_classId <= MAX_SITE_ID) revert();
totalItem += 1;
Item storage item = items[totalItem];
item.classId = _classId;
item.value = _value;
_mint(_owner, totalItem);
return totalItem;
}
// public write
function useSingleItem(uint _tokenId, uint _target, uint _param) isActive requireAdventureHandler public {
// check ownership
if (_tokenId == 0 || idToOwner[_tokenId] != msg.sender) revert();
Item storage item = items[_tokenId];
EtheremonAdventureHandler handler = EtheremonAdventureHandler(adventureHandler);
handler.handleSingleItem(msg.sender, item.classId, item.value, _target, _param);
_burn(msg.sender, _tokenId);
}
function useMultipleItem(uint _token1, uint _token2, uint _token3, uint _target, uint _param) isActive requireAdventureHandler public {
if (_token1 > 0 && idToOwner[_token1] != msg.sender) revert();
if (_token2 > 0 && idToOwner[_token2] != msg.sender) revert();
if (_token3 > 0 && idToOwner[_token3] != msg.sender) revert();
Item storage item1 = items[_token1];
Item storage item2 = items[_token2];
Item storage item3 = items[_token3];
EtheremonAdventureHandler handler = EtheremonAdventureHandler(adventureHandler);
handler.handleMultipleItems(msg.sender, item1.classId, item2.classId, item3.classId, _target, _param);
if (_token1 > 0) _burn(msg.sender, _token1);
if (_token2 > 0) _burn(msg.sender, _token2);
if (_token3 > 0) _burn(msg.sender, _token3);
}
// public read
function getItemInfo(uint _tokenId) constant public returns(uint classId, uint value) {
Item storage item = items[_tokenId];
classId = item.classId;
value = item.value;
}
}File 3 of 4: EtheremonAdventureData
pragma solidity ^0.4.23;
/**
* @title SafeMath
* @dev Math operations with safety checks that throw on error
*/
library SafeMath {
/**
* @dev Multiplies two numbers, throws on overflow.
*/
function mul(uint256 a, uint256 b) internal pure returns (uint256 c) {
if (a == 0) {
return 0;
}
c = a * b;
assert(c / a == b);
return c;
}
/**
* @dev Integer division of two numbers, truncating the quotient.
*/
function div(uint256 a, uint256 b) internal pure returns (uint256) {
// assert(b > 0); // Solidity automatically throws when dividing by 0
// uint256 c = a / b;
// assert(a == b * c + a % b); // There is no case in which this doesn't hold
return a / b;
}
/**
* @dev Subtracts two numbers, throws on overflow (i.e. if subtrahend is greater than minuend).
*/
function sub(uint256 a, uint256 b) internal pure returns (uint256) {
assert(b <= a);
return a - b;
}
/**
* @dev Adds two numbers, throws on overflow.
*/
function add(uint256 a, uint256 b) internal pure returns (uint256 c) {
c = a + b;
assert(c >= a);
return c;
}
}
contract BasicAccessControl {
address public owner;
// address[] public moderators;
uint16 public totalModerators = 0;
mapping (address => bool) public moderators;
bool public isMaintaining = false;
constructor() public {
owner = msg.sender;
}
modifier onlyOwner {
require(msg.sender == owner);
_;
}
modifier onlyModerators() {
require(msg.sender == owner || moderators[msg.sender] == true);
_;
}
modifier isActive {
require(!isMaintaining);
_;
}
function ChangeOwner(address _newOwner) onlyOwner public {
if (_newOwner != address(0)) {
owner = _newOwner;
}
}
function AddModerator(address _newModerator) onlyOwner public {
if (moderators[_newModerator] == false) {
moderators[_newModerator] = true;
totalModerators += 1;
}
}
function RemoveModerator(address _oldModerator) onlyOwner public {
if (moderators[_oldModerator] == true) {
moderators[_oldModerator] = false;
totalModerators -= 1;
}
}
function UpdateMaintaining(bool _isMaintaining) onlyOwner public {
isMaintaining = _isMaintaining;
}
}
contract EtheremonAdventureData is BasicAccessControl {
using SafeMath for uint;
struct LandTokenClaim {
uint emontAmount;
uint etherAmount;
}
// total revenue
struct LandRevenue {
uint emontAmount;
uint etherAmount;
}
struct ExploreData {
address sender;
uint typeId;
uint monsterId;
uint siteId;
uint itemSeed;
uint startAt; // blocknumber
}
uint public exploreCount = 0;
mapping(uint => ExploreData) public exploreData; // explore count => data
mapping(address => uint) public explorePending; // address => explore id
mapping(uint => LandTokenClaim) public claimData; // tokenid => claim info
mapping(uint => LandRevenue) public siteData; // class id => amount
function addLandRevenue(uint _siteId, uint _emontAmount, uint _etherAmount) onlyModerators external {
LandRevenue storage revenue = siteData[_siteId];
revenue.emontAmount = revenue.emontAmount.add(_emontAmount);
revenue.etherAmount = revenue.etherAmount.add(_etherAmount);
}
function addTokenClaim(uint _tokenId, uint _emontAmount, uint _etherAmount) onlyModerators external {
LandTokenClaim storage claim = claimData[_tokenId];
claim.emontAmount = claim.emontAmount.add(_emontAmount);
claim.etherAmount = claim.etherAmount.add(_etherAmount);
}
function addExploreData(address _sender, uint _typeId, uint _monsterId, uint _siteId, uint _startAt, uint _emontAmount, uint _etherAmount) onlyModerators external returns(uint){
if (explorePending[_sender] > 0) revert();
exploreCount += 1;
ExploreData storage data = exploreData[exploreCount];
data.sender = _sender;
data.typeId = _typeId;
data.monsterId = _monsterId;
data.siteId = _siteId;
data.itemSeed = 0;
data.startAt = _startAt;
explorePending[_sender] = exploreCount;
LandRevenue storage revenue = siteData[_siteId];
revenue.emontAmount = revenue.emontAmount.add(_emontAmount);
revenue.etherAmount = revenue.etherAmount.add(_etherAmount);
return exploreCount;
}
function removePendingExplore(uint _exploreId, uint _itemSeed) onlyModerators external {
ExploreData storage data = exploreData[_exploreId];
if (explorePending[data.sender] != _exploreId)
revert();
explorePending[data.sender] = 0;
data.itemSeed = _itemSeed;
}
// public function
function getLandRevenue(uint _classId) constant public returns(uint _emontAmount, uint _etherAmount) {
LandRevenue storage revenue = siteData[_classId];
return (revenue.emontAmount, revenue.etherAmount);
}
function getTokenClaim(uint _tokenId) constant public returns(uint _emontAmount, uint _etherAmount) {
LandTokenClaim storage claim = claimData[_tokenId];
return (claim.emontAmount, claim.etherAmount);
}
function getExploreData(uint _exploreId) constant public returns(address _sender, uint _typeId, uint _monsterId, uint _siteId, uint _itemSeed, uint _startAt) {
ExploreData storage data = exploreData[_exploreId];
return (data.sender, data.typeId, data.monsterId, data.siteId, data.itemSeed, data.startAt);
}
function getPendingExplore(address _player) constant public returns(uint) {
return explorePending[_player];
}
function getPendingExploreData(address _player) constant public returns(uint _exploreId, uint _typeId, uint _monsterId, uint _siteId, uint _itemSeed, uint _startAt) {
_exploreId = explorePending[_player];
if (_exploreId > 0) {
ExploreData storage data = exploreData[_exploreId];
return (_exploreId, data.typeId, data.monsterId, data.siteId, data.itemSeed, data.startAt);
}
}
}File 4 of 4: EtheremonAdventureSetting
pragma solidity ^0.4.23;
contract BasicAccessControl {
address public owner;
// address[] public moderators;
uint16 public totalModerators = 0;
mapping (address => bool) public moderators;
bool public isMaintaining = false;
constructor() public {
owner = msg.sender;
}
modifier onlyOwner {
require(msg.sender == owner);
_;
}
modifier onlyModerators() {
require(msg.sender == owner || moderators[msg.sender] == true);
_;
}
modifier isActive {
require(!isMaintaining);
_;
}
function ChangeOwner(address _newOwner) onlyOwner public {
if (_newOwner != address(0)) {
owner = _newOwner;
}
}
function AddModerator(address _newModerator) onlyOwner public {
if (moderators[_newModerator] == false) {
moderators[_newModerator] = true;
totalModerators += 1;
}
}
function RemoveModerator(address _oldModerator) onlyOwner public {
if (moderators[_oldModerator] == true) {
moderators[_oldModerator] = false;
totalModerators -= 1;
}
}
function UpdateMaintaining(bool _isMaintaining) onlyOwner public {
isMaintaining = _isMaintaining;
}
}
contract EtheremonAdventureSetting is BasicAccessControl {
struct RewardData {
uint monster_rate;
uint monster_id;
uint shard_rate;
uint shard_id;
uint level_rate;
uint exp_rate;
uint emont_rate;
}
mapping(uint => uint[]) public siteSet; // monster class -> site id
mapping(uint => uint) public monsterClassSiteSet;
mapping(uint => RewardData) public siteRewards; // site id => rewards (monster_rate, monster_id, shard_rate, shard_id, level_rate, exp_rate, emont_rate)
uint public levelItemClass = 200;
uint public expItemClass = 201;
uint[4] public levelRewards = [1, 1, 1, 2];
uint[11] public expRewards = [50, 50, 50, 50, 100, 100, 100, 100, 200, 200, 500];
uint[6] public emontRewards = [300000000, 300000000, 500000000, 500000000, 1000000000, 150000000];
function setConfig(uint _levelItemClass, uint _expItemClass) onlyModerators public {
levelItemClass = _levelItemClass;
expItemClass = _expItemClass;
}
function addSiteSet(uint _setId, uint _siteId) onlyModerators public {
uint[] storage siteList = siteSet[_setId];
for (uint index = 0; index < siteList.length; index++) {
if (siteList[index] == _siteId) {
return;
}
}
siteList.push(_siteId);
}
function removeSiteSet(uint _setId, uint _siteId) onlyModerators public {
uint[] storage siteList = siteSet[_setId];
uint foundIndex = 0;
for (; foundIndex < siteList.length; foundIndex++) {
if (siteList[foundIndex] == _siteId) {
break;
}
}
if (foundIndex < siteList.length) {
siteList[foundIndex] = siteList[siteList.length-1];
delete siteList[siteList.length-1];
siteList.length--;
}
}
function setMonsterClassSiteSet(uint _monsterId, uint _siteSetId) onlyModerators public {
monsterClassSiteSet[_monsterId] = _siteSetId;
}
function setSiteRewards(uint _siteId, uint _monster_rate, uint _monster_id, uint _shard_rate, uint _shard_id, uint _level_rate, uint _exp_rate, uint _emont_rate) onlyModerators public {
RewardData storage reward = siteRewards[_siteId];
reward.monster_rate = _monster_rate;
reward.monster_id = _monster_id;
reward.shard_rate = _shard_rate;
reward.shard_id = _shard_id;
reward.level_rate = _level_rate;
reward.exp_rate = _exp_rate;
reward.emont_rate = _emont_rate;
}
function setLevelRewards(uint _index, uint _value) onlyModerators public {
levelRewards[_index] = _value;
}
function setExpRewards(uint _index, uint _value) onlyModerators public {
expRewards[_index] = _value;
}
function setEmontRewards(uint _index, uint _value) onlyModerators public {
emontRewards[_index] = _value;
}
function initSiteSet(uint _turn) onlyModerators public {
if (_turn == 1) {
siteSet[1] = [35, 3, 4, 37, 51, 8, 41, 11, 45, 47, 15, 16, 19, 52, 23, 36, 27, 30, 31];
siteSet[2] = [35, 3, 4, 49, 39, 8, 41, 11, 13, 15, 48, 43, 18, 19, 53, 23, 27, 30, 31];
siteSet[3] = [2, 4, 39, 40, 9, 47, 12, 14, 44, 16, 49, 20, 46, 54, 24, 25, 27, 36, 29, 31];
siteSet[4] = [51, 3, 5, 38, 7, 40, 11, 12, 45, 14, 47, 16, 35, 52, 21, 22, 26, 30, 31];
siteSet[5] = [33, 3, 4, 54, 38, 8, 10, 43, 45, 14, 50, 18, 35, 21, 22, 46, 26, 28, 42];
siteSet[6] = [51, 3, 36, 5, 7, 44, 42, 12, 13, 47, 17, 37, 19, 52, 24, 26, 28, 29, 31];
siteSet[7] = [32, 48, 2, 43, 4, 38, 7, 9, 42, 11, 34, 15, 16, 49, 21, 23, 25, 30, 53];
siteSet[8] = [1, 34, 54, 6, 33, 8, 44, 39, 12, 13, 46, 17, 50, 20, 22, 40, 24, 25, 29];
siteSet[9] = [32, 2, 6, 7, 40, 10, 39, 44, 34, 15, 48, 17, 50, 20, 21, 24, 25, 29, 52];
siteSet[10] = [32, 1, 36, 5, 38, 48, 9, 11, 45, 15, 16, 49, 19, 41, 23, 27, 28, 53, 37];
} else {
siteSet[11] = [2, 35, 37, 6, 7, 10, 46, 44, 50, 14, 18, 51, 21, 22, 26, 53, 42, 30, 31];
siteSet[12] = [1, 34, 5, 51, 33, 9, 10, 45, 14, 47, 16, 18, 19, 52, 41, 23, 27, 29, 37];
siteSet[13] = [32, 2, 35, 4, 5, 38, 49, 9, 42, 43, 12, 13, 48, 17, 21, 24, 25, 28, 53];
siteSet[14] = [1, 34, 3, 37, 6, 33, 8, 41, 10, 45, 46, 15, 17, 50, 20, 54, 24, 25, 29];
siteSet[15] = [33, 2, 34, 6, 7, 40, 42, 11, 13, 47, 50, 43, 18, 20, 22, 39, 26, 30, 52];
siteSet[16] = [32, 1, 36, 5, 39, 54, 9, 10, 43, 14, 18, 51, 20, 46, 22, 41, 27, 28, 53];
siteSet[17] = [32, 1, 49, 36, 38, 6, 33, 8, 44, 12, 13, 48, 17, 19, 40, 54, 23, 26, 28];
}
}
function initMonsterClassSiteSet() onlyModerators public {
monsterClassSiteSet[1] = 1;
monsterClassSiteSet[2] = 2;
monsterClassSiteSet[3] = 3;
monsterClassSiteSet[4] = 4;
monsterClassSiteSet[5] = 5;
monsterClassSiteSet[6] = 6;
monsterClassSiteSet[7] = 7;
monsterClassSiteSet[8] = 8;
monsterClassSiteSet[9] = 8;
monsterClassSiteSet[10] = 2;
monsterClassSiteSet[11] = 9;
monsterClassSiteSet[12] = 10;
monsterClassSiteSet[13] = 11;
monsterClassSiteSet[14] = 12;
monsterClassSiteSet[15] = 3;
monsterClassSiteSet[16] = 13;
monsterClassSiteSet[17] = 3;
monsterClassSiteSet[18] = 8;
monsterClassSiteSet[19] = 8;
monsterClassSiteSet[20] = 14;
monsterClassSiteSet[21] = 13;
monsterClassSiteSet[22] = 4;
monsterClassSiteSet[23] = 9;
monsterClassSiteSet[24] = 1;
monsterClassSiteSet[25] = 1;
monsterClassSiteSet[26] = 3;
monsterClassSiteSet[27] = 2;
monsterClassSiteSet[28] = 6;
monsterClassSiteSet[29] = 4;
monsterClassSiteSet[30] = 14;
monsterClassSiteSet[31] = 10;
monsterClassSiteSet[32] = 1;
monsterClassSiteSet[33] = 15;
monsterClassSiteSet[34] = 3;
monsterClassSiteSet[35] = 3;
monsterClassSiteSet[36] = 2;
monsterClassSiteSet[37] = 8;
monsterClassSiteSet[38] = 1;
monsterClassSiteSet[39] = 2;
monsterClassSiteSet[40] = 3;
monsterClassSiteSet[41] = 4;
monsterClassSiteSet[42] = 5;
monsterClassSiteSet[43] = 6;
monsterClassSiteSet[44] = 7;
monsterClassSiteSet[45] = 8;
monsterClassSiteSet[46] = 8;
monsterClassSiteSet[47] = 2;
monsterClassSiteSet[48] = 9;
monsterClassSiteSet[49] = 10;
monsterClassSiteSet[50] = 8;
monsterClassSiteSet[51] = 14;
monsterClassSiteSet[52] = 1;
monsterClassSiteSet[53] = 3;
monsterClassSiteSet[54] = 2;
monsterClassSiteSet[55] = 6;
monsterClassSiteSet[56] = 4;
monsterClassSiteSet[57] = 14;
monsterClassSiteSet[58] = 10;
monsterClassSiteSet[59] = 1;
monsterClassSiteSet[60] = 15;
monsterClassSiteSet[61] = 3;
monsterClassSiteSet[62] = 8;
monsterClassSiteSet[63] = 8;
monsterClassSiteSet[64] = 1;
monsterClassSiteSet[65] = 2;
monsterClassSiteSet[66] = 4;
monsterClassSiteSet[67] = 5;
monsterClassSiteSet[68] = 14;
monsterClassSiteSet[69] = 1;
monsterClassSiteSet[70] = 3;
monsterClassSiteSet[71] = 3;
monsterClassSiteSet[72] = 16;
monsterClassSiteSet[73] = 17;
monsterClassSiteSet[74] = 5;
monsterClassSiteSet[75] = 7;
monsterClassSiteSet[76] = 1;
monsterClassSiteSet[77] = 17;
monsterClassSiteSet[78] = 10;
monsterClassSiteSet[79] = 1;
monsterClassSiteSet[80] = 13;
monsterClassSiteSet[81] = 4;
monsterClassSiteSet[82] = 17;
monsterClassSiteSet[83] = 10;
monsterClassSiteSet[84] = 1;
monsterClassSiteSet[85] = 13;
monsterClassSiteSet[86] = 4;
monsterClassSiteSet[87] = 1;
monsterClassSiteSet[88] = 4;
monsterClassSiteSet[89] = 1;
monsterClassSiteSet[90] = 2;
monsterClassSiteSet[91] = 2;
monsterClassSiteSet[92] = 2;
monsterClassSiteSet[93] = 15;
monsterClassSiteSet[94] = 15;
monsterClassSiteSet[95] = 15;
monsterClassSiteSet[96] = 12;
monsterClassSiteSet[97] = 12;
monsterClassSiteSet[98] = 12;
monsterClassSiteSet[99] = 5;
monsterClassSiteSet[100] = 5;
monsterClassSiteSet[101] = 8;
monsterClassSiteSet[102] = 8;
monsterClassSiteSet[103] = 2;
monsterClassSiteSet[104] = 2;
monsterClassSiteSet[105] = 15;
monsterClassSiteSet[106] = 1;
monsterClassSiteSet[107] = 1;
monsterClassSiteSet[108] = 1;
monsterClassSiteSet[109] = 9;
monsterClassSiteSet[110] = 10;
monsterClassSiteSet[111] = 13;
monsterClassSiteSet[112] = 11;
monsterClassSiteSet[113] = 14;
monsterClassSiteSet[114] = 6;
monsterClassSiteSet[115] = 8;
monsterClassSiteSet[116] = 3;
monsterClassSiteSet[117] = 3;
monsterClassSiteSet[118] = 3;
monsterClassSiteSet[119] = 13;
monsterClassSiteSet[120] = 13;
monsterClassSiteSet[121] = 13;
monsterClassSiteSet[122] = 5;
monsterClassSiteSet[123] = 5;
monsterClassSiteSet[124] = 5;
monsterClassSiteSet[125] = 15;
monsterClassSiteSet[126] = 15;
monsterClassSiteSet[127] = 15;
monsterClassSiteSet[128] = 1;
monsterClassSiteSet[129] = 1;
monsterClassSiteSet[130] = 1;
monsterClassSiteSet[131] = 14;
monsterClassSiteSet[132] = 14;
monsterClassSiteSet[133] = 14;
monsterClassSiteSet[134] = 16;
monsterClassSiteSet[135] = 16;
monsterClassSiteSet[136] = 13;
monsterClassSiteSet[137] = 13;
monsterClassSiteSet[138] = 4;
monsterClassSiteSet[139] = 4;
monsterClassSiteSet[140] = 7;
monsterClassSiteSet[141] = 7;
monsterClassSiteSet[142] = 4;
monsterClassSiteSet[143] = 4;
monsterClassSiteSet[144] = 13;
monsterClassSiteSet[145] = 13;
monsterClassSiteSet[146] = 9;
monsterClassSiteSet[147] = 9;
monsterClassSiteSet[148] = 14;
monsterClassSiteSet[149] = 14;
monsterClassSiteSet[150] = 14;
monsterClassSiteSet[151] = 1;
monsterClassSiteSet[152] = 1;
monsterClassSiteSet[153] = 12;
monsterClassSiteSet[154] = 9;
monsterClassSiteSet[155] = 14;
monsterClassSiteSet[156] = 16;
monsterClassSiteSet[157] = 16;
monsterClassSiteSet[158] = 8;
}
function initSiteRewards(uint _turn) onlyModerators public {
if (_turn == 1) {
siteRewards[1] = RewardData(25, 116, 350, 350, 50, 350, 225);
siteRewards[2] = RewardData(25, 119, 350, 350, 50, 350, 225);
siteRewards[3] = RewardData(25, 122, 350, 350, 50, 350, 225);
siteRewards[4] = RewardData(25, 116, 350, 351, 50, 350, 225);
siteRewards[5] = RewardData(25, 119, 350, 351, 50, 350, 225);
siteRewards[6] = RewardData(25, 122, 350, 351, 50, 350, 225);
siteRewards[7] = RewardData(25, 116, 350, 352, 50, 350, 225);
siteRewards[8] = RewardData(25, 119, 350, 352, 50, 350, 225);
siteRewards[9] = RewardData(25, 122, 350, 352, 50, 350, 225);
siteRewards[10] = RewardData(25, 125, 350, 320, 50, 350, 225);
siteRewards[11] = RewardData(25, 128, 350, 320, 50, 350, 225);
siteRewards[12] = RewardData(25, 131, 350, 320, 50, 350, 225);
siteRewards[13] = RewardData(25, 125, 350, 321, 50, 350, 225);
siteRewards[14] = RewardData(25, 128, 350, 321, 50, 350, 225);
siteRewards[15] = RewardData(25, 131, 350, 321, 50, 350, 225);
siteRewards[16] = RewardData(25, 125, 350, 322, 50, 350, 225);
siteRewards[17] = RewardData(25, 128, 350, 322, 50, 350, 225);
siteRewards[18] = RewardData(25, 131, 350, 322, 50, 350, 225);
siteRewards[19] = RewardData(25, 134, 350, 340, 50, 350, 225);
siteRewards[20] = RewardData(25, 136, 350, 340, 50, 350, 225);
siteRewards[21] = RewardData(25, 138, 350, 340, 50, 350, 225);
siteRewards[22] = RewardData(25, 134, 350, 341, 50, 350, 225);
siteRewards[23] = RewardData(25, 136, 350, 341, 50, 350, 225);
siteRewards[24] = RewardData(25, 138, 350, 341, 50, 350, 225);
siteRewards[25] = RewardData(25, 134, 350, 342, 50, 350, 225);
siteRewards[26] = RewardData(25, 136, 350, 342, 50, 350, 225);
siteRewards[27] = RewardData(25, 138, 350, 342, 50, 350, 225);
} else {
siteRewards[28] = RewardData(25, 140, 350, 300, 50, 350, 225);
siteRewards[29] = RewardData(25, 142, 350, 300, 50, 350, 225);
siteRewards[30] = RewardData(25, 144, 350, 300, 50, 350, 225);
siteRewards[31] = RewardData(25, 140, 350, 301, 50, 350, 225);
siteRewards[32] = RewardData(25, 142, 350, 301, 50, 350, 225);
siteRewards[33] = RewardData(25, 144, 350, 301, 50, 350, 225);
siteRewards[34] = RewardData(25, 140, 350, 302, 50, 350, 225);
siteRewards[35] = RewardData(25, 142, 350, 302, 50, 350, 225);
siteRewards[36] = RewardData(25, 144, 350, 302, 50, 350, 225);
siteRewards[37] = RewardData(25, 153, 350, 310, 50, 350, 225);
siteRewards[38] = RewardData(25, 154, 350, 310, 50, 350, 225);
siteRewards[39] = RewardData(25, 155, 350, 310, 50, 350, 225);
siteRewards[40] = RewardData(25, 146, 350, 311, 50, 350, 225);
siteRewards[41] = RewardData(25, 148, 350, 311, 50, 350, 225);
siteRewards[42] = RewardData(25, 151, 350, 311, 50, 350, 225);
siteRewards[43] = RewardData(25, 146, 350, 312, 50, 350, 225);
siteRewards[44] = RewardData(25, 148, 350, 312, 50, 350, 225);
siteRewards[45] = RewardData(25, 151, 350, 312, 50, 350, 225);
siteRewards[46] = RewardData(25, 151, 350, 330, 50, 350, 225);
siteRewards[47] = RewardData(25, 146, 350, 330, 50, 350, 225);
siteRewards[48] = RewardData(25, 148, 350, 330, 50, 350, 225);
siteRewards[49] = RewardData(5, 153, 350, 331, 50, 350, 245);
siteRewards[50] = RewardData(5, 154, 350, 331, 50, 350, 245);
siteRewards[51] = RewardData(5, 155, 350, 331, 50, 350, 245);
siteRewards[52] = RewardData(25, 151, 350, 332, 50, 350, 225);
siteRewards[53] = RewardData(25, 146, 350, 332, 50, 350, 225);
siteRewards[54] = RewardData(25, 148, 350, 332, 50, 350, 225);
}
}
function getSiteRewards(uint _siteId) constant public returns(uint monster_rate, uint monster_id, uint shard_rate, uint shard_id, uint level_rate, uint exp_rate, uint emont_rate) {
RewardData storage reward = siteRewards[_siteId];
return (reward.monster_rate, reward.monster_id, reward.shard_rate, reward.shard_id, reward.level_rate, reward.exp_rate, reward.emont_rate);
}
function getSiteId(uint _classId, uint _seed) constant public returns(uint) {
uint[] storage siteList = siteSet[monsterClassSiteSet[_classId]];
if (siteList.length == 0) return 0;
return siteList[_seed % siteList.length];
}
function getSiteItem(uint _siteId, uint _seed) constant public returns(uint _monsterClassId, uint _tokenClassId, uint _value) {
uint value = _seed % 1000;
RewardData storage reward = siteRewards[_siteId];
// assign monster
if (value < reward.monster_rate) {
return (reward.monster_id, 0, 0);
}
value -= reward.monster_rate;
// shard
if (value < reward.shard_rate) {
return (0, reward.shard_id, 0);
}
value -= reward.shard_rate;
// level
if (value < reward.level_rate) {
return (0, levelItemClass, levelRewards[value%4]);
}
value -= reward.level_rate;
// exp
if (value < reward.exp_rate) {
return (0, expItemClass, expRewards[value%11]);
}
value -= reward.exp_rate;
return (0, 0, emontRewards[value%6]);
}
}