遗迹挖掘开发

This commit is contained in:
daixiawu 2026-06-11 19:45:03 +08:00
parent cfc7189b15
commit c7557171b9
9 changed files with 24561 additions and 7532 deletions

View File

@ -1,5 +1,5 @@
{
"nextId": 333,
"nextId": 334,
"bugs": [
{
"id": 2,
@ -3365,6 +3365,17 @@
"longTerm": false,
"createdAt": 1781146760266,
"updatedAt": 1781146760266
},
{
"id": 333,
"title": "联机房间套用的是 单机的或者上次地图配置 而非开房时所选席位,这是否会导致联机席位与实际数量不符",
"description": "",
"status": "open",
"priority": "medium",
"module": "",
"longTerm": false,
"createdAt": 1781178145290,
"updatedAt": 1781178145290
}
]
}

View File

@ -174,14 +174,17 @@ namespace RuntimeData
public ActionOptionGroup(ActionOptionGroup copyData) : this(copyData.GroupId, copyData.SourceGridId, copyData.SourceUnitId)
{
if (copyData.ActionOptionList == null) return;
foreach (var option in copyData.ActionOptionList)
{
if (option == null) continue;
ActionOptionList.Add(new ActionOption(option));
}
}
public bool TryGetOption(PlayerActionType playerActionType, out ActionOption option)
{
ActionOptionList ??= new List<ActionOption>();
foreach (var actionOption in ActionOptionList)
{
if (actionOption?.ActionId?.PlayerActionType != playerActionType) continue;
@ -443,6 +446,9 @@ namespace RuntimeData
// 是否投降
public bool IsSurrender;
// 遗迹待选择奖励组。GroupId 使用来源遗迹 GridId选择完成后移除。
[MemoryPackIgnore]
public List<ActionOptionGroup> TreasureActionOptionGroupList;
// 玩家是否存活要用这条来判断
public bool IsSurvival => !IsSurrender && Alive;
@ -471,6 +477,7 @@ namespace RuntimeData
PlayerNamerData = new PlayerNamerData();
MomentData = new MomentData();
PlayerCultureInfo = new PlayerCultureInfo();
TreasureActionOptionGroupList = new List<ActionOptionGroup>();
}
// 带 ID 初始化
@ -493,6 +500,7 @@ namespace RuntimeData
MomentData = new MomentData();
MomentData.InitItems();
PlayerCultureInfo = new PlayerCultureInfo();
TreasureActionOptionGroupList = new List<ActionOptionGroup>();
MeetPlayers = new List<uint>();
MeetPlayers.Add(Id);
InitData(civId,forceId);
@ -519,6 +527,15 @@ namespace RuntimeData
PlayerNamerData = new PlayerNamerData(copyData.PlayerNamerData);
MomentData = new MomentData(copyData.MomentData);
PlayerCultureInfo = new PlayerCultureInfo(copyData.PlayerCultureInfo);
TreasureActionOptionGroupList = new List<ActionOptionGroup>();
if (copyData.TreasureActionOptionGroupList != null)
{
foreach (var optionGroup in copyData.TreasureActionOptionGroupList)
{
if (optionGroup == null) continue;
TreasureActionOptionGroupList.Add(new ActionOptionGroup(optionGroup));
}
}
CurAttackPlayers = new List<uint>();
foreach (var id in copyData.CurAttackPlayers) CurAttackPlayers.Add(id);
@ -561,6 +578,16 @@ namespace RuntimeData
PlayerNamerData.DeepCopy(copyData.PlayerNamerData);
MomentData.DeepCopy(copyData.MomentData);
PlayerCultureInfo.DeepCopy(copyData.PlayerCultureInfo);
TreasureActionOptionGroupList ??= new List<ActionOptionGroup>();
TreasureActionOptionGroupList.Clear();
if (copyData.TreasureActionOptionGroupList != null)
{
foreach (var optionGroup in copyData.TreasureActionOptionGroupList)
{
if (optionGroup == null) continue;
TreasureActionOptionGroupList.Add(new ActionOptionGroup(optionGroup));
}
}
CurAttackPlayers.Clear();
foreach (var id in copyData.CurAttackPlayers) CurAttackPlayers.Add(id);
@ -580,6 +607,34 @@ namespace RuntimeData
giantPenalty[i] = copyData.giantPenalty[i];
}
}
public void AddTreasureActionOptionGroup(ActionOptionGroup group)
{
if (group == null) return;
TreasureActionOptionGroupList ??= new List<ActionOptionGroup>();
TreasureActionOptionGroupList.RemoveAll(t => t == null || t.GroupId == group.GroupId);
TreasureActionOptionGroupList.Add(group);
}
public bool TryGetTreasureActionOptionGroup(uint groupId, out ActionOptionGroup group)
{
TreasureActionOptionGroupList ??= new List<ActionOptionGroup>();
foreach (var optionGroup in TreasureActionOptionGroupList)
{
if (optionGroup == null || optionGroup.GroupId != groupId) continue;
group = optionGroup;
return true;
}
group = null;
return false;
}
public bool RemoveTreasureActionOptionGroup(uint groupId)
{
TreasureActionOptionGroupList ??= new List<ActionOptionGroup>();
return TreasureActionOptionGroupList.RemoveAll(t => t == null || t.GroupId == groupId) > 0;
}
private void InitData(uint civId,uint forceId)
{

View File

@ -442,9 +442,17 @@ namespace Logic.Action
{
CommonActionId commonActionId;
//填加外交行为
foreach (PlayerActionType playerActionType in System.Enum.GetValues(typeof(PlayerActionType)))
var diplomacyActionTypes = new[]
{
PlayerActionType.OfferAlly,
PlayerActionType.AcceptAlly,
PlayerActionType.RefuseAlly,
PlayerActionType.BreakAlly,
PlayerActionType.Embassy,
PlayerActionType.BreakEmbassy,
};
foreach (var playerActionType in diplomacyActionTypes)
{
if (playerActionType == PlayerActionType.None) continue;
commonActionId = new CommonActionId
{
ActionType = CommonActionType.PlayerAction,
@ -452,6 +460,19 @@ namespace Logic.Action
};
ActionLogicDict[commonActionId] = new PlayerActionDiplomacy(commonActionId);
}
commonActionId = new CommonActionId
{
ActionType = CommonActionType.PlayerAction,
PlayerActionType = PlayerActionType.SelectTreasureOptionA,
};
ActionLogicDict[commonActionId] = new PlayerActionSelectTreasureOption(commonActionId);
commonActionId = new CommonActionId
{
ActionType = CommonActionType.PlayerAction,
PlayerActionType = PlayerActionType.SelectTreasureOptionB,
};
ActionLogicDict[commonActionId] = new PlayerActionSelectTreasureOption(commonActionId);
//填加英雄相关行为
foreach (GiantType giantType in System.Enum.GetValues(typeof(GiantType)))
{
@ -527,16 +548,6 @@ namespace Logic.Action
ActionLogicDict[commonActionId] = new AIParamControlAction(commonActionId);
}
for (int i = (int)PlayerActionType.OfferAlly; i < (int)PlayerActionType.Max; i++)
{
commonActionId = new CommonActionId
{
ActionType = CommonActionType.PlayerAction,
PlayerActionType = (PlayerActionType)i,
};
ActionLogicDict[commonActionId] = new PlayerActionDiplomacy(commonActionId);
}
foreach (ResourceType resourceType in System.Enum.GetValues(typeof(ResourceType)))
{
if (resourceType == ResourceType.None) continue;

View File

@ -12,6 +12,7 @@ using System.Collections.Generic;
using System.Linq;
using Logic;
using Logic.Action;
using Logic.Skill;
using RuntimeData;
using TH1_Core.Events;
using TH1_Core.Managers;
@ -36,6 +37,8 @@ namespace TH1_Logic.Action
SelectHero,
FinishHeroTask,
BreakEmbassy,
SelectTreasureOptionA,
SelectTreasureOptionB,
Max
}
@ -552,6 +555,103 @@ namespace TH1_Logic.Action
return true;
}
}
public class PlayerActionSelectTreasureOption : PlayerActionAction
{
public PlayerActionSelectTreasureOption(CommonActionId id) : base(id) { }
protected override bool Execute(CommonActionParams actionParams)
{
if (!CheckCan(actionParams)) return false;
var player = actionParams.PlayerData;
var groupId = actionParams.GridId;
if (!player.TryGetTreasureActionOptionGroup(groupId, out var group)) return false;
if (!group.TryGetOption(_actionId.PlayerActionType, out var option)) return false;
var ret = ExecuteTreasureReward(actionParams, group, option);
if (!ret) return false;
player.RemoveTreasureActionOptionGroup(groupId);
return true;
}
public override bool CheckCan(CommonActionParams actionParams)
{
if (!PlayerActionCheckBaseInfo(actionParams)) return false;
if (actionParams.MainObjectType != MainObjectType.Player) return false;
if (_actionId.PlayerActionType != PlayerActionType.SelectTreasureOptionA &&
_actionId.PlayerActionType != PlayerActionType.SelectTreasureOptionB) return false;
if (actionParams.GridId == 0) return false;
if (!actionParams.PlayerData.TryGetTreasureActionOptionGroup(actionParams.GridId, out var group)) return false;
return group.TryGetOption(_actionId.PlayerActionType, out _);
}
public override bool CheckShow(CommonActionParams actionParams, out ShowType showType)
{
showType = ShowType.None;
return CheckCan(actionParams);
}
private bool ExecuteTreasureReward(CommonActionParams actionParams, ActionOptionGroup group, ActionOption option)
{
if (!actionParams.MapData.GridMap.GetGridDataByGid(group.SourceGridId, out var sourceGrid)) return false;
var player = actionParams.PlayerData;
if (option.RewardType == TreasureActionRewardType.Coin)
{
player.AddCoin(option.Value, Table.Instance.GridToWorld(sourceGrid));
return true;
}
if (option.RewardType == TreasureActionRewardType.Unit)
{
if (!actionParams.MapData.GetCapitalCityDataByPlayerId(player.Id, out var capital)) return false;
if (actionParams.MapData.UnitMap.GetUnitDataByUnitId(group.SourceUnitId, out var sourceUnit) &&
actionParams.MapData.GetGridDataByUnitId(sourceUnit.Id, out var sourceUnitGrid) &&
sourceUnitGrid.Id == sourceGrid.Id)
Main.UnitLogic.PassiveMoveAway(actionParams.MapData, sourceUnit);
if (!actionParams.MapData.AddUnitData(sourceGrid.Id, capital.Id, option.UnitFullType, out var unit))
return false;
if (option.UnitFullType.UnitType == UnitType.RammerShip)
unit.AddSkill_Legacy(SkillType.OFFICER, actionParams.MapData, true, -1, false, -1, false, SpecialAddSkillType.Normal, 0);
unit.SetOfficer();
unit.Health = unit.GetMaxHealth();
unit.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
capital.SetCityRenderer(actionParams.MapData);
return true;
}
if (option.RewardType == TreasureActionRewardType.Tech)
{
if (option.TechType == TechType.None) return false;
Main.PlayerLogic.ResearchTech(actionParams.MapData, player, option.TechType, 0);
if (player.IsSelfPlayer())
EventManager.Publish(new ShowUINotifyCommon(){UINotifyCommonType = UINotifyCommonType.ExamineTech});
return true;
}
if (option.RewardType == TreasureActionRewardType.Culture)
{
player.AddCulturePoint(option.Value);
if (player.IsSelfPlayer())
EventManager.Publish(new ShowUINotifyCommon(){UINotifyCommonType = UINotifyCommonType.ExamineCulture});
return true;
}
if (option.RewardType == TreasureActionRewardType.CityExp)
{
if (!actionParams.MapData.GetCapitalCityDataByPlayerId(player.Id, out var capital)) return false;
Main.CityLogic.GridGiveCityExp_LogicView(actionParams.MapData, player, capital.Grid(actionParams.MapData), capital, option.Value);
if (player.IsSelfPlayer())
EventManager.Publish(new ShowUINotifyCommon(){UINotifyCommonType = UINotifyCommonType.ExamineCityExp});
return true;
}
return false;
}
}
//立即完成一个英雄的升级任务
//[actionId参数]只要一个giantType即可

View File

@ -18,6 +18,7 @@ using RuntimeData;
using Steamworks;
using TH1_Core.Events;
using TH1_Core.Managers;
using TH1_Logic.Action;
using TH1_Logic.Core;
using UnityEngine;
using TH1Renderer;
@ -308,7 +309,6 @@ namespace Logic.Action
}
gridData.Resource = ResourceType.None;
gridData.Renderer(actionParams.MapData)?.InstantUpdateGrid(true);
var value = actionParams.MapData.Net.GetRandom(actionParams.MapData).Next(0, 5);
//播放雾效
if (actionParams.MapData == Main.MapData && actionParams.MapData.PlayerMap.SelfPlayerId == playerData.Id)
{
@ -316,88 +316,10 @@ namespace Logic.Action
AudioManager.Instance.PlayAudio("SFX/UNIT_treasure");
}
if (value == 0)
{
actionParams.PlayerData.AddCoin(10,Table.Instance.GridToWorld(gridData));
}
//给一个单位
else if (value == 1)
{
Main.UnitLogic.PassiveMoveAway(actionParams.MapData, actionParams.UnitData);
if(!actionParams.MapData.GetCapitalCityDataByPlayerId(actionParams.PlayerData.Id, out var capital))
return false;
if (gridData.Terrain == TerrainType.Land)
{
if (actionParams.MapData.AddUnitData(gridData.Id, capital.Id,new UnitFullType(UnitType.Swordsman,GiantType.None,0) , out var unit))
{
unit.SetOfficer();
unit.Health = unit.GetMaxHealth();
unit.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
};
}
else
{
if (actionParams.MapData.AddUnitData(gridData.Id, capital.Id,
new UnitFullType(UnitType.RammerShip, GiantType.None, 0), out var unit))
{
unit.AddSkill_Legacy(SkillType.OFFICER,actionParams.MapData,true,-1,false,-1,false,SpecialAddSkillType.Normal,0);
unit.SetOfficer();
unit.Health = unit.GetMaxHealth();
unit.Renderer(actionParams.MapData)?.InstantUpdateUnit(true);
}
}
capital.SetCityRenderer(actionParams.MapData);
}
//随机赠送一个当前可学习科技
else if (value == 2)
{
if (Table.Instance.PlayerDataAssets.GetPlayerInfo(actionParams.PlayerData, out var playerInfo))
{
var canLearnTechList = new List<TechType>();
foreach (var techType in playerInfo.TechPool)
{
if (actionParams.PlayerData.TechTree.CheckIfTechCanLearn(techType))
canLearnTechList.Add(techType);
}
if (canLearnTechList.Count > 0)
{
var index = actionParams.MapData.Net.GetRandom(actionParams.MapData).Next(0, canLearnTechList.Count);
var techType = canLearnTechList[index];
Main.PlayerLogic.ResearchTech(actionParams.MapData, actionParams.PlayerData, techType, 0);
if (actionParams.PlayerData.IsSelfPlayer())
EventManager.Publish(new ShowUINotifyCommon(){UINotifyCommonType = UINotifyCommonType.ExamineTech});
}
else
{
actionParams.PlayerData.AddCoin(10,Table.Instance.GridToWorld(gridData));
}
}
else
{
actionParams.PlayerData.AddCoin(10,Table.Instance.GridToWorld(gridData));
}
}
//获得4点文化点
else if (value == 3)
{
actionParams.PlayerData.AddCulturePoint(4);
if (actionParams.PlayerData.IsSelfPlayer())
EventManager.Publish(new ShowUINotifyCommon(){UINotifyCommonType = UINotifyCommonType.ExamineCulture});
}
//给首都3点城市经验
else
{
if (!actionParams.MapData.GetCapitalCityDataByPlayerId(actionParams.PlayerData.Id, out var capital))
return false;
Main.CityLogic.GridGiveCityExp_LogicView(actionParams.MapData, actionParams.PlayerData, capital.Grid(actionParams.MapData), capital, 3);
if (actionParams.PlayerData.IsSelfPlayer())
EventManager.Publish(new ShowUINotifyCommon(){UINotifyCommonType = UINotifyCommonType.ExamineCityExp});
}
var optionGroup = new ActionOptionGroup(gridData.Id, gridData.Id, unitData.Id);
optionGroup.ActionOptionList.Add(CreateTreasureActionOption(actionParams, gridData, 0, PlayerActionType.SelectTreasureOptionA));
optionGroup.ActionOptionList.Add(CreateTreasureActionOption(actionParams, gridData, 1, PlayerActionType.SelectTreasureOptionB));
actionParams.PlayerData.AddTreasureActionOptionGroup(optionGroup);
ret = true;
//Step #4 Moment
if (actionParams.MapData == Main.MapData && actionParams.UnitData.Player(actionParams.MapData) ==
@ -422,6 +344,77 @@ namespace Logic.Action
return ret;
}
private ActionOption CreateTreasureActionOption(CommonActionParams actionParams, GridData sourceGrid, int optionIndex, PlayerActionType selectActionType)
{
var random = actionParams.MapData.Net.GetRandom(actionParams.MapData);
var rewardType = (TreasureActionRewardType)random.Next((int)TreasureActionRewardType.Coin, (int)TreasureActionRewardType.CityExp + 1);
var option = new ActionOption
{
OptionIndex = optionIndex,
ActionId = new CommonActionId
{
ActionType = CommonActionType.PlayerAction,
PlayerActionType = selectActionType,
},
Param = new CommonActionParams(actionParams.MapData, actionParams.PlayerData, mainObjectType: MainObjectType.Player)
{
GridId = sourceGrid.Id,
},
RewardType = rewardType,
};
if (rewardType == TreasureActionRewardType.Coin)
{
option.Value = 10;
}
else if (rewardType == TreasureActionRewardType.Unit)
{
option.UnitFullType = sourceGrid.Terrain == TerrainType.Land
? new UnitFullType(UnitType.Swordsman, GiantType.None, 0)
: new UnitFullType(UnitType.RammerShip, GiantType.None, 0);
}
else if (rewardType == TreasureActionRewardType.Tech)
{
if (TryGetRandomTreasureTech(actionParams, out var techType))
{
option.TechType = techType;
}
else
{
option.RewardType = TreasureActionRewardType.Coin;
option.Value = 10;
}
}
else if (rewardType == TreasureActionRewardType.Culture)
{
option.Value = 4;
}
else if (rewardType == TreasureActionRewardType.CityExp)
{
option.Value = 3;
}
return option;
}
private bool TryGetRandomTreasureTech(CommonActionParams actionParams, out TechType techType)
{
techType = TechType.None;
if (!Table.Instance.PlayerDataAssets.GetPlayerInfo(actionParams.PlayerData, out var playerInfo)) return false;
var canLearnTechList = new List<TechType>();
foreach (var candidate in playerInfo.TechPool)
{
if (actionParams.PlayerData.TechTree.CheckIfTechCanLearn(candidate))
canLearnTechList.Add(candidate);
}
if (canLearnTechList.Count <= 0) return false;
var index = actionParams.MapData.Net.GetRandom(actionParams.MapData).Next(0, canLearnTechList.Count);
techType = canLearnTechList[index];
return true;
}
public override bool CheckCan(CommonActionParams actionParams)
{

View File

@ -13,7 +13,7 @@ PlayerSettings:
useOnDemandResources: 0
accelerometerFrequency: 60
companyName: Remilia Command
productName: TOHOTOPIA
productName: TOHOTOPIA v0.7.3f
defaultCursor: {fileID: 0}
cursorHotspot: {x: 0, y: 0}
m_SplashScreenBackgroundColor: {r: 0.13725491, g: 0.12156863, b: 0.1254902, a: 1}

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff