Debug_interface - old Server Communicate
This commit is contained in:
commit
d54b51538d
|
@ -22,7 +22,7 @@ namespace Constants
|
||||||
SCCI int32_t DestroyFarmBonus = 4000;
|
SCCI int32_t DestroyFarmBonus = 4000;
|
||||||
// SCCI double recoverMultiplier = 1.2;
|
// SCCI double recoverMultiplier = 1.2;
|
||||||
// SCCI double recycleMultiplier = 0.5;
|
// SCCI double recycleMultiplier = 0.5;
|
||||||
//角色
|
// 角色
|
||||||
SCCI int32_t sizeofCharacter = 800;
|
SCCI int32_t sizeofCharacter = 800;
|
||||||
SCCI int32_t Speed = 2500;
|
SCCI int32_t Speed = 2500;
|
||||||
struct Monk
|
struct Monk
|
||||||
|
@ -92,39 +92,39 @@ namespace Constants
|
||||||
SCCI int32_t attackRange = 5;
|
SCCI int32_t attackRange = 5;
|
||||||
SCCI int32_t Cost = 3000;
|
SCCI int32_t Cost = 3000;
|
||||||
};
|
};
|
||||||
//模块
|
// 模块
|
||||||
|
|
||||||
struct resumption //生命之泉
|
struct resumption // 生命之泉
|
||||||
{
|
{
|
||||||
SCCI int32_t recovery1 = 50;
|
SCCI int32_t recovery1 = 50;
|
||||||
SCCI int32_t recovery2 = 100;
|
SCCI int32_t recovery2 = 100;
|
||||||
SCCI int32_t recovery3 = 150;
|
SCCI int32_t recovery3 = 150;
|
||||||
SCCI int32_t score1 = 2000; //一级生命之泉分数
|
SCCI int32_t score1 = 2000; // 一级生命之泉分数
|
||||||
SCCI int32_t score2 = 3000; //二级生命之泉分数
|
SCCI int32_t score2 = 3000; // 二级生命之泉分数
|
||||||
SCCI int32_t score3 = 4000; //三级生命之泉分数
|
SCCI int32_t score3 = 4000; // 三级生命之泉分数
|
||||||
SCCI int32_t maxHp1 = 200; //一级生命之泉守关怪物血量
|
SCCI int32_t maxHp1 = 200; // 一级生命之泉守关怪物血量
|
||||||
SCCI int32_t maxHp2 = 300; //二级生命之泉守关怪物血量
|
SCCI int32_t maxHp2 = 300; // 二级生命之泉守关怪物血量
|
||||||
SCCI int32_t maxHp3 = 400; //三级生命之泉守关怪物血量
|
SCCI int32_t maxHp3 = 400; // 三级生命之泉守关怪物血量
|
||||||
SCCI int32_t attack = 10; //生命之泉守关怪物攻击力
|
SCCI int32_t attack = 10; // 生命之泉守关怪物攻击力
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Attack_Boost //狂战士之力
|
struct Attack_Boost // 狂战士之力
|
||||||
{
|
{
|
||||||
SCCI int32_t attack_boost1 = 10;
|
SCCI int32_t attack_boost1 = 10;
|
||||||
SCCI int32_t attack_boost2 = 15;
|
SCCI int32_t attack_boost2 = 15;
|
||||||
SCCI int32_t attack_boost3 = 20;
|
SCCI int32_t attack_boost3 = 20;
|
||||||
SCCI int32_t time1 = 30; //一级狂战士之力持续时间
|
SCCI int32_t time1 = 30; // 一级狂战士之力持续时间
|
||||||
SCCI int32_t time2 = 45; //二级狂战士之力持续时间
|
SCCI int32_t time2 = 45; // 二级狂战士之力持续时间
|
||||||
SCCI int32_t time3 = 60; //三级狂战士之力持续时间
|
SCCI int32_t time3 = 60; // 三级狂战士之力持续时间
|
||||||
SCCI int32_t score1 = 4000; //一级狂战士之力分数
|
SCCI int32_t score1 = 4000; // 一级狂战士之力分数
|
||||||
SCCI int32_t score2 = 5000; //二级狂战士之力分数
|
SCCI int32_t score2 = 5000; // 二级狂战士之力分数
|
||||||
SCCI int32_t score3 = 6000; //三级狂战士之力分数
|
SCCI int32_t score3 = 6000; // 三级狂战士之力分数
|
||||||
SCCI int32_t maxHp1 = 400; //一级狂战士之力守关怪物血量
|
SCCI int32_t maxHp1 = 400; // 一级狂战士之力守关怪物血量
|
||||||
SCCI int32_t maxHp2 = 500; //二级狂战士之力守关怪物血量
|
SCCI int32_t maxHp2 = 500; // 二级狂战士之力守关怪物血量
|
||||||
SCCI int32_t maxHp3 = 600; //三级狂战士之力守关怪物血量
|
SCCI int32_t maxHp3 = 600; // 三级狂战士之力守关怪物血量
|
||||||
SCCI int32_t attack1 = 10; //一级狂战士之力守关怪物攻击力
|
SCCI int32_t attack1 = 10; // 一级狂战士之力守关怪物攻击力
|
||||||
SCCI int32_t attack2 = 15; //二级狂战士之力守关怪物攻击力
|
SCCI int32_t attack2 = 15; // 二级狂战士之力守关怪物攻击力
|
||||||
SCCI int32_t attack3 = 20; //三级狂战士之力守关怪物攻击力
|
SCCI int32_t attack3 = 20; // 三级狂战士之力守关怪物攻击力
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Speed_Boost
|
struct Speed_Boost
|
||||||
|
@ -168,7 +168,7 @@ namespace Constants
|
||||||
SCCI int32_t time_cost = 10;
|
SCCI int32_t time_cost = 10;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Trap
|
struct Hole
|
||||||
{
|
{
|
||||||
SCCI int32_t cost = 1000;
|
SCCI int32_t cost = 1000;
|
||||||
SCCI int32_t time = 5;
|
SCCI int32_t time = 5;
|
||||||
|
@ -182,7 +182,7 @@ namespace Constants
|
||||||
SCCI int32_t time = 5;
|
SCCI int32_t time = 5;
|
||||||
SCCI int32_t continous_time = 30;
|
SCCI int32_t continous_time = 30;
|
||||||
};
|
};
|
||||||
//商店商品
|
// 商店商品
|
||||||
struct blood_vial
|
struct blood_vial
|
||||||
{
|
{
|
||||||
SCCI int32_t cost1 = 1500;
|
SCCI int32_t cost1 = 1500;
|
||||||
|
@ -226,9 +226,9 @@ namespace Constants
|
||||||
{
|
{
|
||||||
SCCI int32_t cost = 10000;
|
SCCI int32_t cost = 10000;
|
||||||
SCCI int32_t time = 30;
|
SCCI int32_t time = 30;
|
||||||
SCCI int32_t attack_boost = 1.2; //注意这是提升的倍数
|
SCCI int32_t attack_boost = 1.2; // 注意这是提升的倍数
|
||||||
SCCI int32_t speed_boost = 300; //注意这是直接叠加
|
SCCI int32_t speed_boost = 300; // 注意这是直接叠加
|
||||||
SCCI int32_t attack_freq_boost = 1.25; //注意这是提升的倍数
|
SCCI int32_t attack_freq_boost = 1.25; // 注意这是提升的倍数
|
||||||
};
|
};
|
||||||
} // namespace Constants
|
} // namespace Constants
|
||||||
#endif
|
#endif
|
|
@ -8,23 +8,26 @@
|
||||||
// 为假则play()期间确保游戏状态不更新,为真则只保证游戏状态在调用相关方法时不更新,大致一帧更新一次
|
// 为假则play()期间确保游戏状态不更新,为真则只保证游戏状态在调用相关方法时不更新,大致一帧更新一次
|
||||||
extern const bool asynchronous = false;
|
extern const bool asynchronous = false;
|
||||||
|
|
||||||
// 选手需要依次将player1到player4的角色类型在这里定义
|
// 选手需要依次将player1到player5的角色类型在这里定义
|
||||||
extern const std::array<THUAI8::CharacterType, 12> CharacterTypeDict = {
|
extern const std::array<THUAI8::CharacterType, 5> BuddhistsCharacterTypeDict = {
|
||||||
THUAI8::CharacterType::Monk,
|
THUAI8::CharacterType::Monk,
|
||||||
THUAI8::CharacterType::MonkeyKing,
|
THUAI8::CharacterType::MonkeyKing,
|
||||||
THUAI8::CharacterType::Pigsy,
|
THUAI8::CharacterType::Pigsy,
|
||||||
THUAI8::CharacterType::ShaWujing,
|
THUAI8::CharacterType::ShaWujing,
|
||||||
THUAI8::CharacterType::Whitedragonhorse,
|
THUAI8::CharacterType::Whitedragonhorse,
|
||||||
|
};
|
||||||
|
|
||||||
|
extern const std::array<THUAI8::CharacterType, 5> MonstersCharacterTypeDict = {
|
||||||
THUAI8::CharacterType::JiuTouYuanSheng,
|
THUAI8::CharacterType::JiuTouYuanSheng,
|
||||||
THUAI8::CharacterType::Honghaier,
|
THUAI8::CharacterType::Honghaier,
|
||||||
THUAI8::CharacterType::Gyuumao,
|
THUAI8::CharacterType::Gyuumao,
|
||||||
THUAI8::CharacterType::Princess_Iron_Fan,
|
THUAI8::CharacterType::Princess_Iron_Fan,
|
||||||
THUAI8::CharacterType::Spider,
|
THUAI8::CharacterType::Spider,
|
||||||
};
|
}
|
||||||
|
|
||||||
// 可以在AI.cpp内部声明变量与函数
|
// 可以在AI.cpp内部声明变量与函数
|
||||||
|
|
||||||
void AI::play(ICharacterAPI& api)
|
void AI::play(ICharacterAPI & api)
|
||||||
{
|
{
|
||||||
if (this->playerID == 1)
|
if (this->playerID == 1)
|
||||||
{
|
{
|
||||||
|
|
|
@ -27,9 +27,9 @@ Logic::Logic(int32_t pID, int32_t tID, THUAI8::PlayerType pType, THUAI8::Charact
|
||||||
bufferState->gameInfo = std::make_shared<THUAI8::GameInfo>();
|
bufferState->gameInfo = std::make_shared<THUAI8::GameInfo>();
|
||||||
bufferState->mapInfo = std::make_shared<THUAI8::GameMap>();
|
bufferState->mapInfo = std::make_shared<THUAI8::GameMap>();
|
||||||
if (teamID == 0)
|
if (teamID == 0)
|
||||||
playerTeam = THUAI8::PlayerTeam::Red;
|
playerTeam = THUAI8::PlayerTeam::BuddhistsTeam;
|
||||||
else if (teamID == 1)
|
else if (teamID == 1)
|
||||||
playerTeam = THUAI8::PlayerTeam::Blue;
|
playerTeam = THUAI8::PlayerTeam::MonstersTeam;
|
||||||
else
|
else
|
||||||
playerTeam = THUAI8::PlayerTeam::NullTeam;
|
playerTeam = THUAI8::PlayerTeam::NullTeam;
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ std::vector<std::shared_ptr<const THUAI8::Character>> Logic::GetCharacters() con
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<const THUAI8::Character>> Logic::GetEnemySCharacters() const
|
std::vector<std::shared_ptr<const THUAI8::Character>> Logic::GetEnemyCharacters() const
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(mtxState);
|
std::unique_lock<std::mutex> lock(mtxState);
|
||||||
std::vector<std::shared_ptr<const THUAI8::Character>> temp(currentState->enemyCharacters.begin(), currentState->enemyCharacters.end());
|
std::vector<std::shared_ptr<const THUAI8::Character>> temp(currentState->enemyCharacters.begin(), currentState->enemyCharacters.end());
|
||||||
|
|
|
@ -1,10 +1,12 @@
|
||||||
import PyAPI.structures as THUAI8
|
|
||||||
from PyAPI.Interface import ICharacterAPI, ITeamAPI, IAI
|
|
||||||
from PyAPI.utils import AssistFunction
|
|
||||||
from typing import Union, Final, cast, List
|
|
||||||
from PyAPI.constants import Constants
|
|
||||||
import queue
|
import queue
|
||||||
import time
|
import time
|
||||||
|
from typing import Final, List, Union, cast
|
||||||
|
|
||||||
|
import PyAPI.structures as THUAI8
|
||||||
|
from PyAPI.constants import Constants
|
||||||
|
from PyAPI.Interface import IAI, ICharacterAPI, ITeamAPI
|
||||||
|
from PyAPI.utils import AssistFunction
|
||||||
|
|
||||||
|
|
||||||
class Setting:
|
class Setting:
|
||||||
# 为假则play()期间确保游戏状态不更新,为真则只保证游戏状态在调用相关方法时不更新,大致一帧更新一次
|
# 为假则play()期间确保游戏状态不更新,为真则只保证游戏状态在调用相关方法时不更新,大致一帧更新一次
|
||||||
|
@ -13,6 +15,22 @@ class Setting:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
<<<<<<< HEAD
|
||||||
|
def BuddhistsCharacterTypes() -> List[THUAI8.CharacterType]:
|
||||||
|
return [
|
||||||
|
THUAI8.CharacterType.Monk,
|
||||||
|
THUAI8.CharacterType.MonkyKing,
|
||||||
|
THUAI8.CharacterType.Pigsy,
|
||||||
|
THUAI8.CharacterType.ShaWujing,
|
||||||
|
THUAI8.CharacterType.Whitedragonhorse,
|
||||||
|
]
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def MonsterCharacterTypes() -> List[THUAI8.CharacterType]:
|
||||||
|
return [
|
||||||
|
THUAI8.CharacterType.JiuTouYuanSheng,
|
||||||
|
THUAI8.CharacterType.HongHaier,
|
||||||
|
=======
|
||||||
def ShipTypes() -> List[THUAI8.CharacterType]:
|
def ShipTypes() -> List[THUAI8.CharacterType]:
|
||||||
return [
|
return [
|
||||||
THUAI8.CharacterType.Monk,
|
THUAI8.CharacterType.Monk,
|
||||||
|
@ -22,17 +40,30 @@ class Setting:
|
||||||
THUAI8.CharacterType.Whitedragonhorse,
|
THUAI8.CharacterType.Whitedragonhorse,
|
||||||
THUAI8.CharacterType.JiuTouYuanSheng,
|
THUAI8.CharacterType.JiuTouYuanSheng,
|
||||||
THUAI8.CharacterType.Honghaier,
|
THUAI8.CharacterType.Honghaier,
|
||||||
|
>>>>>>> 5a1751dc64f09ba19aaa818e5dc99172d15f4c69
|
||||||
THUAI8.CharacterType.Gyuumao,
|
THUAI8.CharacterType.Gyuumao,
|
||||||
THUAI8.CharacterType.Princess_Iron_Fan,
|
THUAI8.CharacterType.Princess_Iron_Fan,
|
||||||
THUAI8.CharacterType.Spider,
|
THUAI8.CharacterType.Spider,
|
||||||
]
|
]
|
||||||
|
<<<<<<< HEAD
|
||||||
|
|
||||||
|
|
||||||
numOfGridPerCell: Final[int] = 1000
|
numOfGridPerCell: Final[int] = 1000
|
||||||
|
|
||||||
|
|
||||||
|
=======
|
||||||
|
numOfGridPerCell: Final[int] = 1000
|
||||||
|
|
||||||
|
>>>>>>> 5a1751dc64f09ba19aaa818e5dc99172d15f4c69
|
||||||
class AI(IAI):
|
class AI(IAI):
|
||||||
def __init__(self, pID: int):
|
def __init__(self, pID: int):
|
||||||
self.__playerID = pID
|
self.__playerID = pID
|
||||||
|
|
||||||
|
<<<<<<< HEAD
|
||||||
|
def CharacterPlay(self, api: ICharacterAPI) -> None:
|
||||||
|
=======
|
||||||
def ShipPlay(self, api: IShipAPI) -> None:
|
def ShipPlay(self, api: IShipAPI) -> None:
|
||||||
|
>>>>>>> 5a1751dc64f09ba19aaa818e5dc99172d15f4c69
|
||||||
# 公共操作
|
# 公共操作
|
||||||
if self.__playerID == 1:
|
if self.__playerID == 1:
|
||||||
# player1的操作
|
# player1的操作
|
||||||
|
@ -46,9 +77,13 @@ class AI(IAI):
|
||||||
elif self.__playerID == 4:
|
elif self.__playerID == 4:
|
||||||
# player4的操作
|
# player4的操作
|
||||||
return
|
return
|
||||||
|
<<<<<<< HEAD
|
||||||
|
return
|
||||||
|
=======
|
||||||
elif self.__playerID == 5:
|
elif self.__playerID == 5:
|
||||||
# player4的操作
|
# player4的操作
|
||||||
return
|
return
|
||||||
|
>>>>>>> 5a1751dc64f09ba19aaa818e5dc99172d15f4c69
|
||||||
|
|
||||||
def TeamPlay(self, api: ITeamAPI) -> None:
|
def TeamPlay(self, api: ITeamAPI) -> None:
|
||||||
# player0的操作
|
# player0的操作
|
||||||
|
|
|
@ -0,0 +1,199 @@
|
||||||
|
class Constants:
|
||||||
|
frameDuration = 50
|
||||||
|
|
||||||
|
numofGridPerCell = 1000
|
||||||
|
rows = 50
|
||||||
|
cols = 50
|
||||||
|
|
||||||
|
destroyBarracksBonus = 6000
|
||||||
|
destroySpringBonus = 3000
|
||||||
|
destroyFarmBonus = 4000
|
||||||
|
|
||||||
|
sizeofCharacter = 800
|
||||||
|
speed = 2500
|
||||||
|
|
||||||
|
|
||||||
|
class Monk:
|
||||||
|
maxHp = 1000
|
||||||
|
|
||||||
|
|
||||||
|
class MonkyKing:
|
||||||
|
maxHp = 200
|
||||||
|
commonAttackPower = 30
|
||||||
|
attackRange = 1
|
||||||
|
cost = 5000
|
||||||
|
|
||||||
|
|
||||||
|
class Pigsy:
|
||||||
|
maxHp = 300
|
||||||
|
commonAttackPower = 20
|
||||||
|
attackRange = 2
|
||||||
|
cost = 4000
|
||||||
|
|
||||||
|
|
||||||
|
class ShaWujing:
|
||||||
|
maxHp = 150
|
||||||
|
commonAttackPower = 10
|
||||||
|
attackRange = 5
|
||||||
|
cost = 3000
|
||||||
|
|
||||||
|
|
||||||
|
class Whitedragonhorse:
|
||||||
|
maxHp = 150
|
||||||
|
commonAttackPower = 10
|
||||||
|
attackRange = 5
|
||||||
|
cost = 4000
|
||||||
|
|
||||||
|
|
||||||
|
class JiuTouYuanSheng:
|
||||||
|
maxHp = 1000
|
||||||
|
|
||||||
|
|
||||||
|
class HongHaier:
|
||||||
|
maxHp = 200
|
||||||
|
commonAttackPower = 25
|
||||||
|
attackRange = 1
|
||||||
|
cost = 5000
|
||||||
|
|
||||||
|
|
||||||
|
class Gyuumao:
|
||||||
|
maxHp = 300
|
||||||
|
commonAttackPower = 20
|
||||||
|
attackRange = 2
|
||||||
|
cost = 4000
|
||||||
|
|
||||||
|
|
||||||
|
class Princess_Iron_Fan:
|
||||||
|
maxHp = 150
|
||||||
|
commonAttackPower = 10
|
||||||
|
attackRange = 5
|
||||||
|
cost = 3000
|
||||||
|
|
||||||
|
|
||||||
|
class Spider:
|
||||||
|
maxHp = 150
|
||||||
|
commonAttackPower = 10
|
||||||
|
attackRange = 5
|
||||||
|
cost = 3000
|
||||||
|
|
||||||
|
|
||||||
|
class resumption:
|
||||||
|
recovery1 = 50
|
||||||
|
recovery2 = 100
|
||||||
|
recovery3 = 150
|
||||||
|
score1 = 2000
|
||||||
|
score2 = 3000
|
||||||
|
score3 = 4000
|
||||||
|
maxHp1 = 200
|
||||||
|
maxHp2 = 300
|
||||||
|
maxHp3 = 400
|
||||||
|
attack = 10
|
||||||
|
|
||||||
|
|
||||||
|
class Attack_Boost:
|
||||||
|
attackBoost1 = 10
|
||||||
|
attackBoost2 = 15
|
||||||
|
attackBoost3 = 20
|
||||||
|
time1 = 30
|
||||||
|
time2 = 45
|
||||||
|
time3 = 60
|
||||||
|
score1 = 4000
|
||||||
|
score2 = 5000
|
||||||
|
score3 = 6000
|
||||||
|
maxHp1 = 400
|
||||||
|
maxHp2 = 500
|
||||||
|
maxHp3 = 600
|
||||||
|
attack1 = 10
|
||||||
|
attack2 = 15
|
||||||
|
attack3 = 20
|
||||||
|
|
||||||
|
|
||||||
|
class Speed_Boost:
|
||||||
|
speedBoost1 = 500
|
||||||
|
time = 60
|
||||||
|
score = 3000
|
||||||
|
maxHp = 300
|
||||||
|
attack = 10
|
||||||
|
|
||||||
|
|
||||||
|
class View_Boost:
|
||||||
|
time = 60
|
||||||
|
score = 3000
|
||||||
|
maxHp = 300
|
||||||
|
attack = 10
|
||||||
|
|
||||||
|
|
||||||
|
class Barracks:
|
||||||
|
maxHp = 600
|
||||||
|
cost = 10000
|
||||||
|
sabotage_score = 6000
|
||||||
|
time_cost = 15
|
||||||
|
|
||||||
|
|
||||||
|
class Spring:
|
||||||
|
maxHp = 300
|
||||||
|
cost = 8000
|
||||||
|
sabotage_score = 3000
|
||||||
|
time_cost = 10
|
||||||
|
|
||||||
|
|
||||||
|
class Farm:
|
||||||
|
maxHp = 400
|
||||||
|
cost = 8000
|
||||||
|
sabotage_score = 3000
|
||||||
|
time_cost = 10
|
||||||
|
|
||||||
|
|
||||||
|
class Hole:
|
||||||
|
cost = 1000
|
||||||
|
time = 5
|
||||||
|
attack = 20
|
||||||
|
continous_time = 5
|
||||||
|
|
||||||
|
|
||||||
|
class Cage:
|
||||||
|
cost = 1000
|
||||||
|
time = 5
|
||||||
|
continueous_time = 30
|
||||||
|
|
||||||
|
|
||||||
|
class blood_vial:
|
||||||
|
cost1 = 1500
|
||||||
|
cost2 = 3000
|
||||||
|
cost3 = 4500
|
||||||
|
recovery1 = 50
|
||||||
|
recovery2 = 100
|
||||||
|
recovery3 = 150
|
||||||
|
|
||||||
|
|
||||||
|
class Shield:
|
||||||
|
cost1 = 2000
|
||||||
|
cost2 = 3500
|
||||||
|
cost3 = 5000
|
||||||
|
defence1 = 50
|
||||||
|
defence2 = 100
|
||||||
|
defence3 = 150
|
||||||
|
|
||||||
|
|
||||||
|
class Speed_shoes:
|
||||||
|
speedBoost = 500
|
||||||
|
time = 60
|
||||||
|
cost = 1500
|
||||||
|
|
||||||
|
|
||||||
|
class purification_medicine:
|
||||||
|
cost = 2000
|
||||||
|
time = 30
|
||||||
|
|
||||||
|
|
||||||
|
class invisibility:
|
||||||
|
cost = 4000
|
||||||
|
time = 10
|
||||||
|
|
||||||
|
|
||||||
|
class berserk:
|
||||||
|
cost = 10000
|
||||||
|
time = 30
|
||||||
|
attack_boost = 1.2 # 注意这是提升的倍数
|
||||||
|
speed_boost = 300 # 注意这是直接叠加
|
||||||
|
attack_freq_boost = 1.25 # 注意这是提升的倍数
|
|
@ -1,20 +1,18 @@
|
||||||
using Avalonia;
|
using Avalonia;
|
||||||
using Avalonia.Controls.ApplicationLifetimes;
|
using Avalonia.Controls.ApplicationLifetimes;
|
||||||
using Avalonia.Data.Core;
|
|
||||||
using Avalonia.Data.Core.Plugins;
|
|
||||||
using Avalonia.Markup.Xaml;
|
using Avalonia.Markup.Xaml;
|
||||||
|
using debug_interface.Services;
|
||||||
using debug_interface.ViewModels;
|
using debug_interface.ViewModels;
|
||||||
using debug_interface.Views;
|
using debug_interface.Views;
|
||||||
using System.Linq;
|
using System;
|
||||||
|
using System.IO;
|
||||||
|
using installer.Model;
|
||||||
|
using installer.Data;
|
||||||
|
|
||||||
namespace debug_interface
|
namespace debug_interface
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// 应用程序的后置代码,负责初始化和启动主窗口。
|
|
||||||
/// </summary>
|
|
||||||
public partial class App : Application
|
public partial class App : Application
|
||||||
{
|
{
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
AvaloniaXamlLoader.Load(this);
|
AvaloniaXamlLoader.Load(this);
|
||||||
|
@ -24,34 +22,43 @@ namespace debug_interface
|
||||||
{
|
{
|
||||||
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
if (ApplicationLifetime is IClassicDesktopStyleApplicationLifetime desktop)
|
||||||
{
|
{
|
||||||
// Avoid duplicate validations from both Avalonia and the CommunityToolkit.
|
// 加载配置
|
||||||
// More info: https://docs.avaloniaui.net/docs/guides/development-guides/data-validation#manage-validationplugins
|
var config = new ConfigData();
|
||||||
DisableAvaloniaDataAnnotationValidation();
|
|
||||||
|
|
||||||
var mainWindowViewModel = new MainWindowViewModel();
|
// 设置日志目录
|
||||||
|
string logDir = Path.Combine(config.InstallPath, "Logs");
|
||||||
|
Directory.CreateDirectory(logDir);
|
||||||
|
|
||||||
|
// 创建日志记录器
|
||||||
|
var logFilePath = Path.Combine(logDir, $"debug_interface_{DateTime.Now:yyyyMMdd_HHmmss}.log");
|
||||||
|
var logger = new FileLogger(logFilePath);
|
||||||
|
|
||||||
|
// 创建主窗口视图模型
|
||||||
|
var mainWindowViewModel = new MainWindowViewModel(logger, config);
|
||||||
|
|
||||||
|
// 创建服务器通信服务
|
||||||
|
var serverCommunicationService = new ServerCommunicationService(mainWindowViewModel, logger, config);
|
||||||
|
|
||||||
|
// 设置主窗口
|
||||||
desktop.MainWindow = new MainWindow
|
desktop.MainWindow = new MainWindow
|
||||||
{
|
{
|
||||||
DataContext = new MainWindowViewModel(),
|
DataContext = mainWindowViewModel
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// 尝试连接服务器或启动回放
|
||||||
|
if (string.IsNullOrEmpty(config.Commands.PlaybackFile))
|
||||||
|
{
|
||||||
|
// 连接到服务器
|
||||||
|
_ = serverCommunicationService.ConnectToServer();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// 启动回放模式
|
||||||
|
serverCommunicationService.StartPlaybackMode();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
base.OnFrameworkInitializationCompleted();
|
base.OnFrameworkInitializationCompleted();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DisableAvaloniaDataAnnotationValidation()
|
|
||||||
{
|
|
||||||
// Get an array of plugins to remove
|
|
||||||
var dataValidationPluginsToRemove =
|
|
||||||
BindingPlugins.DataValidators.OfType<DataAnnotationsValidationPlugin>().ToArray();
|
|
||||||
|
|
||||||
// remove each entry found
|
|
||||||
foreach (var plugin in dataValidationPluginsToRemove)
|
|
||||||
{
|
|
||||||
BindingPlugins.DataValidators.Remove(plugin);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
//MapCell.cs
|
//MapCell.cs
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
|
using debug_interface.ViewModels;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
|
@ -0,0 +1,776 @@
|
||||||
|
using System;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Avalonia.Threading;
|
||||||
|
using debug_interface.ViewModels;
|
||||||
|
using Grpc.Core;
|
||||||
|
using installer.Model;
|
||||||
|
using installer.Data;
|
||||||
|
|
||||||
|
namespace debug_interface.Services
|
||||||
|
{
|
||||||
|
public class ServerCommunicationService
|
||||||
|
{
|
||||||
|
private readonly MainWindowViewModel _viewModel;
|
||||||
|
private readonly Logger _logger;
|
||||||
|
private readonly ConfigData _config;
|
||||||
|
private bool _isConnected = false;
|
||||||
|
private bool _isPlaybackMode = false;
|
||||||
|
|
||||||
|
public ServerCommunicationService(MainWindowViewModel viewModel, Logger logger, ConfigData config)
|
||||||
|
{
|
||||||
|
_viewModel = viewModel;
|
||||||
|
_logger = logger;
|
||||||
|
_config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task ConnectToServer()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
string ip = _config.Commands.IP;
|
||||||
|
string port = _config.Commands.Port;
|
||||||
|
|
||||||
|
_logger.LogInfo($"尝试连接服务器 {ip}:{port}");
|
||||||
|
|
||||||
|
// 由于没有正确的Proto引用,这里暂时只模拟连接行为
|
||||||
|
await Task.Delay(1000); // 模拟连接延迟
|
||||||
|
|
||||||
|
await Dispatcher.UIThread.InvokeAsync(() => {
|
||||||
|
_viewModel.GameLog = $"已连接到服务器 {ip}:{port}";
|
||||||
|
});
|
||||||
|
|
||||||
|
_isConnected = true;
|
||||||
|
_logger.LogInfo("已模拟连接到服务器");
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError($"连接失败: {ex.Message}");
|
||||||
|
|
||||||
|
await Dispatcher.UIThread.InvokeAsync(() => {
|
||||||
|
_viewModel.GameLog = $"连接失败: {ex.Message}";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void StartPlaybackMode()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
_isPlaybackMode = true;
|
||||||
|
string playbackFile = _config.Commands.PlaybackFile ?? "";
|
||||||
|
|
||||||
|
_logger.LogInfo($"模拟回放: {playbackFile}");
|
||||||
|
|
||||||
|
Dispatcher.UIThread.InvokeAsync(() => {
|
||||||
|
_viewModel.GameLog = $"模拟回放: {playbackFile}";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
|
_logger.LogError($"回放错误: {ex.Message}");
|
||||||
|
|
||||||
|
Dispatcher.UIThread.InvokeAsync(() => {
|
||||||
|
_viewModel.GameLog = $"回放错误: {ex.Message}";
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//using System;
|
||||||
|
//using System.Linq;
|
||||||
|
//using System.Threading.Tasks;
|
||||||
|
//using Avalonia.Threading;
|
||||||
|
//using debug_interface.ViewModels;
|
||||||
|
//using Grpc.Core;
|
||||||
|
//using Google.Protobuf; // 假设这是proto文件生成的命名空间
|
||||||
|
//using installer.Model; // Logger的命名空间
|
||||||
|
//using installer.Data; // ConfigData的命名空间
|
||||||
|
//using System.Collections.Generic;
|
||||||
|
//using Avalonia.Data;
|
||||||
|
//using System.Threading.Channels;
|
||||||
|
|
||||||
|
//namespace debug_interface.Services
|
||||||
|
//{
|
||||||
|
// public class ServerCommunicationService
|
||||||
|
// {
|
||||||
|
// private readonly MainWindowViewModel _viewModel;
|
||||||
|
// private readonly Logger _logger;
|
||||||
|
// private readonly ConfigData _config;
|
||||||
|
// private AvailableService.AvailableServiceClient? _client;
|
||||||
|
// private AsyncServerStreamingCall<MessageToClient>? _responseStream;
|
||||||
|
// private bool _isConnected = false;
|
||||||
|
// private bool _isPlaybackMode = false;
|
||||||
|
|
||||||
|
// public ServerCommunicationService(MainWindowViewModel viewModel, Logger logger, ConfigData config)
|
||||||
|
// {
|
||||||
|
// _viewModel = viewModel;
|
||||||
|
// _logger = logger;
|
||||||
|
// _config = config;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public async Task ConnectToServer()
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// if (_isPlaybackMode)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
// string ip = _config.Commands.IP;
|
||||||
|
// string port = _config.Commands.Port;
|
||||||
|
// long playerId = _config.Commands.PlayerID;
|
||||||
|
// long teamId = _config.Commands.TeamID;
|
||||||
|
// int characterType = _config.Commands.CharacterType;
|
||||||
|
|
||||||
|
// string connectionString = $"{ip}:{port}";
|
||||||
|
// _logger.LogInfo($"正在连接到服务器 {connectionString}");
|
||||||
|
|
||||||
|
// // 创建gRPC通道和客户端
|
||||||
|
// var channel = new Channel(connectionString, ChannelCredentials.Insecure);
|
||||||
|
// _client = new AvailableService.AvailableServiceClient(channel);
|
||||||
|
|
||||||
|
// // 创建连接消息
|
||||||
|
// var characterMsg = new CharacterMsg
|
||||||
|
// {
|
||||||
|
// CharacterId = playerId,
|
||||||
|
// TeamId = teamId,
|
||||||
|
// CharacterType = (CharacterType)characterType
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // 连接到服务器
|
||||||
|
// _responseStream = _client.AddCharacter(characterMsg);
|
||||||
|
// _isConnected = true;
|
||||||
|
|
||||||
|
// // 开始接收消息
|
||||||
|
// _ = StartReceivingMessagesAsync();
|
||||||
|
|
||||||
|
// _logger.LogInfo("成功连接到服务器");
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// _isConnected = false;
|
||||||
|
// _logger.LogError($"连接服务器失败: {ex.Message}");
|
||||||
|
|
||||||
|
// // 在UI中显示错误
|
||||||
|
// await Dispatcher.UIThread.InvokeAsync(() => {
|
||||||
|
// _viewModel.GameLog = $"连接服务器错误: {ex.Message}";
|
||||||
|
// });
|
||||||
|
|
||||||
|
// throw;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// public void StartPlaybackMode()
|
||||||
|
// {
|
||||||
|
// _isPlaybackMode = true;
|
||||||
|
// string playbackFile = _config.Commands.PlaybackFile ?? "";
|
||||||
|
// double playbackSpeed = _config.Commands.PlaybackSpeed;
|
||||||
|
|
||||||
|
// _logger.LogInfo($"正在从{playbackFile}以{playbackSpeed}倍速开始回放模式");
|
||||||
|
|
||||||
|
// // 这里可以实现回放逻辑,读取文件并模拟服务器消息
|
||||||
|
// // 例如启动一个单独的任务来读取和处理文件
|
||||||
|
// _ = Task.Run(async () => {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// // 简单的回放逻辑示例
|
||||||
|
// if (System.IO.File.Exists(playbackFile))
|
||||||
|
// {
|
||||||
|
// // 读取文件内容...
|
||||||
|
// _logger.LogInfo("回放文件存在,开始读取数据");
|
||||||
|
|
||||||
|
// // 这里是简化实现,实际应根据文件格式处理
|
||||||
|
// var fileBytes = System.IO.File.ReadAllBytes(playbackFile);
|
||||||
|
|
||||||
|
// // 通知UI
|
||||||
|
// await Dispatcher.UIThread.InvokeAsync(() => {
|
||||||
|
// _viewModel.GameLog = "正在回放...";
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// _logger.LogError($"回放文件不存在: {playbackFile}");
|
||||||
|
// await Dispatcher.UIThread.InvokeAsync(() => {
|
||||||
|
// _viewModel.GameLog = "回放文件不存在!";
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// _logger.LogError($"回放过程中出错: {ex.Message}");
|
||||||
|
// await Dispatcher.UIThread.InvokeAsync(() => {
|
||||||
|
// _viewModel.GameLog = $"回放错误: {ex.Message}";
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private async Task StartReceivingMessagesAsync()
|
||||||
|
// {
|
||||||
|
// if (_responseStream == null)
|
||||||
|
// return;
|
||||||
|
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// _logger.LogInfo("开始接收服务器消息");
|
||||||
|
|
||||||
|
// while (await _responseStream.ResponseStream.MoveNext(default))
|
||||||
|
// {
|
||||||
|
// var message = _responseStream.ResponseStream.Current;
|
||||||
|
|
||||||
|
// // 在UI线程上处理消息,以安全地更新UI
|
||||||
|
// await Dispatcher.UIThread.InvokeAsync(() => {
|
||||||
|
// ProcessServerMessage(message);
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (RpcException ex) when (ex.StatusCode == StatusCode.Cancelled)
|
||||||
|
// {
|
||||||
|
// _logger.LogInfo("服务器流已取消");
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// _logger.LogError($"接收服务器消息错误: {ex.Message}");
|
||||||
|
|
||||||
|
// await Dispatcher.UIThread.InvokeAsync(() => {
|
||||||
|
// _viewModel.GameLog = $"连接错误: {ex.Message}";
|
||||||
|
// });
|
||||||
|
|
||||||
|
// // 尝试重新连接
|
||||||
|
// await TryReconnectAsync();
|
||||||
|
// }
|
||||||
|
// finally
|
||||||
|
// {
|
||||||
|
// _isConnected = false;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private async Task TryReconnectAsync()
|
||||||
|
// {
|
||||||
|
// _logger.LogInfo("尝试重新连接服务器...");
|
||||||
|
|
||||||
|
// // 等待一段时间后重试
|
||||||
|
// await Task.Delay(5000);
|
||||||
|
|
||||||
|
// if (!_isConnected && !_isPlaybackMode)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// await ConnectToServer();
|
||||||
|
// }
|
||||||
|
// catch
|
||||||
|
// {
|
||||||
|
// // 重连失败,等待更长时间后再次尝试
|
||||||
|
// await Task.Delay(10000);
|
||||||
|
// _ = TryReconnectAsync();
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private void ProcessServerMessage(MessageToClient message)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// // 更新游戏状态
|
||||||
|
// switch (message.GameState)
|
||||||
|
// {
|
||||||
|
// case GameState.GameStart:
|
||||||
|
// _logger.LogInfo("游戏开始");
|
||||||
|
// _viewModel.GameLog = "游戏开始...";
|
||||||
|
// break;
|
||||||
|
|
||||||
|
// case GameState.GameRunning:
|
||||||
|
// // 处理运行中的游戏数据
|
||||||
|
// _viewModel.GameLog = "游戏运行中...";
|
||||||
|
// break;
|
||||||
|
|
||||||
|
// case GameState.GameEnd:
|
||||||
|
// _logger.LogInfo("游戏结束");
|
||||||
|
// _viewModel.GameLog = "游戏结束";
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 更新全局游戏信息
|
||||||
|
// if (message.AllMessage != null)
|
||||||
|
// {
|
||||||
|
// UpdateGlobalGameInfo(message.AllMessage);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 处理单个对象消息
|
||||||
|
// foreach (var obj in message.ObjMessage)
|
||||||
|
// {
|
||||||
|
// ProcessObjectMessage(obj);
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// _logger.LogError($"处理服务器消息错误: {ex.Message}");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private void UpdateGlobalGameInfo(MessageOfAll allMessage)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// // 更新游戏时间
|
||||||
|
// _viewModel.CurrentTime = FormatGameTime(allMessage.GameTime);
|
||||||
|
|
||||||
|
// // 更新队伍得分
|
||||||
|
// _viewModel.RedScore = allMessage.BuddhistsTeamScore;
|
||||||
|
// _viewModel.BlueScore = allMessage.MonstersTeamScore;
|
||||||
|
|
||||||
|
// // 更新队伍经济/资源
|
||||||
|
// _viewModel.BuddhistTeamEconomy = allMessage.BuddhistsTeamEconomy;
|
||||||
|
// _viewModel.MonstersTeamEconomy = allMessage.MonstersTeamEconomy;
|
||||||
|
|
||||||
|
// // 更新英雄HP (如果ViewModel中有对应属性)
|
||||||
|
// if (typeof(MainWindowViewModel).GetProperty("BuddhistHeroHp") != null)
|
||||||
|
// {
|
||||||
|
// _viewModel.BuddhistHeroHp = allMessage.BuddhistsHeroHp;
|
||||||
|
// _viewModel.MonstersHeroHp = allMessage.MonstersHeroHp;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// _logger.LogError($"更新全局游戏信息失败: {ex.Message}");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private void ProcessObjectMessage(MessageOfObj objMessage)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// switch (objMessage.MessageOfObjCase)
|
||||||
|
// {
|
||||||
|
// case MessageOfObj.MessageOfObjOneofCase.CharacterMessage:
|
||||||
|
// UpdateCharacter(objMessage.CharacterMessage);
|
||||||
|
// break;
|
||||||
|
|
||||||
|
// case MessageOfObj.MessageOfObjOneofCase.BarracksMessage:
|
||||||
|
// UpdateBuilding(objMessage.BarracksMessage, "兵营");
|
||||||
|
// break;
|
||||||
|
|
||||||
|
// case MessageOfObj.MessageOfObjOneofCase.SpringMessage:
|
||||||
|
// UpdateBuilding(objMessage.SpringMessage, "泉水");
|
||||||
|
// break;
|
||||||
|
|
||||||
|
// case MessageOfObj.MessageOfObjOneofCase.FarmMessage:
|
||||||
|
// UpdateBuilding(objMessage.FarmMessage, "农场");
|
||||||
|
// break;
|
||||||
|
|
||||||
|
// case MessageOfObj.MessageOfObjOneofCase.TrapMessage:
|
||||||
|
// UpdateTrap(objMessage.TrapMessage);
|
||||||
|
// break;
|
||||||
|
|
||||||
|
// case MessageOfObj.MessageOfObjOneofCase.EconomyResourceMessage:
|
||||||
|
// UpdateResource(objMessage.EconomyResourceMessage);
|
||||||
|
// break;
|
||||||
|
|
||||||
|
// case MessageOfObj.MessageOfObjOneofCase.AdditionResourceMessage:
|
||||||
|
// UpdateAdditionResource(objMessage.AdditionResourceMessage);
|
||||||
|
// break;
|
||||||
|
|
||||||
|
// case MessageOfObj.MessageOfObjOneofCase.MapMessage:
|
||||||
|
// UpdateMap(objMessage.MapMessage);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// _logger.LogError($"处理对象消息失败: {ex.Message} (类型: {objMessage.MessageOfObjCase})");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private void UpdateCharacter(MessageOfCharacter character)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// // 在适当的团队集合中查找角色
|
||||||
|
// var isRedTeam = character.TeamId == 1; // 1表示取经队
|
||||||
|
// var collection = isRedTeam
|
||||||
|
// ? _viewModel.RedTeamCharacters
|
||||||
|
// : _viewModel.BlueTeamCharacters;
|
||||||
|
|
||||||
|
// // 计算网格坐标
|
||||||
|
// int gridX = character.X / 1000;
|
||||||
|
// int gridY = character.Y / 1000;
|
||||||
|
|
||||||
|
// // 尝试查找现有角色
|
||||||
|
// var existingCharacter = collection.FirstOrDefault(c => c.CharacterId == character.PlayerId);
|
||||||
|
|
||||||
|
// if (existingCharacter != null)
|
||||||
|
// {
|
||||||
|
// // 更新现有角色
|
||||||
|
// existingCharacter.Name = GetCharacterTypeName(character.CharacterType);
|
||||||
|
// existingCharacter.Hp = character.Hp;
|
||||||
|
// existingCharacter.PosX = gridX;
|
||||||
|
// existingCharacter.PosY = gridY;
|
||||||
|
|
||||||
|
// // 更新主动状态
|
||||||
|
// existingCharacter.ActiveState = GetCharacterStateText(character.CharacterActiveState);
|
||||||
|
|
||||||
|
// // 更新被动状态
|
||||||
|
// existingCharacter.PassiveStates.Clear();
|
||||||
|
|
||||||
|
// // 根据需要添加被动状态
|
||||||
|
// if (character.BlindState != CharacterState.NullCharacterState)
|
||||||
|
// existingCharacter.PassiveStates.Add("致盲");
|
||||||
|
// if (character.StunnedState != CharacterState.NullCharacterState)
|
||||||
|
// existingCharacter.PassiveStates.Add("定身");
|
||||||
|
// if (character.InvisibleState != CharacterState.NullCharacterState)
|
||||||
|
// existingCharacter.PassiveStates.Add("隐身");
|
||||||
|
// if (character.BurnedState != CharacterState.NullCharacterState)
|
||||||
|
// existingCharacter.PassiveStates.Add("灼烧");
|
||||||
|
|
||||||
|
// // 更新装备
|
||||||
|
// existingCharacter.EquipmentInventory.Clear();
|
||||||
|
// if (character.ShieldEquipment > 0)
|
||||||
|
// existingCharacter.EquipmentInventory.Add(new EquipmentItem("护盾", character.ShieldEquipment));
|
||||||
|
// if (character.ShoesEquipment > 0)
|
||||||
|
// existingCharacter.EquipmentInventory.Add(new EquipmentItem("鞋子", 1));
|
||||||
|
// if (character.PurificationEquipmentTime > 0)
|
||||||
|
// existingCharacter.EquipmentInventory.Add(new EquipmentItem("净化药水", 1));
|
||||||
|
|
||||||
|
// // 通知UI更新显示的状态和装备文本
|
||||||
|
// existingCharacter.OnPropertyChanged(nameof(CharacterViewModel.DisplayStates));
|
||||||
|
// existingCharacter.OnPropertyChanged(nameof(CharacterViewModel.DisplayEquipments));
|
||||||
|
// }
|
||||||
|
// else
|
||||||
|
// {
|
||||||
|
// // 创建新角色
|
||||||
|
// var newCharacter = new CharacterViewModel
|
||||||
|
// {
|
||||||
|
// CharacterId = character.PlayerId,
|
||||||
|
// Name = GetCharacterTypeName(character.CharacterType),
|
||||||
|
// Hp = character.Hp,
|
||||||
|
// PosX = gridX,
|
||||||
|
// PosY = gridY,
|
||||||
|
// ActiveState = GetCharacterStateText(character.CharacterActiveState)
|
||||||
|
// };
|
||||||
|
|
||||||
|
// // 添加被动状态
|
||||||
|
// if (character.BlindState != CharacterState.NullCharacterState)
|
||||||
|
// newCharacter.PassiveStates.Add("致盲");
|
||||||
|
// if (character.StunnedState != CharacterState.NullCharacterState)
|
||||||
|
// newCharacter.PassiveStates.Add("定身");
|
||||||
|
// if (character.InvisibleState != CharacterState.NullCharacterState)
|
||||||
|
// newCharacter.PassiveStates.Add("隐身");
|
||||||
|
// if (character.BurnedState != CharacterState.NullCharacterState)
|
||||||
|
// newCharacter.PassiveStates.Add("灼烧");
|
||||||
|
|
||||||
|
// // 添加装备
|
||||||
|
// if (character.ShieldEquipment > 0)
|
||||||
|
// newCharacter.EquipmentInventory.Add(new EquipmentItem("护盾", character.ShieldEquipment));
|
||||||
|
// if (character.ShoesEquipment > 0)
|
||||||
|
// newCharacter.EquipmentInventory.Add(new EquipmentItem("鞋子", 1));
|
||||||
|
// if (character.PurificationEquipmentTime > 0)
|
||||||
|
// newCharacter.EquipmentInventory.Add(new EquipmentItem("净化药水", 1));
|
||||||
|
|
||||||
|
// // 添加到集合
|
||||||
|
// collection.Add(newCharacter);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 更新地图上的角色位置
|
||||||
|
// _viewModel.MapVM.UpdateCharacterPosition(
|
||||||
|
// character.PlayerId,
|
||||||
|
// character.TeamId,
|
||||||
|
// gridX,
|
||||||
|
// gridY,
|
||||||
|
// GetCharacterTypeName(character.CharacterType)
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// _logger.LogError($"更新角色失败: {ex.Message}");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private string GetCharacterTypeName(CharacterType type)
|
||||||
|
// {
|
||||||
|
// return type switch
|
||||||
|
// {
|
||||||
|
// CharacterType.TangSeng => "唐僧",
|
||||||
|
// CharacterType.SunWukong => "孙悟空",
|
||||||
|
// CharacterType.ZhuBajie => "猪八戒",
|
||||||
|
// CharacterType.ShaWujing => "沙悟净",
|
||||||
|
// CharacterType.BaiLongma => "白龙马",
|
||||||
|
// CharacterType.Monkid => "小和尚",
|
||||||
|
// CharacterType.JiuLing => "九灵元圣",
|
||||||
|
// CharacterType.HongHaier => "红孩儿",
|
||||||
|
// CharacterType.NiuMowang => "牛魔王",
|
||||||
|
// CharacterType.TieShan => "铁扇公主",
|
||||||
|
// CharacterType.ZhiZhujing => "蜘蛛精",
|
||||||
|
// CharacterType.Pawn => "小妖",
|
||||||
|
// _ => "未知角色"
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private string GetCharacterStateText(CharacterState state)
|
||||||
|
// {
|
||||||
|
// return state switch
|
||||||
|
// {
|
||||||
|
// CharacterState.Idle => "空置",
|
||||||
|
// CharacterState.Harvesting => "开采",
|
||||||
|
// CharacterState.Attacking => "攻击",
|
||||||
|
// CharacterState.SkillCasting => "释放技能",
|
||||||
|
// CharacterState.Constructing => "建造",
|
||||||
|
// CharacterState.Moving => "移动",
|
||||||
|
// _ => "未知状态"
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private void UpdateBuilding(MessageOfBarracks building, string buildingType)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// // 转换为网格坐标
|
||||||
|
// int gridX = building.X / 1000;
|
||||||
|
// int gridY = building.Y / 1000;
|
||||||
|
|
||||||
|
// // 确保坐标在有效范围内
|
||||||
|
// if (gridX >= 0 && gridX < 50 && gridY >= 0 && gridY < 50)
|
||||||
|
// {
|
||||||
|
// // 在地图上更新建筑
|
||||||
|
// _viewModel.MapVM.UpdateBuildingCell(
|
||||||
|
// gridX,
|
||||||
|
// gridY,
|
||||||
|
// building.TeamId == 1 ? "取经队" : "妖怪队",
|
||||||
|
// buildingType,
|
||||||
|
// building.Hp
|
||||||
|
// );
|
||||||
|
|
||||||
|
// // 更新建筑信息文本 (假设ViewModel有这些属性)
|
||||||
|
// string buildingInfo = $"{buildingType} 位置:({gridX},{gridY}) 血量:{building.Hp}";
|
||||||
|
// if (building.TeamId == 1) // 取经队
|
||||||
|
// {
|
||||||
|
// // 尝试更新建筑信息,如果属性存在的话
|
||||||
|
// if (typeof(MainWindowViewModel).GetProperty("SomeBuildingInfo") != null)
|
||||||
|
// {
|
||||||
|
// _viewModel.SomeBuildingInfo = buildingInfo;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// else // 妖怪队
|
||||||
|
// {
|
||||||
|
// if (typeof(MainWindowViewModel).GetProperty("AnotherBuildingInfo") != null)
|
||||||
|
// {
|
||||||
|
// _viewModel.AnotherBuildingInfo = buildingInfo;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// _logger.LogError($"更新建筑(兵营)失败: {ex.Message}");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private void UpdateBuilding(MessageOfSpring building, string buildingType)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// // 类似于UpdateBuilding(MessageOfBarracks...)的实现
|
||||||
|
// int gridX = building.X / 1000;
|
||||||
|
// int gridY = building.Y / 1000;
|
||||||
|
|
||||||
|
// if (gridX >= 0 && gridX < 50 && gridY >= 0 && gridY < 50)
|
||||||
|
// {
|
||||||
|
// _viewModel.MapVM.UpdateBuildingCell(
|
||||||
|
// gridX,
|
||||||
|
// gridY,
|
||||||
|
// building.TeamId == 1 ? "取经队" : "妖怪队",
|
||||||
|
// buildingType,
|
||||||
|
// building.Hp
|
||||||
|
// );
|
||||||
|
|
||||||
|
// string buildingInfo = $"{buildingType} 位置:({gridX},{gridY}) 血量:{building.Hp}";
|
||||||
|
// if (building.TeamId == 1 &&
|
||||||
|
// typeof(MainWindowViewModel).GetProperty("SomeBuildingInfo") != null)
|
||||||
|
// {
|
||||||
|
// _viewModel.SomeBuildingInfo += "\n" + buildingInfo;
|
||||||
|
// }
|
||||||
|
// else if (building.TeamId != 1 &&
|
||||||
|
// typeof(MainWindowViewModel).GetProperty("AnotherBuildingInfo") != null)
|
||||||
|
// {
|
||||||
|
// _viewModel.AnotherBuildingInfo += "\n" + buildingInfo;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// _logger.LogError($"更新建筑(泉水)失败: {ex.Message}");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private void UpdateBuilding(MessageOfFarm building, string buildingType)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// // 类似于其他建筑更新方法
|
||||||
|
// int gridX = building.X / 1000;
|
||||||
|
// int gridY = building.Y / 1000;
|
||||||
|
|
||||||
|
// if (gridX >= 0 && gridX < 50 && gridY >= 0 && gridY < 50)
|
||||||
|
// {
|
||||||
|
// _viewModel.MapVM.UpdateBuildingCell(
|
||||||
|
// gridX,
|
||||||
|
// gridY,
|
||||||
|
// building.TeamId == 1 ? "取经队" : "妖怪队",
|
||||||
|
// buildingType,
|
||||||
|
// building.Hp
|
||||||
|
// );
|
||||||
|
|
||||||
|
// string buildingInfo = $"{buildingType} 位置:({gridX},{gridY}) 血量:{building.Hp}";
|
||||||
|
// if (building.TeamId == 1 &&
|
||||||
|
// typeof(MainWindowViewModel).GetProperty("SomeBuildingInfo") != null)
|
||||||
|
// {
|
||||||
|
// _viewModel.SomeBuildingInfo += "\n" + buildingInfo;
|
||||||
|
// }
|
||||||
|
// else if (building.TeamId != 1 &&
|
||||||
|
// typeof(MainWindowViewModel).GetProperty("AnotherBuildingInfo") != null)
|
||||||
|
// {
|
||||||
|
// _viewModel.AnotherBuildingInfo += "\n" + buildingInfo;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// _logger.LogError($"更新建筑(农场)失败: {ex.Message}");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private void UpdateTrap(MessageOfTrap trap)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// int gridX = trap.X / 1000;
|
||||||
|
// int gridY = trap.Y / 1000;
|
||||||
|
|
||||||
|
// if (gridX >= 0 && gridX < 50 && gridY >= 0 && gridY < 50)
|
||||||
|
// {
|
||||||
|
// string trapTypeName = trap.TrapType switch
|
||||||
|
// {
|
||||||
|
// TrapType.Hole => "陷阱坑",
|
||||||
|
// TrapType.Cage => "牢笼",
|
||||||
|
// _ => "未知陷阱"
|
||||||
|
// };
|
||||||
|
|
||||||
|
// _viewModel.MapVM.UpdateTrapCell(
|
||||||
|
// gridX,
|
||||||
|
// gridY,
|
||||||
|
// trap.TeamId == 1 ? "取经队" : "妖怪队",
|
||||||
|
// trapTypeName
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// _logger.LogError($"更新陷阱失败: {ex.Message}");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private void UpdateResource(MessageOfEconomyResource resource)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// int gridX = resource.X / 1000;
|
||||||
|
// int gridY = resource.Y / 1000;
|
||||||
|
|
||||||
|
// if (gridX >= 0 && gridX < 50 && gridY >= 0 && gridY < 50)
|
||||||
|
// {
|
||||||
|
// string resourceTypeName = resource.EconomyResourceType switch
|
||||||
|
// {
|
||||||
|
// EconomyResourceType.SmallEconomyResource => "小经济资源",
|
||||||
|
// EconomyResourceType.MediumEconomyResource => "中经济资源",
|
||||||
|
// EconomyResourceType.LargeEconomyResource => "大经济资源",
|
||||||
|
// _ => "未知资源"
|
||||||
|
// };
|
||||||
|
|
||||||
|
// _viewModel.MapVM.UpdateResourceCell(
|
||||||
|
// gridX,
|
||||||
|
// gridY,
|
||||||
|
// resourceTypeName,
|
||||||
|
// resource.Process
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// _logger.LogError($"更新经济资源失败: {ex.Message}");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private void UpdateAdditionResource(MessageOfAdditionResource resource)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// int gridX = resource.X / 1000;
|
||||||
|
// int gridY = resource.Y / 1000;
|
||||||
|
|
||||||
|
// if (gridX >= 0 && gridX < 50 && gridY >= 0 && gridY < 50)
|
||||||
|
// {
|
||||||
|
// string resourceName = GetAdditionResourceName(resource.AdditionResourceType);
|
||||||
|
|
||||||
|
// _viewModel.MapVM.UpdateAdditionResourceCell(
|
||||||
|
// gridX,
|
||||||
|
// gridY,
|
||||||
|
// resourceName,
|
||||||
|
// resource.Hp
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// _logger.LogError($"更新附加资源失败: {ex.Message}");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private string GetAdditionResourceName(AdditionResourceType type)
|
||||||
|
// {
|
||||||
|
// return type switch
|
||||||
|
// {
|
||||||
|
// AdditionResourceType.LifePool1 => "生命池(小)",
|
||||||
|
// AdditionResourceType.LifePool2 => "生命池(中)",
|
||||||
|
// AdditionResourceType.LifePool3 => "生命池(大)",
|
||||||
|
// AdditionResourceType.CrazyMan1 => "疯人(小)",
|
||||||
|
// AdditionResourceType.CrazyMan2 => "疯人(中)",
|
||||||
|
// AdditionResourceType.CrazyMan3 => "疯人(大)",
|
||||||
|
// AdditionResourceType.QuickStep => "神行步",
|
||||||
|
// AdditionResourceType.WideView => "千里眼",
|
||||||
|
// _ => "未知加成资源"
|
||||||
|
// };
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private void UpdateMap(MessageOfMap map)
|
||||||
|
// {
|
||||||
|
// try
|
||||||
|
// {
|
||||||
|
// // 将地图数据转换为二维数组
|
||||||
|
// int[,] mapData = new int[50, 50];
|
||||||
|
|
||||||
|
// for (int i = 0; i < map.Rows.Count && i < 50; i++)
|
||||||
|
// {
|
||||||
|
// for (int j = 0; j < map.Rows[i].Cols.Count && j < 50; j++)
|
||||||
|
// {
|
||||||
|
// mapData[i, j] = (int)map.Rows[i].Cols[j];
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// // 更新地图视图模型
|
||||||
|
// _viewModel.MapVM.UpdateMap(mapData);
|
||||||
|
|
||||||
|
// _logger.LogInfo("地图数据已更新");
|
||||||
|
// }
|
||||||
|
// catch (Exception ex)
|
||||||
|
// {
|
||||||
|
// _logger.LogError($"更新地图数据时出错: {ex.Message}");
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private string FormatGameTime(int milliseconds)
|
||||||
|
// {
|
||||||
|
// TimeSpan time = TimeSpan.FromMilliseconds(milliseconds);
|
||||||
|
// return $"{time.Minutes:00}:{time.Seconds:00}";
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
|
@ -1,102 +1,55 @@
|
||||||
//CharacterViewModel.cs
|
using System.Collections.ObjectModel;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace debug_interface.ViewModels
|
namespace debug_interface.ViewModels
|
||||||
{
|
{
|
||||||
public partial class CharacterViewModel : ViewModelBase
|
public partial class CharacterViewModel : ViewModelBase
|
||||||
{
|
{
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string name = "角色"; // 默认角色名,可由服务器更新
|
private long characterId;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private int hp = 1000; // 血量,可由服务器动态更新
|
private string name = "";
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private int posX = 0;
|
private int hp;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private int posY = 0;
|
private int posX;
|
||||||
|
|
||||||
// 主动状态(单一)
|
|
||||||
// 可能值: "空置","开采","攻击","释放技能","建造","移动"
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string activeState = "空置";
|
private int posY;
|
||||||
|
|
||||||
// 被动状态(可叠加)
|
[ObservableProperty]
|
||||||
// 可能值: "致盲","击退","定身","隐身" 等,可由服务器控制增减
|
private string activeState = "";
|
||||||
public ObservableCollection<string> PassiveStates { get; } = new ObservableCollection<string>();
|
|
||||||
|
|
||||||
// 装备清单:用名称+数量表示。如 {"小血瓶":2, "鞋子":1, "大护盾":1, "净化药水":3}
|
public ObservableCollection<string> PassiveStates { get; } = new();
|
||||||
// 为了方便绑定,用 ObservableCollection 来存储装备条目,每个条目包含Name和Count
|
|
||||||
public ObservableCollection<EquipmentItem> EquipmentInventory { get; } = new ObservableCollection<EquipmentItem>();
|
|
||||||
|
|
||||||
// 状态选项列表和装备选项列表已不再使用ComboBox选择,而是纯展示。
|
public ObservableCollection<EquipmentItem> EquipmentInventory { get; } = new();
|
||||||
// 如果需要仍保留可由服务器更新,但这里不会再用于交互。
|
|
||||||
|
|
||||||
// 构造函数
|
// 格式化状态文本的属性
|
||||||
public CharacterViewModel()
|
public string DisplayStates =>
|
||||||
{
|
$"{ActiveState} {(PassiveStates.Count > 0 ? $"[{string.Join(", ", PassiveStates)}]" : "")}";
|
||||||
PassiveStates = new ObservableCollection<string>();
|
|
||||||
EquipmentInventory = new ObservableCollection<EquipmentItem>();
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用于UI展示状态字符串
|
// 格式化装备文本的属性
|
||||||
// 格式: (主动:xx 被动:xx yy zz)
|
public string DisplayEquipments =>
|
||||||
public string DisplayStates
|
EquipmentInventory.Count > 0 ? string.Join(", ", EquipmentInventory) : "无";
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
var sb = new StringBuilder();
|
|
||||||
sb.Append("(主动:").Append(ActiveState).Append(" 被动:");
|
|
||||||
if (PassiveStates.Count > 0)
|
|
||||||
sb.Append(string.Join(" ", PassiveStates));
|
|
||||||
else
|
|
||||||
sb.Append("无");
|
|
||||||
sb.Append(")");
|
|
||||||
return sb.ToString();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用于UI展示装备字符串
|
|
||||||
// 格式: 装备: 小血瓶x2 鞋子x1 大护盾x1 净化药水x3
|
|
||||||
public string DisplayEquipments
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
if (EquipmentInventory.Count == 0)
|
|
||||||
{
|
|
||||||
return "装备:无";
|
|
||||||
}
|
|
||||||
return "装备: " + string.Join(", ",
|
|
||||||
EquipmentInventory.Select(e => $"{e.Name}×{e.Count}"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 当ActiveState或PassiveStates变化后,通知UI更新 DisplayStates
|
|
||||||
partial void OnActiveStateChanged(string oldValue, string newValue)
|
|
||||||
{
|
|
||||||
OnPropertyChanged(nameof(DisplayStates));
|
|
||||||
}
|
|
||||||
|
|
||||||
// 如果被动状态列表更新,需要调用OnPropertyChanged(nameof(DisplayStates))
|
|
||||||
// 可以在服务器更新逻辑中调用。
|
|
||||||
|
|
||||||
// 同理,当EquipmentInventory变化时,需要更新DisplayEquipments
|
|
||||||
// 可以在添加/移除装备后调用OnPropertyChanged(nameof(DisplayEquipments))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 定义装备类
|
|
||||||
public class EquipmentItem
|
public class EquipmentItem
|
||||||
{
|
{
|
||||||
public string Name { get; set; }
|
public string Name { get; }
|
||||||
public int Count { get; set; }
|
public int Count { get; }
|
||||||
|
|
||||||
public EquipmentItem(string name, int count)
|
public EquipmentItem(string name, int count)
|
||||||
{
|
{
|
||||||
Name = name;
|
Name = name;
|
||||||
Count = count;
|
Count = count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override string ToString()
|
||||||
|
{
|
||||||
|
return Count > 1 ? $"{Name}x{Count}" : Name;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,29 +1,19 @@
|
||||||
// ViewModels/MainWindowViewModel.cs
|
using System;
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using System.Timers;
|
using installer.Model;
|
||||||
using debug_interface.ViewModels;
|
using installer.Data;
|
||||||
|
|
||||||
namespace debug_interface.ViewModels
|
namespace debug_interface.ViewModels
|
||||||
{
|
{
|
||||||
public partial class MainWindowViewModel : ViewModelBase
|
public partial class MainWindowViewModel : ViewModelBase
|
||||||
{
|
{
|
||||||
// Keep only one definition of MapVM
|
// 属性定义
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private MapViewModel mapVM;
|
private string gameLog = "等待连接...";
|
||||||
|
|
||||||
public ObservableCollection<CharacterViewModel> RedTeamCharacters { get; }
|
|
||||||
public ObservableCollection<CharacterViewModel> BlueTeamCharacters { get; }
|
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string someBuildingInfo = "红方建筑信息...";
|
private string currentTime = "00:00";
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string anotherBuildingInfo = "蓝方建筑信息...";
|
|
||||||
|
|
||||||
[ObservableProperty]
|
|
||||||
private string currentTime = DateTime.Now.ToString("HH:mm:ss");
|
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private int redScore = 0;
|
private int redScore = 0;
|
||||||
|
@ -32,85 +22,74 @@ namespace debug_interface.ViewModels
|
||||||
private int blueScore = 0;
|
private int blueScore = 0;
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private bool isBlueView = true;
|
private string someBuildingInfo = "";
|
||||||
|
|
||||||
public bool IsRedView
|
|
||||||
{
|
|
||||||
get => !IsBlueView;
|
|
||||||
set => IsBlueView = !value;
|
|
||||||
}
|
|
||||||
|
|
||||||
[ObservableProperty]
|
[ObservableProperty]
|
||||||
private string gameLog = "地图...";
|
private string anotherBuildingInfo = "";
|
||||||
|
|
||||||
private Timer _timer;
|
[ObservableProperty]
|
||||||
|
private int buddhistTeamEconomy = 0;
|
||||||
|
|
||||||
public MainWindowViewModel()
|
[ObservableProperty]
|
||||||
|
private int monstersTeamEconomy = 0;
|
||||||
|
|
||||||
|
[ObservableProperty]
|
||||||
|
private MapViewModel mapVM;
|
||||||
|
|
||||||
|
// 团队角色集合
|
||||||
|
public ObservableCollection<CharacterViewModel> RedTeamCharacters { get; } = new();
|
||||||
|
public ObservableCollection<CharacterViewModel> BlueTeamCharacters { get; } = new();
|
||||||
|
|
||||||
|
// 构造函数
|
||||||
|
public MainWindowViewModel(Logger logger, ConfigData config) : base(logger)
|
||||||
{
|
{
|
||||||
// Initialize collections first
|
// 初始化MapViewModel
|
||||||
RedTeamCharacters = new ObservableCollection<CharacterViewModel>();
|
|
||||||
BlueTeamCharacters = new ObservableCollection<CharacterViewModel>();
|
|
||||||
|
|
||||||
// Initialize characters
|
|
||||||
for (int i = 0; i < 6; i++)
|
|
||||||
{
|
|
||||||
var redChar = new CharacterViewModel()
|
|
||||||
{
|
|
||||||
Name = "红方角色" + (i + 1),
|
|
||||||
Hp = 1000 * (i + 1),
|
|
||||||
ActiveState = i % 2 == 0 ? "攻击" : "移动",
|
|
||||||
};
|
|
||||||
redChar.PassiveStates.Add("致盲");
|
|
||||||
if (i % 3 == 0) redChar.PassiveStates.Add("定身");
|
|
||||||
redChar.EquipmentInventory.Add(new EquipmentItem("小血瓶", 2));
|
|
||||||
if (i % 2 == 0)
|
|
||||||
redChar.EquipmentInventory.Add(new EquipmentItem("大护盾", 1));
|
|
||||||
|
|
||||||
RedTeamCharacters.Add(redChar);
|
|
||||||
|
|
||||||
var blueChar = new CharacterViewModel()
|
|
||||||
{
|
|
||||||
Name = "蓝方角色" + (i + 1),
|
|
||||||
Hp = 1500 + i * 500,
|
|
||||||
ActiveState = "空置",
|
|
||||||
};
|
|
||||||
blueChar.PassiveStates.Add("隐身");
|
|
||||||
blueChar.EquipmentInventory.Add(new EquipmentItem("净化药水", 3));
|
|
||||||
if (i % 2 == 1)
|
|
||||||
blueChar.EquipmentInventory.Add(new EquipmentItem("鞋子", 1));
|
|
||||||
|
|
||||||
BlueTeamCharacters.Add(blueChar);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Initialize MapViewModel
|
|
||||||
MapVM = new MapViewModel();
|
MapVM = new MapViewModel();
|
||||||
|
|
||||||
// Assign random initial positions to characters
|
// 如果在设计模式下,可以添加一些测试数据
|
||||||
Random rnd = new Random();
|
if (Avalonia.Controls.Design.IsDesignMode)
|
||||||
foreach (var character in RedTeamCharacters)
|
|
||||||
{
|
{
|
||||||
character.PosX = rnd.Next(10, 40);
|
InitializeDesignTimeData();
|
||||||
character.PosY = rnd.Next(10, 40);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var character in BlueTeamCharacters)
|
// 启动UI更新定时器
|
||||||
{
|
StartUiUpdateTimer();
|
||||||
character.PosX = rnd.Next(10, 40);
|
|
||||||
character.PosY = rnd.Next(10, 40);
|
|
||||||
}
|
|
||||||
|
|
||||||
_timer = new Timer(1000);
|
|
||||||
_timer.Elapsed += Timer_Elapsed;
|
|
||||||
_timer.Start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Timer_Elapsed(object? sender, ElapsedEventArgs e)
|
// 设计时数据
|
||||||
|
private void InitializeDesignTimeData()
|
||||||
{
|
{
|
||||||
CurrentTime = DateTime.Now.ToString("HH:mm:ss");
|
GameLog = "设计模式 - 模拟数据";
|
||||||
Avalonia.Threading.Dispatcher.UIThread.Post(() =>
|
CurrentTime = "12:34";
|
||||||
|
RedScore = 50;
|
||||||
|
BlueScore = 30;
|
||||||
|
|
||||||
|
// 添加一些测试角色
|
||||||
|
for (int i = 0; i < 3; i++)
|
||||||
{
|
{
|
||||||
OnPropertyChanged(nameof(CurrentTime));
|
RedTeamCharacters.Add(new CharacterViewModel
|
||||||
});
|
{
|
||||||
|
CharacterId = i + 1,
|
||||||
|
Name = $"取经队角色{i + 1}",
|
||||||
|
Hp = 1000,
|
||||||
|
ActiveState = "空置"
|
||||||
|
});
|
||||||
|
|
||||||
|
BlueTeamCharacters.Add(new CharacterViewModel
|
||||||
|
{
|
||||||
|
CharacterId = i + 101,
|
||||||
|
Name = $"妖怪队角色{i + 1}",
|
||||||
|
Hp = 1200,
|
||||||
|
ActiveState = "移动"
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 定时器更新方法
|
||||||
|
protected override void OnTimerTick(object? sender, EventArgs e)
|
||||||
|
{
|
||||||
|
// 更新当前时间显示
|
||||||
|
CurrentTime = DateTime.Now.ToString("HH:mm:ss");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,137 +1,201 @@
|
||||||
//MapViewModel.cs
|
using System.Collections.ObjectModel;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Text;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using CommunityToolkit.Mvvm.ComponentModel;
|
using CommunityToolkit.Mvvm.ComponentModel;
|
||||||
using System.Collections.ObjectModel;
|
|
||||||
using debug_interface.Models;
|
|
||||||
using Avalonia.Media;
|
using Avalonia.Media;
|
||||||
|
using debug_interface.Models;
|
||||||
|
|
||||||
namespace debug_interface.ViewModels
|
namespace debug_interface.ViewModels
|
||||||
{
|
{
|
||||||
// 地图视图模型,管理整个 50×50 的地图数据
|
public partial class MapViewModel : ViewModelBase
|
||||||
public partial class MapViewModel : ObservableObject
|
|
||||||
{
|
{
|
||||||
// 定义地图网格大小为 50(行)× 50(列)
|
private const int GridSize = 50;
|
||||||
public const int GridSize = 50;
|
|
||||||
|
|
||||||
// ObservableCollection 存放 2500 个 MapCell 对象,每个对象代表一个地图格子
|
[ObservableProperty]
|
||||||
// 数据绑定到视图后,界面会显示出整个地图
|
private ObservableCollection<MapCell> mapCells = new();
|
||||||
public ObservableCollection<MapCell> MapCells { get; }
|
|
||||||
public ObservableCollection<CharacterViewModel> RedTeamCharacters { get; }
|
|
||||||
public ObservableCollection<CharacterViewModel> BlueTeamCharacters { get; }
|
|
||||||
|
|
||||||
public MapViewModel(ObservableCollection<CharacterViewModel> redTeam, ObservableCollection<CharacterViewModel> blueTeam)
|
|
||||||
{
|
|
||||||
MapCells = new ObservableCollection<MapCell>();
|
|
||||||
RedTeamCharacters = redTeam;
|
|
||||||
BlueTeamCharacters = blueTeam;
|
|
||||||
InitializeDefaultMap();
|
|
||||||
}
|
|
||||||
// 构造函数,用于测试
|
|
||||||
public MapViewModel()
|
public MapViewModel()
|
||||||
{
|
{
|
||||||
MapCells = new ObservableCollection<MapCell>();
|
// 初始化地图单元格
|
||||||
InitializeDefaultMap();
|
InitializeMapCells();
|
||||||
}
|
}
|
||||||
|
|
||||||
// 初始化默认地图数据,用于测试效果
|
private void InitializeMapCells()
|
||||||
private void InitializeDefaultMap()
|
|
||||||
{
|
{
|
||||||
// 遍历所有行和列
|
MapCells.Clear();
|
||||||
for (int i = 0; i < GridSize; i++)
|
for (int i = 0; i < GridSize * GridSize; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < GridSize; j++)
|
MapCells.Add(new MapCell
|
||||||
{
|
{
|
||||||
// 创建一个 MapCell 对象,并设置行列信息
|
Row = i / GridSize,
|
||||||
var cell = new MapCell
|
Col = i % GridSize,
|
||||||
{
|
CellType = MapCellType.Empty,
|
||||||
CellX = i,
|
DisplayText = "",
|
||||||
CellY = j,
|
DisplayColor = new SolidColorBrush(Colors.White),
|
||||||
// 根据坐标决定默认单元格类型
|
BackgroundColor = new SolidColorBrush(Colors.LightGray)
|
||||||
CellType = GetDefaultCellType(i, j),
|
});
|
||||||
DisplayText = "" // 默认无文本显示,可后续根据需要设置
|
|
||||||
};
|
|
||||||
// 设置显示颜色,根据单元格类型获取颜色
|
|
||||||
cell.DisplayColor = new SolidColorBrush(GetColorForCellType(cell.CellType));
|
|
||||||
|
|
||||||
MapCells.Add(cell);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// 根据单元格在地图中的坐标决定默认类型
|
// 更新整个地图
|
||||||
private MapCellType GetDefaultCellType(int i, int j)
|
public void UpdateMap(int[,] mapData)
|
||||||
{
|
{
|
||||||
// 1. 边界(第一行、最后一行、第一列、最后一列)均设为障碍物
|
|
||||||
if (i == 0 || i == GridSize - 1 || j == 0 || j == GridSize - 1)
|
|
||||||
{
|
|
||||||
return MapCellType.Obstacle;
|
|
||||||
}
|
|
||||||
// 2. 在特定位置放置资源点(测试用)
|
|
||||||
if ((i == 10 && j == 10) || (i == 20 && j == 20) || (i == 30 && j == 30))
|
|
||||||
{
|
|
||||||
return MapCellType.Resource;
|
|
||||||
}
|
|
||||||
// 3. 在特定位置放置草丛(测试用)
|
|
||||||
if ((i == 15 && j == 35) || (i == 35 && j == 15))
|
|
||||||
{
|
|
||||||
return MapCellType.Grass;
|
|
||||||
}
|
|
||||||
// 4. 可预留一个建筑点,例如 (25,25)
|
|
||||||
if (i == 25 && j == 25)
|
|
||||||
{
|
|
||||||
return MapCellType.Building;
|
|
||||||
}
|
|
||||||
// 5. 其他区域默认为空地
|
|
||||||
return MapCellType.OpenLand;
|
|
||||||
}
|
|
||||||
|
|
||||||
// 根据单元格类型返回对应的颜色(可根据需要调整颜色)
|
|
||||||
private Color GetColorForCellType(MapCellType type)
|
|
||||||
{
|
|
||||||
switch (type)
|
|
||||||
{
|
|
||||||
case MapCellType.Obstacle:
|
|
||||||
return Colors.DarkGray;
|
|
||||||
case MapCellType.OpenLand:
|
|
||||||
return Colors.LightGreen;
|
|
||||||
case MapCellType.Grass:
|
|
||||||
return Colors.Green;
|
|
||||||
case MapCellType.Resource:
|
|
||||||
return Colors.Yellow;
|
|
||||||
case MapCellType.Building:
|
|
||||||
return Colors.Orange;
|
|
||||||
default:
|
|
||||||
return Colors.Black;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// 用于更新地图数据的方法,
|
|
||||||
// newMapData 是一个 50x50 的二维整型数组,数值应能映射为 MapCellType 枚举值
|
|
||||||
public void UpdateMap(int[,] newMapData)
|
|
||||||
{
|
|
||||||
if (newMapData.GetLength(0) != GridSize || newMapData.GetLength(1) != GridSize)
|
|
||||||
throw new ArgumentException("地图数据尺寸不正确");
|
|
||||||
|
|
||||||
// 遍历二维数组更新每个 MapCell 对象
|
|
||||||
for (int i = 0; i < GridSize; i++)
|
for (int i = 0; i < GridSize; i++)
|
||||||
{
|
{
|
||||||
for (int j = 0; j < GridSize; j++)
|
for (int j = 0; j < GridSize; j++)
|
||||||
{
|
{
|
||||||
int index = i * GridSize + j;
|
int index = i * GridSize + j;
|
||||||
// 将整型转换为 MapCellType 枚举
|
if (index < MapCells.Count)
|
||||||
MapCellType newType = (MapCellType)newMapData[i, j];
|
{
|
||||||
var cell = MapCells[index];
|
int cellType = mapData[i, j];
|
||||||
cell.CellType = newType;
|
UpdateCellType(MapCells[index], cellType);
|
||||||
// 更新颜色
|
}
|
||||||
cell.DisplayColor = new SolidColorBrush(GetColorForCellType(newType));
|
|
||||||
// 如果需要,可以根据新数据更新文本(例如建筑血量、资源剩余)
|
|
||||||
cell.DisplayText = "123"; // 这里留空,可扩展
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OnPropertyChanged(nameof(MapCells));
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateCellType(MapCell cell, int cellType)
|
||||||
|
{
|
||||||
|
// 根据cellType设置单元格属性
|
||||||
|
// 这里简化处理
|
||||||
|
switch (cellType)
|
||||||
|
{
|
||||||
|
case 0: // 空地
|
||||||
|
cell.CellType = MapCellType.Empty;
|
||||||
|
cell.BackgroundColor = new SolidColorBrush(Colors.White);
|
||||||
|
break;
|
||||||
|
case 1: // 障碍物
|
||||||
|
cell.CellType = MapCellType.Obstacle;
|
||||||
|
cell.BackgroundColor = new SolidColorBrush(Colors.DarkGray);
|
||||||
|
break;
|
||||||
|
case 2: // 资源
|
||||||
|
cell.CellType = MapCellType.Resource;
|
||||||
|
cell.BackgroundColor = new SolidColorBrush(Colors.Green);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
cell.CellType = MapCellType.Empty;
|
||||||
|
cell.BackgroundColor = new SolidColorBrush(Colors.LightGray);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新角色位置
|
||||||
|
public void UpdateCharacterPosition(long characterId, long teamId, int x, int y, string name)
|
||||||
|
{
|
||||||
|
// 简化实现
|
||||||
|
int index = x * GridSize + y;
|
||||||
|
if (index >= 0 && index < MapCells.Count)
|
||||||
|
{
|
||||||
|
MapCells[index].DisplayText = name.Substring(0, 1);
|
||||||
|
MapCells[index].DisplayColor = teamId == 1
|
||||||
|
? new SolidColorBrush(Colors.Red)
|
||||||
|
: new SolidColorBrush(Colors.Blue);
|
||||||
|
|
||||||
|
OnPropertyChanged(nameof(MapCells));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新建筑
|
||||||
|
public void UpdateBuildingCell(int x, int y, string team, string buildingType, int hp)
|
||||||
|
{
|
||||||
|
int index = x * GridSize + y;
|
||||||
|
if (index >= 0 && index < MapCells.Count)
|
||||||
|
{
|
||||||
|
MapCells[index].CellType = MapCellType.Building;
|
||||||
|
MapCells[index].DisplayText = buildingType.Substring(0, 1);
|
||||||
|
MapCells[index].DisplayColor = team == "取经队"
|
||||||
|
? new SolidColorBrush(Colors.DarkRed)
|
||||||
|
: new SolidColorBrush(Colors.DarkBlue);
|
||||||
|
|
||||||
|
OnPropertyChanged(nameof(MapCells));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新陷阱
|
||||||
|
public void UpdateTrapCell(int x, int y, string team, string trapType)
|
||||||
|
{
|
||||||
|
int index = x * GridSize + y;
|
||||||
|
if (index >= 0 && index < MapCells.Count)
|
||||||
|
{
|
||||||
|
MapCells[index].CellType = MapCellType.Obstacle;
|
||||||
|
MapCells[index].DisplayText = trapType.Substring(0, 1);
|
||||||
|
MapCells[index].DisplayColor = team == "取经队"
|
||||||
|
? new SolidColorBrush(Colors.IndianRed)
|
||||||
|
: new SolidColorBrush(Colors.CornflowerBlue);
|
||||||
|
|
||||||
|
OnPropertyChanged(nameof(MapCells));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新资源
|
||||||
|
public void UpdateResourceCell(int x, int y, string resourceType, int process)
|
||||||
|
{
|
||||||
|
int index = x * GridSize + y;
|
||||||
|
if (index >= 0 && index < MapCells.Count)
|
||||||
|
{
|
||||||
|
MapCells[index].CellType = MapCellType.Resource;
|
||||||
|
MapCells[index].DisplayText = process.ToString();
|
||||||
|
MapCells[index].DisplayColor = new SolidColorBrush(Colors.DarkGreen);
|
||||||
|
|
||||||
|
OnPropertyChanged(nameof(MapCells));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 更新额外资源
|
||||||
|
public void UpdateAdditionResourceCell(int x, int y, string resourceName, int value)
|
||||||
|
{
|
||||||
|
int index = x * GridSize + y;
|
||||||
|
if (index >= 0 && index < MapCells.Count)
|
||||||
|
{
|
||||||
|
MapCells[index].CellType = MapCellType.Resource;
|
||||||
|
MapCells[index].DisplayText = value.ToString();
|
||||||
|
|
||||||
|
// 根据资源类型选择颜色
|
||||||
|
if (resourceName.Contains("生命池"))
|
||||||
|
{
|
||||||
|
MapCells[index].DisplayColor = new SolidColorBrush(Colors.LightGreen);
|
||||||
|
}
|
||||||
|
else if (resourceName.Contains("疯人"))
|
||||||
|
{
|
||||||
|
MapCells[index].DisplayColor = new SolidColorBrush(Colors.OrangeRed);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
MapCells[index].DisplayColor = new SolidColorBrush(Colors.Purple);
|
||||||
|
}
|
||||||
|
|
||||||
|
OnPropertyChanged(nameof(MapCells));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
//public enum MapCellType
|
||||||
|
//{
|
||||||
|
// Empty,
|
||||||
|
// Obstacle,
|
||||||
|
// Building,
|
||||||
|
// Resource,
|
||||||
|
// Character
|
||||||
|
//}
|
||||||
|
|
||||||
|
//public partial class MapCell : ViewModelBase
|
||||||
|
//{
|
||||||
|
// [ObservableProperty]
|
||||||
|
// private int row;
|
||||||
|
|
||||||
|
// [ObservableProperty]
|
||||||
|
// private int col;
|
||||||
|
|
||||||
|
// [ObservableProperty]
|
||||||
|
// private MapCellType cellType;
|
||||||
|
|
||||||
|
// [ObservableProperty]
|
||||||
|
// private string displayText = "";
|
||||||
|
|
||||||
|
// [ObservableProperty]
|
||||||
|
// private IBrush displayColor = new SolidColorBrush(Colors.Black);
|
||||||
|
|
||||||
|
// [ObservableProperty]
|
||||||
|
// private IBrush backgroundColor = new SolidColorBrush(Colors.White);
|
||||||
|
//}
|
||||||
|
}
|
|
@ -1,4 +1,3 @@
|
||||||
//ViewModeBase.cs
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
using Avalonia.Threading;
|
using Avalonia.Threading;
|
||||||
|
|
|
@ -1,24 +1,22 @@
|
||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>net8.0-windows</TargetFramework>
|
<TargetFramework>net8.0-windows</TargetFramework>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
<BuiltInComInteropSupport>true</BuiltInComInteropSupport>
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
<ApplicationManifest>app.manifest</ApplicationManifest>
|
||||||
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
<AvaloniaUseCompiledBindingsByDefault>true</AvaloniaUseCompiledBindingsByDefault>
|
||||||
<AssemblyName>debug_interface</AssemblyName>
|
<AssemblyName>debug_interface</AssemblyName>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<AvaloniaResource Include="Assets\**" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<AvaloniaResource Include="Assets\**" />
|
<ProjectReference Include="..\..\..\logic\proto\proto.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<!-- 相对路径 -->
|
|
||||||
<Protobuf Include="..\..\..\dependency\proto\*.proto" GrpcServices="Client">
|
|
||||||
<Link>Protos\%(RecursiveDir)%(Filename)%(Extension)</Link>
|
|
||||||
</Protobuf>
|
|
||||||
</ItemGroup>
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<!-- 使用正斜杠 / 确保跨平台兼容 -->
|
<!-- 使用正斜杠 / 确保跨平台兼容 -->
|
||||||
<Compile Include="..\..\..\installer\Data\ConfigFileData.cs" Link="Interact/ConfigFileData.cs">
|
<Compile Include="..\..\..\installer\Data\ConfigFileData.cs" Link="Interact/ConfigFileData.cs">
|
||||||
|
@ -30,26 +28,26 @@
|
||||||
<Error Condition="!Exists('../../installer/Model/Logger.cs')" />
|
<Error Condition="!Exists('../../installer/Model/Logger.cs')" />
|
||||||
</Compile>
|
</Compile>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
<ItemGroup>
|
<PackageReference Include="Avalonia" Version="11.2.5" />
|
||||||
<PackageReference Include="Avalonia" Version="11.2.5" />
|
<PackageReference Include="Avalonia.Desktop" Version="11.2.5" />
|
||||||
<PackageReference Include="Avalonia.Desktop" Version="11.2.5" />
|
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.5" />
|
||||||
<PackageReference Include="Avalonia.Themes.Fluent" Version="11.2.5" />
|
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.2.5" />
|
||||||
<PackageReference Include="Avalonia.Fonts.Inter" Version="11.2.5" />
|
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
||||||
<!--Condition below is needed to remove Avalonia.Diagnostics package from build output in Release configuration.-->
|
<PackageReference Include="Avalonia.Diagnostics" Version="11.2.5">
|
||||||
<PackageReference Include="Avalonia.Diagnostics" Version="11.2.5">
|
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
|
||||||
<IncludeAssets Condition="'$(Configuration)' != 'Debug'">None</IncludeAssets>
|
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
|
||||||
<PrivateAssets Condition="'$(Configuration)' != 'Debug'">All</PrivateAssets>
|
</PackageReference>
|
||||||
</PackageReference>
|
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
<PackageReference Include="Google.Protobuf" Version="3.30.2" />
|
||||||
<PackageReference Include="Google.Protobuf" Version="3.30.2" />
|
<PackageReference Include="Grpc.Net.Client" Version="2.70.0" />
|
||||||
<PackageReference Include="Grpc.Net.Client" Version="2.70.0" />
|
<PackageReference Include="Grpc.Tools" Version="2.71.0">
|
||||||
<PackageReference Include="Grpc.Tools" Version="2.71.0">
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<PrivateAssets>all</PrivateAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
</PackageReference>
|
||||||
</PackageReference>
|
</ItemGroup>
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Folder Include="Utili\" />
|
<Folder Include="Utili\" />
|
||||||
|
|
|
@ -253,6 +253,7 @@ public class Character : Movable, ICharacter
|
||||||
Shield = new(0);
|
Shield = new(0);
|
||||||
NiuShield = new(0);
|
NiuShield = new(0);
|
||||||
AttackSize = new(Occupation.BaseAttackSize);
|
AttackSize = new(Occupation.BaseAttackSize);
|
||||||
|
HP = new(Occupation.MaxHp);
|
||||||
AttackPower = new(Occupation.AttackPower);
|
AttackPower = new(Occupation.AttackPower);
|
||||||
MoneyPool = pool;
|
MoneyPool = pool;
|
||||||
Init();
|
Init();
|
||||||
|
@ -340,10 +341,6 @@ public class Character : Movable, ICharacter
|
||||||
}
|
}
|
||||||
case EquipmentType.BERSERK_POTION:
|
case EquipmentType.BERSERK_POTION:
|
||||||
{
|
{
|
||||||
if (IsBerserk)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
IsBerserk = true;
|
IsBerserk = true;
|
||||||
BerserkTime = Environment.TickCount64;
|
BerserkTime = Environment.TickCount64;
|
||||||
SetCharacterState(CharacterState1, CharacterState.BERSERK);//此处缺少时间限制
|
SetCharacterState(CharacterState1, CharacterState.BERSERK);//此处缺少时间限制
|
||||||
|
|
|
@ -299,6 +299,7 @@ namespace Gaming
|
||||||
character.Shoes.SubPositiveV(GameData.CrazySpeed);
|
character.Shoes.SubPositiveV(GameData.CrazySpeed);
|
||||||
character.ATKFrequency = GameData.ATKFreq;
|
character.ATKFrequency = GameData.ATKFreq;
|
||||||
character.BerserkTime = long.MaxValue;
|
character.BerserkTime = long.MaxValue;
|
||||||
|
character.IsBerserk = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -314,7 +315,15 @@ namespace Gaming
|
||||||
character.IsShoes = false;
|
character.IsShoes = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
public void CheckInvisibility(Character character)
|
||||||
|
{
|
||||||
|
int nowtime = gameMap.Timer.NowTime();
|
||||||
|
if (nowtime >= GameData.SevenMinutes
|
||||||
|
)
|
||||||
|
{
|
||||||
|
character.visible = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,7 +35,7 @@ namespace Gaming
|
||||||
return GameObj.invalidID;
|
return GameObj.invalidID;
|
||||||
}
|
}
|
||||||
teamList[(int)playerInitInfo.teamID].CharacterNum.Add(1);
|
teamList[(int)playerInitInfo.teamID].CharacterNum.Add(1);
|
||||||
if (gameMap.TeamExists(playerInitInfo.teamID))
|
if (!gameMap.TeamExists(playerInitInfo.teamID))
|
||||||
{
|
{
|
||||||
return GameObj.invalidID;
|
return GameObj.invalidID;
|
||||||
}
|
}
|
||||||
|
@ -423,6 +423,18 @@ namespace Gaming
|
||||||
{
|
{
|
||||||
if (!gameMap.Timer.IsGaming)
|
if (!gameMap.Timer.IsGaming)
|
||||||
return false;
|
return false;
|
||||||
|
int nowtime = gameMap.Timer.NowTime();
|
||||||
|
if (nowtime >= GameData.SevenMinutes)
|
||||||
|
{
|
||||||
|
if (equiptype == EquipmentType.INVISIBILITY_POTION)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (equiptype == EquipmentType.BERSERK_POTION)
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
Character? character = gameMap.FindCharacterInPlayerID(teamID, characterID);
|
Character? character = gameMap.FindCharacterInPlayerID(teamID, characterID);
|
||||||
if (character != null && character.IsRemoved == false)
|
if (character != null && character.IsRemoved == false)
|
||||||
return equipManager.GetEquipment(character, equiptype);
|
return equipManager.GetEquipment(character, equiptype);
|
||||||
|
|
|
@ -214,5 +214,6 @@ namespace Preparation.Utility
|
||||||
public const int InitialMoney = 5000;
|
public const int InitialMoney = 5000;
|
||||||
public const int CharacterTotalNumMax = 6;
|
public const int CharacterTotalNumMax = 6;
|
||||||
public const double RecycleRate = 0.5;
|
public const double RecycleRate = 0.5;
|
||||||
|
public const int SevenMinutes = 420000;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue