182 lines
5.8 KiB
C#
182 lines
5.8 KiB
C#
using Google.Protobuf;
|
|
using Google.Protobuf.WellKnownTypes;
|
|
|
|
|
|
using ServerCore;
|
|
using ServerBase;
|
|
using ServerCommon;
|
|
using ServerCommon.BusinessLogDomain;
|
|
using MetaAssets;
|
|
|
|
|
|
namespace GameServer;
|
|
|
|
public class PropGroup
|
|
{
|
|
public int PropGroupId { get; set; }
|
|
public DateTime LatestRespawnTime { get; set; }
|
|
public List<string> AnchorGuids { get; set; } = new();
|
|
|
|
}
|
|
|
|
internal class PropGroupManager
|
|
{
|
|
Dictionary<int, PropGroup> m_prop_groups = new();
|
|
|
|
public bool init(Map map)
|
|
{
|
|
foreach (var prop_group in m_prop_groups.Values)
|
|
{
|
|
if (!MetaData.Instance._PropGroupMetaTable.TryGetValue(prop_group.PropGroupId, out var prop_group_data))
|
|
{
|
|
Log.getLogger().error($"Failed to MetaData.TryGetValue() !!! : propGroupMetaId:{prop_group.PropGroupId}");
|
|
continue;
|
|
}
|
|
|
|
if (prop_group_data.prop_order_data.Count <= 0)
|
|
{
|
|
Log.getLogger().error($"PropGroupData.prop_order_data.Count <= 0 !!! : {prop_group.PropGroupId}");
|
|
continue;
|
|
}
|
|
|
|
// GroupProp 기본값 세팅
|
|
foreach (var anchor_guid in prop_group.AnchorGuids)
|
|
{
|
|
if (!map.getAnchors().TryGetValue(anchor_guid, out var anchor_info))
|
|
continue;
|
|
|
|
anchor_info.AnchorProp.TableId = prop_group_data.prop_order_data[0].prop_id;
|
|
}
|
|
|
|
int spawn_count = 0;
|
|
while (spawn_count < prop_group_data.max_spawn_quantity)
|
|
{
|
|
var spawn_prop_id = getSpawnPropId(prop_group_data);
|
|
|
|
var index = RandomHelper.next(0, prop_group.AnchorGuids.Count);
|
|
string activation_anchor_guid = prop_group.AnchorGuids[index];
|
|
|
|
if (false == map.getAnchors().TryGetValue(activation_anchor_guid, out var activation_anchor_info))
|
|
return false;
|
|
|
|
if (activation_anchor_info.PropState == PropState.Activation)
|
|
continue;
|
|
|
|
activation_anchor_info.AnchorProp.TableId = spawn_prop_id;
|
|
activation_anchor_info.PropState = PropState.Activation;
|
|
|
|
spawn_count++;
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
int getSpawnPropId(PropGroupData propGroupData)
|
|
{
|
|
int spawn_prop_id = -1;
|
|
int low_spawn_weight = 0;
|
|
int high_spawn_weight = 0;
|
|
var prop_spawn_weight = RandomHelper.next(0, propGroupData.max_prop_spawn_weight);
|
|
foreach (var prop_order in propGroupData.prop_order_data)
|
|
{
|
|
low_spawn_weight = high_spawn_weight;
|
|
high_spawn_weight += prop_order.prop_spawn_weight;
|
|
|
|
if (low_spawn_weight <= prop_spawn_weight && prop_spawn_weight < high_spawn_weight)
|
|
{
|
|
spawn_prop_id = prop_order.prop_id;
|
|
break;
|
|
}
|
|
}
|
|
|
|
return spawn_prop_id;
|
|
}
|
|
|
|
public bool addAnchor(AnchorInfo anchorInfo)
|
|
{
|
|
if (!MapHelper.isGroupProp(anchorInfo.AnchorGuid))
|
|
return false;
|
|
|
|
if (!MapDataTable.Instance.getAnchor(anchorInfo.AnchorGuid, out var anchor))
|
|
return false;
|
|
|
|
if (!m_prop_groups.TryGetValue(anchor.TableID, out var prop_group))
|
|
{
|
|
prop_group = new();
|
|
prop_group.PropGroupId = anchor.TableID;
|
|
|
|
if (!m_prop_groups.TryAdd(anchor.TableID, prop_group))
|
|
{
|
|
Log.getLogger().error($"Failed to PropGroup Add !!! : propGroupMetaId:{anchor.TableID}");
|
|
return false;
|
|
}
|
|
}
|
|
|
|
prop_group.AnchorGuids.Add(anchorInfo.AnchorGuid);
|
|
|
|
return true;
|
|
}
|
|
|
|
public void checkRespawnPropGroup(Map map)
|
|
{
|
|
foreach (var prop_group_id in m_prop_groups.Keys)
|
|
{
|
|
respawnPropGroup(map, prop_group_id);
|
|
}
|
|
}
|
|
|
|
bool respawnPropGroup(Map map, int propGroupId)
|
|
{
|
|
var err_msg = string.Empty;
|
|
|
|
if (!MetaData.Instance._PropGroupMetaTable.TryGetValue(propGroupId, out var prop_group_data))
|
|
{
|
|
err_msg = $"Failed to MetaData.TryGetValue() !!! : propGroupMetaId:{propGroupId}";
|
|
Log.getLogger().error(err_msg);
|
|
return false;
|
|
}
|
|
|
|
if (!m_prop_groups.TryGetValue(propGroupId, out var prop_group))
|
|
return false;
|
|
|
|
int activationAndRespawningCount = 0;
|
|
List<string> deactivateAnchorGuids = new();
|
|
foreach (var anchor_guid in prop_group.AnchorGuids)
|
|
{
|
|
if (false == map.getAnchors().TryGetValue(anchor_guid, out var anchor_info))
|
|
continue;
|
|
|
|
if (anchor_info.PropState == PropState.Activation || anchor_info.PropState == PropState.Respawning)
|
|
{
|
|
activationAndRespawningCount++;
|
|
continue;
|
|
}
|
|
|
|
deactivateAnchorGuids.Add((anchor_guid));
|
|
}
|
|
|
|
if (activationAndRespawningCount >= prop_group_data.max_spawn_quantity)
|
|
return false;
|
|
|
|
|
|
int respwan_prop_id = getSpawnPropId(prop_group_data);
|
|
|
|
var index = RandomHelper.next(0, deactivateAnchorGuids.Count);
|
|
string respwan_anchor_guid = deactivateAnchorGuids[index];
|
|
|
|
if (false == map.getAnchors().TryGetValue(respwan_anchor_guid, out var respwan_anchor_info))
|
|
return false;
|
|
|
|
var respwan_time = prop_group.LatestRespawnTime > DateTime.UtcNow ? prop_group.LatestRespawnTime : DateTime.UtcNow;
|
|
respwan_time = respwan_time.AddSeconds(prop_group_data.group_respawn_time);
|
|
prop_group.LatestRespawnTime = respwan_time;
|
|
|
|
respwan_anchor_info.AnchorProp.TableId = respwan_prop_id;
|
|
respwan_anchor_info.PropState = PropState.Respawning;
|
|
respwan_anchor_info.respawnTime = respwan_time.ToTimestamp();
|
|
|
|
return true;
|
|
}
|
|
}
|