Просмотр полной версии : Произнесение фразы игроком
Есть спелл с эффектом SPELL_EFFECT_SCRIPT_EFFECT, которым является произнесение игроком одной из 3 фраз случайным образом.
Через `spell_scripts` сделать не получается, т.к. там указывается код текста явным образом.
Реализовал через СД2, скрипт навесил на итем, но столкнулся в очередной раз с проблемой, что скрипт СД2 отрабатывает, не дожидаясь окончания каста спелла.
В ядре есть функции для игрока:
void Player::Say(const std::string& text, const uint32 language)
void Player::Yell(const std::string& text, const uint32 language)
...
По идее, данные функции решили бы проблему, но от них пришлось отказаться сразу, т.к. текст будет без локализации.
В коде нашел пример использования одной из функций:
target = this;
if (roll_chance_i(10))
((Player*)this)->Say("This is Madness!", LANG_UNIVERSAL);
break;
В связи с этим возникли вопросы:
1. Можно ли в ядре как-нибудь заставить игрока произносить фразы, чтобы при этом можно было использовать локализацию, и при этом патч имел бы шансы на принятие (коды фраз в разных базах могут иметь различные значения)?
2. Зачем в коде явным образом указывать фразы, которые нельзя будет перевести ни на один язык (пример выше)?
1. Можно ли в ядре как-нибудь заставить игрока произносить фразы, чтобы при этом можно было использовать локализацию, и при этом патч имел бы шансы на принятие (коды фраз в разных базах могут иметь различные значения)?
2. Зачем в коде явным образом указывать фразы, которые нельзя будет перевести ни на один язык (пример выше)?
1. Можно. Код получается толстый и привязанный к базе, но вполне в мэйнстриме.
2. Обломки от старых захардкоженных хаков...
Я себе для такого дела в SD2 спец. функцию встроил, потому как работать с тем что есть сильно напряжно...
На СД2 я написал патч, текст берется из базы, как и во всех подобных случаях.
Получилось, что патч нужен только для произнесения одной из 3 фраз и состоит фактически из одной строки кода.
Не знаю, стоит ли из-за одной строки городить скрипт СД2 или лучше ее прописать в ядро.
Если бы можно было реализовать это в ядре, то все работало бы, как часы.
Допустим, что надо делать через СД2.
Произнесение фразы - это эффект от спелла.
Через скрипт на итем нет ожидания каста спелла, поэтому сначала игрок кричит фразу, а потом уже идет каст.
Как на СД2 сделать, чтобы код отрабатывал при касте спелла, как если бы код был написан в ядре в соответствующем обработчике?
Давно имхо уже пора удалить все Creature::Say/Yell/... и Player::Say/Yell/.. и использовать вместо этого Unit. Ведь разговор НПС от разговора игрока ничем не отличается, кроме обычно используемых типов. По наблюдениям с офа могу сказать, что в квестах, где игрок разговаривает, подчиняясь серверным командам, используются как стандартные плееровские CHAT_MSG_SAY, так и присущие кричерам CHAT_MSG_MONSTER_SAY.
Давно имхо уже пора удалить все Creature::Say/Yell/... и Player::Say/Yell/.. и использовать вместо этого Unit. Ведь разговор НПС от разговора игрока ничем не отличается, кроме обычно используемых типов. По наблюдениям с офа могу сказать, что в квестах, где игрок разговаривает, подчиняясь серверным командам, используются как стандартные плееровские CHAT_MSG_SAY, так и присущие кричерам CHAT_MSG_MONSTER_SAY.
Как реализовать выкрик случайной фразы в СД2 или ядре, чтобы не потерять локализацию (проблемы описаны постами выше)?
Насколько я помню, из SD2 доступен вызов sObjectMgr.GetMangosString(...), через него можно, я так думаю.
В СД2 есть функция произнесения фраз по кодам из `script_texts`, я ее и использую.
Только скрипт на итем отрабатывает при его использовании, а не при касте спелла итема.
Думми в СД2 реализованы через нпц и го, а в данном случае - скрипт-эффект.
Если только в `spell_scripts` добавить возможность указания гурппы текстов, из которых случайным образом выбирается один.
Нужно произносить фразу в момент каста спелла, а не использования итема.
В СД2 есть функция произнесения фраз по кодам из `script_texts`, я ее и использую.
Только скрипт на итем отрабатывает при его использовании, а не при касте спелла итема.
Думми в СД2 реализованы через нпц и го, а в данном случае - скрипт-эффект.
Если только в `spell_scripts` добавить возможность указания гурппы текстов, из которых случайным образом выбирается один.
Нужно произносить фразу в момент каста спелла, а не использования итема.
Указание группы фраз в `spell_scripts` мягко говоря нецелесообразно...
Может просто использовать скрипт юза итема с задержкой...
Задержка должна равняться времени применении спелла.
По идее, должен быть какой-то общий обработчик.
Как сделать задержку в СД2 на выполнение при использовании итема с учетом того, что каст может быть не выполнен при использовании итема?
virusav, я же вам еще про квесты в Нордсколе рассказывал... ну есть же функция AI::SpellHit — через нее и делайте.
В СД2 на игрока навесить произнесение фразы при касте на него спелла?
Если на игрока — тогда через ядро.
О том и речь, что каст на игрока, а не нпц.
А в ядро не примут коды из базы для текстов.
На СД2 как-нибудь можно реализовать, чтобы работало, как полагается?
Как на СД2 сделать, чтобы код отрабатывал при касте спелла, как если бы код был написан в ядре в соответствующем обработчике?
В принципе способов куча, но единственный без серьезных граблей - ждать в UpdateAI()
!pCaster->IsNonMeleeSpellCasted(false)
все остальные это просто минное поле какое-то :(
UpdateAI() для игрока?
Нет. Для фейк-моба который будет рулить всем процессом.
Не осилил.:)
Игрок может использовать итем в любой точке, после чего на него накладывается спелл.
Что за фейк-моб?
Может просто использовать скрипт юза итема с задержкой...
Нельзя, если не добавлять совершенно другой функционал для юза итема. Сейчас эта функция вызывается в
void WorldSession::HandleUseItemOpcode(WorldPacket& recvPacket)
Никаких задержек здесь сделать невозможно
Не осилил.:)
Игрок может использовать итем в любой точке, после чего на него накладывается спелл.
Что за фейк-моб?
Контроллер, например вызываемый при касте(скрипт юза итема собсно) - далее раз игрок юзает итем, он кастует спелл, значит в апдейтАИ контроллера можно это отслеживать, как предлагает rsa - и как только это состояние кончится - кастануть нужный спелл и обработать тексты
А вообще, пришла в голову только мысль добавить для EFFECT_SCRIPT_EFFECT такую же обработку как и для dummy, хотя по идее сложный скрипт-эффекты обрабатываются в ядре, более простые - в БД, но мб этот вариант уже назрел
Как это для dummy
void Spell::EffectDummy(SpellEffectIndex eff_idx)
обьект Script есть стандартная часть кода и связан с вызовом скриптов в ScriptCalls.cpp, т.е дополнительно какой-то гемор с обьявлениями не будет
Вот так в конце кода обработки dummy-эффектов
// Script based implementation. Must be used only for not good for implementation in core spell effects
// So called only for not processed cases
if (gameObjTarget)
Script->EffectDummyGameObj(m_caster, m_spellInfo->Id, eff_idx, gameObjTarget);
else if (unitTarget && unitTarget->GetTypeId()==TYPEID_UNIT)
Script->EffectDummyCreature(m_caster, m_spellInfo->Id, eff_idx, (Creature*)unitTarget);
else if (itemTarget)
Script->EffectDummyItem(m_caster, m_spellInfo->Id, eff_idx, itemTarget);
Примеров с EffectDummyItem в СД2 не видел.
У итема как раз спелл с таким эффектом, попробую через него.
Попробовал сделать так:
static uint32 m_YellTexts[] = {-1000006, -1000007, -1000008};
enum
{
// quest 11989
SPELL_BLOOD_OATH = 50141,
SPELL_BLOOD_OATH_AURA = 50001
};
bool EffectDummyItem_spell_dummy_item(Unit* pCaster, uint32 uiSpellId, SpellEffectIndex uiEffIndex, Item *pItemTarget)
{
switch(uiSpellId)
{
case SPELL_BLOOD_OATH:
{
if (uiEffIndex == EFFECT_INDEX_0)
{
pCaster->CastSpell(pCaster, SPELL_BLOOD_OATH_AURA, true);
DoScriptText(m_YellTexts[urand(0, 2)], pCaster);
return true;
}
}
}
return false;
}
...
newscript = new Script;
newscript->Name = "spell_dummy_item";
newscript->pEffectDummyItem = &EffectDummyItem_spell_dummy_item;
newscript->RegisterSelf();
Назначил итему скрипт spell_dummy_item, но при использовании итема ничего не произошло.
В чем может быть проблема?
То, что вы собираетесь наложить - является dummy аурой, а не dummy эффектом, но даже если б это был эффект - использование сего метода скрипта требует itemTarget - коим каст с квест-итема не является
Обработка dummy ауры выглядит вот так
// script has to "handle with care", only use where data are not ok to use in the above code.
if (m_target->GetTypeId() == TYPEID_UNIT)
Script->EffectAuraDummy(this, apply);
Причем как видно - это только если цель ауры - тип Unit, а у нас аура имеет TARGET_SELF и должна ложится на плеера, так что это условие игнорится
Как вариант - разрешить выполнение скрипта ауры всегда, но вести проверку типов целей в самих скриптах спеллов, как пример :
bool EffectAuraDummy_spell_aura_dummy_npc(const Aura* pAura, bool bApply)
{
switch(pAura->GetId())
{
case SPELL_HEALING_SALVE:
{
if (pAura->GetEffIndex() != EFFECT_INDEX_0)
return true;
if (bApply)
{
if (Unit* pCaster = pAura->GetCaster())
pCaster->CastSpell(pAura->GetTarget(), SPELL_HEALING_SALVE_DUMMY, true);
}
return true;
}
добавить что-то вроде
if (Unit* pCaster = pAura->GetCaster())
if (pAura->GetTarget()->GetTypeID() == TYPEID_UNIT)
pCaster->CastSpell(pAura->GetTarget(), SPELL_HEALING_SALVE_DUMMY, true);
Мб конечно это и неправильно, но по-моему других вариантов обработать каст в СД2 чтоб игрок мог сказать текст - нету
Не стал делать через EffectAuraDummy_spell_aura_dummy_npc, т.к. скрипт надо назначать на нпц, которого может не быть рядом в момент каста.
да, я ток сейчас соообразил, что ограничение из-за того, что мы используем скрипт моба, который является m_target для dummy ауры
Ну тогда скорей всего надо дописывать какой-то новый фукционал, связанный с расширенными скриптами на итемы
vBulletin® v3.8.4, Copyright ©2000-2024, Jelsoft Enterprises Ltd. Перевод: zCarot