forked from mico/idle_moloch
Boss mechanics compile
This commit is contained in:
parent
64832617cc
commit
ecbadf3809
@ -48,14 +48,14 @@ contract RaidGeld is ERC20, Ownable, Constants {
|
||||
}
|
||||
|
||||
modifier onlyActiveSession() {
|
||||
require(players[msg.sender].active_session, "Session is not active, you need to buy into the game first");
|
||||
require(players[msg.sender].has_active_session, "Session is not active, you need to buy into the game first");
|
||||
_;
|
||||
}
|
||||
|
||||
modifier newPlay() {
|
||||
Player memory player = players[msg.sender];
|
||||
bool notRegistered = player.created_at == 0;
|
||||
bool returningPlayer = player.has_registered && !player.has_active_session;
|
||||
bool returningPlayer = player.is_registered && !player.has_active_session;
|
||||
require(notRegistered || returningPlayer, "Active session already in progress");
|
||||
_;
|
||||
}
|
||||
@ -86,7 +86,7 @@ contract RaidGeld is ERC20, Ownable, Constants {
|
||||
Player memory player = players[addr];
|
||||
uint32 current_n_runs = player.n_runs + 1;
|
||||
uint256 current_total_rewards = player.total_rewards;
|
||||
bool has_registered = player.is_registered;
|
||||
bool current_is_registered = player.is_registered;
|
||||
// Set initial states
|
||||
players[msg.sender] = Player({
|
||||
total_minted: INITIAL_GELD,
|
||||
@ -94,7 +94,8 @@ contract RaidGeld is ERC20, Ownable, Constants {
|
||||
last_raided_at: block.timestamp,
|
||||
n_runs: current_n_runs,
|
||||
total_rewards: current_total_rewards,
|
||||
active_session: false
|
||||
has_active_session: false,
|
||||
is_registered: current_is_registered
|
||||
});
|
||||
armies[msg.sender] = Army({
|
||||
moloch_denier: Raider({level: 0}),
|
||||
@ -148,7 +149,7 @@ contract RaidGeld is ERC20, Ownable, Constants {
|
||||
|
||||
// Manual minting for itchy fingers
|
||||
function raid() external onlyActiveSession {
|
||||
performRaid();
|
||||
performRaid(msg.sender);
|
||||
}
|
||||
|
||||
// Helper so we can use it when buying units too
|
||||
@ -202,9 +203,7 @@ contract RaidGeld is ERC20, Ownable, Constants {
|
||||
uint256 time_past = block.timestamp - players[msg.sender].last_raided_at;
|
||||
uint256 new_geld = armies[msg.sender].profit_per_second * time_past;
|
||||
require(balanceOf(msg.sender) + new_geld >= cost, "Not enough GELD to add this unit");
|
||||
uint256 totalMinted = performRaid(msg.sender);
|
||||
|
||||
// Emit event
|
||||
performRaid(msg.sender);
|
||||
|
||||
// TODO: Since we are first minting then burning the token, this could be simplified
|
||||
// by first calculating the difference and then minting / burning in just one operation
|
||||
@ -246,14 +245,14 @@ contract RaidGeld is ERC20, Ownable, Constants {
|
||||
|
||||
function battle_with_boss() external onlyActiveSession {
|
||||
// first perform raid
|
||||
performRaid();
|
||||
performRaid(msg.sender);
|
||||
Boss memory boss_to_attack = bosses[msg.sender];
|
||||
// calculate how much the player will put into battle
|
||||
uint256 geld_to_burn = balanceOf(msg.sender) >= RaidGeldUtils.BOSS_POWERS[boss_to_attack.level]
|
||||
? RaidGeldUtils.BOSS_POWERS[boss_to_attack.level]
|
||||
uint256 geld_to_burn = balanceOf(msg.sender) >= RaidGeldUtils.getBossPower(boss_to_attack.level)
|
||||
? RaidGeldUtils.getBossPower(boss_to_attack.level)
|
||||
: balanceOf(msg.sender);
|
||||
bool hasWonBattle = RaidGeldUtils.calculateBossFight(
|
||||
boss_to_attack.level, geld_to_burn, block.timestamp, block.difficulty
|
||||
boss_to_attack.level, geld_to_burn, block.prevrandao
|
||||
);
|
||||
if (hasWonBattle) {
|
||||
// Burn geld, get some sweet DAO Token and continue
|
||||
@ -268,7 +267,7 @@ contract RaidGeld is ERC20, Ownable, Constants {
|
||||
}
|
||||
|
||||
function player_dies(address player) private {
|
||||
reset_player();
|
||||
reset_player(player);
|
||||
players[player].has_active_session = false;
|
||||
_burn(msg.sender, balanceOf(player));
|
||||
}
|
||||
|
||||
@ -19,26 +19,32 @@ library RaidGeldUtils {
|
||||
uint256 constant ANOINTED_BASE_COST = 30096000;
|
||||
uint256 constant CHAMPION_BASE_COST = 255816000;
|
||||
|
||||
// Boss lvels
|
||||
uint256[7] constant BOSS_POWERS = [
|
||||
9000000, // 900e4
|
||||
90000000, // 900e5
|
||||
900000000, // 900e6
|
||||
9000000000, // 900e7
|
||||
90000000000, // 900e8
|
||||
900000000000, // 900e9
|
||||
9000000000000 // 900e10
|
||||
];
|
||||
|
||||
// First boss is almost guaranteed, others arent
|
||||
uint256[7] constant BOSS_CHANCES = [99, 89, 80, 70, 62, 51, 40];
|
||||
|
||||
// These are cumulative chances from above with precision 18
|
||||
uint256[7] constant CUMULATIVE_BOSS_CHANCES =
|
||||
[99e16, 8811e14, 7048e14, 493416e12, 30591792e10, 1560181392e8, 6240725568e7];
|
||||
|
||||
uint256 constant RISK_BETA = 15e17;
|
||||
|
||||
function getBossPower(uint8 level) internal pure returns (uint256 power) {
|
||||
require(level <= 7, "Bosses only go to level 7");
|
||||
if (level == 0) return 9000000; // 900e4
|
||||
else if (level == 1) return 90000000; // 900e5
|
||||
else if (level == 2) return 900000000; // 900e6
|
||||
else if (level == 3) return 9000000000; // 900e7
|
||||
else if (level == 4) return 90000000000; // 900e8
|
||||
else if (level == 5) return 900000000000; // 900e9
|
||||
else if (level == 6) return 9000000000000; // 900e10
|
||||
}
|
||||
|
||||
function getBossCumulativeChance(uint8 level) internal pure returns (uint256 chance) {
|
||||
// for boss chances (percent) [99, 89, 80, 70, 62, 51, 40]
|
||||
// where cumulative chance is in the form of 18 precision related to 1e18
|
||||
require(level <= 7, "Bosses only go to level 7");
|
||||
if (level == 0) return 99e16;
|
||||
else if (level == 1) return 8811e14;
|
||||
else if (level == 2) return 7048e14;
|
||||
else if (level == 3) return 493416e12;
|
||||
else if (level == 4) return 30591792e10;
|
||||
else if (level == 5) return 1560181392e8;
|
||||
else if (level == 6) return 6240725568e7;
|
||||
}
|
||||
|
||||
function calculateUnitPrice(uint8 unit, uint16 currentLevel, uint16 units) internal pure returns (uint256) {
|
||||
require(unit <= 3, "No matching unit found");
|
||||
uint256 rollingPriceCalculation = MOLOCH_DENIER_BASE_COST;
|
||||
@ -67,24 +73,23 @@ library RaidGeldUtils {
|
||||
uint256 apprentice_profit = army.apprentice.level * APPRENTICE_PROFIT;
|
||||
uint256 anointed_profit = army.anointed.level * ANOINTED_PROFIT;
|
||||
uint256 champion_profit = army.champion.level * CHAMPION_PROFIT;
|
||||
|
||||
return moloch_denier_profit + apprentice_profit + anointed_profit + champion_profit;
|
||||
}
|
||||
|
||||
// Returns how much Dao Token player is due for winning
|
||||
function calculateBossReward(uint256 bossLevel) public view returns (uint256) {
|
||||
return BOSS_POWERS[bossLevel] * (CUMULATIVE_BOSS_CHANCES[bossLevel] * 10 / 5) ** 2;
|
||||
function calculateBossReward(uint8 bossLevel) internal pure returns (uint256) {
|
||||
return getBossPower(bossLevel) * (getBossCumulativeChance(bossLevel) * 10 / 5) ** 2;
|
||||
}
|
||||
|
||||
// Calculates whether user survives the fight
|
||||
function calculateBossFight(uint8 bossLevel, uint256 geldBurnt, uint256 timestamp, uint256 difficulty)
|
||||
function calculateBossFight(uint8 bossLevel, uint256 geldBurnt, uint256 prevrandao)
|
||||
internal
|
||||
pure
|
||||
returns (uint256)
|
||||
returns (bool)
|
||||
{
|
||||
uint256 bossPower = BOSS_POWERS[bossLevel];
|
||||
uint256 bossPower = getBossPower(bossLevel);
|
||||
require(geldBurnt <= bossPower, "Cant try to defeat boss with more than what boss power is");
|
||||
uint256 random_n = random(timestamp, difficulty, 1, 100);
|
||||
uint256 random_n = random(prevrandao, 1, 100);
|
||||
// Relative power as in, you can only put in 800 geld to defeat 900 geld boss,
|
||||
// but you will get exponentially worse chances
|
||||
uint256 relativePower = ((geldBurnt ** 2) * 100) / bossPower ** 2;
|
||||
@ -93,10 +98,10 @@ library RaidGeldUtils {
|
||||
}
|
||||
|
||||
// TODO: Implement actual randomness
|
||||
function random(uint256 timestamp, uint256 difficulty, uint256 min, uint256 max) internal pure returns (uint256) {
|
||||
function random(uint256 prevrandao, uint256 min, uint256 max) internal pure returns (uint256) {
|
||||
// returns 0 - 100
|
||||
require(max >= min, "Max must be greater than or equal to min");
|
||||
uint256 range = max - min + 1;
|
||||
return min + (uint256(keccak256(abi.encodePacked(timestamp, difficulty))) % range);
|
||||
return min + (uint256(keccak256(abi.encodePacked(prevrandao))) % range);
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ contract raid_geldTest is Test {
|
||||
assertGt(price, basePriceChamp * 12);
|
||||
}
|
||||
|
||||
function test_1_profits_per_second(uint16 _dLvl, uint16 _apLvl, uint16 _anLvl, uint16 _cLvl) public {
|
||||
function test_1_profits_per_second(uint16 _dLvl, uint16 _apLvl, uint16 _anLvl, uint16 _cLvl) public pure {
|
||||
Army memory army = Army({
|
||||
moloch_denier: Raider({level: 1}),
|
||||
apprentice: Raider({level: 0}),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user