Browse Source

fix: 🐛 add the Skill SummonGolem

tags/v0.1.0
shangfengh 2 years ago
parent
commit
8ae678b967
15 changed files with 253 additions and 106 deletions
  1. +3
    -1
      docs/版本更新说明.md
  2. +53
    -52
      logic/Client/MainWindow.xaml.cs
  3. +27
    -9
      logic/GameClass/GameObj/Character/Character.cs
  4. +29
    -0
      logic/GameClass/GameObj/GameObj.cs
  5. +9
    -3
      logic/GameClass/GameObj/Map/Map.cs
  6. +1
    -2
      logic/GameClass/GameObj/Moveable.cs
  7. +1
    -2
      logic/GameClass/GameObj/ObjOfCharacter.cs
  8. +25
    -1
      logic/GameClass/GameObj/Prop/Item.cs
  9. +32
    -21
      logic/Gaming/ActionManager.cs
  10. +7
    -0
      logic/Gaming/AttackManager.cs
  11. +50
    -12
      logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs
  12. +3
    -1
      logic/Preparation/Interface/ICharacter.cs
  13. +5
    -2
      logic/Preparation/Interface/ISkill.cs
  14. +6
    -0
      logic/Preparation/Utility/Debugger.cs
  15. +2
    -0
      logic/Preparation/Utility/Transformation.cs

+ 3
- 1
docs/版本更新说明.md View File

@@ -36,4 +36,6 @@

# 5月15日更新
- feat:Robot可用
- hotfix: 修复了移动相关的bug
- hotfix: 修复了移动相关的bug

# 最新更新

+ 53
- 52
logic/Client/MainWindow.xaml.cs View File

@@ -816,63 +816,63 @@ namespace Client

private void Refresh(object? sender, EventArgs e) //log未更新
{
lock (drawPicLock) // 加锁是必要的,画图操作和接收信息操作不能同时进行
try
{
// Bonus();
if (WindowState == WindowState.Maximized)
MaxButton.Content = "❐";
else
MaxButton.Content = "🗖";
foreach (var obj in listOfHuman)
lock (drawPicLock) // 加锁是必要的,画图操作和接收信息操作不能同时进行
{
if (!isDataFixed[obj.PlayerId] && obj.PlayerId < GameData.numOfStudent && obj.StudentType != StudentType.Robot)
// Bonus();
if (WindowState == WindowState.Maximized)
MaxButton.Content = "❐";
else
MaxButton.Content = "🗖";
foreach (var obj in listOfHuman)
{
IStudentType occupation = (IStudentType)OccupationFactory.FindIOccupation(Transformation.ToStudentType(obj.StudentType));
totalLife[obj.PlayerId] = occupation.MaxHp;
totalDeath[obj.PlayerId] = occupation.MaxGamingAddiction;
int i = 0;
foreach (var skill in occupation.ListOfIActiveSkill)
if (obj.PlayerId < GameData.numOfStudent && !isDataFixed[obj.PlayerId])
{
var iActiveSkill = SkillFactory.FindActiveSkill(skill);
coolTime[i, obj.PlayerId] = iActiveSkill.SkillCD;
++i;
IStudentType occupation = (IStudentType)OccupationFactory.FindIOccupation(Transformation.ToStudentType(obj.StudentType));
totalLife[obj.PlayerId] = occupation.MaxHp;
totalDeath[obj.PlayerId] = occupation.MaxGamingAddiction;
int i = 0;
foreach (var skill in occupation.ListOfIActiveSkill)
{
var iActiveSkill = SkillFactory.FindActiveSkill(skill);
coolTime[i, obj.PlayerId] = iActiveSkill.SkillCD;
++i;
}
isDataFixed[obj.PlayerId] = true;
}
isDataFixed[obj.PlayerId] = true;
}
}
foreach (var obj in listOfButcher)
{
if (!isDataFixed[obj.PlayerId])
foreach (var obj in listOfButcher)
{
IGhostType occupation1 = (IGhostType)OccupationFactory.FindIOccupation(Transformation.ToTrickerType(obj.TrickerType));
int j = 0;
foreach (var skill in occupation1.ListOfIActiveSkill)
if (!isDataFixed[obj.PlayerId])
{
var iActiveSkill = SkillFactory.FindActiveSkill(skill);
coolTime[j, GameData.numOfStudent] = iActiveSkill.SkillCD;
++j;
IGhostType occupation1 = (IGhostType)OccupationFactory.FindIOccupation(Transformation.ToTrickerType(obj.TrickerType));
int j = 0;
foreach (var skill in occupation1.ListOfIActiveSkill)
{
var iActiveSkill = SkillFactory.FindActiveSkill(skill);
coolTime[j, GameData.numOfStudent] = iActiveSkill.SkillCD;
++j;
}
isDataFixed[obj.PlayerId] = true;
}
isDataFixed[obj.PlayerId] = true;
}
}

for (int i = 0; i < GameData.numOfStudent; i++)
{
StatusBarsOfSurvivor[i].NewData(totalLife, totalDeath, coolTime);
}
for (int i = 0; i < GameData.numOfStudent; i++)
{
StatusBarsOfSurvivor[i].NewData(totalLife, totalDeath, coolTime);
}

StatusBarsOfHunter.NewData(totalLife, totalDeath, coolTime);
StatusBarsOfHunter.NewData(totalLife, totalDeath, coolTime);

for (int i = 0; i < GameData.numOfStudent; i++)
{
StatusBarsOfSurvivor[i].SetFontSize(12 * unitFontsize);
}
for (int i = 0; i < GameData.numOfStudent; i++)
{
StatusBarsOfSurvivor[i].SetFontSize(12 * unitFontsize);
}

StatusBarsOfHunter.SetFontSize(12 * unitFontsize);
StatusBarsOfCircumstance.SetFontSize(12 * unitFontsize);
if (!isClientStocked)
{
try
StatusBarsOfHunter.SetFontSize(12 * unitFontsize);
StatusBarsOfCircumstance.SetFontSize(12 * unitFontsize);
if (!isClientStocked)
{
UpperLayerOfMap.Children.Clear();
foreach (var data in listOfAll)
@@ -885,7 +885,7 @@ namespace Client
}
foreach (var data in listOfHuman)
{
if (data.StudentType != StudentType.Robot)
if (data.PlayerId < GameData.numOfStudent)
StatusBarsOfSurvivor[data.PlayerId].SetValue(data, data.PlayerId);
if (CanSee(data))
{
@@ -1136,15 +1136,15 @@ namespace Client
}
}
}
catch (Exception exc)
{
ErrorDisplayer error = new("Error: " + exc.ToString());
error.Show();
isClientStocked = true;
PorC.Content = "▶";
}
counter++;
}
counter++;
}
catch (Exception exc)
{
ErrorDisplayer error = new("Error: " + exc.ToString());
error.Show();
isClientStocked = true;
PorC.Content = "▶";
}
}

@@ -1309,6 +1309,7 @@ namespace Client
{
PlayerId = playerID,
SkillId = 0,
SkillParam = 0,
};
client.UseSkill(msgB);
break;


+ 27
- 9
logic/GameClass/GameObj/Character/Character.cs View File

@@ -442,8 +442,9 @@ namespace GameClass.GameObj
}


public long SetPlayerState(PlayerStateType value = PlayerStateType.Null, GameObj? gameObj = null)
public long SetPlayerState(PlayerStateType value = PlayerStateType.Null, IGameObj? obj = null)
{
GameObj? gameObj = (GameObj?)obj;
lock (actionLock)
{
PlayerStateType nowPlayerState = PlayerState;
@@ -468,20 +469,21 @@ namespace GameClass.GameObj
else return -1;

case PlayerStateType.TryingToAttack:
if (value != PlayerStateType.Moving && value != PlayerStateType.ClimbingThroughWindows
&& value != PlayerStateType.LockingTheDoor && value != PlayerStateType.OpeningTheDoor)
if (value == PlayerStateType.Addicted || value == PlayerStateType.Swinging
|| value == PlayerStateType.Deceased || value == PlayerStateType.Stunned
|| value == PlayerStateType.Charmed || value == PlayerStateType.Null)
return ChangePlayerState(value, gameObj);
else return -1;
case PlayerStateType.Stunned:
case PlayerStateType.Charmed:
if (value != PlayerStateType.Moving && value != PlayerStateType.ClimbingThroughWindows
&& value != PlayerStateType.LockingTheDoor && value != PlayerStateType.OpeningTheDoor
&& value != PlayerStateType.Swinging)
if (value == PlayerStateType.Addicted || value == PlayerStateType.Deceased
|| value == PlayerStateType.Null)
return ChangePlayerState(value, gameObj);
else return -1;
case PlayerStateType.Swinging:
if (value != PlayerStateType.Moving && value != PlayerStateType.ClimbingThroughWindows
&& value != PlayerStateType.LockingTheDoor && value != PlayerStateType.OpeningTheDoor)
if (value == PlayerStateType.Addicted
|| value == PlayerStateType.Deceased || value == PlayerStateType.Stunned
|| value == PlayerStateType.Charmed || value == PlayerStateType.Null)
{
try
{
@@ -494,7 +496,9 @@ namespace GameClass.GameObj
}
else return -1;
case PlayerStateType.ClimbingThroughWindows:
if (value != PlayerStateType.Moving && value != PlayerStateType.LockingTheDoor && value != PlayerStateType.OpeningTheDoor)
if (value == PlayerStateType.Addicted
|| value == PlayerStateType.Deceased || value == PlayerStateType.Stunned
|| value == PlayerStateType.Charmed || value == PlayerStateType.Null)
{
Window window = (Window)WhatInteractingWith!;
try
@@ -537,6 +541,20 @@ namespace GameClass.GameObj
{
ThreadNum.Release();
}
case PlayerStateType.UsingSkill:
if (typeof(CraftingBench).IsInstanceOfType(whatInteractingWith))
{
try
{
((CraftingBench)whatInteractingWith!).StopSkill();
return ChangePlayerState(value, gameObj);
}
finally
{
ThreadNum.Release();
}
}
return ChangePlayerState(value, gameObj);
default:
return ChangePlayerState(value, gameObj);
}


+ 29
- 0
logic/GameClass/GameObj/GameObj.cs View File

@@ -36,6 +36,35 @@ namespace GameClass.GameObj

public abstract ShapeType Shape { get; }

protected bool isRemoved = false;
public virtual bool IsRemoved
{
get
{
gameObjReaderWriterLock.EnterReadLock();
try
{
return isRemoved;
}
finally
{
gameObjReaderWriterLock.ExitReadLock();
}
}
}
public virtual void TryToRemove()
{
gameObjReaderWriterLock.EnterWriteLock();
try
{
isRemoved = true;
}
finally
{
gameObjReaderWriterLock.ExitWriteLock();
}
}

public int Radius { get; }

public virtual bool IgnoreCollideExecutor(IGameObj targetObj) => false;


+ 9
- 3
logic/GameClass/GameObj/Map/Map.cs View File

@@ -231,7 +231,10 @@ namespace GameClass.GameObj
}
}
if (ToDel != null)
{
GameObjDict[gameObj.Type].Remove(ToDel);
ToDel.TryToRemove();
}
}
finally
{
@@ -242,16 +245,19 @@ namespace GameClass.GameObj
public bool RemoveJustFromMap(GameObj gameObj)
{
GameObjLockDict[gameObj.Type].EnterWriteLock();
bool flag;
try
{
flag = GameObjDict[gameObj.Type].Remove(gameObj);
if (GameObjDict[gameObj.Type].Remove(gameObj))
{
gameObj.TryToRemove();
return true;
}
return false;
}
finally
{
GameObjLockDict[gameObj.Type].ExitWriteLock();
}
return flag;
}
public void Add(GameObj gameObj)
{


+ 1
- 2
logic/GameClass/GameObj/Moveable.cs View File

@@ -126,8 +126,7 @@ namespace GameClass.GameObj
}
}

protected bool isRemoved;
public bool IsRemoved
public override bool IsRemoved
{
get
{


+ 1
- 2
logic/GameClass/GameObj/ObjOfCharacter.cs View File

@@ -1,5 +1,4 @@
using Google.Protobuf.WellKnownTypes;
using Preparation.Interface;
using Preparation.Interface;
using Preparation.Utility;
using System.Threading;



+ 25
- 1
logic/GameClass/GameObj/Prop/Item.cs View File

@@ -1,5 +1,6 @@
using Preparation.Interface;
using Preparation.Utility;
using System.Threading;

namespace GameClass.GameObj
{
@@ -32,9 +33,32 @@ namespace GameClass.GameObj

public sealed class CraftingBench : Item
{
public CraftingBench(XY initPos) :
public CraftingBench(XY initPos, Character character, int num) :
base(initPos)
{
Parent = character;
this.num = num;
}
private readonly int num;
private long parentStateNum;
public long ParentStateNum
{
get => Interlocked.Read(ref parentStateNum);
set => Interlocked.Exchange(ref parentStateNum, value);
}
public void StopSkill()
{
((SummonGolem)Parent!.FindActiveSkill(ActiveSkillType.SummonGolem)).DeleteGolem((int)num);
}
public void TryStopSkill()
{
lock (Parent!.ActionLock)
{
if (Parent!.StateNum == parentStateNum)
{
Parent!.SetPlayerState();
}
}
}
public override PropType GetPropType() => PropType.CraftingBench;
}


+ 32
- 21
logic/Gaming/ActionManager.cs View File

@@ -1,4 +1,5 @@
using System;
using System.Numerics;
using System.Threading;
using GameClass.GameObj;
using GameEngine;
@@ -13,26 +14,6 @@ namespace Gaming
private readonly ActionManager actionManager;
private class ActionManager
{

// 人物移动
private void SkillWhenColliding(Character player, IGameObj collisionObj)
{
if (collisionObj.Type == GameObjType.Bullet)
{
if (((Bullet)collisionObj).Parent != player && ((Bullet)collisionObj).TypeOfBullet == BulletType.JumpyDumpty)
{
if (characterManager.BeStunned((Character)player, GameData.timeOfStunnedWhenJumpyDumpty) > 0)
player.AddScore(GameData.TrickerScoreStudentBeStunned(GameData.timeOfStunnedWhenJumpyDumpty));
gameMap.Remove((GameObj)collisionObj);
}
}
if (player.FindActiveSkill(ActiveSkillType.CanBeginToCharge).IsBeingUsed == 1 && collisionObj.Type == GameObjType.Character && ((Character)collisionObj).IsGhost())
{
if (characterManager.BeStunned((Character)collisionObj, GameData.timeOfGhostStunnedWhenCharge) > 0)
player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.timeOfGhostStunnedWhenCharge));
characterManager.BeStunned(player, GameData.timeOfStudentStunnedWhenCharge);
}
}
public bool MovePlayer(Character playerToMove, int moveTimeInMilliseconds, double moveDirection)
{
if (moveTimeInMilliseconds < 5) return false;
@@ -561,7 +542,37 @@ namespace Gaming
gameMap: gameMap,
OnCollision: (obj, collisionObj, moveVec) =>
{
SkillWhenColliding((Character)obj, collisionObj);
Character player = (Character)obj;
switch (collisionObj.Type)
{
case GameObjType.Bullet:

if (((Bullet)collisionObj).Parent != player && ((Bullet)collisionObj).TypeOfBullet == BulletType.JumpyDumpty)
{
if (characterManager.BeStunned((Character)player, GameData.timeOfStunnedWhenJumpyDumpty) > 0)
player.AddScore(GameData.TrickerScoreStudentBeStunned(GameData.timeOfStunnedWhenJumpyDumpty));
gameMap.Remove((GameObj)collisionObj);
}
break;
case GameObjType.Character:
if (player.FindActiveSkill(ActiveSkillType.CanBeginToCharge).IsBeingUsed == 1 && ((Character)collisionObj).IsGhost())
{
if (characterManager.BeStunned((Character)collisionObj, GameData.timeOfGhostStunnedWhenCharge) > 0)
player.AddScore(GameData.StudentScoreTrickerBeStunned(GameData.timeOfGhostStunnedWhenCharge));
characterManager.BeStunned(player, GameData.timeOfStudentStunnedWhenCharge);
}
break;
case GameObjType.Item:
if (((Item)collisionObj).GetPropType() == PropType.CraftingBench)
{
((CraftingBench)collisionObj).TryStopSkill();
gameMap.Remove((Item)collisionObj);
}
break;
default:
break;
}

//Preparation.Utility.Debugger.Output(obj, " end move with " + collisionObj.ToString());
//if (collisionObj is Mine)
//{


+ 7
- 0
logic/Gaming/AttackManager.cs View File

@@ -74,6 +74,13 @@ namespace Gaming
if (bullet.CanBeBombed(GameObjType.Door))
;
break;
case GameObjType.Item:
if (((Item)objBeingShot).GetPropType() == PropType.CraftingBench)
{
((CraftingBench)objBeingShot).TryStopSkill();
gameMap.Remove(objBeingShot);
}
break;
default:
break;
}


+ 50
- 12
logic/Gaming/SkillManager/SkillManager.ActiveSkill.cs View File

@@ -151,24 +151,61 @@ namespace Gaming
public bool SummonGolem(Character player)
{
ActiveSkill activeSkill = player.FindActiveSkill(ActiveSkillType.SummonGolem);
long num = ((SummonGolem)activeSkill).AddGolem();
int num = ((SummonGolem)activeSkill).AddGolem();
if (num >= GameData.maxSummonedGolemNum) return false;
num = (num + 1) * GameData.numOfPeople + player.PlayerID;
Debugger.Output(player, num.ToString());

/* if ((!player.Commandable())) return false;
XY res = player.Position + new XY(player.FacingDirection, player.Radius * 2);
if (actionManager.moveEngine.CheckCollision(player, res) != null)
return false;
Golem? golem = (Golem?)characterManager.AddPlayer(res, player.TeamID, player.PlayerID + GameData.numOfPeople, CharacterType.Robot, player);
if (golem == null) return false;
((SummonGolem)activeSkill).GolemSummoned = golem;
XY res = player.Position + new XY(player.FacingDirection, player.Radius * 2);
CraftingBench craftingBench = new(res, player, num);

long stateNum = player.SetPlayerState(PlayerStateType.UsingSkill, craftingBench);
if (stateNum == -1)
{
((SummonGolem)activeSkill).DeleteGolem(num);
return false;
}

player.ThreadNum.WaitOne();
if (stateNum != player.StateNum)
{
((SummonGolem)activeSkill).DeleteGolem(num);
player.ThreadNum.Release();
return false;
}

if (actionManager.moveEngine.CheckCollision(craftingBench, res) != null)
{
((SummonGolem)activeSkill).DeleteGolem(num);
player.ThreadNum.Release();
return false;
}
craftingBench.ParentStateNum = stateNum;
gameMap.Add(craftingBench);
/*
*/
return ActiveSkillEffect(activeSkill, player, () =>
{
},
() =>
{ });

() =>
{
lock (player.ActionLock)
{
if (stateNum == player.StateNum)
{
gameMap.RemoveJustFromMap(craftingBench);
Golem? golem = (Golem?)characterManager.AddPlayer(res, player.TeamID, (num + 1) * GameData.numOfPeople + player.PlayerID, CharacterType.Robot, player);
if (golem == null)
{
((SummonGolem)activeSkill).DeleteGolem(num);
}
Debugger.Output(player, activeSkill.DurationTime.ToString());
player.SetPlayerStateNaturally();
Debugger.Output(player, player.StateNum.ToString());
player.ThreadNum.Release();
}
}
}
);
}

public static bool UseKnife(Character player)
@@ -336,6 +373,7 @@ namespace Gaming
if (activeSkill.TimeUntilActiveSkillAvailable == 0)
{
activeSkill.TimeUntilActiveSkillAvailable = activeSkill.SkillCD;

new Thread
(() =>
{


+ 3
- 1
logic/Preparation/Interface/ICharacter.cs View File

@@ -3,7 +3,7 @@ using Preparation.Utility;

namespace Preparation.Interface
{
public interface ICharacter : IGameObj
public interface ICharacter : IMoveable
{
public long TeamID { get; }
public int HP { get; set; }
@@ -13,7 +13,9 @@ namespace Preparation.Interface
public PlayerStateType PlayerState { get; }
public BulletType BulletOfPlayer { get; set; }
public CharacterType CharacterType { get; }
public ActiveSkill FindActiveSkill(ActiveSkillType activeSkillType);
public int UpdateBulletNum(int time);
public long SetPlayerState(PlayerStateType value = PlayerStateType.Null, IGameObj? obj = null);

public bool IsGhost();
}


+ 5
- 2
logic/Preparation/Interface/ISkill.cs View File

@@ -32,7 +32,10 @@ namespace Preparation.Interface
private int timeUntilActiveSkillAvailable = 0;
public int TimeUntilActiveSkillAvailable
{
get => Interlocked.CompareExchange(ref timeUntilActiveSkillAvailable, 0, 1);
get
{
return Interlocked.CompareExchange(ref timeUntilActiveSkillAvailable, 0, 1);
}
set
{
if (value < 0) value = 0;
@@ -138,7 +141,7 @@ namespace Preparation.Interface
public class SummonGolem : ActiveSkill
{
public override int SkillCD => GameData.commonSkillCD * 4 / 3;
public override int DurationTime => 6;
public override int DurationTime => 6000;

private bool[] golemIDArray = new bool[GameData.maxSummonedGolemNum] { false, false, false };
public bool[] GolemIDArray


+ 6
- 0
logic/Preparation/Utility/Debugger.cs View File

@@ -8,6 +8,12 @@ namespace Preparation.Utility
{
#if DEBUG
Console.WriteLine(current.GetType() + " " + current.ToString() + " " + str);
#endif
}
static public void Output(string str)
{
#if DEBUG
Console.WriteLine(str);
#endif
}
}


+ 2
- 0
logic/Preparation/Utility/Transformation.cs View File

@@ -55,6 +55,8 @@ namespace Preparation.Utility
return Protobuf.PropType.ShieldOrSpear;
case Preparation.Utility.PropType.RecoveryFromDizziness:
return Protobuf.PropType.RecoveryFromDizziness;
case PropType.CraftingBench:
return Protobuf.PropType.CraftingBench;
case Preparation.Utility.PropType.Key3:
return Protobuf.PropType.Key3;
case Preparation.Utility.PropType.Key5:


Loading…
Cancel
Save