18.16
($-1.65%)
| 1 Gwei
// SPDX-License-Identifier: GLWTPL pragma solidity ^0.8.11; contract tmwstw_light_vehicles{ string private token_name = "TMWSTW Light Vehicles"; string private token_symbol = "TMWSTW_LV"; address private contract_creator; string private base_uri = ""; address public slag_contract; address public PR_address; address public inventory_address; uint private VEHICLE_PRICE = 100; uint private last_token_id = 0; //AT START constructor(){ contract_creator = msg.sender; base_uri = "https://meta.tmwstw.io/meta_lvr_"; slag_contract = 0xa1Ccb330165cda264f35De7630De084e83d39134; PR_address = 0xA9f7CfcA37bF53cD7F33bC4408990Ff90915960c; inventory_address = 0x9AaF1be2a532738A501E4934C4Bb6c2F06eB4085; } //MAPS mapping(uint => address) private token_ownership;// Mapping from token ID to owner address mapping(address => uint256) private balance_per_owner;// Mapping owner address to token count mapping(uint => address) private approval_per_token;// Mapping from token ID to approved address mapping(address => mapping(address => bool)) private operator_approvals;// Mapping from owner to operator approvals mapping(uint => address) private asset_holder;// Mapping from token ID to address of current holder //.............................CONTRACTS function register_SLAG(address thi_address)public CREATOR_ONLY{ slag_contract = thi_address; } function register_P_ROUTERS(address thi_address)public CREATOR_ONLY{ PR_address = thi_address; } function register_INVENTORY(address thi_address)public CREATOR_ONLY{ inventory_address = thi_address; } //...................................CRAFT functions //CRAFT DATA MAPS -- always use this order struct vehicle_data{ //256/256 uint16 mesh_id; // 1 to 64k+ uint16 plot_id; // TOKYO = 1 uint8 body_type; //1 = classic_mesh,2 = nft_box,3 = pool_mesh, uint8 player_pose_type; //1 = streight_stand/ 2 = side_stand/ 3 = chair_sit/4 = yoga_sit/5 = horse_sit/ 6 = lay/ 7 = levitate uint8 movement_type; //1 = hoover/2 = flyer/3 = roller/4 = swimmer uint8 fuel_type; //fuel_type_id uint8 speed; //multiplier remaped to 256 uint8 rand_var_0; //for future uint8 weight; //make uint16 if needed uint8 gas_usage; uint8 reliability;// 1 to 10 uint8 rand_var_1; //for future uint8 rand_var_2; //for future bool is_broken; bool anti_theft; bool anti_drop;//new bool craft_complete;//new uint8 world_location_mode;// 1 = inventory/ 2 = locker/3 = post_box/ 4 = world int32 pos_x; //100,000x position int32 pos_y; //100,000x position int32 pos_z; //100,000x position } mapping(uint => vehicle_data) private data_per_vehicle; //..................................CRAFT function craft( address new_owner, uint16[] calldata all_uints16, //mesh_id,plot_id uint8[] calldata all_uints8, //12 uint8s bool[] calldata all_bools, //anti_theft,anti_drop,craft_complete int32[] calldata pos_array )public{ require(PR(PR_address).is_personal_router(msg.sender,new_owner),"Bad personal router"); SLAG(slag_contract).transferFrom(new_owner,slag_contract,VEHICLE_PRICE); uint this_token_id = last_token_id + 1; require(new_owner != address(0),"cant be minted to null"); require(token_ownership[this_token_id] == address(0),"token already exists"); balance_per_owner[new_owner] += 1; token_ownership[this_token_id] = new_owner; //store onchain data data_per_vehicle[this_token_id].mesh_id = all_uints16[0]; data_per_vehicle[this_token_id].plot_id = all_uints16[1]; data_per_vehicle[this_token_id].body_type = all_uints8[0]; data_per_vehicle[this_token_id].player_pose_type = all_uints8[1]; data_per_vehicle[this_token_id].movement_type = all_uints8[2]; data_per_vehicle[this_token_id].fuel_type = all_uints8[3]; data_per_vehicle[this_token_id].speed = all_uints8[4]; data_per_vehicle[this_token_id].rand_var_0 = all_uints8[5]; data_per_vehicle[this_token_id].weight = all_uints8[6]; data_per_vehicle[this_token_id].gas_usage = all_uints8[7]; data_per_vehicle[this_token_id].reliability = all_uints8[8]; data_per_vehicle[this_token_id].rand_var_1 = all_uints8[9]; data_per_vehicle[this_token_id].rand_var_2 = all_uints8[10]; data_per_vehicle[this_token_id].is_broken = false; data_per_vehicle[this_token_id].anti_theft = all_bools[0]; data_per_vehicle[this_token_id].anti_drop = all_bools[1]; data_per_vehicle[this_token_id].craft_complete = all_bools[2]; data_per_vehicle[this_token_id].world_location_mode = 4;//always crafted to world change_xyz(this_token_id,pos_array[0],pos_array[1],pos_array[2]); //update inventory INVENTORY(inventory_address).move_asset_at_craft(new_owner,address(this),this_token_id); last_token_id = this_token_id; // update last id emit Transfer(address(0), new_owner, this_token_id); } //ALL COMBINED DATA function retrieve_data(uint this_token_id)public view returns( uint8[16] memory, //all uint8s int32[3] memory, //pos uint16[2] memory, //mesh_id , plot_id address, //owner address //current holder ){ require(token_exists(this_token_id), "Token doesn't exist"); return ( [ data_per_vehicle[this_token_id].body_type, data_per_vehicle[this_token_id].player_pose_type, data_per_vehicle[this_token_id].movement_type, data_per_vehicle[this_token_id].fuel_type, data_per_vehicle[this_token_id].speed, data_per_vehicle[this_token_id].rand_var_0, data_per_vehicle[this_token_id].weight, data_per_vehicle[this_token_id].gas_usage, data_per_vehicle[this_token_id].reliability, data_per_vehicle[this_token_id].rand_var_1, data_per_vehicle[this_token_id].rand_var_2, bool_to_uint8(data_per_vehicle[this_token_id].is_broken), bool_to_uint8(data_per_vehicle[this_token_id].anti_theft), bool_to_uint8(data_per_vehicle[this_token_id].anti_drop), bool_to_uint8(data_per_vehicle[this_token_id].craft_complete), data_per_vehicle[this_token_id].world_location_mode ], [ data_per_vehicle[this_token_id].pos_x, data_per_vehicle[this_token_id].pos_y, data_per_vehicle[this_token_id].pos_z ], [ data_per_vehicle[this_token_id].mesh_id, data_per_vehicle[this_token_id].plot_id ], token_ownership[this_token_id], asset_holder[this_token_id] ); } //....................................BURN //burn asset in ownership by owner only in market state function burn_token(uint this_token_id)public{ require(token_exists(this_token_id), "Token doesn't exist"); require(is_owner(this_token_id,msg.sender), "Wrong owner"); require(is_in_postbox(this_token_id), "Cant be burned outside of postbox"); balance_per_owner[msg.sender] -= 1; token_ownership[this_token_id] = address(0); emit Transfer(msg.sender, address(0), this_token_id); } //..............................BREAK/FIX vehicle //fixed by personal router after spending ffix resource //broken by personal router after some action is taken (insures router is topped up) function break_fix_vehicle(uint this_token_id,bool this_action)public{ require(token_exists(this_token_id), "Token doesn't exist"); address this_owner = token_ownership[this_token_id]; require(PR(PR_address).is_personal_router(msg.sender,this_owner),"Bad personal router"); require(data_per_vehicle[this_token_id].is_broken != this_action,"Cant apply similar action"); data_per_vehicle[this_token_id].is_broken = this_action; emit break_fix_event(this_token_id,this_action); } event break_fix_event(uint token_id,bool is_broken); //// 1 = inventory/ 2 = locker/3 = post_box/ 4 = world ///.............................WORLD MODE/STATES function change_world_location_mode(address requester,uint this_token_id,uint8 new_mode,int32 pos_x,int32 pos_y,int32 pos_z,uint16 plot_id)public{ require(token_exists(this_token_id), "Token doesn't exist"); require(PR(PR_address).is_personal_router(msg.sender,requester),"Bad personal router"); //for chief (non owner) if(token_ownership[this_token_id] != requester){ require(if_chief_actions_allowed(this_token_id,new_mode),"Not allowed outside of ownership"); } uint8 weight = data_per_vehicle[this_token_id].weight; INVENTORY(inventory_address).move_asset(new_mode,requester,address(this),this_token_id,weight); if(new_mode == 4){ asset_holder[this_token_id] = address(0); change_xyz(this_token_id,pos_x,pos_y,pos_z); data_per_vehicle[this_token_id].plot_id = plot_id; } else if(new_mode == 3){ asset_holder[this_token_id] = address(0); change_xyz(this_token_id,0,0,0); data_per_vehicle[this_token_id].plot_id = 0; } else{ asset_holder[this_token_id] = requester; change_xyz(this_token_id,0,0,0); data_per_vehicle[this_token_id].plot_id = 0; } data_per_vehicle[this_token_id].world_location_mode = new_mode; emit world_location_mode_changed(this_token_id,new_mode); } event world_location_mode_changed(uint token_id,uint8 moved_to); function change_xyz(uint this_token_id,int32 pos_x,int32 pos_y,int32 pos_z)internal{ data_per_vehicle[this_token_id].pos_x = pos_x; data_per_vehicle[this_token_id].pos_y = pos_y; data_per_vehicle[this_token_id].pos_z = pos_z; } //for non owner only function if_chief_actions_allowed(uint this_token_id,uint8 new_mode)internal view returns(bool){ uint8 current_mode = data_per_vehicle[this_token_id].world_location_mode; //cant be moved to or from postbox if(current_mode != 3){ if(new_mode != 3){ return true; } } //check antithieft if(current_mode == 4){ //from world if(data_per_vehicle[this_token_id].anti_theft == false){ return true; } } return false; } //uint8 world_location_mode;// 1 = inventory/ 2 = locker/3 = post_box/ 4 = world //opens up market functionality function is_in_postbox(uint this_token_id)internal view returns(bool){ if(data_per_vehicle[this_token_id].world_location_mode == 3){ return true; } return false; } //COMPLETE CRAFT FOR CUSTOM_MESH function complete_custom_mesh_craft(address requester,uint token_id)public{ require(token_exists(token_id), "Token doesn't exist"); require(PR(PR_address).is_personal_router(msg.sender,requester),"Bad personal router"); require(data_per_vehicle[token_id].craft_complete == false, "Token already complete"); data_per_vehicle[token_id].craft_complete = true; emit custom_mesh_craft_complete(token_id); } event custom_mesh_craft_complete(uint token_id); //.............................MODIFIERS modifier CREATOR_ONLY { require(msg.sender == contract_creator,"must be creator"); _; } //...............................kinda ERC721 classics function name() external view returns (string memory){ return token_name; } function symbol() external view returns (string memory){ return token_symbol; } function tokenURI(uint this_token_id) external view returns (string memory){ require(token_exists(this_token_id),"Token doesn't exist"); string memory baseURI = base_uri; if(bytes(baseURI).length > 0){ string memory string_token = toString(this_token_id); return string(abi.encodePacked(baseURI, string_token)); } else{ return ""; } } function set_base_uri(string calldata this_base_uri)public CREATOR_ONLY{ base_uri = this_base_uri; } //good function balanceOf(address this_owner) external view returns (uint256){ require(this_owner != address(0), "Zero address has nothing in ownership"); return balance_per_owner[this_owner]; } //good function ownerOf(uint this_token_id) public view returns (address){ address this_owner = token_ownership[this_token_id]; require(this_owner != address(0), "Token doesn't exist"); return this_owner; } //ERC721 pack of transfers function safeTransferFrom(address from, address to, uint this_token_id) public{ safeTransferFrom(from, to, this_token_id, ""); } function safeTransferFrom(address from, address to, uint this_token_id, bytes memory ) public{ require(is_in_postbox(this_token_id), "Cant be transfered outside of postbox"); require(is_owner_or_approved(msg.sender, this_token_id),"not owner or approved"); transfer_token(from, to, this_token_id); } function transferFrom( address from,address to,uint this_token_id) public { require(is_in_postbox(this_token_id), "Cant be transfered outside of postbox"); require(is_owner_or_approved(msg.sender, this_token_id),"not owner or approved"); transfer_token(from, to, this_token_id); } //MAIN TRANSFER function transfer_token(address from,address to,uint this_token_id) internal { require(ownerOf(this_token_id) == from, "bad owner"); require(to != address(0), "no zero transfers"); inner_approve(address(0), this_token_id); // Clear approvals from the previous owner balance_per_owner[from] -= 1; balance_per_owner[to] += 1; token_ownership[this_token_id] = to; emit Transfer(from, to, this_token_id); } event Transfer(address indexed from, address indexed to, uint256 indexed token_id); //APPROVALS function approve(address to, uint this_token_id) public { address owner = ownerOf(this_token_id); require(to != owner, "cant approve to owner"); require(msg.sender == owner || isApprovedForAll(owner,msg.sender), "sender is not owner nor approved for all"); inner_approve(to, this_token_id); } function inner_approve(address to, uint this_token_id) internal { if(approval_per_token[this_token_id] != to){ approval_per_token[this_token_id] = to; emit Approval(ownerOf(this_token_id), to, this_token_id); } } event Approval(address indexed owner, address indexed is_approved, uint256 indexed token_id); function setApprovalForAll(address operator, bool approved) public { require(msg.sender != operator, "cant approve to itself"); operator_approvals[msg.sender][operator] = approved; emit ApprovalForAll(msg.sender, operator, approved); } event ApprovalForAll(address indexed owner, address indexed operator, bool is_approved); //Verify STF function is_owner_or_approved(address msg_sender, uint this_token_id) internal view returns (bool) { address this_owner = ownerOf(this_token_id); return (msg_sender == this_owner || isApprovedForAll(this_owner, msg_sender) || getApproved(this_token_id) == msg_sender); } function is_owner(uint this_token_id, address requester)internal view returns (bool){ address this_owner = ownerOf(this_token_id); if(this_owner == requester){ return true; } return false; } function isApprovedForAll(address this_owner, address operator) public view returns (bool) { return operator_approvals[this_owner][operator]; } function getApproved(uint this_token_id) public view returns (address) { require(token_exists(this_token_id), "Token doesn't exist"); return approval_per_token[this_token_id]; } function token_exists(uint this_token_id) public view returns (bool) { return token_ownership[this_token_id] != address(0); } //...................................INTERFACES function supportsInterface(bytes4 interface_id) external pure returns (bool){ return interface_id == 0x80ac58cd; } function onERC721Received(address ,address ,uint256 ,bytes calldata ) external pure returns (bytes4){ return 0; } //..........................................UTILS function toString(uint256 value) internal pure returns (string memory) { if (value == 0) { return "0"; } uint256 temp = value; uint256 digits; while (temp != 0) { digits++; temp /= 10; } bytes memory buffer = new bytes(digits); while (value != 0) { digits -= 1; buffer[digits] = bytes1(uint8(48 + uint256(value % 10))); value /= 10; } return string(buffer); } function bool_to_uint8(bool this_bool)internal pure returns(uint8){ if(this_bool == true){ return 1; } else{ return 0; } } } //.................. external contracts contract SLAG{ function transferFrom(address _from, address _to, uint256 _value) public {} } contract PR{ function is_personal_router(address p_router,address router_owner)public returns(bool){} } contract INVENTORY{ function move_asset_at_craft(address owner,address asset_address,uint token_id) public {} function move_asset(uint8 new_mode,address owner,address asset_address,uint token_id,uint8 weight) public {} }
[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"is_approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"token_id","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"is_approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"token_id","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"token_id","type":"uint256"},{"indexed":false,"internalType":"bool","name":"is_broken","type":"bool"}],"name":"break_fix_event","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"token_id","type":"uint256"}],"name":"custom_mesh_craft_complete","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"token_id","type":"uint256"},{"indexed":false,"internalType":"uint8","name":"moved_to","type":"uint8"}],"name":"world_location_mode_changed","type":"event"},{"inputs":[],"name":"PR_address","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"this_owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"},{"internalType":"bool","name":"this_action","type":"bool"}],"name":"break_fix_vehicle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"burn_token","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"requester","type":"address"},{"internalType":"uint256","name":"this_token_id","type":"uint256"},{"internalType":"uint8","name":"new_mode","type":"uint8"},{"internalType":"int32","name":"pos_x","type":"int32"},{"internalType":"int32","name":"pos_y","type":"int32"},{"internalType":"int32","name":"pos_z","type":"int32"},{"internalType":"uint16","name":"plot_id","type":"uint16"}],"name":"change_world_location_mode","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"requester","type":"address"},{"internalType":"uint256","name":"token_id","type":"uint256"}],"name":"complete_custom_mesh_craft","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"new_owner","type":"address"},{"internalType":"uint16[]","name":"all_uints16","type":"uint16[]"},{"internalType":"uint8[]","name":"all_uints8","type":"uint8[]"},{"internalType":"bool[]","name":"all_bools","type":"bool[]"},{"internalType":"int32[]","name":"pos_array","type":"int32[]"}],"name":"craft","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"inventory_address","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"this_owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC721Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"thi_address","type":"address"}],"name":"register_INVENTORY","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"thi_address","type":"address"}],"name":"register_P_ROUTERS","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"thi_address","type":"address"}],"name":"register_SLAG","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"retrieve_data","outputs":[{"internalType":"uint8[16]","name":"","type":"uint8[16]"},{"internalType":"int32[3]","name":"","type":"int32[3]"},{"internalType":"uint16[2]","name":"","type":"uint16[2]"},{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"this_token_id","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"this_base_uri","type":"string"}],"name":"set_base_uri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"slag_contract","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interface_id","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"token_exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"this_token_id","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"}]