Skip to content

Commit

Permalink
ADDED: new class GO_SpellCaster. Implements Type 22 GameObjects.
Browse files Browse the repository at this point in the history
MODIFIED: Some refactoring regarding Spell::SpellEffectSummonObject.
  • Loading branch information
dfighter1985 committed Dec 20, 2010
1 parent 7b1968d commit 34dd7ff
Show file tree
Hide file tree
Showing 9 changed files with 95 additions and 135 deletions.
4 changes: 4 additions & 0 deletions src/arcemu-world/CObjectFactory.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,10 @@ namespace Arcemu{
case GAMEOBJECT_TYPE_RITUAL:
go = new Arcemu::GO_Ritual( GUID );
break;

case GAMEOBJECT_TYPE_SPELLCASTER:
go = new Arcemu::GO_SpellCaster( GUID );
break;

case GAMEOBJECT_TYPE_FISHINGHOLE:
go = new Arcemu::GO_FishingHole( GUID );
Expand Down
2 changes: 2 additions & 0 deletions src/arcemu-world/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ arcemu_world_SOURCES = \
Object/GameObject/Ritual.h \
Object/GameObject/GO_Ritual.cpp \
Object/GameObject/GO_Ritual.h \
Object/GameObject/GO_SpellCaster.cpp \
Object/GameObject/GO_SpellCaster.h \
Object/GameObject/GO_SpellFocus.cpp \
Object/GameObject/GO_SpellFocus.h \
Object/GameObject/GO_Trap.cpp \
Expand Down
43 changes: 21 additions & 22 deletions src/arcemu-world/MiscHandler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1558,24 +1558,23 @@ void WorldSession::HandleGameObjectUse(WorldPacket & recv_data)
}break;
case GAMEOBJECT_TYPE_SPELLCASTER:
{
if (obj->m_summoner != NULL && obj->m_summoner->IsPlayer() && plyr != TO< Player* >(obj->m_summoner))
{
if (TO< Player* >(obj->m_summoner)->GetGroup() == NULL)
break;
else if (TO< Player* >(obj->m_summoner)->GetGroup() != plyr->GetGroup())
break;

if( obj->GetInfo()->spellcaster.partyOnly != 0 ){

if( obj->m_summoner != NULL && obj->m_summoner->IsPlayer() ){
Player *summoner = TO< Player* >( obj->m_summoner );

if( summoner->GetGUID() != plyr->GetGUID() ){
if( !plyr->InGroup() )
return;

if( plyr->GetGroup() != summoner->GetGroup() )
return;
}
}
}

SpellEntry *info = dbcSpell.LookupEntryForced(goinfo->raw.sound0);
if(!info)
break;
spell = new Spell(plyr, info, false, NULL);
//spell->SpellByOther = true;
targets.m_targetMask |= TARGET_FLAG_UNIT;
targets.m_unitTarget = plyr->GetGUID();
spell->prepare(&targets);
if ( obj->charges > 0 && !--obj->charges )
obj->ExpireAndDelete();
obj->Use( plyr->GetGUID() );
}break;
case GAMEOBJECT_TYPE_RITUAL:
{
Expand Down Expand Up @@ -1622,7 +1621,7 @@ void WorldSession::HandleGameObjectUse(WorldPacket & recv_data)
{
if ( robj->GetRitual()->GetTargetGUID() == 0 )
return;
info = dbcSpell.LookupEntryForced( goinfo->raw.sound1 );
info = dbcSpell.LookupEntryForced( goinfo->summoningRitual.spellId );
if ( !info )
break;
Player * target = objmgr.GetPlayer( robj->GetRitual()->GetTargetGUID() );
Expand All @@ -1644,15 +1643,15 @@ void WorldSession::HandleGameObjectUse(WorldPacket & recv_data)
if(!psacrifice || !pCaster)
return;

info = dbcSpell.LookupEntryForced(goinfo->raw.sound4);
info = dbcSpell.LookupEntryForced( goinfo->summoningRitual.casterTargetSpell );
if(!info)
break;
spell = new Spell(psacrifice, info, true, NULL);
targets.m_unitTarget = psacrifice->GetGUID();
spell->prepare(&targets);

// summons demon
info = dbcSpell.LookupEntry(goinfo->raw.sound1);
info = dbcSpell.LookupEntry( goinfo->summoningRitual.spellId );
spell = new Spell(pCaster, info, true, NULL);
SpellCastTargets targets2;
targets2.m_unitTarget = pCaster->GetGUID();
Expand All @@ -1668,7 +1667,7 @@ void WorldSession::HandleGameObjectUse(WorldPacket & recv_data)
if(!pleader)
return;

info = dbcSpell.LookupEntry(goinfo->raw.sound1);
info = dbcSpell.LookupEntry( goinfo->summoningRitual.spellId );
spell = new Spell( pleader, info, true, NULL );
SpellCastTargets targets2( plr->GetGUID() );
spell->prepare(&targets2);
Expand All @@ -1678,11 +1677,11 @@ void WorldSession::HandleGameObjectUse(WorldPacket & recv_data)
}
else if ( goinfo->ID == 186811 || goinfo->ID == 181622 )
{
info = dbcSpell.LookupEntryForced( goinfo->raw.sound1 );
info = dbcSpell.LookupEntryForced( goinfo->summoningRitual.spellId );
if ( info == NULL )
return;
spell = new Spell( _player->GetMapMgr()->GetPlayer( robj->GetRitual()->GetCasterGUID() ), info, true, NULL );
SpellCastTargets targets2( robj->GetRitual()->GetTargetGUID() );
SpellCastTargets targets2( robj->GetRitual()->GetCasterGUID() );
spell->prepare( &targets2 );
robj->ExpireAndDelete();
}
Expand Down
14 changes: 14 additions & 0 deletions src/arcemu-world/Object/GameObject/GO_FishingNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ namespace Arcemu{
GO_FishingNode::~GO_FishingNode(){
}

void GO_FishingNode::OnPushToWorld(){
uint32 zone = GetMapMgr()->GetAreaID( GetPositionX(), GetPositionY() );
if( zone == 0 )
zone = GetZoneId();

if( lootmgr.IsFishable( zone ) ){ // Only set a 'splash' if there is any loot in this area / zone
uint32 seconds[] = { 0, 4, 10, 14 };
uint32 rnd = RandomUInt( 3 );
sEventMgr.AddEvent( this, &Arcemu::GO_FishingNode::EventFishHooked, EVENT_GAMEOBJECT_FISH_HOOKED, seconds[ rnd ] * 1000, 1, 0 );
}

sEventMgr.AddEvent( this, &Arcemu::GO_FishingNode::EndFishing, true, EVENT_GAMEOBJECT_END_FISHING, 17 * 1000, 1, EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT );
}

bool GO_FishingNode::UseNode(){
sEventMgr.RemoveEvents( this );

Expand Down
2 changes: 2 additions & 0 deletions src/arcemu-world/Object/GameObject/GO_FishingNode.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,8 @@ namespace Arcemu{

~GO_FishingNode();

void OnPushToWorld();

///////////////////////////////////////////////////////////////////////
//bool UseNode()
// Uses the fishing node.
Expand Down
34 changes: 11 additions & 23 deletions src/arcemu-world/Spell.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2296,34 +2296,22 @@ void Spell::SendChannelUpdate(uint32 time)

void Spell::SendChannelStart(uint32 duration)
{
if (!m_caster->IsGameObject())
{
// Send Channel Start
WorldPacket data(MSG_CHANNEL_START, 22);
data << m_caster->GetNewGUID();
data << GetProto()->Id;
data << duration;
m_caster->SendMessageToSet(&data, true);
if( !m_caster->IsGameObject() ){
WorldPacket data( MSG_CHANNEL_START, 22 );

data << WoWGuid( m_caster->GetNewGUID() );
data << uint32( m_spellInfo->Id );
data << uint32( duration );

m_caster->SendMessageToSet( &data, true );
}

m_castTime = m_timer = duration;

if( u_caster != NULL )
if( u_caster != NULL ){
u_caster->SetChannelSpellId( GetProto()->Id);

/*
Unit* target = objmgr.GetCreature( TO< Player* >( m_caster )->GetSelection());
if(!target)
target = objmgr.GetObject<Player>( TO< Player* >( m_caster )->GetSelection());
if(!target)
return;
m_caster->SetUInt32Value(UNIT_FIELD_CHANNEL_OBJECT,target->GetGUIDLow());
m_caster->SetUInt32Value(UNIT_FIELD_CHANNEL_OBJECT+1,target->GetGUIDHigh());
//disabled it can be not only creature but GO as well
//and GO is not selectable, so this method will not work
//these fields must be filled @ place of call
*/
sEventMgr.AddEvent( u_caster, &Unit::EventStopChanneling, false, EVENT_STOP_CHANNELING, duration, 1, EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT );
}
}

void Spell::SendResurrectRequest(Player* target)
Expand Down
126 changes: 36 additions & 90 deletions src/arcemu-world/SpellEffects.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3132,9 +3132,16 @@ void Spell::SpellEffectSpawn(uint32 i)

void Spell::SpellEffectSummonObject(uint32 i)
{
if( !u_caster ) return;
if( u_caster == NULL )
return;

uint32 entry = GetProto()->EffectMiscValue[i];

GameObjectInfo *info = GameObjectNameStorage.LookupEntry( entry );
if( info == NULL ){
sLog.outError("Spell %u ( %s ) Effect %u tried to summon a GameObject with ID %u. GameObject is not in the database.", m_spellInfo->Id, m_spellInfo->Name, i, entry);
return;
}

uint32 mapid = u_caster->GetMapId();
float px = u_caster->GetPositionX();
Expand All @@ -3143,12 +3150,15 @@ void Spell::SpellEffectSummonObject(uint32 i)
float orient = m_caster->GetOrientation();
float posx = 0,posy = 0,posz = 0;

if( entry == GO_FISHING_BOBBER && p_caster)
{
GameObject *go = NULL;

if( info->Type == GAMEOBJECT_TYPE_FISHINGNODE ){
if( p_caster == NULL )
return;

float co = cos( orient );
float si = sin( orient );
MapMgr * map = m_caster->GetMapMgr();
Spell * spell = u_caster->GetCurrentSpell();

float r;
for( r = 20; r > 10; r-- )
Expand All @@ -3165,118 +3175,54 @@ void Spell::SpellEffectSummonObject(uint32 i)
posx = px + r * co;
posy = py + r * si;

// Todo / Fix me: This should be loaded / cached
uint32 zone = p_caster->GetAreaID();
if( zone == 0 ) // If the player's area ID is 0, use the zone ID instead
zone = p_caster->GetZoneId();

uint32 minskill;
FishingZoneEntry *fishentry = FishingZoneStorage.LookupEntry( zone );
if( !fishentry ) // Check database if there is fishing area / zone information, if not, return
return;
go = u_caster->GetMapMgr()->CreateGameObject( entry );

// Todo / Fix me: Add fishskill to the calculations
minskill = fishentry->MinSkill;
spell->SendChannelStart( 20000 ); // 30 seconds

GameObject *go = u_caster->GetMapMgr()->CreateGameObject(GO_FISHING_BOBBER);

go->CreateFromProto( GO_FISHING_BOBBER, mapid, posx, posy, posz, orient );
go->CreateFromProto( entry, mapid, posx, posy, posz, orient );
go->SetFlags( 0 );
go->SetState( 0 );
go->SetUInt64Value( OBJECT_FIELD_CREATED_BY, m_caster->GetGUID() );
u_caster->SetChannelSpellTargetGUID( go->GetGUID() );
go->SetFaction( u_caster->GetFaction() );
go->Phase(PHASE_SET, u_caster->GetPhase());

go->PushToWorld( m_caster->GetMapMgr() );

Arcemu::GO_FishingNode *fn = static_cast< Arcemu::GO_FishingNode* >( go );

if( lootmgr.IsFishable( zone ) ){ // Only set a 'splash' if there is any loot in this area / zone
uint32 seconds[] = { 0, 4, 10, 14 };
uint32 rnd = RandomUInt( 3 );
sEventMgr.AddEvent( fn, &Arcemu::GO_FishingNode::EventFishHooked, EVENT_GAMEOBJECT_FISH_HOOKED, seconds[ rnd ] * 1000, 1, 0 );
}
sEventMgr.AddEvent( fn, &Arcemu::GO_FishingNode::EndFishing, true, EVENT_GAMEOBJECT_END_FISHING, 17 * 1000, 1, EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT );
sEventMgr.AddEvent( TO< Unit* >( p_caster ), &Unit::EventStopChanneling, false, EVENT_STOP_CHANNELING, 17 * 1000, 1, EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT );
u_caster->SetChannelSpellTargetGUID( go->GetGUID() );

}else{

p_caster->SetSummonedObject( go );
}
else
{
posx=px;
posy=py;
GameObjectInfo * goI = GameObjectNameStorage.LookupEntry(entry);
if(!goI)
{
if( p_caster )
{
sChatHandler.BlueSystemMessage(p_caster->GetSession(), "non-existent gameobject %u tried to be created by SpellEffectSummonObject. Report to devs!", entry);
}
return;
}
if( m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION && m_targets.m_destX && m_targets.m_destY && m_targets.m_destZ )
{

if( ( m_targets.m_targetMask & TARGET_FLAG_DEST_LOCATION ) && ( m_targets.m_destX && m_targets.m_destY && m_targets.m_destZ ) ){
posx = m_targets.m_destX;
posy = m_targets.m_destY;
pz = m_targets.m_destZ;
}
GameObject *go=m_caster->GetMapMgr()->CreateGameObject(entry);

go->CreateFromProto(entry,mapid,posx,posy,pz,orient);
go->SetState( 1);
go = m_caster->GetMapMgr()->CreateGameObject( entry );

go->CreateFromProto( entry, mapid, posx, posy, pz, orient );
go->SetUInt64Value(OBJECT_FIELD_CREATED_BY,m_caster->GetGUID());
go->Phase(PHASE_SET, u_caster->GetPhase());
go->PushToWorld(m_caster->GetMapMgr());
sEventMgr.AddEvent(go, &GameObject::ExpireAndDelete, EVENT_GAMEOBJECT_EXPIRE, GetDuration(), 1, EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT);
if ( entry == 17032 && p_caster) // this is a portal
{
// enable it for party only
go->SetState( 0 );
//disable by default
WorldPacket * pkt = go->BuildFieldUpdatePacket(GAMEOBJECT_BYTES_1, 1 << 24);
SubGroup * pGroup = p_caster->GetGroup() ? p_caster->GetGroup()->GetSubGroup(p_caster->GetSubGroup()) : NULL;

if ( pGroup )
{
p_caster->GetGroup()->Lock();
for ( GroupMembersSet::iterator itr = pGroup->GetGroupMembersBegin(); itr != pGroup->GetGroupMembersEnd(); ++itr )
{
if( (*itr)->m_loggedInPlayer && m_caster != (*itr)->m_loggedInPlayer )
(*itr)->m_loggedInPlayer->GetSession()->SendPacket( pkt );
}
p_caster->GetGroup()->Unlock();
}
delete pkt;
}
else if ( entry == 36727 || entry == 177193 || entry == 194108 ) // Portal of Summoning and portal of doom
{
if(!p_caster) return;

Arcemu::GO_Ritual *rgo = static_cast< Arcemu::GO_Ritual* >( go );

Player * pTarget = objmgr.GetPlayer( (uint32)p_caster->GetSelection() );
if ( !pTarget || !pTarget->IsInWorld() )
sEventMgr.AddEvent(go, &GameObject::ExpireAndDelete, EVENT_GAMEOBJECT_EXPIRE, GetDuration(), 1, EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT);


if( info->Type == GAMEOBJECT_TYPE_RITUAL ){
if( p_caster == NULL )
return;

rgo->GetRitual()->Setup( p_caster->GetLowGUID(), pTarget->GetLowGUID(), m_spellInfo->Id );

}
else if ( entry == 186811 || entry == 181622 ) // ritual of refreshment, ritual of souls
{
if(!p_caster) return;

Arcemu::GO_Ritual *rgo = static_cast< Arcemu::GO_Ritual* >( go );

rgo->GetRitual()->Setup( p_caster->GetLowGUID(), static_cast< uint32 >( p_caster->GetSelection() ), m_spellInfo->Id );

rgo->GetRitual()->Setup( p_caster->GetLowGUID(), 0, m_spellInfo->Id );
}
else//Lightwell,if there is some other type -- add it
{
go->charges = 5;//Max 5 charges
}
if(p_caster)
p_caster->SetSummonedObject(go);//p_caster

}

if( p_caster != NULL )
p_caster->SetSummonedObject(go);
}

void Spell::SpellEffectEnchantItem(uint32 i) // Enchant Item Permanent
Expand Down
1 change: 1 addition & 0 deletions src/arcemu-world/StdAfx.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ template< class T, class U > T TO( U u ){ return static_cast< T >( u ); }
#include "Object/GameObject/GO_Trap.h"
#include "Object/GameObject/GO_FishingHole.h"
#include "Object/GameObject/GO_Goober.h"
#include "Object/GameObject/GO_SpellCaster.h"
#include "Object/GameObject/GO_SpellFocus.h"
#include "Object/GameObject/GO_FishingNode.h"
#include "Object/GameObject/CRitual.h"
Expand Down
4 changes: 4 additions & 0 deletions win/VC/arcemu-world.vcxproj
Original file line number Diff line number Diff line change
Expand Up @@ -304,6 +304,9 @@
<ClCompile Include="..\..\src\arcemu-world\Object\GameObject\GO_Ritual.cpp">
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../StdAfx.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\..\src\arcemu-world\Object\GameObject\GO_SpellCaster.cpp">
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../StdAfx.h</PrecompiledHeaderFile>
</ClCompile>
<ClCompile Include="..\..\src\arcemu-world\Object\GameObject\GO_SpellFocus.cpp">
<PrecompiledHeaderFile Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">../../StdAfx.h</PrecompiledHeaderFile>
</ClCompile>
Expand Down Expand Up @@ -469,6 +472,7 @@
<ClInclude Include="..\..\src\arcemu-world\Object\GameObject\GO_Lootable.h" />
<ClInclude Include="..\..\src\arcemu-world\Object\GameObject\GO_Questgiver.h" />
<ClInclude Include="..\..\src\arcemu-world\Object\GameObject\GO_Ritual.h" />
<ClInclude Include="..\..\src\arcemu-world\Object\GameObject\GO_SpellCaster.h" />
<ClInclude Include="..\..\src\arcemu-world\Object\GameObject\GO_SpellFocus.h" />
<ClInclude Include="..\..\src\arcemu-world\Object\GameObject\GO_Trap.h" />
<ClInclude Include="..\..\src\arcemu-world\object\gameobject\CRitual.h" />
Expand Down

0 comments on commit 34dd7ff

Please sign in to comment.