PDA

Просмотр полной версии : Произнесение фразы игроком


virusav
12.07.2010, 22:32
Есть спелл с эффектом 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. Зачем в коде явным образом указывать фразы, которые нельзя будет перевести ни на один язык (пример выше)?

rsa
13.07.2010, 07:05
1. Можно ли в ядре как-нибудь заставить игрока произносить фразы, чтобы при этом можно было использовать локализацию, и при этом патч имел бы шансы на принятие (коды фраз в разных базах могут иметь различные значения)?
2. Зачем в коде явным образом указывать фразы, которые нельзя будет перевести ни на один язык (пример выше)?
1. Можно. Код получается толстый и привязанный к базе, но вполне в мэйнстриме.
2. Обломки от старых захардкоженных хаков...

Я себе для такого дела в SD2 спец. функцию встроил, потому как работать с тем что есть сильно напряжно...

virusav
13.07.2010, 08:59
На СД2 я написал патч, текст берется из базы, как и во всех подобных случаях.
Получилось, что патч нужен только для произнесения одной из 3 фраз и состоит фактически из одной строки кода.
Не знаю, стоит ли из-за одной строки городить скрипт СД2 или лучше ее прописать в ядро.

Если бы можно было реализовать это в ядре, то все работало бы, как часы.

Допустим, что надо делать через СД2.
Произнесение фразы - это эффект от спелла.

Через скрипт на итем нет ожидания каста спелла, поэтому сначала игрок кричит фразу, а потом уже идет каст.
Как на СД2 сделать, чтобы код отрабатывал при касте спелла, как если бы код был написан в ядре в соответствующем обработчике?

LordJZ
13.07.2010, 10:58
Давно имхо уже пора удалить все Creature::Say/Yell/... и Player::Say/Yell/.. и использовать вместо этого Unit. Ведь разговор НПС от разговора игрока ничем не отличается, кроме обычно используемых типов. По наблюдениям с офа могу сказать, что в квестах, где игрок разговаривает, подчиняясь серверным командам, используются как стандартные плееровские CHAT_MSG_SAY, так и присущие кричерам CHAT_MSG_MONSTER_SAY.

virusav
13.07.2010, 13:46
Давно имхо уже пора удалить все Creature::Say/Yell/... и Player::Say/Yell/.. и использовать вместо этого Unit. Ведь разговор НПС от разговора игрока ничем не отличается, кроме обычно используемых типов. По наблюдениям с офа могу сказать, что в квестах, где игрок разговаривает, подчиняясь серверным командам, используются как стандартные плееровские CHAT_MSG_SAY, так и присущие кричерам CHAT_MSG_MONSTER_SAY.

Как реализовать выкрик случайной фразы в СД2 или ядре, чтобы не потерять локализацию (проблемы описаны постами выше)?

LordJZ
13.07.2010, 14:33
Насколько я помню, из SD2 доступен вызов sObjectMgr.GetMangosString(...), через него можно, я так думаю.

virusav
13.07.2010, 15:14
В СД2 есть функция произнесения фраз по кодам из `script_texts`, я ее и использую.
Только скрипт на итем отрабатывает при его использовании, а не при касте спелла итема.

Думми в СД2 реализованы через нпц и го, а в данном случае - скрипт-эффект.

Если только в `spell_scripts` добавить возможность указания гурппы текстов, из которых случайным образом выбирается один.

Нужно произносить фразу в момент каста спелла, а не использования итема.

KiriX
13.07.2010, 15:25
В СД2 есть функция произнесения фраз по кодам из `script_texts`, я ее и использую.
Только скрипт на итем отрабатывает при его использовании, а не при касте спелла итема.

Думми в СД2 реализованы через нпц и го, а в данном случае - скрипт-эффект.

Если только в `spell_scripts` добавить возможность указания гурппы текстов, из которых случайным образом выбирается один.

Нужно произносить фразу в момент каста спелла, а не использования итема.
Указание группы фраз в `spell_scripts` мягко говоря нецелесообразно...
Может просто использовать скрипт юза итема с задержкой...

virusav
13.07.2010, 15:55
Задержка должна равняться времени применении спелла.
По идее, должен быть какой-то общий обработчик.

Как сделать задержку в СД2 на выполнение при использовании итема с учетом того, что каст может быть не выполнен при использовании итема?

LordJZ
13.07.2010, 16:03
virusav, я же вам еще про квесты в Нордсколе рассказывал... ну есть же функция AI::SpellHit — через нее и делайте.

virusav
13.07.2010, 16:42
В СД2 на игрока навесить произнесение фразы при касте на него спелла?

LordJZ
13.07.2010, 19:39
Если на игрока — тогда через ядро.

virusav
13.07.2010, 19:53
О том и речь, что каст на игрока, а не нпц.
А в ядро не примут коды из базы для текстов.

На СД2 как-нибудь можно реализовать, чтобы работало, как полагается?

rsa
13.07.2010, 20:14
Как на СД2 сделать, чтобы код отрабатывал при касте спелла, как если бы код был написан в ядре в соответствующем обработчике?
В принципе способов куча, но единственный без серьезных граблей - ждать в UpdateAI()
!pCaster->IsNonMeleeSpellCasted(false)

все остальные это просто минное поле какое-то :(

virusav
13.07.2010, 20:17
UpdateAI() для игрока?

rsa
13.07.2010, 20:23
UpdateAI() для игрока?

Нет. Для фейк-моба который будет рулить всем процессом.

virusav
13.07.2010, 20:51
Не осилил.:)
Игрок может использовать итем в любой точке, после чего на него накладывается спелл.
Что за фейк-моб?

MaS0n
14.07.2010, 06:55
Может просто использовать скрипт юза итема с задержкой...
Нельзя, если не добавлять совершенно другой функционал для юза итема. Сейчас эта функция вызывается в

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);

virusav
14.07.2010, 09:05
Примеров с EffectDummyItem в СД2 не видел.
У итема как раз спелл с таким эффектом, попробую через него.

virusav
15.07.2010, 21:26
Попробовал сделать так:
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, но при использовании итема ничего не произошло.

В чем может быть проблема?

MaS0n
16.07.2010, 17:03
То, что вы собираетесь наложить - является 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 чтоб игрок мог сказать текст - нету

virusav
16.07.2010, 17:08
Не стал делать через EffectAuraDummy_spell_aura_dummy_npc, т.к. скрипт надо назначать на нпц, которого может не быть рядом в момент каста.

MaS0n
16.07.2010, 17:17
да, я ток сейчас соообразил, что ограничение из-за того, что мы используем скрипт моба, который является m_target для dummy ауры

Ну тогда скорей всего надо дописывать какой-то новый фукционал, связанный с расширенными скриптами на итемы