将[模板_随机技能组]功能独立出来
This commit is contained in:
parent
7b6e27c422
commit
c084a36878
112
modules/mod_GhostScripts/src/mod-RandSpell/RandSpell.cpp
Normal file
112
modules/mod_GhostScripts/src/mod-RandSpell/RandSpell.cpp
Normal file
@ -0,0 +1,112 @@
|
||||
#include "random"
|
||||
#include <Utilities/Timer.h>
|
||||
#include "algorithm"
|
||||
#include "vector"
|
||||
#include "Creature.h"
|
||||
#include <DataLoader.h>
|
||||
#include <Logging/Log.h>
|
||||
#include "AllCreatureScript.h"
|
||||
|
||||
#include "RandSpell.h"
|
||||
#include <mod_CustomCreature/mod_CustomCreature.h>
|
||||
#include <mod_GhostScripts/src/mod_UnitMod/CreatureMod/CreatureMod.h>
|
||||
|
||||
void CustomRandSpellScript::Load()
|
||||
{
|
||||
uint32 oldMSTime = getMSTime();
|
||||
AIRandSpellMap.clear();
|
||||
|
||||
QueryResult result = WorldDatabase.Query(
|
||||
"SELECT 随机技能组ID,技能ID,释放下一技能最小延迟,释放下一技能最大延迟 FROM acore_custom._模板_随机技能组");
|
||||
|
||||
if (result)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = result->Fetch();
|
||||
AIRandSpellTemplate temp;
|
||||
temp.GroupId = fields[0].Get<uint32>();
|
||||
temp.SpellId = fields[1].Get<uint32>();
|
||||
temp.MinDelayTime = fields[2].Get<uint32>() * IN_MILLISECONDS;
|
||||
temp.MaxDelayTime = fields[3].Get<uint32>() * IN_MILLISECONDS;
|
||||
|
||||
if (temp.MaxDelayTime < temp.MinDelayTime)
|
||||
temp.MaxDelayTime = temp.MinDelayTime;
|
||||
|
||||
// 按GroupId分组存储
|
||||
AIRandSpellMap[temp.GroupId].push_back(temp);
|
||||
|
||||
} while (result->NextRow());
|
||||
|
||||
sLog->outMessage("server", LogLevel::LOG_LEVEL_INFO,
|
||||
">> 读取自定义功能数据表【_模板_随机技能组】,共{}个技能组,{}条技能数据,用时{}毫秒",
|
||||
AIRandSpellMap.size(),
|
||||
[this]() {
|
||||
uint32 total = 0;
|
||||
for (const auto& pair : AIRandSpellMap)
|
||||
total += pair.second.size();
|
||||
return total;
|
||||
}(),
|
||||
GetMSTimeDiffToNow(oldMSTime));
|
||||
}
|
||||
}
|
||||
|
||||
void CustomRandSpellScript::CastRandSpell(Creature* creature, uint32 diff)
|
||||
{
|
||||
if (!creature)
|
||||
return;
|
||||
|
||||
mod_CustomCreature* customCreature = mod_CustomCreature::GetForCreature(creature);
|
||||
if (!customCreature || customCreature->RandSpellGroupId == 0)
|
||||
return;
|
||||
|
||||
// 快速查找对应的技能组
|
||||
auto it = AIRandSpellMap.find(customCreature->RandSpellGroupId);
|
||||
if (it == AIRandSpellMap.end() || it->second.empty())
|
||||
return;
|
||||
|
||||
if (creature->IsInCombat())
|
||||
{
|
||||
customCreature->RandSpellTimer -= diff;
|
||||
|
||||
if (customCreature->RandSpellTimer < 0)
|
||||
{
|
||||
const std::vector<AIRandSpellTemplate>& spellGroup = it->second;
|
||||
|
||||
// 直接使用随机索引,避免创建临时vector和shuffle操作
|
||||
uint32 index = urand(0, spellGroup.size() - 1);
|
||||
const AIRandSpellTemplate& selectedSpell = spellGroup[index];
|
||||
|
||||
customCreature->RandSpellTimer = urand(selectedSpell.MinDelayTime, selectedSpell.MaxDelayTime);
|
||||
|
||||
if (Unit* victim = creature->GetVictim())
|
||||
creature->CastSpell(victim, selectedSpell.SpellId);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
customCreature->RandSpellTimer = 0;
|
||||
}
|
||||
}
|
||||
|
||||
class Mod_CustomAllCreatureRandSpellScript : public AllCreatureScript
|
||||
{
|
||||
public:
|
||||
Mod_CustomAllCreatureRandSpellScript() : AllCreatureScript("Mod_CustomAllCreatureRandSpellScript") {}
|
||||
|
||||
// 生物更新结束时调用
|
||||
virtual void OnAllCreatureUpdate(Creature* creature, uint32 diff) override
|
||||
{
|
||||
// 检查是否在"_属性调整_生物"表中且有随机技能组ID
|
||||
if (mod_CustomCreature* customCreature = mod_CustomCreature::GetForCreature(creature))
|
||||
{
|
||||
if (customCreature->RandSpellGroupId > 0)
|
||||
sCustomRandSpellScript->CastRandSpell(creature, diff);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
void AddSC_CustomRandSpellScript()
|
||||
{
|
||||
new Mod_CustomAllCreatureRandSpellScript();
|
||||
}
|
||||
30
modules/mod_GhostScripts/src/mod-RandSpell/RandSpell.h
Normal file
30
modules/mod_GhostScripts/src/mod-RandSpell/RandSpell.h
Normal file
@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
|
||||
struct AIRandSpellTemplate
|
||||
{
|
||||
uint32 GroupId;
|
||||
uint32 SpellId;
|
||||
uint32 MinDelayTime;
|
||||
uint32 MaxDelayTime;
|
||||
};
|
||||
|
||||
class CustomRandSpellScript
|
||||
{
|
||||
public:
|
||||
static CustomRandSpellScript* instance()
|
||||
{
|
||||
static CustomRandSpellScript instance;
|
||||
return &instance;
|
||||
}
|
||||
|
||||
void Load();
|
||||
void CastRandSpell(Creature* creature, uint32 diff);
|
||||
|
||||
private:
|
||||
// 使用unordered_map按GroupId分组存储,提高查找效率
|
||||
std::unordered_map<uint32, std::vector<AIRandSpellTemplate>> AIRandSpellMap;
|
||||
};
|
||||
|
||||
#define sCustomRandSpellScript CustomRandSpellScript::instance()
|
||||
@ -84,6 +84,7 @@
|
||||
#include <MountRestriction.h>
|
||||
#include <rune_system.h>
|
||||
#include <mod_ItemDisable_Enchantment.h>
|
||||
#include <mod_GhostScripts/src/mod-RandSpell/RandSpell.h>
|
||||
|
||||
using namespace Acore::ChatCommands;
|
||||
|
||||
@ -207,6 +208,7 @@ void DataLoader::LoadAll()
|
||||
sServerAnnounce->Load(); // __全服提示
|
||||
sCustomScript->LoadGobScripts(); // _自定义AI_物体
|
||||
sCustomScript->LoadCreautreScripts(); // _自定义AI_生物
|
||||
sCustomRandSpellScript->Load(); // _模板_随机技能组
|
||||
sCustomScript->LoadCircleData(); // _circle_script 代码已经注释了,好像没用?
|
||||
sDeadline->Load(); // _副本_限时模式
|
||||
sLeaderReward->Load(); // 团队领袖奖励系统 目前禁用状态
|
||||
|
||||
@ -54,7 +54,8 @@ void AddSC_Random_Enchant();
|
||||
void AddSC_RECRUIT();
|
||||
void AddSC_Reincarnation();
|
||||
void AddSC_ResetInsNPC();
|
||||
void AddSC_CustomCreatureScript();
|
||||
void AddSC_CustomCreatureScript(); // 自定义AI_生物
|
||||
void AddSC_CustomRandSpellScript(); // 随机技能组
|
||||
void AddSC_SpellScripts();
|
||||
void AddSC_SignIn();
|
||||
void AddSC_CUSTOM_SKILL();
|
||||
@ -169,7 +170,8 @@ void Addmod_GhostScriptsScripts(){
|
||||
AddSC_RECRUIT();
|
||||
AddSC_Reincarnation();
|
||||
AddSC_ResetInsNPC();
|
||||
AddSC_CustomCreatureScript();
|
||||
AddSC_CustomCreatureScript(); // 自定义AI_生物
|
||||
AddSC_CustomRandSpellScript(); // 随机技能组
|
||||
AddSC_SpellScripts();
|
||||
AddSC_SignIn();
|
||||
AddSC_CUSTOM_SKILL();
|
||||
|
||||
@ -16,7 +16,6 @@
|
||||
#include <WorldSessionMgr.h>
|
||||
|
||||
std::vector<CreatureScriptTemplate> CreatureScriptVec;
|
||||
std::vector<AIRandSpellTemplate> AIRandSpellVec;
|
||||
|
||||
|
||||
// 在文件开头添加这些辅助类用于延迟处理标志修改dsa
|
||||
@ -180,66 +179,8 @@ void CustomScript::LoadCreautreScripts()
|
||||
CreatureScriptVec.push_back(Temp);
|
||||
} while (ResultCreatureScrip->NextRow());
|
||||
sLog->outMessage("server", LogLevel::LOG_LEVEL_INFO, ">> 读取自定义功能数据表【_自定义AI_生物-----------】,共{}条数据读取加载,用时{}毫秒", CreatureScriptVec.size(), GetMSTimeDiffToNow(CreatureScriptVec_OldMSTime));
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
//for (uint32 i = 0; i < CreatureScriptVec.size(); i++)
|
||||
//{
|
||||
// uint32 entry = CreatureScriptVec[i].entry;
|
||||
|
||||
// // 使用const指针来接收数据
|
||||
// const CreatureTemplateContainer* creatureTemplateStore = sCustomObjectMgr->GetCreatureTemplatesStore();
|
||||
|
||||
// // 使用const迭代器,因为我们不能通过const指针修改数据
|
||||
// CreatureTemplateContainer::const_iterator itr = creatureTemplateStore->find(entry);
|
||||
|
||||
// //if (itr != creatureTemplateStore->end())
|
||||
// //{
|
||||
// // itr->second.AIName = "";
|
||||
// // itr->second.ScriptID = sObjectMgr->GetScriptId("CustomCreatureScript");
|
||||
// //}
|
||||
|
||||
// for (uint32 i = 0; i < CreatureScriptVec.size(); i++)
|
||||
// {
|
||||
// uint32 entry = CreatureScriptVec[i].entry;
|
||||
// sCustomObjectMgr->ModCreatureTemplate(entry, "CustomCreatureScript", sObjectMgr->GetScriptId("CustomCreatureScript"));
|
||||
|
||||
// }
|
||||
//}
|
||||
|
||||
// 移除原来的ModCreatureTemplate调用,改为动态检查
|
||||
/*for (const auto& script : CreatureScriptVec)
|
||||
{
|
||||
sCustomObjectMgr->ModCreatureTemplate(script.entry, "CustomCreatureScript", sObjectMgr->GetScriptId("CustomCreatureScript"));
|
||||
}*/
|
||||
|
||||
uint32 AIRandSpellVec_OldMSTime = getMSTime();
|
||||
AIRandSpellVec.clear();
|
||||
QueryResult ResultAIRandSpell = WorldDatabase.Query(
|
||||
// 0 1 2 3
|
||||
"SELECT 随机技能组ID,技能ID,释放下一技能最小延迟,释放下一技能最大延迟 FROM acore_custom._模板_随机技能组");
|
||||
if (ResultAIRandSpell)
|
||||
{
|
||||
do
|
||||
{
|
||||
Field* fields = ResultAIRandSpell->Fetch();
|
||||
AIRandSpellTemplate Temp;
|
||||
Temp.GroupId = fields[0].Get<uint32>();
|
||||
Temp.SpellId = fields[1].Get<uint32>();
|
||||
Temp.MinDelayTime = fields[2].Get<uint32>() * IN_MILLISECONDS;
|
||||
Temp.MaxDelayTime = fields[3].Get<uint32>() * IN_MILLISECONDS;
|
||||
|
||||
if (Temp.MaxDelayTime < Temp.MinDelayTime)
|
||||
Temp.MaxDelayTime = Temp.MinDelayTime;
|
||||
|
||||
AIRandSpellVec.push_back(Temp);
|
||||
} while (ResultAIRandSpell->NextRow());
|
||||
sLog->outMessage("server", LogLevel::LOG_LEVEL_INFO, ">> 读取自定义功能数据表【_模板_随机技能组---------】,共{}条数据读取加载,用时{}毫秒", AIRandSpellVec.size(), GetMSTimeDiffToNow(AIRandSpellVec_OldMSTime));
|
||||
}
|
||||
|
||||
// 在函数末尾添加:
|
||||
std::set<uint32> uniqueEntries;
|
||||
for (const auto& script : CreatureScriptVec)
|
||||
{
|
||||
@ -262,55 +203,6 @@ bool HasCustomAI(uint32 entry)
|
||||
return false;
|
||||
}
|
||||
|
||||
void CustomScript::CastRandSpell(Creature* creature, uint32 diff)
|
||||
{
|
||||
|
||||
if (!creature)
|
||||
return;
|
||||
|
||||
//std::unique_ptr<mod_CustomCreature> customCreature(new mod_CustomCreature(creature));
|
||||
|
||||
mod_CustomCreature* customCreature = mod_CustomCreature::GetForCreature(creature); // CreatureScripts.cpp 第251行附近
|
||||
// 添加空指针检查
|
||||
if (!customCreature)
|
||||
return;
|
||||
|
||||
if (customCreature->RandSpellGroupId == 0)
|
||||
return;
|
||||
|
||||
if (AIRandSpellVec.empty())
|
||||
return;
|
||||
|
||||
if (creature->IsInCombat())
|
||||
{
|
||||
customCreature->RandSpellTimer -= diff;
|
||||
|
||||
if (customCreature->RandSpellTimer < 0)
|
||||
{
|
||||
std::vector<AIRandSpellTemplate> v;
|
||||
|
||||
for (auto itr = AIRandSpellVec.begin(); itr != AIRandSpellVec.end(); itr++)
|
||||
if (itr->GroupId == customCreature->RandSpellGroupId)
|
||||
v.push_back(*itr);
|
||||
|
||||
if (!v.empty())
|
||||
{
|
||||
//std::random_shuffle(v.begin(), v.end());
|
||||
std::default_random_engine generator{ std::random_device{}() };
|
||||
std::shuffle(std::begin(v), std::end(v), generator);
|
||||
|
||||
customCreature->RandSpellTimer = urand(v[0].MinDelayTime, v[0].MaxDelayTime);
|
||||
if (creature->GetVictim())
|
||||
creature->CastSpell(creature->GetVictim(), v[0].SpellId);
|
||||
}
|
||||
else
|
||||
customCreature->RandSpellTimer = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
customCreature->RandSpellTimer = 0;
|
||||
}
|
||||
|
||||
enum EVENT_IDS
|
||||
{
|
||||
EVENT_CHECK_HEALTH = 1,
|
||||
@ -416,9 +308,6 @@ public:
|
||||
|
||||
void UpdateAI(uint32 diff)
|
||||
{
|
||||
// 添加随机技能处理
|
||||
sCustomScript->CastRandSpell(me, diff);
|
||||
|
||||
if (!UpdateVictim())
|
||||
return;
|
||||
|
||||
|
||||
@ -126,16 +126,6 @@ enum SpellModTypes
|
||||
SMT_STUN_BREAKABLE, //受到伤害可打断昏迷
|
||||
};
|
||||
|
||||
struct AIRandSpellTemplate
|
||||
{
|
||||
uint32 GroupId;
|
||||
uint32 SpellId;
|
||||
uint32 MinDelayTime;
|
||||
uint32 MaxDelayTime;
|
||||
};
|
||||
|
||||
extern std::vector<AIRandSpellTemplate> AIRandSpellVec;
|
||||
|
||||
class CustomScript
|
||||
{
|
||||
public:
|
||||
@ -157,9 +147,6 @@ public:
|
||||
void CastSpellToNearbyPlayers(Unit* caster, uint32 e_spellId, uint32 f_spellId, float range);
|
||||
void CastSpellToNearbyUnits(Unit* caster, uint32 e_spellId, uint32 f_spellId, float range);
|
||||
|
||||
|
||||
void CastRandSpell(Creature* creautre, uint32 diff);
|
||||
|
||||
void ReloadCreatureAI(uint32 entry); // 强制重新分配AI
|
||||
private:
|
||||
|
||||
|
||||
@ -522,7 +522,6 @@ public:
|
||||
virtual void OnAllCreatureUpdate(Creature* creature, uint32 diff) override
|
||||
{
|
||||
sCreatureMod->CreatureReset(creature, diff);//防止BOSS离开原位置过远
|
||||
sCustomScript->CastRandSpell(creature, diff);//额外技能
|
||||
}
|
||||
|
||||
//补丁用@尚美[模块] 20240316 当函数Respawn前调用
|
||||
|
||||
@ -49,6 +49,13 @@ public:
|
||||
// 快速查找函数
|
||||
CreautreModTemplate* FindTemplate(uint32 entry, uint32 challengeLv, uint32 diff);
|
||||
|
||||
// 简单高效的检查函数,检查"_属性调整_生物"表中是否存在该生物
|
||||
bool HasCreatureMod(uint32 entry)
|
||||
{
|
||||
auto entryIt = _modIndex.find(entry);
|
||||
return entryIt != _modIndex.end();
|
||||
}
|
||||
|
||||
private:
|
||||
CreatureModIndex _modIndex; // [Entry][ChallengeLv][Diff] -> Template*
|
||||
std::vector<CreautreModTemplate> _modTemplates; // 存储实际数据
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user