Boss updates

This commit is contained in:
syahirAmali 2024-11-01 05:37:36 +08:00
parent 3aa429fdd7
commit 76fc15faab
4 changed files with 1173 additions and 668 deletions

File diff suppressed because it is too large Load Diff

View File

@ -1,33 +1,50 @@
type Player @entity {
id: ID! # player address
createdAt: BigInt!
lastRaidedAt: BigInt!
totalMinted: BigInt!
currentBalance: BigInt!
numberOfRaids: Int!
army: Army! @derivedFrom(field: "player")
armyStrength: BigInt! # Calculated field for total army power
rank: Int # Position in leaderboard, can be updated periodically
id: ID! # player address
createdAt: BigInt!
lastRaidedAt: BigInt!
totalMinted: BigInt!
currentBalance: BigInt!
numberOfRaids: Int!
army: Army! @derivedFrom(field: "player")
armyStrength: BigInt! # Calculated field for total army power
rank: Int # Position in leaderboard, can be updated periodically
prestigeLevel: BigInt!
totalRuns: Int! # Track number of times player has started a new run
bossesDefeated: Int!
totalRewards: BigInt! # Track total DAO tokens earned from boss battles
isActiveSession: Boolean! # Track if player has an active session
}
type Army @entity {
id: ID! # player address
player: Player!
molochDenierLevel: Int!
apprenticeLevel: Int!
anointedLevel: Int!
championLevel: Int!
profitPerSecond: BigInt!
projectedDailyEarnings: BigInt! # Derived from profitPerSecond
totalUnitsPurchased: Int!
lastUnitPurchaseTime: BigInt
id: ID! # player address
player: Player!
molochDenierLevel: Int!
apprenticeLevel: Int!
anointedLevel: Int!
championLevel: Int!
profitPerSecond: BigInt!
projectedDailyEarnings: BigInt! # Derived from profitPerSecond
totalUnitsPurchased: Int!
lastUnitPurchaseTime: BigInt
currentBossLevel: Int! # Track current boss level
}
type GlobalStat @entity {
id: ID! # Can be "1" as we only need one instance
totalPlayers: Int!
totalGeldMinted: BigInt!
totalArmyUnits: Int!
lastUpdateTime: BigInt!
topEarnerProfit: BigInt! # Track highest profit per second
}
id: ID! # Can be "1" as we only need one instance
totalPlayers: Int!
totalGeldMinted: BigInt!
totalArmyUnits: Int!
lastUpdateTime: BigInt!
topEarnerProfit: BigInt! # Track highest profit per second
totalPrestigeLevels: Int! # Sum of all player prestige levels
totalBossesDefeated: Int!
totalRuns: Int! # Track total number of runs across all players
}
type BossDefeat @entity {
id: ID! # player address + timestamp
player: Player!
bossLevel: Int!
earnings: BigInt!
timestamp: BigInt!
}

View File

@ -1,164 +1,258 @@
import {
PlayerRegistered,
RaidPerformed,
UnitAdded
} from "../generated/RaidGeld/RaidGeld"
import { Player, Army, GlobalStat } from "../generated/schema"
import { BigInt } from "@graphprotocol/graph-ts"
PlayerRegistered,
RaidPerformed,
UnitAdded,
PlayerStrikesAgain,
BossDefeated,
PrestigeGained,
} from "../generated/RaidGeld/RaidGeld";
import { Player, Army, GlobalStat, BossDefeat } from "../generated/schema";
import { BigInt } from "@graphprotocol/graph-ts";
// Constants from RaidGeldUtils
const PRECISION = BigInt.fromI32(10000)
const PRICE_FACTOR = BigInt.fromI32(11500)
const PRECISION = BigInt.fromI32(10000);
const PRICE_FACTOR = BigInt.fromI32(11500);
// Unit profits
const MOLOCH_DENIER_PROFIT = BigInt.fromI32(2533)
const APPRENTICE_PROFIT = BigInt.fromI32(27863)
const ANOINTED_PROFIT = BigInt.fromI32(306493)
const CHAMPION_PROFIT = BigInt.fromI32(3371423)
const MOLOCH_DENIER_PROFIT = BigInt.fromI32(2533);
const APPRENTICE_PROFIT = BigInt.fromI32(27863);
const ANOINTED_PROFIT = BigInt.fromI32(306493);
const CHAMPION_PROFIT = BigInt.fromI32(3371423);
// Base costs (not used in profit calculation but useful for reference)
const MOLOCH_DENIER_BASE_COST = BigInt.fromI32(380000)
const APPRENTICE_BASE_COST = BigInt.fromI32(3420000)
const ANOINTED_BASE_COST = BigInt.fromI32(30096000)
const CHAMPION_BASE_COST = BigInt.fromI32(255816000)
const MOLOCH_DENIER_BASE_COST = BigInt.fromI32(380000);
const APPRENTICE_BASE_COST = BigInt.fromI32(3420000);
const ANOINTED_BASE_COST = BigInt.fromI32(30096000);
const CHAMPION_BASE_COST = BigInt.fromI32(255816000);
function calculateProfitPerSecond(
molochLevel: i32,
apprenticeLevel: i32,
anointedLevel: i32,
championLevel: i32
molochLevel: i32,
apprenticeLevel: i32,
anointedLevel: i32,
championLevel: i32
): BigInt {
// Exactly matching the RaidGeldUtils calculation
let molochDenierProfit = MOLOCH_DENIER_PROFIT.times(BigInt.fromI32(molochLevel))
let apprenticeProfit = APPRENTICE_PROFIT.times(BigInt.fromI32(apprenticeLevel))
let anointedProfit = ANOINTED_PROFIT.times(BigInt.fromI32(anointedLevel))
let championProfit = CHAMPION_PROFIT.times(BigInt.fromI32(championLevel))
// Exactly matching the RaidGeldUtils calculation
let molochDenierProfit = MOLOCH_DENIER_PROFIT.times(
BigInt.fromI32(molochLevel)
);
let apprenticeProfit = APPRENTICE_PROFIT.times(
BigInt.fromI32(apprenticeLevel)
);
let anointedProfit = ANOINTED_PROFIT.times(BigInt.fromI32(anointedLevel));
let championProfit = CHAMPION_PROFIT.times(BigInt.fromI32(championLevel));
return molochDenierProfit
.plus(apprenticeProfit)
.plus(anointedProfit)
.plus(championProfit)
return molochDenierProfit
.plus(apprenticeProfit)
.plus(anointedProfit)
.plus(championProfit);
}
function getOrCreateGlobalStats(): GlobalStat {
let stats = GlobalStat.load("1")
if (!stats) {
stats = new GlobalStat("1")
stats.totalPlayers = 0
stats.totalGeldMinted = BigInt.fromI32(0)
stats.totalArmyUnits = 0
stats.lastUpdateTime = BigInt.fromI32(0)
stats.topEarnerProfit = BigInt.fromI32(0)
}
return stats
let stats = GlobalStat.load("1");
if (!stats) {
stats = new GlobalStat("1");
stats.totalPlayers = 0;
stats.totalGeldMinted = BigInt.fromI32(0);
stats.totalArmyUnits = 0;
stats.lastUpdateTime = BigInt.fromI32(0);
stats.topEarnerProfit = BigInt.fromI32(0);
}
return stats;
}
function calculateArmyStrength(army: Army): BigInt {
// Using the exact same profit calculation for army strength
return calculateProfitPerSecond(
army.molochDenierLevel,
army.apprenticeLevel,
army.anointedLevel,
army.championLevel
)
// Using the exact same profit calculation for army strength
return calculateProfitPerSecond(
army.molochDenierLevel,
army.apprenticeLevel,
army.anointedLevel,
army.championLevel
);
}
function calculateProjectedDailyEarnings(profitPerSecond: BigInt): BigInt {
return profitPerSecond.times(BigInt.fromI32(86400)) // 86400 seconds in a day
return profitPerSecond.times(BigInt.fromI32(86400)); // 86400 seconds in a day
}
export function handlePlayerRegistered(event: PlayerRegistered): void {
let player = new Player(event.params.player.toHexString())
player.createdAt = event.block.timestamp
player.lastRaidedAt = event.block.timestamp
player.totalMinted = event.params.initialGeld
player.currentBalance = event.params.initialGeld
player.numberOfRaids = 0
player.armyStrength = BigInt.fromI32(0)
player.rank = 0
player.save()
let player = new Player(event.params.player.toHexString());
player.createdAt = event.block.timestamp;
player.lastRaidedAt = event.block.timestamp;
player.totalMinted = event.params.initialGeld;
player.currentBalance = event.params.initialGeld;
player.numberOfRaids = 0;
player.armyStrength = BigInt.fromI32(0);
player.rank = 0;
// Initialize new fields
player.prestigeLevel = BigInt.fromI32(0);
player.totalRuns = 1;
player.bossesDefeated = 0;
player.totalRewards = BigInt.fromI32(0);
player.isActiveSession = true;
player.save();
let army = new Army(event.params.player.toHexString())
army.player = player.id
army.molochDenierLevel = 0
army.apprenticeLevel = 0
army.anointedLevel = 0
army.championLevel = 0
army.profitPerSecond = BigInt.fromI32(0)
army.projectedDailyEarnings = BigInt.fromI32(0)
army.totalUnitsPurchased = 0
army.lastUnitPurchaseTime = event.block.timestamp
army.save()
let army = new Army(event.params.player.toHexString());
army.player = player.id;
army.molochDenierLevel = 0;
army.apprenticeLevel = 0;
army.anointedLevel = 0;
army.championLevel = 0;
army.profitPerSecond = BigInt.fromI32(0);
army.projectedDailyEarnings = BigInt.fromI32(0);
army.totalUnitsPurchased = 0;
army.lastUnitPurchaseTime = event.block.timestamp;
army.currentBossLevel = 0;
army.save();
let stats = getOrCreateGlobalStats()
stats.totalPlayers += 1
stats.totalGeldMinted = stats.totalGeldMinted.plus(event.params.initialGeld)
stats.lastUpdateTime = event.block.timestamp
stats.save()
let stats = getOrCreateGlobalStats();
stats.totalPlayers += 1;
stats.totalGeldMinted = stats.totalGeldMinted.plus(
event.params.initialGeld
);
stats.totalRuns += 1;
stats.lastUpdateTime = event.block.timestamp;
stats.save();
}
export function handlePlayerStrikesAgain(event: PlayerStrikesAgain): void {
let player = Player.load(event.params.player.toHexString());
if (!player) return;
player.totalRuns += 1;
player.currentBalance = event.params.initialGeld;
player.totalMinted = event.params.initialGeld;
player.lastRaidedAt = event.block.timestamp;
player.isActiveSession = true;
player.save();
// Reset army for new run
let army = Army.load(event.params.player.toHexString());
if (!army) return;
army.molochDenierLevel = 0;
army.apprenticeLevel = 0;
army.anointedLevel = 0;
army.championLevel = 0;
army.profitPerSecond = BigInt.fromI32(0);
army.projectedDailyEarnings = BigInt.fromI32(0);
army.currentBossLevel = 0;
army.save();
let stats = getOrCreateGlobalStats();
stats.totalRuns += 1;
stats.lastUpdateTime = event.block.timestamp;
stats.save();
}
export function handleBossDefeated(event: BossDefeated): void {
let player = Player.load(event.params.player.toHexString());
if (!player) return;
player.bossesDefeated += 1;
player.totalRewards = player.totalRewards.plus(event.params.earnings);
player.save();
let army = Army.load(event.params.player.toHexString());
if (!army) return;
army.currentBossLevel += 1;
army.save();
// Create boss defeat record
let bossDefeat = new BossDefeat(
event.params.player.toHexString() +
"-" +
event.block.timestamp.toString()
);
bossDefeat.player = player.id;
bossDefeat.bossLevel = event.params.bossLevel;
bossDefeat.earnings = event.params.earnings;
bossDefeat.timestamp = event.block.timestamp;
bossDefeat.save();
let stats = getOrCreateGlobalStats();
stats.totalBossesDefeated += 1;
stats.lastUpdateTime = event.block.timestamp;
stats.save();
}
export function handlePrestigeGained(event: PrestigeGained): void {
let player = Player.load(event.params.player.toHexString());
if (!player) return;
player.prestigeLevel = event.params.prestigeLevel;
player.isActiveSession = false;
player.save();
let stats = getOrCreateGlobalStats();
stats.totalPrestigeLevels += 1;
stats.lastUpdateTime = event.block.timestamp;
stats.save();
}
export function handleRaidPerformed(event: RaidPerformed): void {
let player = Player.load(event.params.player.toHexString())
if (!player) return
let player = Player.load(event.params.player.toHexString());
if (!player) return;
// Calculate new GELD minted in this raid
let newGeldMinted = event.params.totalMinted.minus(player.totalMinted)
player.totalMinted = event.params.totalMinted
player.currentBalance = event.params.geldBalance
player.lastRaidedAt = event.block.timestamp
player.numberOfRaids += 1
player.save()
// Calculate new GELD minted in this raid
let newGeldMinted = event.params.totalMinted.minus(player.totalMinted);
let stats = getOrCreateGlobalStats()
stats.totalGeldMinted = stats.totalGeldMinted.plus(newGeldMinted)
stats.lastUpdateTime = event.block.timestamp
stats.save()
player.totalMinted = event.params.totalMinted;
player.currentBalance = event.params.geldBalance;
player.lastRaidedAt = event.block.timestamp;
player.numberOfRaids += 1;
player.save();
let stats = getOrCreateGlobalStats();
stats.totalGeldMinted = stats.totalGeldMinted.plus(newGeldMinted);
stats.lastUpdateTime = event.block.timestamp;
stats.save();
}
export function handleUnitAdded(event: UnitAdded): void {
let army = Army.load(event.params.player.toHexString())
if (!army) return
let army = Army.load(event.params.player.toHexString());
if (!army) return;
// Update army levels based on the event
if (event.params.unitType == 0) {
army.molochDenierLevel = event.params.molochDenierLevel
} else if (event.params.unitType == 1) {
army.apprenticeLevel = event.params.apprenticeLevel
} else if (event.params.unitType == 2) {
army.anointedLevel = event.params.anointedLevel
} else if (event.params.unitType == 3) {
army.championLevel = event.params.championLevel
}
// Update army levels based on the event
if (event.params.unitType == 0) {
army.molochDenierLevel = event.params.molochDenierLevel;
} else if (event.params.unitType == 1) {
army.apprenticeLevel = event.params.apprenticeLevel;
} else if (event.params.unitType == 2) {
army.anointedLevel = event.params.anointedLevel;
} else if (event.params.unitType == 3) {
army.championLevel = event.params.championLevel;
}
// Calculate new profit per second using exact RaidGeldUtils values
let profitPerSecond = calculateProfitPerSecond(
army.molochDenierLevel,
army.apprenticeLevel,
army.anointedLevel,
army.championLevel
)
army.profitPerSecond = profitPerSecond
army.projectedDailyEarnings = calculateProjectedDailyEarnings(profitPerSecond)
army.totalUnitsPurchased += event.params.nUnits
army.lastUnitPurchaseTime = event.block.timestamp
army.save()
// Calculate new profit per second using exact RaidGeldUtils values
let profitPerSecond = calculateProfitPerSecond(
army.molochDenierLevel,
army.apprenticeLevel,
army.anointedLevel,
army.championLevel
);
// Update player's army strength and balance
let player = Player.load(event.params.player.toHexString())
if (!player) return
player.currentBalance = event.params.geldBalance
player.armyStrength = calculateArmyStrength(army)
player.save()
army.profitPerSecond = profitPerSecond;
army.projectedDailyEarnings =
calculateProjectedDailyEarnings(profitPerSecond);
army.totalUnitsPurchased += event.params.nUnits;
army.lastUnitPurchaseTime = event.block.timestamp;
army.save();
// Update global stats
let stats = getOrCreateGlobalStats()
stats.totalArmyUnits += event.params.nUnits
if (profitPerSecond > stats.topEarnerProfit) {
stats.topEarnerProfit = profitPerSecond
}
stats.lastUpdateTime = event.block.timestamp
stats.save()
}
// Update player's army strength and balance
let player = Player.load(event.params.player.toHexString());
if (!player) return;
player.currentBalance = event.params.geldBalance;
player.armyStrength = calculateArmyStrength(army);
player.save();
// Update global stats
let stats = getOrCreateGlobalStats();
stats.totalArmyUnits += event.params.nUnits;
if (profitPerSecond > stats.topEarnerProfit) {
stats.topEarnerProfit = profitPerSecond;
}
stats.lastUpdateTime = event.block.timestamp;
stats.save();
}

View File

@ -1,35 +1,44 @@
specVersion: 1.0.0
indexerHints:
prune: auto
prune: auto
schema:
file: ./schema.graphql
file: ./schema.graphql
dataSources:
- kind: ethereum
name: RaidGeld
network: base-sepolia
source:
address: "0xC912823B231f5d052eF334a8f8B73F6354909cd0"
abi: RaidGeld
startBlock: 17213030
mapping:
kind: ethereum/events
apiVersion: 0.0.7
language: wasm/assemblyscript
entities:
- Approval
- OwnershipTransferred
- PlayerRegistered
- RaidPerformed
- Transfer
- UnitAdded
abis:
- name: RaidGeld
file: ./abis/RaidGeld.json
eventHandlers:
- event: PlayerRegistered(indexed address,uint256)
handler: handlePlayerRegistered
- event: RaidPerformed(indexed address,uint256,uint256)
handler: handleRaidPerformed
- event: UnitAdded(indexed address,uint8,uint16,uint256,uint256,uint16,uint16,uint16,uint16)
handler: handleUnitAdded
file: ./src/raid-geld.ts
- kind: ethereum
name: RaidGeld
network: base-sepolia
source:
address: "0xC912823B231f5d052eF334a8f8B73F6354909cd0"
abi: RaidGeld
startBlock: 17213030
mapping:
kind: ethereum/events
apiVersion: 0.0.7
language: wasm/assemblyscript
entities:
- Approval
- OwnershipTransferred
- PlayerRegistered
- PlayerStrikesAgain
- RaidPerformed
- Transfer
- UnitAdded
- BossDefeated
- PrestigeGained
abis:
- name: RaidGeld
file: ./abis/RaidGeld.json
eventHandlers:
- event: PlayerRegistered(indexed address,uint256)
handler: handlePlayerRegistered
- event: PlayerStrikesAgain(indexed address,uint256,uint256)
handler: handlePlayerStrikesAgain
- event: RaidPerformed(indexed address,uint256,uint256)
handler: handleRaidPerformed
- event: UnitAdded(indexed address,uint8,uint16,uint256,uint256,uint16,uint16,uint16,uint16)
handler: handleUnitAdded
- event: BossDefeated(indexed address,uint8,uint256)
handler: handleBossDefeated
- event: PrestigeGained(indexed address,uint32)
handler: handlePrestigeGained
file: ./src/raid-geld.ts