Skip to content

Commit

Permalink
chore: optimze battle system
Browse files Browse the repository at this point in the history
  • Loading branch information
lewis committed Oct 23, 2023
1 parent 01fd8c5 commit a35640f
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 47 deletions.
12 changes: 12 additions & 0 deletions packages/contracts/src/systems/BattlePrepareSystem.sol
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,18 @@ contract BattlePrepareSystem is System {
// GameConfig.pushBattlefieldPlayers(GAME_CONFIG_KEY, _player);
}

function goHome() external {
// 回家,将用户脱离战区,血量回满

PlayerData memory player = Player.get(_msgSender());
require(player.state == PlayerState.Exploring, "You should in exploring state");
require(
player.x == GameConfig.getOriginX(GAME_CONFIG_KEY) && player.y == GameConfig.getOriginY(GAME_CONFIG_KEY),
"You are not in the origin point"
);
BattleUtils.outBattlefield(_msgSender());
}

function battleInvitation(
address _targetAddress,
Position[] memory positionList
Expand Down
86 changes: 43 additions & 43 deletions packages/contracts/src/systems/BattleSystem.sol
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ contract BattleSystem is System {
BattleList.setDefenderArg(_battleId, _arg);
BattleList.setDefenderState(_battleId, BattleState.Revealed);
}
if (battle.attackerState == BattleState.Revealed && battle.defenderState == BattleState.Revealed) {
// if (battle.attackerState == BattleState.Revealed && battle.defenderState == BattleState.Revealed) {
if (BattleList.getAttackerState(_battleId) == BattleState.Revealed
&& BattleList.getDefenderState(_battleId) == BattleState.Revealed) {
// 结算战斗
revealWinner(_battleId);
}
Expand All @@ -51,6 +53,8 @@ contract BattleSystem is System {
//set attack
uint256 attackerFirepower = Player.getAttack(battle.attacker);
uint256 defenderFirepower = Player.getAttack(battle.defender);
Buff attackerBuff = Buff(battle.defenderArg);
Buff defenderBuff = Buff(battle.defenderArg);

// address attacker = BattleList.getAttacker(_battleId);
// address defender = BattleList.getDefender(_battleId);
Expand All @@ -61,8 +65,7 @@ contract BattleSystem is System {
if (battle.attackerAction == bytes32("attack") && battle.defenderAction == bytes32("attack")) {
// Buff attackerBuff = Buff(battle.attackerArg);
// Buff defenderBuff = Buff(battle.defenderArg);
Buff attackerBuff = Buff(battle.attackerArg);
Buff defenderBuff = Buff(battle.defenderArg);

// 任意攻击buff都强于None
uint256 attackerAttackPower = BattleUtils.getAttackPower(attackerBuff, defenderBuff, attackerFirepower);
uint256 defenderAttackPower = BattleUtils.getAttackPower(defenderBuff, attackerBuff, defenderFirepower);
Expand All @@ -89,6 +92,7 @@ contract BattleSystem is System {
}
}


if (battle.attackerAction == bytes32("escape") && battle.defenderAction == bytes32("escape")) {
// 双方都逃走,则战斗结束(这里应该都传送到更远地方)
// battle.isEnd = true;
Expand All @@ -100,8 +104,8 @@ contract BattleSystem is System {
emit BattleEnd(_battleId, BattleEndType.AllEscape, address(0));
}
if (battle.attackerAction == bytes32("escape") && battle.defenderAction == bytes32("attack")) {
Buff attackerBuff = Buff(battle.defenderArg);
Buff defenderBuff = Buff(battle.defenderArg);
// Buff attackerBuff = Buff(battle.defenderArg);
// Buff defenderBuff = Buff(battle.defenderArg);
// 任意攻击buff都强于None
if (attackerBuff == defenderBuff || BattleUtils.compareBuff(attackerBuff, defenderBuff) == 2) {
// 逃跑成功
Expand Down Expand Up @@ -132,8 +136,8 @@ contract BattleSystem is System {
}
}
if (battle.attackerAction == bytes32("attack") && battle.defenderAction == bytes32("escape")) {
Buff attackerBuff = Buff(battle.attackerArg);
Buff defenderBuff = Buff(battle.defenderArg);
// Buff attackerBuff = Buff(battle.attackerArg);
// Buff defenderBuff = Buff(battle.defenderArg);
// 任意攻击buff都强于None
if (attackerBuff == defenderBuff || BattleUtils.compareBuff(defenderBuff, attackerBuff) == 2) {
// 逃跑成功
Expand Down Expand Up @@ -169,6 +173,37 @@ contract BattleSystem is System {
}
}

function attackerAttackDenfenderEscape(uint _battleId, BattleListData memory battle, Buff attackerBuff, Buff defenderBuff, uint defenderFirepower) internal {
// 任意攻击buff都强于None
if (attackerBuff == defenderBuff || BattleUtils.compareBuff(attackerBuff, defenderBuff) == 2) {
// 逃跑成功
Player.setState(battle.attacker, PlayerState.Exploring);
Player.setState(battle.defender, PlayerState.Exploring);
// PlayerLocationLock[battle.defender] = block.timestamp; //将被逃跑方禁锢一段时间
PlayerLocationLock.set(battle.defender, block.timestamp);
} else {
// 逃跑失败,被动挨打
uint256 defenderAttackPower = BattleUtils.getAttackPower(defenderBuff, attackerBuff, defenderFirepower);
// battle.attackerHP = BattleUtils.getAttackResult(
// battle.attackerHP,
// defenderAttackPower
// );
// if (battle.attackerHP == 0) {
// battle.winer = battle.defender;
// battle.isEnd = true;
// }
BattleList.setAttackerHP(_battleId, BattleUtils.getAttackResult(battle.attackerHP, defenderAttackPower));
if (BattleList.getAttackerHP(_battleId) == 0) {
// battle.winer = battle.defender;
// battle.isEnd = true;
BattleList.setWinner(_battleId, battle.defender);
BattleList.setIsEnd(_battleId, true);

emit BattleEnd(_battleId, BattleEndType.NormalEnd, battle.defender);
}
}
}

function getAttackResult(uint256 _hp, uint256 _attackPower) internal pure returns (uint256) {
// TODO 后期添加防御力抵消对方的攻击力
if (_attackPower > _hp) {
Expand All @@ -185,7 +220,7 @@ contract BattleSystem is System {
// 游戏失败,将用户脱离战区,血量回满
// TODO 背包系统,宝物系统

outBattlefield(_looser);
BattleUtils.outBattlefield(_looser);
PlayerData memory losser = Player.get(_looser);
uint256 boxId = GameConfig.getBoxId(GAME_CONFIG_KEY);
BoxListData memory box;
Expand All @@ -204,40 +239,5 @@ contract BattleSystem is System {
GameConfig.setRoomId(GAME_CONFIG_KEY, boxId + 1);
}

function goHome() external {
// 回家,将用户脱离战区,血量回满

PlayerData memory player = Player.get(_msgSender());
require(player.state == PlayerState.Exploring, "You should in exploring state");
require(
player.x == GameConfig.getOriginX(GAME_CONFIG_KEY) && player.y == GameConfig.getOriginY(GAME_CONFIG_KEY),
"You are not in the origin point"
);
outBattlefield(_msgSender());
}

function outBattlefield(address _player) internal {
// 脱离战区,则将用户血量回满,坐标不变,状态改为准备中
require(Player.getState(_player) == PlayerState.Exploring, "You should in exploring state");

// Player.setHp(_player, initPlayerHp(_player)); //Todo: setting to atacker or defender hp
Player.setHp(_player, Player.getMaxHp(_player));

for (uint256 i; i < BattleConfig.lengthBattlefieldPlayers(BATTLE_CONFIG_KEY); i++) {
if (BattleConfig.getItemBattlefieldPlayers(BATTLE_CONFIG_KEY, i) == _player) {
BattleConfig.updateBattlefieldPlayers(
BATTLE_CONFIG_KEY,
i,
BattleConfig.getItemBattlefieldPlayers(
BATTLE_CONFIG_KEY,
BattleConfig.lengthBattlefieldPlayers(BATTLE_CONFIG_KEY) - 1
)
);
BattleConfig.popBattlefieldPlayers(BATTLE_CONFIG_KEY);
break;
}
}
Player.setState(_player, PlayerState.Preparing);
Player.setLastBattleTime(_player, block.timestamp);
}
}
29 changes: 27 additions & 2 deletions packages/contracts/src/systems/library/BattleUtils.sol
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
pragma solidity >=0.8.0;

import { BattleState, Buff, PlayerState } from "../../codegen/Types.sol";
import { BattleListData } from "../../codegen/Tables.sol";
import { BattleListData, Player, BattleConfig } from "../../codegen/Tables.sol";
import { BATTLE_CONFIG_KEY } from "../../Constants.sol";

library BattleUtils {
function compareBuff(
Expand Down Expand Up @@ -63,6 +64,30 @@ library BattleUtils {
require(battleState == _battleState, "You are in the wrong state");

require(!_battle.isEnd, "Battle is end");
}
}

function outBattlefield(address _player) internal {
// 脱离战区,则将用户血量回满,坐标不变,状态改为准备中
require(Player.getState(_player) == PlayerState.Exploring, "You should in exploring state");

// Player.setHp(_player, initPlayerHp(_player)); //Todo: setting to atacker or defender hp
Player.setHp(_player, Player.getMaxHp(_player));

for (uint256 i; i < BattleConfig.lengthBattlefieldPlayers(BATTLE_CONFIG_KEY); i++) {
if (BattleConfig.getItemBattlefieldPlayers(BATTLE_CONFIG_KEY, i) == _player) {
BattleConfig.updateBattlefieldPlayers(
BATTLE_CONFIG_KEY,
i,
BattleConfig.getItemBattlefieldPlayers(
BATTLE_CONFIG_KEY,
BattleConfig.lengthBattlefieldPlayers(BATTLE_CONFIG_KEY) - 1
)
);
BattleConfig.popBattlefieldPlayers(BATTLE_CONFIG_KEY);
break;
}
}
Player.setState(_player, PlayerState.Preparing);
Player.setLastBattleTime(_player, block.timestamp);
}
}
37 changes: 35 additions & 2 deletions packages/contracts/test/BattleTest.t.sol
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
// SPDX-License-Identifier: MIT
pragma solidity >=0.8.0;

import {console} from "forge-std/console.sol";
import "forge-std/Test.sol";
import { MudTest } from "@latticexyz/store/src/MudTest.sol";
import { getKeysWithValue } from "@latticexyz/world/src/modules/keyswithvalue/getKeysWithValue.sol";

import { IWorld } from "../src/codegen/world/IWorld.sol";
import { Position } from "../src/systems/Common.sol";
import { GAME_CONFIG_KEY } from "../src/Constants.sol";
import { Player, GameConfig } from "../src/codegen/Tables.sol";
import { Buff } from "../src/codegen/Types.sol";
import { Player, GameConfig, BattleList } from "../src/codegen/Tables.sol";
import { Buff, BattleState } from "../src/codegen/Types.sol";

contract BattleTest is MudTest {
IWorld public world;
Expand Down Expand Up @@ -40,6 +41,27 @@ contract BattleTest is MudTest {
world.joinBattlefield();
vm.stopPrank();

// player property init
vm.startPrank(vm.addr(vm.envUint("PRIVATE_KEY")));
// init bob property
Player.setMaxHp(bob, 200);
Player.setHp(bob, 200);
Player.setAttack(bob, 10);
Player.setAttackRange(bob, 5);
Player.setSpeed(bob, 5);
Player.setStrength(bob, 5);
Player.setSpace(bob, 5);

// init alice property
Player.setMaxHp(alice, 200);
Player.setHp(alice, 200);
Player.setAttack(alice, 10);
Player.setAttackRange(alice, 5);
Player.setSpeed(alice, 5);
Player.setStrength(alice, 5);
Player.setSpace(alice, 5);
vm.stopPrank();

// bob move
vm.startPrank(bob);
world.move(positions());
Expand Down Expand Up @@ -81,6 +103,17 @@ contract BattleTest is MudTest {
vm.startPrank(alice);
world.revealBattle(1, action2, arg2, nonce2);
vm.stopPrank();

vm.startPrank(vm.addr(vm.envUint("PRIVATE_KEY")));
BattleState attackerState = BattleList.getAttackerState(1);
BattleState defenderState = BattleList.getDefenderState(1);
console.logUint(uint(attackerState));
console.logUint(uint(defenderState));


// console.log("attacker state: %d", bytes32(attackerState));
// console.log("defender state: %s", defenderState);
vm.stopPrank();
}

function positions() public pure returns(Position[] memory) {
Expand Down

0 comments on commit a35640f

Please sign in to comment.