// SPDX-License-Identifier: MIT pragma solidity ^0.8.13; import "@openzeppelin/contracts/token/ERC20/ERC20.sol"; import "@openzeppelin/contracts/access/Ownable.sol"; // DEV import "forge-std/console.sol"; struct Raider { uint16 level; } struct Army { Raider moloch_denier; Raider apprentice; Raider annointed; Raider champion; } struct Player { uint256 total_minted; uint256 created_at; uint256 last_raided_at; } contract RaidGeld is ERC20, Ownable { uint8 constant DECIMALS = 4; uint256 public constant BUY_IN_AMOUNT = 0.0005 ether; uint256 public constant INITIAL_GELD = 50 * 10 ** DECIMALS; uint256 public constant RAID_WAIT = 15 seconds; uint256 public total_minted = 0; mapping(address => Player) private players; mapping(address => Army) private armies; // Modifier for functions that should only be available to registered players modifier onlyPlayer() { require(players[msg.sender].created_at != 0, "Not an initiated player"); _; } constructor() ERC20("Raid Geld", "GELD") Ownable(msg.sender) {} // This effectively registers the user function register() external payable { require(players[msg.sender].created_at == 0, "Whoops, player already exists :)"); require(msg.value == BUY_IN_AMOUNT, "Incorrect buy in amount"); // Mint some starting tokens to the player _mint(msg.sender, INITIAL_GELD); // Set initial states players[msg.sender] = Player({total_minted: INITIAL_GELD, created_at: block.timestamp, last_raided_at: 0}); armies[msg.sender] = Army({ moloch_denier: Raider({level: 0}), apprentice: Raider({level: 0}), annointed: Raider({level: 0}), champion: Raider({level: 0}) }); total_minted += INITIAL_GELD; } // Override for default number of decimals function decimals() public view virtual override returns (uint8) { return 4; } // Allows the owner to withdraw function withdraw() external onlyOwner { payable(owner()).transfer(address(this).balance); } // Manual minting for itchy fingers function raid() external onlyPlayer { require(block.timestamp >= players[msg.sender].last_raided_at + RAID_WAIT, "Tried minting too soon"); // TODO: Make real calculation based on army uint256 new_geld = 50 * 10 ** decimals(); _mint(msg.sender, new_geld); total_minted += new_geld; console.log(players[msg.sender].last_raided_at); players[msg.sender].last_raided_at = block.timestamp; console.log(players[msg.sender].last_raided_at); } // Function to get Player struct function getPlayer(address addr) public view returns (Player memory) { return players[addr]; } // Function to get Army struct function getArmy(address addr) public view returns (Army memory) { return armies[addr]; } // Quick fn to check if user is registered function isRegistered(address addr) public view returns (bool) { return players[addr].created_at != 0; } receive() external payable { revert("No plain Ether accepted, use register() function to check in :)"); } // Revert any non-function-call Ether transfers or calls to non-existent functions fallback() external payable { revert("No fallback calls accepted"); } }