Game Development Community

AFXSpellCooldowns

by James Thompson · 08/04/2008 (7:48 pm) · 4 comments

This resource provides the code needed for spell specific cooldowns in AFX.

First we need the fields for spell cooldowns.

In afxMagicSpell.cpp:

In afxMagicSpellData::afxMagicSpellData()
Add:
spell_cooldown = 0.0f;
  spell_cooldown_cur = 0.0f;

just before the
}


In afxMagicSpellData::initPersistFields()
Add:
addField("spellCooldown",         TypeF32,        myOffset(spell_cooldown));
  addField("spell_cooldown_cur",    TypeF32,        myOffset(spell_cooldown_cur));
At the end.

In afxMagicSpellData::onAdd()
Add:
spell_cooldown_cur = spell_cooldown;
  if((casting_dur + linger_dur) < spell_cooldown)
    linger_dur += (spell_cooldown - (casting_dur + linger_dur));
Before:
return true;

Why? This prevents the spell being paused or deleted before the cooldown timer has had a chance to complete its cooldown.

In afxMagicSpellData::packData(BitStream* stream)
Add:
stream->write(spell_cooldown);
  stream->write(spell_cooldown_cur);
At the end

In afxMagicSpellData::unpackData(BitStream* stream)
Add:
stream->read(&spell_cooldown);
  stream->read(&spell_cooldown_cur);
At the end

In afxMagicSpell::processTick(const Move* m)
Add:
if (datablock->spell_cooldown_cur < datablock->spell_cooldown)
  {
    datablock->spell_cooldown_cur += 0.03125;
    if (datablock->spell_cooldown_cur > datablock->spell_cooldown)
      datablock->spell_cooldown_cur = datablock->spell_cooldown;
  }
Before:
process_server();


In afxMagicSpell.h:
Add:
F32                   spell_cooldown;
  F32                   spell_cooldown_cur;
In the public section of afxMagicSpellData, before:
bool                  do_move_interrupts;
  F32                   move_interrupt_speed;

Now onto the spellbook.
In afxSpellBook.cpp:

Change afxSpellBook::getCooldownFactor(S32 page, S32 slot)
To:
F32 afxSpellBook::getCooldownFactor(S32 page, S32 slot)
{
  F32 retVal = 0.0f;

  afxMagicSpellData* spell_data = getSpellData(page, slot);
  
  if(spell_data->spell_cooldown_cur == spell_data->spell_cooldown)
	  retVal = all_spell_cooldown;
  else
	  retVal = (spell_data->spell_cooldown_cur / spell_data->spell_cooldown);

  if(retVal < 0.0f)
	  retVal = 0.0f;

  if(retVal > 1.0f)
	  retVal = 1.0f;

  return retVal;
}

After debugging i found
if(retVal < 0.0f)
	  retVal = 0.0f;

  if(retVal > 1.0f)
	  retVal = 1.0f;
isnt really needed but, it helps me sleep better...

We also need this new function:
ConsoleMethod(afxSpellBook, startSpellCooldown, void, 3, 3, "startSpellCooldown(afxMagicSpellData)")
{
  afxMagicSpellData* datablock = dynamic_cast<afxMagicSpellData*>(Sim::findObject(argv[2]));
  if (!datablock)
  {
    Con::errorf("startSpellCooldown() -- failed to find spell datablock [%s].", argv[2]);
    return;
  }
  datablock->spell_cooldown_cur = 0.0f;
}


Onto script
In afxSpellCasting.cs
In afxMagicSpellData::onActivate

Add
if (isObject(%caster.activeSpellbook))
    %caster.activeSpellbook.startSpellCooldown(%this);
Before the
}

That should be it...

In your spells you can now add:
spellCooldown = 1.0; // change as you want
to the
afxMagicSpellData
bit.

Enjoy!

#1
08/04/2008 (11:16 pm)
for which version has this been tested in, and will it work for TGE AFX 1.0.2?
#2
08/05/2008 (8:04 am)
I used TGEA 1.7.1 but the changes arent platform specific so it should work on any version.
#3
02/10/2009 (5:36 am)
Works fine in TGEA 1.8 as is.
To prevent players from casting the same spell during it's cooldown edit afxSpellCasting.cs and in function afxPerformSpellCast add:
// Spell is cooling down
  if (%spell_data.spell_cooldown_cur != %spell_data.spellcooldown)
  {
    DisplayScreenMessage(%client, "Wait for this spell to cool down...");
    return;
  }

Ari
#4
02/10/2009 (7:50 am)
After testing, having issues in multiplayer.