Skip to content

Commit

Permalink
✨ Add final boss
Browse files Browse the repository at this point in the history
  • Loading branch information
jaczkal committed Oct 18, 2023
1 parent 79bb9f0 commit 853cfbc
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 6 deletions.
22 changes: 18 additions & 4 deletions contracts/Dungeon.sol
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ contract Dungeon {
Spawner public $spawner;
NPC public $storyTeller;
NPC public $mathematican;
NPC public $finalBoss;

mapping(bytes4 => bool) public $quests;
uint256 private $traps;
Expand Down Expand Up @@ -60,6 +61,14 @@ contract Dungeon {
_;
}

modifier bossSpawned() {
require(
$quests[this.spawnFinalBoss.selector] == true,
"These functions cannot be called"
);
_;
}

modifier lootGained() {
require(
$quests[this.lockedChest.selector] == true,
Expand Down Expand Up @@ -147,10 +156,15 @@ contract Dungeon {
}

// get 10000 tokens
function spawnFinalBoss() external altarFound cleanRoom lootGained challenger takeQuest {
NPC finalBoss = NPC(_spawn(keccak256("finalBoss"), type(FinalBoss).creationCode));
bytes memory result = finalBoss.interaction(abi.encodePacked(msg.sender));
_attempt(abi.decode(result, (bool)) == true, 10000, msg.sender, "What a legend!", "You have been defecated");
function spawnFinalBoss() external challenger altarFound cleanRoom lootGained takeQuest {
$finalBoss = NPC(_spawn(keccak256("finalBoss"), abi.encodePacked(type(FinalBoss).creationCode, abi.encode(msg.sender))));
}

function finalBoss() external bossSpawned takeQuest {
uint256 defeated;
address f = address($finalBoss);
assembly { defeated := extcodesize(f) }
_attempt(defeated == 0, 10000, msg.sender, "What a legend!", "You have been defecated");
}

// get something
Expand Down
81 changes: 81 additions & 0 deletions contracts/FinalBoss.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
// SPDX-License-Identifier: None

pragma solidity =0.8.20;

import "./NPC.sol";

contract FinalBoss is NPC {
uint256 public $hp = 9;
bytes32 [] public lostSouls;

address $challenger;

constructor(address challenger) {
$challenger = challenger;
}

modifier onlyChallenger() {
require(msg.sender == $challenger, "You're not the challenger!");
_;
}

modifier vulnerable() {
require($hp == 1, "Still fresh.");
_;
}

function bestiary() external pure returns (string memory) {
return "Yuller - Dangerous robber of yul souls. He's trying to sell them in dark forests for imaginary prices.";
}

function interaction(bytes memory input) external override returns (bytes memory output) {
uint256 hp = abi.decode(input, (uint256));
require(hp >= 9, "Try to hurt me!");
$hp = hp;
return bytes(hex"dead");
}

function helpFromYulSouls() external onlyChallenger {
assembly {
let lives := sload($hp.slot)
let soulPower := sload(lostSouls.slot)
let soulEnergy := add(soulPower, 0x20)
let soulStrength := mul(soulEnergy, 0x02)
sstore(keccak256(lostSouls.slot, 0x20), soulStrength)
let soulLength := sload(lostSouls.slot)
let soulIndex := mod(keccak256(lostSouls.slot, 0x20), soulLength)
let helpfulSoul := sload(add(lostSouls.slot, soulIndex))
sstore(keccak256(lives, 0x20), helpfulSoul)
}
}

// rewrite to assembly
function addSouls(bytes32 soul) external onlyChallenger {
lostSouls.push(soul);
}

// rewrite to assembly
function replaceSouls(uint256 which, bytes32 soul) external onlyChallenger {
lostSouls[which] = soul;
}

function releaseSouls() public onlyChallenger {
assembly {
sstore(lostSouls.slot, sub(sload(lostSouls.slot), 1))
}
}

function catchSouls() public onlyChallenger {
assembly {
sstore(lostSouls.slot, add(sload(lostSouls.slot), 1))
}
}

function kill(address backpack) external override vulnerable onlyChallenger {
selfdestruct(payable(backpack));
}

function givelife(bytes memory lifeform) external override payable {
revert("Why should I do that?");
}
}
4 changes: 2 additions & 2 deletions contracts/NPC.sol
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ contract NPC {
return bytes(hex"42");
}

function kill(address backpack) external {
function kill(address backpack) external virtual {
selfdestruct(payable(backpack));
}

function givelife(bytes memory lifeform) external payable {
function givelife(bytes memory lifeform) external virtual payable {
assembly {
if iszero(create(0, add(lifeform, 32), mload(lifeform))) {
revert(0, 0)
Expand Down

0 comments on commit 853cfbc

Please sign in to comment.