THUAI8/logic/Gaming/Game.cs

450 lines
19 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using GameClass.GameObj;
using GameClass.GameObj.Map;
using GameClass.GameObj.Areas;
using GameClass.MapGenerator;
using GameClass.GameObj.Occupations;
using Preparation.Utility;
using Preparation.Utility.Value;
using Preparation.Interface;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading;
using System.Reflection.Metadata;
namespace Gaming
{
public partial class Game
{
public struct PlayerInitInfo(long teamID, long playerID, CharacterType characterType, int sideFlag)//sideFlag表示队伍是取经阵营还是妖怪阵营
{
public long teamID = teamID;
public long playerID = playerID;
public CharacterType characterType = characterType;
public int sideFlag = sideFlag;//0是取经队1是妖怪队
}
private readonly List<Base> teamList;
public List<Base> TeamList => teamList;
private readonly Map gameMap;
public Map GameMap => gameMap;
private readonly Random random = new();
public long AddCharacter(PlayerInitInfo playerInitInfo)
{
if (teamList[(int)playerInitInfo.teamID].CharacterNum >= GameData.CharacterTotalNumMax)
{
return GameObj.invalidID;
}
teamList[(int)playerInitInfo.teamID].CharacterNum.Add(1);
if (gameMap.TeamExists(playerInitInfo.teamID))
{
return GameObj.invalidID;
}
if (playerInitInfo.playerID != 0)
{
var characterType = playerInitInfo.characterType;
if (playerInitInfo.sideFlag == 0)
{
switch (characterType)
{
case CharacterType.Null:
return GameObj.invalidID;
case CharacterType.TangSeng:
if (teamList[(int)playerInitInfo.teamID].CharacterPool.GetNum(CharacterType.TangSeng)
>= GameData.MaxCharacterNum)
{
return GameObj.invalidID;
}
break;
case CharacterType.SunWukong:
if (teamList[(int)playerInitInfo.teamID].CharacterPool.GetNum(CharacterType.SunWukong)
>= GameData.MaxCharacterNum)
{
return GameObj.invalidID;
}
break;
case CharacterType.ZhuBajie:
if (teamList[(int)playerInitInfo.teamID].CharacterPool.GetNum(CharacterType.ZhuBajie)
>= GameData.MaxCharacterNum)
{
return GameObj.invalidID;
}
break;
case CharacterType.ShaWujing:
if (teamList[(int)playerInitInfo.teamID].CharacterPool.GetNum(CharacterType.ShaWujing)
>= GameData.MaxCharacterNum)
{
return GameObj.invalidID;
}
break;
case CharacterType.BaiLongma:
if (teamList[(int)playerInitInfo.teamID].CharacterPool.GetNum(CharacterType.BaiLongma)
>= GameData.MaxCharacterNum)
{
return GameObj.invalidID;
}
break;
case CharacterType.Monkid:
break;
default:
return GameObj.invalidID;
}
}
else
{
switch (characterType)
{
case CharacterType.Null:
return GameObj.invalidID;
case CharacterType.JiuLing:
if (teamList[(int)playerInitInfo.teamID].CharacterPool.GetNum(CharacterType.JiuLing)
>= GameData.MaxCharacterNum)
{
return GameObj.invalidID;
}
break;
case CharacterType.HongHaier:
if (teamList[(int)playerInitInfo.teamID].CharacterPool.GetNum(CharacterType.HongHaier)
>= GameData.MaxCharacterNum)
{
return GameObj.invalidID;
}
break;
case CharacterType.NiuMowang:
if (teamList[(int)playerInitInfo.teamID].CharacterPool.GetNum(CharacterType.NiuMowang)
>= GameData.MaxCharacterNum)
{
return GameObj.invalidID;
}
break;
case CharacterType.TieShan:
if (teamList[(int)playerInitInfo.teamID].CharacterPool.GetNum(CharacterType.TieShan)
>= GameData.MaxCharacterNum)
{
return GameObj.invalidID;
}
break;
case CharacterType.ZhiZhujing:
if (teamList[(int)playerInitInfo.teamID].CharacterPool.GetNum(CharacterType.ZhiZhujing)
>= GameData.MaxCharacterNum)
{
return GameObj.invalidID;
}
break;
case CharacterType.Pawn:
break;
default:
return GameObj.invalidID;
}
}
Character? newCharacter = CharacterManager.AddCharacter(playerInitInfo.teamID,
playerInitInfo.playerID,
playerInitInfo.characterType,
teamList[(int)playerInitInfo.teamID].MoneyPool);
if (newCharacter == null)
{
return GameObj.invalidID;
}
teamList[(int)playerInitInfo.teamID].CharacterPool.Append(newCharacter);
return newCharacter.PlayerID;
}
else
{
return playerInitInfo.playerID;
}
}
public bool Recycle(long teamID, long characterID)
{
if (!gameMap.Timer.IsGaming)
return false;
Character? character = gameMap.FindCharacterInPlayerID(teamID, characterID);
if (character != null)
{
if (character.CharacterType == CharacterType.TangSeng || character.CharacterType == CharacterType.JiuLing)
{
return false;
}
if (teamList[(int)teamID].sideFlag == 0)
{
if (character.CharacterType >= CharacterType.JiuLing)
{
return false;
}
}
if (teamList[(int)teamID].sideFlag == 1)
{
if (character.CharacterType < CharacterType.JiuLing)
{
return false;
}
}
}
if (character != null && character.IsRemoved == false)
{
bool validRecyclePoint = false;
foreach (XY recyclePoint in teamList[(int)character.TeamID].BirthPointList)
{
if (GameData.ApproachToInteract(character.Position, recyclePoint) && character.Position != recyclePoint)
{
validRecyclePoint = true;
break;
}
}
if (validRecyclePoint)
{
return characterManager.Recycle(character);
}
}
return false;
}
public long ActivateCharacter(long teamID, CharacterType characterType, int birthPointIndex = 0)
{
GameLogging.logger.ConsoleLogDebug($"Try to activate {teamID} {characterType} at birthpoint {birthPointIndex}");
Character? character = teamList[(int)teamID].CharacterPool.GetObj(characterType);
if (character == null)
{
GameLogging.logger.ConsoleLogDebug($"Fail to activate {teamID} {characterType}, no character available");
return GameObj.invalidID;
}
if (birthPointIndex < 0)
birthPointIndex = 0;
if (birthPointIndex >= teamList[(int)teamID].BirthPointList.Count)
birthPointIndex = teamList[(int)teamID].BirthPointList.Count - 1;
XY pos = teamList[(int)teamID].BirthPointList[birthPointIndex];
pos += new XY(((random.Next() & 2) - 1) * 1000, ((random.Next() & 2) - 1) * 1000);
if (characterManager.ActivateCharacter(character, pos))
{
GameLogging.logger.ConsoleLogDebug($"Successfully activated {teamID} {characterType} at {pos}");
return character.PlayerID;
}
else
{
teamList[(int)teamID].CharacterPool.ReturnObj(character);
GameLogging.logger.ConsoleLogDebug($"Fail to activate {teamID} {characterType} at {pos}, rule not permitted");
return GameObj.invalidID;
}
}
public bool StartGame(int milliSeconds)
{
if (gameMap.Timer.IsGaming)
return false;
// 开始游戏
foreach (var team in TeamList)
{
actionManager.TeamTask(team);
if (team.sideFlag == 0)
{
ActivateCharacter(team.TeamID, CharacterType.TangSeng);
}
else
{
ActivateCharacter(team.TeamID, CharacterType.JiuLing);
}
}
gameMap.Timer.Start(() => { }, () => EndGame(), milliSeconds);
return true;
}
public void EndGame()
{
}
public bool MoveCharacter(long teamID, long characterID, int moveTimeInMilliseconds, double angle)
{
if (!gameMap.Timer.IsGaming)
return false;
Character? character = gameMap.FindCharacterInPlayerID(teamID, characterID);
if (character != null && character.IsRemoved == false)
{
GameLogging.logger.ConsoleLogDebug(
"Try to move "
+ LoggingFunctional.CharacterLogInfo(character)
+ $" {moveTimeInMilliseconds} {angle}");
return actionManager.MoveCharacter(character, moveTimeInMilliseconds, angle);
}
else
{
GameLogging.logger.ConsoleLogDebug(
"Fail to move "
+ LoggingFunctional.CharacterLogInfo(teamID, characterID)
+ ", not found");
return false;
}
}
public void AddBirthPoint(long teamID, XY pos)
{
if (!gameMap.TeamExists(teamID))
return;
if (teamList[(int)teamID].BirthPointList.Contains(pos))
return;
teamList[(int)teamID].BirthPointList.Add(pos);
}
public void RemoveBirthPoint(long teamID, XY pos)
{
if (!gameMap.TeamExists(teamID))
return;
if (!teamList[(int)teamID].BirthPointList.Contains(pos))
return;
teamList[(int)teamID].BirthPointList.Remove(pos);
}
public void AddFactory(long teamID)
{
if (!gameMap.TeamExists(teamID))
return;
teamList[(int)teamID].FarmNum.Add(1);
}
public void RemoveFactory(long teamID)
{
if (!gameMap.TeamExists(teamID))
return;
teamList[(int)teamID].FarmNum.Sub(1);
}
public long GetTeamMoney(long teamID)
{
if (!gameMap.TeamExists(teamID))
return -1;
return teamList[(int)teamID].MoneyPool.Money;
}
public long GetTeamScore(long teamID)
{
if (!gameMap.TeamExists(teamID))
return -1;
return teamList[(int)teamID].MoneyPool.Score;
}
public List<IGameObj> GetGameObj()
{
var gameObjList = new List<IGameObj>();
foreach (var keyValuePair in gameMap.GameObjDict)
{
if (GameData.NeedCopy(keyValuePair.Key))
{
var thisList = gameMap.GameObjDict[keyValuePair.Key].ToNewList();
if (thisList != null) gameObjList.AddRange(thisList);
}
}
return gameObjList;
}
public void ClearAllLists()
{
foreach (var keyValuePair in gameMap.GameObjDict)
{
if (!GameData.NeedCopy(keyValuePair.Key))
{
gameMap.GameObjDict[GameObjType.CHARACTER].ForEach(delegate (IGameObj character)
{
((Character)character).CanMove.SetROri(false);
});
gameMap.GameObjDict[keyValuePair.Key].Clear();
}
}
}
public Game(MapStruct mapResource, int numOfTeam)
{
gameMap = new(mapResource);
characterManager = new(this, gameMap);
ARManager = new(this, gameMap, characterManager);
actionManager = new(this, gameMap, characterManager);
attackManager = new(this, gameMap, characterManager);
skillCastManager = new(this, gameMap, characterManager, ARManager, actionManager);
teamList = [];
gameMap.GameObjDict[GameObjType.HOME].Cast<GameObj>()?.ForEach(
delegate (GameObj gameObj)
{
if (gameObj.Type == GameObjType.HOME)
{
teamList.Add(new Base((Home)gameObj));
teamList.Last().BirthPointList.Add(gameObj.Position);
teamList.Last().AddMoney(GameData.InitialMoney);
}
}
);
}
public bool Recover(long teamID, long characterID, long recover)
{
if (!gameMap.Timer.IsGaming)
return false;
Character? character = gameMap.FindCharacterInPlayerID(teamID, characterID);
if (character != null && character.IsRemoved == false)
{
bool validRecoverPoint = false;
foreach (XY recoverPoint in teamList[(int)character.TeamID].BirthPointList)
{
if (GameData.ApproachToInteract(character.Position, recoverPoint) && character.Position != recoverPoint)
{
validRecoverPoint = true;
break;
}
}
if (validRecoverPoint)
{
return characterManager.Recover(character, recover);
}
}
return false;
}
public bool Attack(long teamID, long characterID, long ATKteamID, long ATKcharacterID)
{
if (!gameMap.Timer.IsGaming)
return false;
Character? character = gameMap.FindCharacterInPlayerID(teamID, characterID);
Character? ObjBeingShot = gameMap.FindCharacterInPlayerID(ATKteamID, ATKcharacterID);
if (character != null && character.IsRemoved == false)
return attackManager.Attack(character, ObjBeingShot);
return false;
}
public bool Construct(long teamID, long characterID, ConstructionType constructionType)
{
if (!gameMap.Timer.IsGaming)
return false;
Character? character = gameMap.FindCharacterInPlayerID(teamID, characterID);
if (character != null && character.IsRemoved == false)
{
return actionManager.Construct(character, constructionType);
}
return false;
}
public bool Produce(long teamID, long characterID)
{
if (!gameMap.Timer.IsGaming)
return false;
Character? character = gameMap.FindCharacterInPlayerID(teamID, characterID);
if (character != null && character.IsRemoved == false)
return actionManager.Produce(character);
return false;
}
public bool CastSkill(long teamID, long characterID, double angle = 0.0)
{
if (!gameMap.Timer.IsGaming)
return false;
Character? character = gameMap.FindCharacterInPlayerID(teamID, characterID);
if (character != null && character.IsRemoved == false)
return skillCastManager.SkillCasting(character, angle);
return false;
}
public bool Equip(long teamID, long characterID, EquipmentType equiptype)
{
if (!gameMap.Timer.IsGaming)
return false;
Character? character = gameMap.FindCharacterInPlayerID(teamID, characterID);
if (character != null && character.IsRemoved == false)
return equipManager.GetEquipment(character, equiptype);
return false;
}
public bool Stop(long teamID, long characterID)
{
if (!gameMap.Timer.IsGaming)
return false;
Character? character = gameMap.FindCharacterInPlayerID(teamID, characterID);
if (character != null)
return ActionManager.Stop(character);
return false;
}
public bool AttackResource(long teamID, long characterID)
{
if (!gameMap.Timer.IsGaming)
return false;
Character? character = gameMap.FindCharacterInPlayerID(teamID, characterID);
if (character != null)
return attackManager.AttackResource(character);
return false;
}
}
}