mod名称为挑战任务。 这个mod的功能是在各个商人的对话框中追加一个挑战任务选项,点击该选项直接弹出任务接取界面(即这个选项相当于一个任务)。
挑战任务设定:
1.挑战任务等级高于玩家目前任务等级,挑战任务等级限制为 玩家当前任务等级+1 ~ 玩家当前任务等级+1+地形加成。其中地形加成为绿地+4,火烧地+3,沙漠+2,雪地+1,废墟+0(这个设定的意义是难度低的地区可以挑战更高级的建筑)
2.挑战任务内容是随机的(随机任务+随机挑战等级)
3.挑战任务上限不超过游戏设定任务上限(如果可以动态获取任务上限则使用动态上限,否则使用配置文件并设定上限为6)
4.玩家达到最大任务等级后,不再出现挑战任务
5.挑战任务默认每日只有一个。(提供xml配置可修改上限)
6.挑战任务奖励为该任务奖励+跨级奖励公爵币。其中跨级公爵币的计算如下:
首先基础设定跨级基础奖励(下面是默认设置,提供xml配置文件方便自定义)为1级任务500公爵币,2级1000,3级1500,4级2000,5级2500,六级3000。
然后,每跨一级公爵币数*2(可配置倍率)
例如当前玩家任务等级为2,完成等级4任务,则额外给予500*2*2=2000公爵币
萌新尝试通过ai辅助写了cs代码,但编译dll后进入游戏没有任何效果……
ChallengeTask.cs
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Xml;
using HarmonyLib;
using UnityEngine;
// 入口类,负责注入 Harmony Patch
public class ChallengeQuestModEntry : IModApi
{
public void InitMod(Mod modInstance)
{
Debug.Log(“[ChallengeQuestMod] Initializing mod and applying Harmony patches…”);
Harmony harmony = new Harmony(“com.example.challengequestmod”);
harmony.PatchAll(Assembly.GetExecutingAssembly());
// 初始化配置文件
ChallengeQuestMod.Init(modInstance);
}
}
// 核心逻辑类
public static class ChallengeQuestMod
{
public static ChallengeQuestModConfig Config = new ChallengeQuestModConfig();
public static Dictionary<int, ChallengeQuestData> PlayerQuestMap = new Dictionary<int, ChallengeQuestData>();
public class ChallengeQuestData
{
public string QuestId;
public int DayGiven;
}
public static void Init(Mod mod)
{
string configPath = $”{mod.Path}/ChallengeQuestConfig.xml”;
Config.Load(configPath);
Debug.Log(“[ChallengeQuestMod] Config loaded from ” + configPath);
}
public static void GiveChallengeQuest(EntityPlayer player, EntityTrader trader)
{
if (!(player is EntityPlayerLocal localPlayer) || trader == null) return;
int baseTier = localPlayer.QuestJournal.GetCurrentFactionTier(trader.NPCInfo.QuestFaction, 0, false);
if (baseTier <= 0) return;
int maxTier = Config.MaxTier;
if (baseTier >= maxTier) return;
int terrainBonus = GetTerrainBonus(localPlayer);
int targetTier = Math.Min(baseTier + 1 + terrainBonus, maxTier);
if (!trader.questDictionary.TryGetValue(targetTier, out List<QuestEntry> quests) || quests.Count == 0)
return;
QuestEntry entry = quests[UnityEngine.Random.Range(0, quests.Count)];
Quest quest = entry.QuestClass.CreateQuest();
quest.QuestGiverID = trader.entityId;
quest.QuestFaction = trader.NPCInfo.QuestFaction;
quest.SetPositionData(Quest.PositionDataTypes.QuestGiver, trader.position);
quest.SetPositionData(Quest.PositionDataTypes.TraderPosition, trader.traderArea?.Position ?? trader.position);
localPlayer.QuestJournal.AddQuest(quest, true);
int baseReward = Config.GetBaseReward(targetTier);
int tierGap = targetTier – baseTier;
int bonusReward = (int)(Config.CrossTierMultiplier * Config.GetBaseReward(baseTier) * tierGap);
int totalReward = baseReward + bonusReward;
ItemStack rewardStack = new ItemStack(ItemClass.GetItem(“casinoCoin”), totalReward);
localPlayer.bag.AddItem(rewardStack);
ulong worldTime = GameManager.Instance.World.GetWorldTime();
PlayerQuestMap[localPlayer.entityId] = new ChallengeQuestData
{
QuestId = quest.ID,
DayGiven = (int)(worldTime / 24000UL)
};
GameManager.ShowTooltip(localPlayer, $”§eAccepted Challenge Quest: {quest.ID}\n+{totalReward} Dukes§r”);
Debug.Log($”[ChallengeQuestMod] Player {localPlayer.entityId} accepted challenge quest {quest.ID} (Tier {targetTier}, +{totalReward} Dukes)”);
}
private static int GetTerrainBonus(EntityPlayerLocal player)
{
Vector3i pos = World.worldToBlockPos(player.GetPosition());
BiomeDefinition biomeDef = GameManager.Instance.World.GetBiome(pos.x, pos.z);
if (biomeDef == null) return 0;
switch (biomeDef.m_BiomeType)
{
case BiomeDefinition.BiomeType.PineForest: return 4;
case BiomeDefinition.BiomeType.burnt_forest: return 3;
case BiomeDefinition.BiomeType.Desert: return 2;
case BiomeDefinition.BiomeType.Snow: return 1;
case BiomeDefinition.BiomeType.Wasteland: return 0;
default: return 0;
}
}
}
// 配置读取类
public class ChallengeQuestModConfig
{
public Dictionary<int, int> BaseDukeRewardPerTier = new Dictionary<int, int>();
public float CrossTierMultiplier = 2f;
public int MaxTier = 6;
public void Load(string path)
{
XmlDocument doc = new XmlDocument();
doc.Load(path);
XmlNode root = doc.DocumentElement;
XmlNode maxTierNode = root.SelectSingleNode(“MaxTier”);
if (maxTierNode != null)
MaxTier = int.Parse(maxTierNode.InnerText);
XmlNode multNode = root.SelectSingleNode(“CrossTierMultiplier”);
if (multNode != null)
CrossTierMultiplier = float.Parse(multNode.InnerText);
foreach (XmlNode node in root.SelectNodes(“Tier”))
{
int level = int.Parse(node.Attributes[“Level”].Value);
int reward = int.Parse(node.Attributes[“Reward”].Value);
BaseDukeRewardPerTier[level] = reward;
}
Debug.Log($”[ChallengeQuestMod] Loaded rewards for {BaseDukeRewardPerTier.Count} tiers.”);
}
public int GetBaseReward(int tier)
{
return BaseDukeRewardPerTier.ContainsKey(tier) ? BaseDukeRewardPerTier[tier] : 0;
}
}
// 给 trader UI 的任务按钮添加逻辑
[HarmonyPatch(typeof(XUiC_TraderWindow), “Init”)]
public class ChallengeQuestTraderButtonPatch
{
static void Postfix(XUiC_TraderWindow __instance)
{
var questBtn = __instance.GetChildById(“btn_quest”)?.Parent?.GetChildById(“btn_quest”);
if (questBtn != null)
{
questBtn.OnPress += new XUiEvent_OnPressEventHandler((XUiController sender, int playerId) =>
{
EntityPlayerLocal player = __instance.xui.playerUI.entityPlayer as EntityPlayerLocal;
EntityTrader trader = __instance.xui.Dialog.Respondent as EntityTrader;
ChallengeQuestMod.GiveChallengeQuest(player, trader);
});
Debug.Log(“[ChallengeQuestMod] Hooked into trader quest button.”);
}
else
{
Debug.Log(“[ChallengeQuestMod] Quest button not found in trader window.”);
}
}
}
ChallengeQuestConfig.xml:
<?xml version=”1.0″ encoding=”UTF-8″?>
<ChallengeQuestConfig>
<!– 最大任务等级(不能超过商人任务等级上限) –>
<MaxTier>6</MaxTier>
<!– 跨级任务的奖励倍率:比基础奖励高 CrossTierMultiplier 倍 –>
<CrossTierMultiplier>2.0</CrossTierMultiplier>
<!– 各个任务等级的基础奖励(单位:公爵币) –>
<Tier Level=”1″ Reward=”2000″ />
<Tier Level=”2″ Reward=”4000″ />
<Tier Level=”3″ Reward=”6000″ />
<Tier Level=”4″ Reward=”9000″ />
<Tier Level=”5″ Reward=”12000″ />
<Tier Level=”6″ Reward=”15000″ />
</ChallengeQuestConfig>
这么复杂的东西你还想AI给你写出来
定制加Q417983415
1111111111111