示例#1
0
void SpellShell::selfStartSpellCast(const uint8_t* data)
{
  const startCastStruct *c = (const startCastStruct *)data;
#ifdef DIAG_SPELLSHELL
  seqDebug("selfStartSpellCast - id=%d (slot=%d, inv=%d) on spawnid=%d", 
	   c->spellId, c->slot, c->inventorySlot, c->targetId);
#endif // DIAG_SPELLSHELL

  // get the target 
  const Item* s;
  QString targetName;
  int duration = 0;
  const Spell* spell = m_spells->spell(c->spellId);
  SpellItem *item;
  if (spell)
    duration = spell->calcDuration(m_player->level()) * 6;

  if (!spell || spell->targetType() != 6)
  {
    if (c->targetId && 
	((s = m_spawnShell->findID(tSpawn, c->targetId))))
      targetName = s->name();
    
    item = findSpell(c->spellId, c->targetId, targetName);
  }
  else
  {
    targetName = m_player->name();
    item = findSpell(c->spellId);
  }

  if (item) 
  { // exists
    item->update(c->spellId, spell, duration,
		 m_player->id(), m_player->name(),
		 c->targetId, targetName);
    emit changeSpell(item);
  } 
  else 
  { // new spell
    item = new SpellItem();
    item->update(c->spellId, spell, duration,
		 m_player->id(), m_player->name(),
		 c->targetId, targetName);
    m_spellList.append(item);
    if ((m_spellList.count() > 0) && (!m_timer->isActive()))
      m_timer->start(1000 *
		     pSEQPrefs->getPrefInt("SpellTimer", "SpellList", 6));
    emit addSpell(item);
    m_lastPlayerSpell = item;
  }
}
示例#2
0
//slot for loading buffs when main char struct is loaded
void SpellShell::buffLoad(const spellBuff* c)
{
#ifdef DIAG_SPELLSHELL
  seqDebug("Loading buff - id=%d.",c->spellid);
#endif // DIAG_SPELLSHELL

  const Spell* spell = m_spells->spell(c->spellid);
  int duration = c->duration * 6;
  SpellItem *item = findSpell(c->spellid, m_player->id(), m_player->name());
  if (item) 
  { // exists
    item->update(c->spellid, spell, duration, 
		 0, "Buff", m_player->id(), m_player->name());
    emit changeSpell(item);
  } 
  else 
  { // new spell
    item = new SpellItem();
    item->update(c->spellid, spell, duration, 
		 0, "Buff", m_player->id(), m_player->name());
    m_spellList.append(item);
    if ((m_spellList.count() > 0) && (!m_timer->isActive()))
      m_timer->start(1000 *
		     pSEQPrefs->getPrefInt("SpellTimer", "SpellList", 6));
    emit addSpell(item);
  }
}
void cNewMagic::execSpell( P_CHAR pMage, UINT8 spell, UINT8 type, cUORxTarget* target )
{
	stNewSpell *sInfo = findSpell( spell );
	P_PLAYER pp = dynamic_cast<P_PLAYER>(pMage);

	if( ( ( pp || !pp->isGM() ) && !checkReagents( pMage, spell ) ) || !useMana( pMage, spell ) )
	{
		pMage->setCasting( false );
		return;
	}
	if( !pp || !pp->isGM() )
		useReagents( pMage, spell );
	
	if( !checkSkill( pMage, spell, false ) )
	{
		disturb( pMage, true, -1 );
		return;
	}
	
	// Call the Spell Effect for this Spell
	if( sInfo->script )
		sInfo->script->onSpellSuccess( pMage, spell, type, target );
	
	// End Casting
	pMage->setCasting( false );
}
/*!
	This checks the needed skill to cast the specified 
	spell. If scroll is true, the spell is cast 
	from a scroll and if needed the scrolllow and scrollhigh 
	values are used instead of the book values. This 
	function returns true if the check was successful. 
*/
bool cNewMagic::checkSkill( P_CHAR pMage, UINT8 spell, bool scroll )
{
	UINT16 lowSkill, highSkill;

	stNewSpell *sInfo = findSpell( spell );

	if( !sInfo )
		return false;

	// Cut the requirements for scrolls if needed
	if( scroll && SrvParams->cutScrollReq() )
	{
		lowSkill = sInfo->scrolllow;
		highSkill = sInfo->scrollhigh;
	}
	else
	{
		lowSkill = sInfo->booklow;
		highSkill = sInfo->bookhigh;
	}

	// Do the skill check
	if( !pMage->checkSkill( MAGERY, lowSkill, highSkill ) )
	{
		disturb( pMage, true, -1 );
		return false;
	}

	// Skillcheck completed
	return true;
}
示例#5
0
void SpellShell::action(const uint8_t* data, size_t, uint8_t)
{
  const actionStruct* a = (const actionStruct*)data;

  if (a->type != 0xe7) // only things to do if action is a spell
    return;

  const Item* s;
  QString targetName;

  if (a->target && 
      ((s = m_spawnShell->findID(tSpawn, a->target))))
    targetName = s->name();

  SpellItem *item = findSpell(a->spell, a->target, targetName);

  if (item || (a->target == m_player->id()))
  {
    int duration = 0;
    const Spell* spell = m_spells->spell(a->spell);
    if (spell)
      duration = spell->calcDuration(a->level) * 6;
    
    QString casterName;
    if (a->source && 
	((s = m_spawnShell->findID(tSpawn, a->source))))
      casterName = s->name();

    if (item)
    {
#ifdef DIAG_SPELLSHELL
      seqDebug("action - found - source=%d (lvl: %d) cast id=%d on target=%d causing %d damage", 
	       a->source, a->level, a->spell, a->target, a->damage);
#endif // DIAG_SPELLSHELL
      
      item->update(a->spell, spell, duration, 
		   a->source, casterName, a->target, targetName);
      emit changeSpell(item);
    }
    else
    {
      // otherwise check for spells cast on us
#ifdef DIAG_SPELLSHELL
      seqDebug("action - new - source=%d (lvl: %d) cast id=%d on target=%d causing %d damage", 
	       a->source, a->level, a->spell, a->target, a->damage);
#endif // DIAG_SPELLSHELL
      
      // only way to get here is if there wasn't an existing spell, so...
      item = new SpellItem();
      item->update(a->spell, spell, duration, 
		   a->source, casterName, a->target, targetName);
      m_spellList.append(item);
      if ((m_spellList.count() > 0) && (!m_timer->isActive()))
	m_timer->start(1000 *
		       pSEQPrefs->getPrefInt("SpellTimer", "SpellList", 6));
      emit addSpell(item);
    }    
  }
}
示例#6
0
void SpellShell::buff(const uint8_t* data, size_t, uint8_t dir)
{
  // we only care about the server
  if (dir == DIR_Client)
    return;

  const buffStruct* b = (const buffStruct*)data;

  // if this is the second server packet then ignore it
  if (b->spellid == 0xffffffff)
    return;

#ifdef DIAG_SPELLSHELL
  seqDebug("Changing buff - id=%d from spawn=%d", b->spellid, b->spawnid);
#endif // DIAG_SPELLSHELL

  const Spell* spell = m_spells->spell(b->spellid);

  // find the spell item
  SpellItem* item;
  const Item* s;
  QString targetName;
  if (!spell || spell->targetType() != 6)
  {
    if (b->spawnid && 
	((s = m_spawnShell->findID(tSpawn, b->spawnid))))
      targetName = s->name();
    
    item = findSpell(b->spellid, b->spawnid, targetName);
  }
  else
    item = findSpell(b->spellid);

  if (!item)
    return;

  if (b->changetype == 0x01) // removing buff
    deleteSpell(item);
  else if (b->changetype == 0x02)
  {
    // right now we only know how to find the updated duration
    item->setDuration(b->duration * 6);
    emit changeSpell(item);
  }
}
/*!
	This function is used to check for the required 
	mana to cast a specific spell. If the character
	does not have enough mana, a message is displayed
	above the characters head and it returns false.
*/
bool cNewMagic::checkMana( P_CHAR pMage, UINT8 spell )
{
	stNewSpell *sInfo = findSpell( spell );
	bool enoughMana = false;

	if( sInfo && pMage->mana() >= sInfo->mana )
		enoughMana = true;

	return enoughMana;
}
/*!
	This function is used to consume the mana for a 
	specific spell. If the character does not have
	enough mana, this function returns false.
*/
bool cNewMagic::useMana( P_CHAR pMage, UINT8 spell )
{
/*	// The character does not need any mana
	if( pMage->priv2() & 0x10 )
		return true;*/

	stNewSpell *sInfo = findSpell( spell );

	if( !sInfo )
		return false;

	if( pMage->mana() < sInfo->mana && pMage->objectType() == enPlayer )
	{
		dynamic_cast<P_PLAYER>(pMage)->message( tr( "You don't have enough mana to cast this spell." ) );
		return false;
	}

	pMage->setMana( pMage->mana() - sInfo->mana );
	return true;
}
void cNewMagic::castSpell( P_PLAYER pMage, UINT8 spell )
{
	P_PLAYER pp = dynamic_cast<P_PLAYER>(pMage);

	if( !pp || !pp->socket() )
		return;

	stNewSpell *sInfo = findSpell( spell );

	if( !sInfo )
	{
		pp->socket()->sysMessage( tr( "This spell is either not implemented or invalid" ) );
		return;
	}

	// Check if we can cast this spell
	if( !hasSpell( pMage, spell ) )
	{
		pp->socket()->sysMessage( tr( "You don't know this spell." ) );
		return;
	}

	// Check for required mana and required reagents, if not present: cancel casting
	if( !checkMana( pMage, spell ) )
	{
		pp->message( tr( "You don't have enough mana to cast this spell." ) );
		return;
	}
	
	if( !pp->isGM() && !checkReagents( pMage, spell ) )
		return;

	if( pMage->isCasting() )
		disturb( pMage, true );

	// We start casting here
	pMage->setCasting( true );

	// We get frozen here too
	pMage->setFrozen( true );

	// Say the mantra
	// Type 0x0A : Spell
	pMage->talk( sInfo->mantra, pMage->saycolor() );

	// This is a very interesting move of OSI 
	// They send all action-packets the character has to perform in a row. 
	// But they use the action 0xE9 instead of 0x10, maybe it's a bitmask 
	// of 0xD9 but i am unsure. 
	// This will repeat the animation until
	// We are done casting or until we are being
	// disturbed.
	//pMage->startRepeatedAction( sInfo->action, sInfo->actiondelay ); // Repeat every 1250 ms
	// I *do* know that this is a drawback but for now a single animation is exactly what we need.
	pMage->action( sInfo->action );

	// Now we have to do the following: 
	// We show the target cursor after a given amount of time (set in the scripts)
	// So what we are adding here is cEndCasting() supplying the Serial of our Mage 
	// And the ID of our Spell.
	TempEffects::instance()->insert( new cEndCasting( pMage, spell, CT_BOOK, sInfo->delay ) );
}
示例#10
0
/*!
	Just like useReagents this function is checking 
	for required reagents on a characater to cast a 
	spell. But unlike useReagents it wont really 
	consume the reagents but just return false if 
	the required reagents are not present.
*/
bool cNewMagic::checkReagents( P_CHAR pMage, UINT8 spell )
{
	// Check for each reagent.
	// So we dont need to loop trough all items over and over again we'll use ONE loop (will be a bit less clean)
	P_ITEM pPack = pMage->getBackpack();

	stNewSpell *sInfo = findSpell( spell );
	UINT8 ginseng = sInfo->reagents.ginseng;
	UINT8 bloodmoss = sInfo->reagents.bloodmoss;
	UINT8 mandrake = sInfo->reagents.mandrake;
	UINT8 blackpearl = sInfo->reagents.blackpearl;
	UINT8 spidersilk = sInfo->reagents.spidersilk;
	UINT8 garlic = sInfo->reagents.garlic;
	UINT8 nightshade = sInfo->reagents.nightshade;
	UINT8 sulfurash = sInfo->reagents.sulfurash;

	QPtrList< cItem > content = pPack->getContainment();

	for( P_ITEM pItem = content.first(); pItem; pItem = content.next() )
	{
		checkReagent( blackpearl, 0xF7A )
		else checkReagent( bloodmoss, 0xF7B )
		else checkReagent( garlic, 0xF84 )
		else checkReagent( ginseng, 0xF85 )
		else checkReagent( mandrake, 0xF86 )
		else checkReagent( nightshade, 0xF88 )
		else checkReagent( sulfurash, 0xF8C )
		else checkReagent( spidersilk, 0xF8D )		
	}

	QStringList missing;

	if( ginseng > 0 )
		missing.append( tr( "Ginseng" ) );
	if( bloodmoss > 0 )
		missing.append( tr( "Bloodmoss" ) );
	if( mandrake > 0 )
		missing.append( tr( "Mandrake" ) );
	if( blackpearl > 0 )
		missing.append( tr( "Black Pearls" ) );
	if( spidersilk > 0 )
		missing.append( tr( "Spider's Silk" ) );
	if( garlic > 0 )
		missing.append( tr( "Garlic" ) );
	if( nightshade > 0 )
		missing.append( tr( "Nightshade" ) );
	if( sulfurash > 0 )
		missing.append( tr( "Sulfurous Ash" ) );

	bool enoughReagents = true;

	if( missing.count() > 0 )
	{
		if( pMage->objectType() == enPlayer )
		{
			P_PLAYER pp = dynamic_cast<P_PLAYER>(pMage);
			if( pp->socket() )
			{
				pp->message( tr( "You don't have enough reagents." ) );
				pp->socket()->sysMessage( tr( "You lack the following reagents: %1" ).arg( missing.join( ", ") ) );
			}
		}
		enoughReagents = false;
	}

	return enoughReagents;
}