public void ChangeState(SActor actor, UpdateStateMachine updateStateMachine, ActorState state, float duration) { actor.ChangeStateServerSide(state, duration); actor.BeginState = Timing.sInstance.GetFrameStartTime(); NetworkManagerServer.sInstance.SetStateDirty(actor.GetNetworkId(), actor.WorldId, (uint)Actor.ReplicationState.State); this.updateStateMachine = updateStateMachine; }
public void SetKingSpell(byte worldId, int playerId) { Entry entry = World.Instance(worldId).GameMode.GetEntry(playerId); if (entry == null) { LogHelper.LogError($"Can't find entry in SetKingSpell playerId : {playerId}"); return; } NetGameObject netGameObject = NetworkManager.Instance.GetGameObject(entry.mNetworkId, worldId); if (netGameObject == null || !(netGameObject is SActor)) { LogHelper.LogError($"netGameObject == null or netGameObject is not SActor playerId : {playerId}, worldId : {worldId}"); return; } SActor actor = netGameObject as SActor; var modeData = ACDC.GameModeData[(int)GetMode()]; for (int i = 0; i < modeData.ModeSpellIDs.Length; ++i) { actor.AddSpell(ACDC.SpellData[modeData.ModeSpellIDs[i]], 0); } if (actor.StateServerSide != ActorState.Ghost) { actor.ResetHealth(actor.GetCharacterHp(), null); } }
/// <summary> /// AI 컨트롤러로 위임. /// 최초 할당한 유저 값만 의미가 있고 이후 위임한 유저의 값은 의미가 없음 /// </summary> /// <param name="actor"></param> /// <param name="original_actor"></param> public void Possess(SActor actor, SActor original_actor) { // 기존 유저 정보를 바탕으로 ai컨트롤러 초기화 if (original_actor.GetActorController() != null) { mSessionId = original_actor.GetActorController().mSessionId; mSelectedCharacter = original_actor.GetActorController().mSelectedCharacter; UserId = original_actor.GetActorController().UserId; mCharacterLevel = original_actor.GetActorController().mCharacterLevel; } mNetworkId = original_actor.GetNetworkId(); mPlayerId = original_actor.GetPlayerId(); ControllPlayerId = actor.GetPlayerId(); Log.Information($"ai Possess original player_id{mPlayerId}, attached player_id{actor.GetPlayerId()}"); // ai 할당되었음을 동기화 actor.AIPlayers.Add(mNetworkId); NetworkManagerServer.sInstance.SetStateDirty(actor.GetNetworkId(), actor.WorldId, (uint)Actor.ReplicationState.AI); original_actor.SetController(this); // 순환 참조 방지 if (actor != original_actor) { actor.GetActorController().AIControllers.Add(this); } World.Instance(original_actor.WorldId).aiList[original_actor.GetPlayerId()] = original_actor; }
public SActor RestoreAI() { SActor actor = null; var actors = World.Instance(mWorldId).playerList.Values.Where(x => x.GetPlayerId() != GetPlayerId() && ((SActor)x).GetActorController() != null).Select(x => (SActor)x).ToList(); foreach (var otherActor in actors) { var aiController = otherActor.GetActorController().GetAIController(this.mSessionId); if (aiController != null && aiController != default(AIController)) { // AI로 대신 플레이 해주었던 유저에게서 때어 내고 actor = (SActor)NetworkManagerServer.sInstance.GetGameObject(aiController.mNetworkId, this.mWorldId); if (actor != null) { aiController.Unpossess(actor); actor.GetActorController().AIControllers.RemoveAll(x => x.mSessionId == this.mSessionId); // 원래 유저에게 다시 붙인다. this.Possess(actor); } } } return(actor); }
public void UpdateIdle(SActor actor) { #if _USE_INPUT_SYNC actor.UpdateMove(); #else actor.UpdateState(); #endif }
/// <summary> /// 해당 객체에서 컨트롤로를 때어냄 /// </summary> /// <param name="actor"></param> public void Unpossess(SActor actor) { Log.Information($"ai Unpossess original player_id{mPlayerId}, network_id{mNetworkId}"); actor.AIPlayers.Remove(this.mNetworkId); NetworkManagerServer.sInstance.SetStateDirty(actor.GetNetworkId(), actor.WorldId, (uint)Actor.ReplicationState.AI); //actor.SetController(null); World.Instance(actor.WorldId).aiList.Remove(mPlayerId); }
public void UpdateTeleport(SActor actor) { if (actor.EndState <= Timing.sInstance.GetFrameStartTime()) { actor.mActorController?.GetUnprocessedMoveList().Clear(); actor.SetLocation(actor.TargetPos); LogHelper.LogInfo($"end teleport pos {actor.TargetPos.ToString()}, degree{actor.degree}"); ChangeState(actor, UpdateIdle, ActorState.Idle, 0f); } }
public override void ActionResult(byte actionToken, List <int> objectList, Vector3 bombedPos) { if (ActionTokens.ContainsKey(actionToken) == false) { //Log.Information($"ActionResult already execute ({string.Join(",", objectList)}), {actionToken}"); return; } //if(objectList.Count > 0) // Log.Information($"ActionResult ({string.Join(",", objectList)}), {actionToken}"); JSkillData skillData = ACDC.SkillData[ActionTokens[actionToken].SkillId]; NetGameObject obj; for (int i = 0; i < objectList.Count; ++i) { obj = NetworkManagerServer.sInstance.GetGameObject(objectList[i], WorldId); if (obj == null) { continue; } var applyDamage = obj.OnExplode((int)GetPlayerId(), GetNetworkId(), GetDamage(ActionTokens[actionToken].SkillId, (GameObjectClassId)obj.GetClassId())); // add spell SActor actor = obj as SActor; if (actor != null && skillData != null) { //actor.AddableSpell((int)GetPlayerId(), skillData.spellId); //Log.Information($"ActionResult AddSpell {skillData.spellId}"); foreach (int nSpellID in skillData.spellId) { actor.AddableSpell(this, (int)GetPlayerId(), nSpellID, applyDamage); } } } // Link Skill if (skillData != null && skillData.linkSkillId != 0) { var linkSkillData = ACDC.SkillData[skillData.linkSkillId]; if (linkSkillData != null && linkSkillData.skillType == (int)SkillType.InstallAreaOfEffect) { AreaOfEffect aoe = (AreaOfEffect)GameObjectRegistry.sInstance.CreateGameObject((uint)GameObjectClassId.AreaOfEffect, true, WorldId); aoe.InitFrom(this, (ushort)linkSkillData.skillId, bombedPos); } } ActionTokens.Remove(actionToken); }
void AddSpell(Actor inActor, JSpellData spellData) { #if UNITY_EDITOR || DEBUG Log.Information($"SAreaOfEffect AddSpell {inActor.GetPlayerId()} spellId {mSkillData.spellId}"); #endif SActor sActor = inActor as SActor; if (sActor != null) { sActor.AddableSpell(sActor, sActor.GetPlayerId(), spellData, 0); } }
public void UpdateDash(SActor actor) { if (actor.EndState <= Timing.sInstance.GetFrameStartTime()) { actor.mActorController?.GetUnprocessedMoveList().Clear(); actor.SetLocation(actor.TargetPos); actor.SetVelocity(Vector3.zero); Log.Information($"end dash pos {actor.TargetPos.ToString()}"); ChangeState(actor, UpdateIdle, ActorState.Idle, 0f); NetworkManagerServer.sInstance.SetStateDirty(actor.GetNetworkId(), actor.WorldId, (uint)Actor.ReplicationState.Pose); } }
public void SpawnActorForPlayer(int inPlayerId, byte worldId) { SActor actor = (SActor)GameObjectRegistry.sInstance.CreateGameObject((uint32_t)GameObjectClassId.kActor, worldId); actor.SetColor(GameMode.sInstance.GetEntry((uint32_t)inPlayerId).GetColor()); actor.SetPlayerId((uint32_t)inPlayerId); actor.Possess(inPlayerId); actor.SetWorldId(worldId); //gotta pick a better spawn location than this... actor.SetLocation(core.Utility.GetRandomVector(-10, 10, 0)); Log.Information(string.Format("SpawnActorForPlayer player_id{0}, world{1}", inPlayerId, worldId)); }
public void Possess(SActor actor) { Log.Information($"player Possess player_id{mPlayerId}, network_id{actor.NetworkId}, world{actor.WorldId}"); ControllPlayerId = mPlayerId; actor.SetPlayerId(mPlayerId); actor.SetController(this); var entry = World.Instance(actor.WorldId).GameMode.GetEntry(mPlayerId); if (entry != null) { entry.Leave = false; } }
public SActor GetActorForPlayer(int inPlayerId, byte worldId) { //run through the objects till we find the actor... //it would be nice if we kept a pointer to the actor on the PlayerController //but then we'd have to clean it up when the actor died, etc. //this will work for now until it's a perf issue var gameObjects = World.Instance(worldId).GetGameObjects(); foreach (var go in gameObjects) { SActor actor = (SActor)go.GetAsActor(); if (actor != null && actor.GetPlayerId() == inPlayerId) { return((SActor)go); } } return(null); }
public void UpdateGhost(SActor actor) { if (actor.EndState <= Timing.sInstance.GetFrameStartTime()) { actor.mActorController?.GetUnprocessedMoveList().Clear(); actor.SetLocation(actor.TargetPos); actor.SetVelocity(Vector3.zero); actor.degree = actor.SpawnAngle; actor.HiddenMapObjects.Clear(); actor.killPlayerId = 0; LogHelper.LogInfo($"end ghost pos {actor.TargetPos.ToString()}"); ChangeState(actor, UpdateIdle, ActorState.Idle, 0f); NetworkManagerServer.sInstance.SetStateDirty(actor.GetNetworkId(), actor.WorldId, (uint)Actor.ReplicationState.Spawn); actor.AddSpellMySelf(core.BuffType.Invincible); World.Instance(actor.WorldId).GameMode.game_mode.OnTrigger(actor.WorldId, actor.GetPlayerId(), PlayPointID.PlayerReborn); } }
public void HandleLostClient(ClientProxy inClientProxy) { //kill client's actor //remove client from scoreboard int playerId = inClientProxy.GetPlayerId(); GameMode.sInstance.RemoveEntry((uint32_t)playerId); SActor actor = GetActorForPlayer(playerId, inClientProxy.GetWorldId()); if (actor != null) { actor.Unpossess(); actor.SetDoesWantToDie(true); } if (ServerMonitor.sInstance.DelUser(inClientProxy.GetWorldId()) == 0) { Log.Information(string.Format("Close World {0}", inClientProxy.GetWorldId())); NetworkManagerServer.sInstance.Clear(inClientProxy.GetWorldId()); World.Instance(inClientProxy.GetWorldId()).Clear(); } }
public void Unpossess(SActor actor, PlayerController newPlayerController, AIController aiController) { Log.Information($"player Unpossess player_id{actor.GetPlayerId()}, network_id{actor.NetworkId}, world{actor.WorldId}"); // 새로운 플레이어컨트롤로 교체인 경우 if (newPlayerController != null) { actor.SetController(newPlayerController); return; } World.Instance(actor.WorldId).GameMode.LeaveEntry(mPlayerId); if (EnableAiSwitch) { // 남은 플레이어중에서 ai가 가장 적게 할당된 유저에게 할당 var otherActor = GetAppropriateActorAIPossess(mWorldId, GetPlayerId()); if (otherActor != null) { if (aiController == null) { // 최초 AI컨트롤러로 위임 aiController = new AIController(); aiController.Possess(otherActor, actor); } else { // 새로운 곳에 붙임 aiController.Possess(otherActor, actor); } // AI 교체 완료 return; } } // 기본적으로 해당 객체에 컨트롤러를 널로 초기화 actor.SetController(null); }
public void AddableSpell(SActor attackPlayer, int attackPlayerId, JSpellData spellData, int applyDamage) { if (StateServerSide != ActorState.Idle) { //Log.Information($"can't add spell in state {StateServerSide}"); return; } if (buff.IsExist(BuffType.Invincible)) { // 무적일때 스펠도 안걸리고 대미지도 안걸림. return; } // 게임 모드별로 데미지 적용 여부 // 데미지 안받으면 스펠도 안걸림. if (attackPlayerId >= 0) // 추락, 트랩등으로 데미지를 얻을 경우는 제외 { if (World.Instance(WorldId).GameMode.TakableDamage(attackPlayerId, GetPlayerId()) == false) { return; } } if (spellData != null) { if (spellData.ApplyObject == (int)ApplyObject.Oneself) { attackPlayer.AddSpell(spellData, applyDamage); } else { AddSpell(spellData, applyDamage); } } }
public SActor SpawnActor(int inPlayerId, byte worldId, int team, int spawn_index) { SActor actor = (SActor)GameObjectRegistry.sInstance.CreateGameObject((UInt32)GameObjectClassId.Actor, true, worldId); var entry = World.Instance(worldId).GameMode.AddEntry(inPlayerId, this.mSessionId.ToString(), (ushort)team, spawn_index, actor.GetNetworkId()); actor.SpawnPoint = World.spawn_position[entry.seat].mapPos; actor.SpawnAngle = new Vector2(World.spawn_position[entry.seat].startVector.x, World.spawn_position[entry.seat].startVector.z).Angle(); actor.degree = actor.SpawnAngle; actor.SetWorldId(worldId); actor.SetLocation(actor.SpawnPoint); actor.SetPhysics(); actor.Team = entry.GetTeam(); actor.SetPlayerId(inPlayerId); //gotta pick a better spawn location than this... //actor.SetLocation(core.Utility.GetRandomVector(-10, 10, 0)); actor.SetCharacter(mSelectedCharacter, mCharacterLevel, UserId); Log.Information($"SpawnActor player_id{inPlayerId}, UserID:{actor.UserId}, network_id{actor.NetworkId}, world{worldId}, idx{entry.seat}, pos{actor.GetLocation()}, angle{actor.degree}, direction({World.spawn_position[entry.seat].startVector.x},{World.spawn_position[entry.seat].startVector.z})"); return(actor); }
public override void ActionResult2(byte actionToken, List <int> objectList, int hitProjectileIdx) { ActionInfo actionInfo = null; //Log.Information($"ActionResult2 ({string.Join(",", objectList)}), {actionToken}, {hitProjectileIdx}"); if (ActionTokens.TryGetValue(actionToken, out actionInfo)) { if (actionInfo.hitIndex == null) { //Log.Information($"ActionResult2 hitIndex is null ({string.Join(",", objectList)}), {actionToken}, {hitProjectileIdx}"); return; } if (actionInfo.hitIndex.Contains((byte)hitProjectileIdx)) { //Log.Information($"ActionResult2 already hit execute ({string.Join(",", objectList)}), {actionToken}, {hitProjectileIdx}, hitIndex:({string.Join(",", actionInfo.hitIndex)})"); return; } } else { //Log.Information($"ActionResult2 already execute ({string.Join(",", objectList)}), {actionToken}, {hitProjectileIdx}"); return; } //Log.Information($"ActionResult2 OK objectList:({string.Join(",", objectList)}), actionToken:{actionToken}, {hitProjectileIdx}, ({string.Join(",", actionInfo.hitIndex)})"); JSkillData skillData = ACDC.SkillData[actionInfo.SkillId]; NetGameObject obj; for (int i = 0; i < objectList.Count; ++i) { obj = NetworkManagerServer.sInstance.GetGameObject(objectList[i], WorldId); if (obj == null) { continue; } var applyDamage = obj.OnExplode((int)GetPlayerId(), GetNetworkId(), GetDamage(ActionTokens[actionToken].SkillId, (GameObjectClassId)obj.GetClassId())); // add spell SActor actor = obj as SActor; if (actor != null && skillData != null) { //Log.Information($"ActionResult AddSpell {skillData.spellId}"); //actor.AddableSpell((int)GetPlayerId(), skillData.spellId); foreach (int nSpellID in skillData.spellId) { actor.AddableSpell(this, (int)GetPlayerId(), nSpellID, applyDamage); } } } actionInfo.hitIndex.Add((byte)hitProjectileIdx); if (skillData.projectileNum.Aggregate(1, (a, b) => a * b) <= actionInfo.hitIndex.Count) { //Log.Information($"ActionResult2 remove ({string.Join(",", objectList)}), {actionToken}, {hitProjectileIdx}, {string.Join(", ", actionInfo.hitIndex)}"); ActionTokens.Remove(actionToken); } }
public int TakeDamage(int inDamagingPlayerId, int damage = 1) { // 추락으로 데미지가 발생할 경우 무적 상태 예외 처리를 하지 않고 무조건 데미지를 준다. if (inDamagingPlayerId != (int)ReservedPlayerId.Fall) { if (StateServerSide != ActorState.Idle) { //Log.Information($"can't do damage in state {StateServerSide}"); return(0); } if (buff.IsExist(BuffType.Invincible)) { // 무적 상태. //Log.Information($"can't do damage in state Invincible "); return(0); } } // 게임 모드별로 데미지 적용 여부 if (inDamagingPlayerId >= 0) // 추락, 트랩등으로 데미지를 얻을 경우는 제외 { if (World.Instance(WorldId).GameMode.TakableDamage(inDamagingPlayerId, GetPlayerId()) == false) { return(0); } } SActor damagingPlayer = null; if (inDamagingPlayerId >= 0) // 추락, 트랩등으로 데미지를 얻을 경우는 제외 { damagingPlayer = (SActor)World.Instance(WorldId).GameMode.GetActor(inDamagingPlayerId); } int applyDamage = _TakeDamage(inDamagingPlayerId, damagingPlayer, damage); if (applyDamage != 0) { if (damagingPlayer != null) { var entry = World.Instance(WorldId).GameMode.GetEntry(inDamagingPlayerId); if (entry != null) { entry.Missions.Increment((int)MissionType.Mission_Damage, applyDamage); } } List <int> player_list = new List <int>(); player_list.Add(GetPlayerId()); if (damagingPlayer != null) { player_list.Add(damagingPlayer.GetPlayerId()); } LogHelper.LogInfo($"TakeDamage playerId:{GetPlayerId()}, hp:{-1 * applyDamage}"); InvokeClientRpc(NoticeHealth, player_list, -1 * applyDamage); } return(applyDamage); }
private int _TakeDamage(int inDamagingPlayerId, SActor damagingPlayer, int damage) { GameMode gameMode = World.Instance(WorldId).GameMode; var lastBuffHealth = buff.HP; // 버프로 받은 HP가 있는 경우 if (buff.HP > 0) { if (buff.HP >= damage) { // 버프 HP만 감소 buff.HP -= damage; return(damage); } else { // 버프 HP 0 및 actor HP 감소 damage -= buff.HP; buff.HP = 0; } } int applyDamage; var lastHealth = mHealth; mHealth -= damage; if (mHealth <= 0) { if (mHealth < 0) { mHealth = 0; } // die 함수에서 mHealth 값을 수정하여 미리 적용 데미지를 구해놓는다. applyDamage = lastHealth - mHealth + lastBuffHealth; //score one for damaging player... //World.Instance(WorldId).GameMode.IncScore(inDamagingPlayerId, 1); //and you want to die //SetDoesWantToDie(true); TryDie(SpawnPoint, inDamagingPlayerId); // 리스폰 //PlayerController PlayerController = NetworkManagerServer.sInstance.GetPlayerController((int)GetPlayerId()); //if (PlayerController != null) //{ // PlayerController.HandleActorDied(); //} bool isKing = gameMode.game_mode.GetMode() == GameModeType.KillTheKing && (gameMode.game_mode as KillTheKing).IsKing(GetPlayerId()); bool isKingKiller = false; if (damagingPlayer != null) { isKingKiller = gameMode.game_mode.GetMode() == GameModeType.KillTheKing && (gameMode.game_mode as KillTheKing).IsKing(damagingPlayer.GetPlayerId()); PlayPointID pointId = isKing ? PlayPointID.KillTheKing : PlayPointID.EnemyKill; gameMode.OnTrigger(damagingPlayer.GetPlayerId(), pointId); //Log.Information($"give point for player({damagingPlayer.UserId}), pointId : {pointId}"); var entry = World.Instance(WorldId).GameMode.GetEntry(inDamagingPlayerId); if (entry != null) { entry.Missions.Increment((int)MissionType.Mission_KillCount, 1); } ++World.Instance(WorldId).GameMode.statistics.attacked_death; } else if (inDamagingPlayerId == (int)ReservedPlayerId.Fall) { ++World.Instance(WorldId).GameMode.statistics.fall_death; } else if (inDamagingPlayerId == (int)ReservedPlayerId.Train) { ++World.Instance(WorldId).GameMode.statistics.train_death; } else { ++World.Instance(WorldId).GameMode.statistics.other_death; } gameMode.OnTrigger(GetPlayerId(), PlayPointID.PlayerDeath); var player_list = World.Instance(WorldId).playerList.Keys.ToList(); //Log.Information($"NoticeKillDeath {inDamagingPlayerId}, {GetPlayerId()}, players{string.Join(", ", player_list)}"); InvokeClientRpc(NoticeKillDeath, player_list, inDamagingPlayerId, GetPlayerId(), isKingKiller, isKing); } else { applyDamage = lastHealth - mHealth + lastBuffHealth; var player = (SActor)World.Instance(WorldId).GameMode.GetActor(inDamagingPlayerId); if (player != null) { World.Instance(WorldId).GameMode.OnTrigger(player.GetPlayerId(), PlayPointID.EnemyAttack); } } if (lastHealth != mHealth) { NetworkManagerServer.sInstance.SetStateDirty(GetNetworkId(), WorldId, (uint)ReplicationState.Health); } return(applyDamage); }
public void AddableSpell(SActor attackPlayer, int attackPlayerId, int spellID, int applyDamage) { var data = ACDC.SpellData[spellID]; AddableSpell(attackPlayer, attackPlayerId, data, applyDamage); }
public int HandleNewClient() { int playerId = this.GetPlayerId(); byte worldId = this.GetWorldId(); if (World.Instance(worldId).playerList.ContainsKey(playerId)) { Log.Information($"already exist player {playerId}"); return(0); } if (World.Instance(worldId).playerList.Count(x => ((SActor)x.Value).GetSessionId() == this.mSessionId) > 0) { Log.Information($"already exist player {playerId}, {this.mSessionId}"); return(0); } SActor actor = null; if (EnableAiSwitch) { // 다른 플레이어가 AI로 제어중이라면 제어권을 다시 가져온다. actor = RestoreAI(); } if (actor == null) { foreach (var entity in World.Instance(worldId).GameMode.GetEntries()) { if (entity.GetPlayerId() == playerId) { actor = (SActor)NetworkManagerServer.sInstance.GetGameObject(entity.mNetworkId, worldId); Log.Information($"found reserved actor player id : {playerId}, session id : {this.mSessionId}, network id : {entity.mNetworkId}"); Possess(actor); break; } } } // AI 컨트롤러가 없었다면 새로운 객체 할당 if (actor == null) { actor = SpawnActor(playerId, worldId, this.mTeam, this.mSpawnIndex); Possess(actor); //if (Possess(actor) == false) //{ // NetworkManagerServer.sInstance.UnregisterGameObject(actor); // NetworkManagerServer.sInstance.CancelGameObject(actor); // World.Instance(worldId).RemoveGameObject(actor); // Log.Information($"SpawnActor error player_id{playerId}, network_id{actor.NetworkId}, world{worldId}, pos{actor.GetLocation()}"); // World.Instance(worldId).GameMode.LeaveEntry(playerId); // Log.Information($"HandleNewClient error {playerId}, {this.mSessionId}"); // return 0; //} } World.Instance(worldId).playerList.Add(playerId, actor); #if UNITY_EDITOR || UNITY_STANDALONE_WIN || UNITY_IOS || UNITY_ANDROID #else Cache.sInstance.AddUser(worldId); #endif this.IsStartedPlay = true; return(actor.GetNetworkId()); }
public void Update(SActor actor) { updateStateMachine.Invoke(actor); }