477 lines
20 KiB
C#
477 lines
20 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Linq;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Collections.Concurrent;
|
|
using System.Numerics;
|
|
|
|
|
|
using ServerCore;
|
|
using ServerBase;
|
|
using ServerCommon;
|
|
using ServerCommon.BusinessLogDomain;
|
|
using MetaAssets;
|
|
|
|
|
|
|
|
using SESSION_ID = System.Int32;
|
|
using WORLD_META_ID = System.UInt32;
|
|
using META_ID = System.UInt32;
|
|
using ENTITY_GUID = System.String;
|
|
using ACCOUNT_ID = System.String;
|
|
using OWNER_GUID = System.String;
|
|
using USER_GUID = System.String;
|
|
using CHARACTER_GUID = System.String;
|
|
using ITEM_GUID = System.String;
|
|
using NPC_UNIQUE_ID = System.String;
|
|
using UGC_NPC_META_GUID = System.String;
|
|
using FARMING_PROP_DOC_SK = System.String;
|
|
using ANCHOR_META_GUID = System.String;
|
|
using MASTER_GUID = System.String;
|
|
using GUARD_KEY = System.String;
|
|
|
|
|
|
|
|
namespace GameServer;
|
|
|
|
public class FarmingAction : EntityActionBase
|
|
{
|
|
private FarmingEffect? m_progress_farming_nullable = null;
|
|
|
|
|
|
public FarmingAction(EntityBase owner)
|
|
: base(owner)
|
|
{
|
|
}
|
|
|
|
public override async Task<Result> onInit()
|
|
{
|
|
await Task.CompletedTask;
|
|
|
|
var result = new Result();
|
|
|
|
return result;
|
|
}
|
|
|
|
public override void onClear()
|
|
{
|
|
return;
|
|
}
|
|
|
|
public async Task<Result> resetFarmingState(bool isApplyDb = true)
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var owner = getOwner();
|
|
var server_logic = GameServerApp.getServerLogic();
|
|
var db_client = server_logic.getDynamoDbClient();
|
|
|
|
if (owner is UgcNpc ugc_npc)
|
|
{
|
|
var ugc_npc_action = ugc_npc.getEntityAction<UgcNpcAction>();
|
|
NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {ugc_npc.toBasicString()}");
|
|
|
|
var ugc_npc_attribute = ugc_npc.getEntityAttribute<UgcNpcAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(ugc_npc_attribute, () => $"ugc_npc_attribute is null !!! - {ugc_npc.toBasicString()}");
|
|
|
|
if(EntityStateType.UsingByFarming == ugc_npc_attribute.State)
|
|
{
|
|
ugc_npc_action.resetPos(isApplyDb);
|
|
|
|
if(true == isApplyDb)
|
|
{
|
|
(result, var ugc_npc_doc) = await ugc_npc_attribute.toDocBase();
|
|
if (result.isFail())
|
|
{
|
|
return result;
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(ugc_npc_doc, () => $"ugc_npc_doc is null !!! - {ugc_npc.toBasicString()}");
|
|
|
|
result = await db_client.simpleUpdateDocumentWithDocType(ugc_npc_doc);
|
|
if (result.isFail())
|
|
{
|
|
err_msg = $"Failed to simpleUpdateDocumentWithDocType() !!! in resetFarmingState() : {result.toBasicString()} - {ugc_npc.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
|
|
return result;
|
|
}
|
|
|
|
var origin_entity_attribute = ugc_npc.getOriginEntityAttribute<UgcNpcAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(origin_entity_attribute, () => $"origin_entity_attribute is null !!! - {ugc_npc.toBasicString()}");
|
|
|
|
origin_entity_attribute.copyEntityAttributeFromDoc(ugc_npc_doc);
|
|
|
|
Log.getLogger().debug($"UgcNpc reset of State !!! in resetFarmingState() : {ugc_npc.toStateString()} - {ugc_npc.toBasicString()}");
|
|
}
|
|
}
|
|
}
|
|
|
|
return result;
|
|
}
|
|
|
|
public async Task<(Result, FarmingEffect?)> tryStartFarming( ANCHOR_META_GUID anchorMetaGuid, Int16 farmingActionTryCount )
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var owner = getOwner();
|
|
var game_zone_action = owner.getEntityAction<GameZoneAction>();
|
|
NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!!");
|
|
|
|
var curr_map = game_zone_action.getLinkedToMap();
|
|
if(null == curr_map)
|
|
{
|
|
// 현재 UgcNpc 타입만 해당되는 로직 이다.
|
|
// 추후 인던 관련 설계가 리펙토링되면 재정의된 Map 반환(Master가 입장한 Map 반환) 함수로 처리해야 한다. - kangms
|
|
(result, curr_map) = owner.getCurrMapOfMaster();
|
|
if(result.isFail())
|
|
{
|
|
return (result, null);
|
|
}
|
|
}
|
|
NullReferenceCheckHelper.throwIfNull(curr_map, () => $"curr_map is null !!!");
|
|
|
|
// 파밍중인 Anchor 인가?
|
|
var found_farming_effect = curr_map.findFarmingEffect(anchorMetaGuid);
|
|
if(null != found_farming_effect)
|
|
{
|
|
err_msg = $"Already farming !!! : anchorMetaGuid:{anchorMetaGuid} - {curr_map.toBasicString()}, {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.FarmingAlready, err_msg);
|
|
|
|
return (result, null);
|
|
}
|
|
|
|
// 파밍 객체를 생성 한다.
|
|
var farming_effect = new FarmingEffect( owner, curr_map);
|
|
result = await farming_effect.onInit();
|
|
if (result.isFail())
|
|
{
|
|
return (result, null);
|
|
}
|
|
|
|
var farming_effect_action = farming_effect.getEntityAction<FarmingEffectAction>();
|
|
NullReferenceCheckHelper.throwIfNull(farming_effect_action, () => $"farming_effect_action is null !!! - {owner.toBasicString()}");
|
|
|
|
// 파밍을 시도해 본다 !!!
|
|
result = await farming_effect_action.tryStartEffect( anchorMetaGuid, farmingActionTryCount );
|
|
if (result.isFail())
|
|
{
|
|
return (result, null);
|
|
}
|
|
|
|
if (owner is UgcNpc ugc_npc)
|
|
{
|
|
var ugc_npc_action = ugc_npc.getEntityAction<UgcNpcAction>();
|
|
NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {owner.toBasicString()}");
|
|
|
|
var curr_anchor_info = farming_effect_action.getAnchorInfo();
|
|
NullReferenceCheckHelper.throwIfNull(curr_anchor_info, () => $"curr_anchor_info is null !!! - {owner.toBasicString()}");
|
|
|
|
var farming_prop_meta_id = curr_anchor_info.AnchorProp.TableId;
|
|
if (false == MetaData.Instance._FarmingPropMetaTable.TryGetValue(farming_prop_meta_id, out var found_farming_prop_meta))
|
|
{
|
|
err_msg = $"Not found FarmingPropMeta in FarmingPropMetaTable !!! : FarmingPropMetaId:{farming_prop_meta_id} - {curr_map.toBasicString()}, {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.FarmingPropMetaDataNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, null);
|
|
}
|
|
|
|
if(false == MapHelper.getAnchor(curr_anchor_info.AnchorGuid, out var anchor))
|
|
{
|
|
err_msg = $"Not found FarmingAnchor in Map !!! : FarmingAnchorGuid:{curr_anchor_info.AnchorGuid} - {curr_map.toBasicString()}, {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.FarmingAnchorNotFound, err_msg);
|
|
Log.getLogger().error(result.toBasicString());
|
|
|
|
return (result, null);
|
|
}
|
|
|
|
var base_pos = new System.Numerics.Vector3(curr_anchor_info.AnchorPos.X, curr_anchor_info.AnchorPos.Y, curr_anchor_info.AnchorPos.Z);
|
|
var delta_pos = new System.Numerics.Vector3(found_farming_prop_meta.FarmingStartPosX, found_farming_prop_meta.FarmingStartPosY, found_farming_prop_meta.FarmingStartPosZ);
|
|
var target_position = ugc_npc_action.makeToLocatePosition( base_pos, anchor.Rotation.Pitch, anchor.Rotation.Yaw, anchor.Rotation.Roll
|
|
, delta_pos, found_farming_prop_meta.FarmingStartRotate );
|
|
|
|
ugc_npc_action.modifyStateInfo( EntityStateType.UsingByFarming
|
|
, target_position
|
|
, anchorMetaGuid
|
|
, (META_ID)farming_prop_meta_id
|
|
, true );
|
|
|
|
ugc_npc_action.setCountingAsConnectedUser(true);
|
|
result = await ugc_npc_action.tryLocateInGameZone(curr_map);
|
|
if (result.isFail())
|
|
{
|
|
return (result, null);
|
|
}
|
|
}
|
|
|
|
return (result, farming_effect);
|
|
}
|
|
|
|
public async Task completedFarmingStart( QueryExecutorBase queryExecutorBase
|
|
, Player player
|
|
, FarmingEffect farmingEffect
|
|
, DBQWriteToAttributeAllWithTransactionRunner transactionRunner )
|
|
{
|
|
var game_zone_action = player.getEntityAction<GameZoneAction>();
|
|
NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!!");
|
|
|
|
var curr_map = game_zone_action.getLinkedToMap();
|
|
NullReferenceCheckHelper.throwIfNull(curr_map, () => $"curr_map is null !!!");
|
|
|
|
var result = await curr_map.tryLocateFarming(farmingEffect);
|
|
if (result.isSuccess())
|
|
{
|
|
attachFarmingEffect(farmingEffect);
|
|
|
|
await transactionRunner.onMergeAfterQueryCommit();
|
|
}
|
|
|
|
var farming_effect_action = farmingEffect.getEntityAction<FarmingEffectAction>();
|
|
NullReferenceCheckHelper.throwIfNull(farming_effect_action, () => $"farming_effect_action is null !!! - {player.toBasicString()}");
|
|
|
|
var query_batch = queryExecutorBase.getQueryBatch();
|
|
NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!! - {player.toBasicString()}");
|
|
|
|
var log_action = query_batch.getLogAction();
|
|
NullReferenceCheckHelper.throwIfNull(log_action, () => $"log_action is null !!! - {player.toBasicString()}");
|
|
|
|
queryExecutorBase.appendBusinessLog(new FarmingBusinessLog(log_action, farming_effect_action.getFarmingLogInfo()));
|
|
|
|
if(farmingEffect.onGetOwnerEntityType() == OwnerEntityType.UgcNpc)
|
|
{
|
|
var ugc_npc = farmingEffect.getRootParent() as UgcNpc;
|
|
NullReferenceCheckHelper.throwIfNull(ugc_npc, () => $"ugc_npc is null !!! - {player.toBasicString()}");
|
|
|
|
var ugc_npc_action = ugc_npc.getEntityAction<UgcNpcAction>();
|
|
NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {player.toBasicString()}");
|
|
|
|
UgcNpcNotifyHelper.send_GS2C_NTF_BEACON_COMPACT_UPDATE(player, ugc_npc, ugc_npc_action.toUgcNpcCompact());
|
|
}
|
|
}
|
|
|
|
public async Task<(Result, FarmingEffect?, ReceivedMailDoc?)> tryCancelFarming( ANCHOR_META_GUID anchorMetaGuid )
|
|
{
|
|
var result = new Result();
|
|
var err_msg = string.Empty;
|
|
|
|
var owner = getOwner();
|
|
|
|
var game_zone_action = owner.getEntityAction<GameZoneAction>();
|
|
NullReferenceCheckHelper.throwIfNull(game_zone_action, () => $"game_zone_action is null !!!");
|
|
|
|
var curr_map = game_zone_action.getLinkedToMap();
|
|
NullReferenceCheckHelper.throwIfNull(curr_map, () => $"curr_map is null !!!");
|
|
|
|
// 파밍중인 Anchor 인가?
|
|
var found_farming_effect = curr_map.findFarmingEffect(anchorMetaGuid);
|
|
if (null == found_farming_effect)
|
|
{
|
|
err_msg = $"Not state farming !!! : anchorMetaGuid:{anchorMetaGuid} - {curr_map.toBasicString()}, {owner.toBasicString()}";
|
|
result.setFail(ServerErrorCode.FarmingNotState, err_msg);
|
|
|
|
return (result, null, null);
|
|
}
|
|
|
|
var farming_effect_action = found_farming_effect.getEntityAction<FarmingEffectAction>();
|
|
NullReferenceCheckHelper.throwIfNull(farming_effect_action, () => $"farming_effect_action is null !!! - {owner.toBasicString()}");
|
|
|
|
// 파밍을 취소를 시도 한다.
|
|
(result, var farming_effect, var to_receive_mail_doc_nullable) = await farming_effect_action.tryCancelFarming( anchorMetaGuid );
|
|
if (result.isFail())
|
|
{
|
|
return (result, null, null);
|
|
}
|
|
|
|
return (result, farming_effect, to_receive_mail_doc_nullable);
|
|
}
|
|
|
|
public async Task completedFarmingCancel( QueryExecutorBase queryExecutorBase
|
|
, Player player, Map currMap
|
|
, FarmingEffect farmingEffect, ReceivedMailDoc? receivedMailDoc
|
|
, DBQWriteToAttributeAllWithTransactionRunner transactionRunner )
|
|
{
|
|
var result = await currMap.tryRemoveFarming(farmingEffect);
|
|
if (result.isSuccess())
|
|
{
|
|
var parent = farmingEffect.getRootParent();
|
|
NullReferenceCheckHelper.throwIfNull(parent, () => $"parent is null !!! - {player.toBasicString()}");
|
|
|
|
var farming_action = parent.getEntityAction<FarmingAction>();
|
|
NullReferenceCheckHelper.throwIfNull(farming_action, () => $"farming_action is null !!! - {player.toBasicString()}");
|
|
|
|
farming_action.detachFarmingEffect(farmingEffect);
|
|
|
|
await transactionRunner.onMergeAfterQueryCommit();
|
|
}
|
|
|
|
var found_user_mail_action = player.getEntityAction<MailAction>();
|
|
NullReferenceCheckHelper.throwIfNull(found_user_mail_action, () => $"found_user_mail_action is null !!! - {player.toBasicString()}");
|
|
|
|
if (null != receivedMailDoc)
|
|
{
|
|
found_user_mail_action.NewReceivedMail();
|
|
}
|
|
|
|
var farming_effect_action = farmingEffect.getEntityAction<FarmingEffectAction>();
|
|
NullReferenceCheckHelper.throwIfNull(farming_effect_action, () => $"farming_effect_action is null !!! - {player.toBasicString()}");
|
|
|
|
var query_batch = queryExecutorBase.getQueryBatch();
|
|
NullReferenceCheckHelper.throwIfNull(query_batch, () => $"query_batch is null !!! - {player.toBasicString()}");
|
|
|
|
var log_action = query_batch.getLogAction();
|
|
NullReferenceCheckHelper.throwIfNull(log_action, () => $"log_action is null !!! - {player.toBasicString()}");
|
|
|
|
queryExecutorBase.appendBusinessLog(new FarmingBusinessLog(log_action, farming_effect_action.getFarmingLogInfo()));
|
|
queryExecutorBase.appendBusinessLog(new FarmingRewardBusinessLog(log_action, farming_effect_action.getFarmingRewardLogInfo()));
|
|
|
|
if (farmingEffect.onGetOwnerEntityType() == OwnerEntityType.UgcNpc)
|
|
{
|
|
var ugc_npc = farmingEffect.getRootParent() as UgcNpc;
|
|
NullReferenceCheckHelper.throwIfNull(ugc_npc, () => $"ugc_npc is null !!! - {player.toBasicString()}");
|
|
|
|
var ugc_npc_action = ugc_npc.getEntityAction<UgcNpcAction>();
|
|
NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {player.toBasicString()}");
|
|
|
|
UgcNpcNotifyHelper.send_GS2C_NTF_BEACON_COMPACT_UPDATE(player, ugc_npc, ugc_npc_action.toUgcNpcCompact());
|
|
}
|
|
}
|
|
|
|
public void attachFarmingEffect(FarmingEffect farmingEffect)
|
|
{
|
|
var owner = getOwner();
|
|
|
|
m_progress_farming_nullable = farmingEffect;
|
|
|
|
if(owner is Player player)
|
|
{
|
|
var player_action = player.getEntityAction<PlayerAction>();
|
|
NullReferenceCheckHelper.throwIfNull(player_action, () => $"player_action is null !!! - {owner.toBasicString()}");
|
|
|
|
var selected_character = player_action.getSelectedCharacter();
|
|
NullReferenceCheckHelper.throwIfNull(selected_character, () => $"selected_character is null !!! - {owner.toBasicString()}");
|
|
|
|
var character_action = selected_character.getEntityAction<CharacterAction>();
|
|
NullReferenceCheckHelper.throwIfNull(character_action, () => $"character_action is null !!! - {owner.toBasicString()}");
|
|
|
|
var farming_effect_attribute = farmingEffect.getEntityAttribute<FarmingEffectAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(farming_effect_attribute, () => $"farming_effect_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
character_action.setStateInfo(EntityStateType.UsingByFarming, farming_effect_attribute.AnchorMetaGuid, farming_effect_attribute.FarmingPropMetaId);
|
|
|
|
character_action.broadcastCharacterInfo();
|
|
}
|
|
}
|
|
|
|
public void detachFarmingEffect(FarmingEffect farmingEffect)
|
|
{
|
|
var owner = getOwner();
|
|
|
|
var to_detach_anchor_meta_guid = farmingEffect.getAnchorMetaGuid();
|
|
if (null == m_progress_farming_nullable)
|
|
{
|
|
var err_msg = $"m_progress_farming_nullable is null !!! : toDetachAnchorGuid:{to_detach_anchor_meta_guid} - {owner.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
return;
|
|
}
|
|
|
|
var curr_anchor_meta_guid = m_progress_farming_nullable.getAnchorMetaGuid();
|
|
if (curr_anchor_meta_guid != to_detach_anchor_meta_guid)
|
|
{
|
|
var err_msg = $"Not match AnchorMetaGuid of Farming !!! : currAnchorGuid:{curr_anchor_meta_guid} == toDetachAnchorGuid:{to_detach_anchor_meta_guid} - {owner.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
return;
|
|
}
|
|
|
|
if (owner is Player player)
|
|
{
|
|
var player_action = player.getEntityAction<PlayerAction>();
|
|
NullReferenceCheckHelper.throwIfNull(player_action, () => $"player_action is null !!! - {owner.toBasicString()}");
|
|
|
|
var selected_character = player_action.getSelectedCharacter();
|
|
NullReferenceCheckHelper.throwIfNull(selected_character, () => $"selected_character is null !!! - {owner.toBasicString()}");
|
|
|
|
var character_action = selected_character.getEntityAction<CharacterAction>();
|
|
NullReferenceCheckHelper.throwIfNull(character_action, () => $"character_action is null !!! - {owner.toBasicString()}");
|
|
|
|
character_action.setStateInfo(EntityStateType.None, string.Empty, 0);
|
|
|
|
character_action.broadcastCharacterInfo();
|
|
}
|
|
|
|
m_progress_farming_nullable = null;
|
|
}
|
|
|
|
public void detachFarmingEffectByAnchorMetaGuid(ANCHOR_META_GUID anchorMetaGuid)
|
|
{
|
|
var owner = getOwner();
|
|
|
|
var to_detach_anchor_meta_guid = anchorMetaGuid;
|
|
if (null == m_progress_farming_nullable)
|
|
{
|
|
var err_msg = $"m_progress_farming_nullable is null !!! : toDetachAnchorGuid:{to_detach_anchor_meta_guid} - {owner.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
return;
|
|
}
|
|
|
|
var curr_anchor_meta_guid = m_progress_farming_nullable.getAnchorMetaGuid();
|
|
if (curr_anchor_meta_guid != to_detach_anchor_meta_guid)
|
|
{
|
|
var err_msg = $"Not match AnchorMetaGuid of Farming !!! : currAnchorGuid:{curr_anchor_meta_guid} == toDetachAnchorGuid:{to_detach_anchor_meta_guid} - {owner.toBasicString()}";
|
|
Log.getLogger().error(err_msg);
|
|
return;
|
|
}
|
|
|
|
m_progress_farming_nullable = null;
|
|
}
|
|
|
|
public bool isFarmingHere()
|
|
{
|
|
return m_progress_farming_nullable != null;
|
|
}
|
|
|
|
public bool isFarmingState()
|
|
{
|
|
var owner = getOwner();
|
|
|
|
if (owner is Player player)
|
|
{
|
|
var player_action = player.getEntityAction<PlayerAction>();
|
|
NullReferenceCheckHelper.throwIfNull(player_action, () => $"player_action is null !!! - {owner.toBasicString()}");
|
|
|
|
var selected_character = player_action.getSelectedCharacter();
|
|
NullReferenceCheckHelper.throwIfNull(selected_character, () => $"selected_character is null !!! - {owner.toBasicString()}");
|
|
|
|
var character_action = selected_character.getEntityAction<CharacterAction>();
|
|
NullReferenceCheckHelper.throwIfNull(character_action, () => $"character_action is null !!! - {owner.toBasicString()}");
|
|
|
|
if(true == character_action.isFarming())
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
else if (owner is UgcNpc ugc_npc)
|
|
{
|
|
var ugc_npc_action = ugc_npc.getEntityAction<UgcNpcAction>();
|
|
NullReferenceCheckHelper.throwIfNull(ugc_npc_action, () => $"ugc_npc_action is null !!! - {owner.toBasicString()}");
|
|
|
|
var ugc_npc_attribute = ugc_npc.getEntityAttribute<UgcNpcAttribute>();
|
|
NullReferenceCheckHelper.throwIfNull(ugc_npc_attribute, () => $"ugc_npc_attribute is null !!! - {owner.toBasicString()}");
|
|
|
|
if (EntityStateType.UsingByFarming == ugc_npc_attribute.State)
|
|
{
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
public FarmingEffect? getFarmingEffect()
|
|
{
|
|
return m_progress_farming_nullable;
|
|
}
|
|
}
|