/// <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; }
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 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 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 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); } }
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 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); }