enum MsgId {
S_ENTER_GAME = 0;
S_LEAVE_GAME = 1;
S_SPAWN = 2;
S_DESPAWN = 3;
C_MOVE = 4;
S_MOVE = 5;
C_SKILL = 6;
S_SKILL = 7;
S_CHANGE_HP = 8;
S_DIE = 9;
}
message S_Die {
int32 objectId = 1;
int32 attackerId = 2;
}
누군가 죽었으면 누가 죽었는지, 또 누구에게 죽었는지 정보를 담는 S_Die 패킷을 하나 만들어준다.
public virtual void OnDead(GameObject attacker)
{
S_Die diePacket = new S_Die();
diePacket.ObjectId = Id;
diePacket.AttackerId = attacker.Id;
Room.Broadcast(diePacket);
GameRoom room = Room; // LeaveGame 함수 안에서 player.Room = null;
room.LeaveGame(Id);
Stat.Hp = Stat.MaxHp;
PosInfo.State = CreatureState.Idle;
PosInfo.MoveDir = MoveDir.Down;
PosInfo.PosX = 0;
PosInfo.PosY = 0;
room.EnterGame(this); // 스탯 등 초기화 후 부활
}
public void EnterGame(GameObject gameObject)
{
if (gameObject == null)
return;
GameObjectType type = ObjectManager.GetObjectTypeById(gameObject.Id);
lock (_lock)
{
if (type == GameObjectType.Player)
{
Player player = gameObject as Player;
_players.Add(gameObject.Id, player);
player.Room = this;
Map.ApplyMove(player, new Vector2Int(player.CellPos.x, player.CellPos.y));
// 본인한테 정보 전송
{
S_EnterGame enterPacket = new S_EnterGame();
enterPacket.Player = player.Info;
player.Session.Send(enterPacket);
S_Spawn spawnPacket = new S_Spawn();
foreach (Player p in _players.Values)
{
if (player != p)
spawnPacket.Objects.Add(p.Info);
}
foreach (Monster m in _monsters.Values)
spawnPacket.Objects.Add(m.Info);
foreach (Projectile p in _projectiles.Values)
spawnPacket.Objects.Add(p.Info);
player.Session.Send(spawnPacket);
}
}
Leave 패킷을 날리면 플레이어의 ObjectManager에서 모든 게임 오브젝트들을 담아놓은 것을 clear해주기 때문에, 다시 부활하여 게임 룸에 Enter할때 다시 게임룸에 존재하는 오브젝트를 돌면서 전부 패킷에 담아주고 스폰 패킷으로 날려줘서 다시 플레이어의 ObjectManager의 objects에 담아줘야 한다.
그리고 부활하면 좌표를 맵에서 갱신시켜줘야하기 때문에 ApplyMove해서 플레이어 위치정보를 업데이트해준다.
public static void S_DieHandler(PacketSession session, IMessage packet)
{
S_Die diePacket = packet as S_Die;
GameObject go = Managers.Object.FindById(diePacket.ObjectId);
if (go == null)
return;
CreatureController cc = go.GetComponent<CreatureController>();
if (cc != null)
{
cc.Hp = 0;
cc.OnDead();
}
}
public virtual void OnDead()
{
State = CreatureState.Dead;
GameObject effect = Managers.Resource.Instantiate("Effect/DieEffect");
effect.transform.position = transform.position;
effect.GetComponent<Animator>().Play("START");
GameObject.Destroy(effect, 0.5f);
}