Skip to content
Permalink
Browse files

Merging changes from dfighter branch. Arcemu now officially supports …

…destructable buildings!
  • Loading branch information
dfighter1985 committed Sep 27, 2011
1 parent 2ed16ae commit d0c3041d3fabfdd8d519ddb48f7b3c3069131de6
@@ -380,10 +380,13 @@ void CommandTableStorage::Init()
{ "spawn", 'o', &ChatHandler::HandleGOSpawn, "Spawns a GameObject by ID", NULL, 0, 0, 0 },
{ "phase", 'o', &ChatHandler::HandleGOPhaseCommand, "<phase> <save> - Phase selected GameObject", NULL, 0, 0, 0 },
{ "info", 'o', &ChatHandler::HandleGOInfo, "Gives you information about selected GO", NULL, 0, 0, 0 },
{ "damage", 'o', &ChatHandler::HandleGODamageCommand,"Damages the GO for the specified hitpoints",NULL, 0, 0, 0},
{ "rebuild", 'o', &ChatHandler::HandleGORebuildCommand,"Rebuilds the GO.", NULL, 0, 0, 0 },
{ "activate", 'o', &ChatHandler::HandleGOActivate, "Activates/Opens the selected GO.", NULL, 0, 0, 0 },
{ "enable", 'o', &ChatHandler::HandleGOEnable, "Enables the selected GO for use.", NULL, 0, 0, 0 },
{ "scale", 'o', &ChatHandler::HandleGOScale, "Sets scale of selected GO", NULL, 0, 0, 0 },
{ "animprogress", 'o', &ChatHandler::HandleGOAnimProgress, "Sets anim progress", NULL, 0, 0, 0 },
{ "faction", 'o', &ChatHandler::HandleGOFactionCommand,"Sets the faction of the GO", NULL, 0, 0, 0 },
{ "export", 'o', &ChatHandler::HandleGOExport, "Exports the current GO selected", NULL, 0, 0, 0 },
{ "move", 'g', &ChatHandler::HandleGOMove, "Moves gameobject to player xyz", NULL, 0, 0, 0 },
{ "rotate", 'g', &ChatHandler::HandleGORotate, "<Axis> <Value> - Rotates the object. <Axis> x,y, Default o.", NULL, 0, 0, 0 },
@@ -450,6 +450,9 @@ class SERVER_DECL ChatHandler : public Singleton<ChatHandler>
bool HandleGetTransporterTime(const char* args, WorldSession* m_session);
bool HandleSendItemPushResult(const char* args, WorldSession* m_session);
bool HandleGOAnimProgress(const char* args, WorldSession* m_session);
bool HandleGOFactionCommand( const char *args, WorldSession *session );
bool HandleGODamageCommand( const char *args, WorldSession *session );
bool HandleGORebuildCommand( const char *args, WorldSession *session );
bool HandleGOExport(const char* args, WorldSession* m_session);
bool HandleRemoveAurasCommand(const char* args, WorldSession* m_session);
bool HandleParalyzeCommand(const char* args, WorldSession* m_session);
@@ -54,6 +54,8 @@ GameObject::GameObject(uint64 guid)
m_respawnCell = NULL;
m_rotation = 0;
m_overrides = 0;
hitpoints = 0;
maxhitpoints = 0;
}

GameObject::~GameObject()
@@ -356,6 +358,9 @@ void GameObject::InitAI()
if(!pInfo)
return;

if( pInfo->Type == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING )
Rebuild();

// this fixes those fuckers in booty bay
if(pInfo->SpellFocus == 0 &&
pInfo->sound1 == 0 &&
@@ -827,3 +832,57 @@ uint8 GameObject::GetState()
return GetByte(GAMEOBJECT_BYTES_1, 0);
}

void GameObject::Damage( uint32 damage, uint64 AttackerGUID, uint64 ControllerGUID, uint32 SpellID ){
// If we are already destroyed there's nothing to damage!
if( hitpoints == 0 )
return;

if( damage >= hitpoints ){
// Instant destruction
hitpoints = 0;

SetFlags( GAMEOBJECT_FLAG_DESTROYED );
SetFlags( GetFlags() & ~GAMEOBJECT_FLAG_DAMAGED );
SetDisplayId( pInfo->sound9); // destroyed display id

CALL_GO_SCRIPT_EVENT( this, OnDestroyed)();

}else{
// Simply damaging
hitpoints -= damage;

if( !HasFlags( GAMEOBJECT_FLAG_DAMAGED ) ){
// Intact -> Damaged

// Are we below the intact-damaged transition treshold?
if( hitpoints <= ( maxhitpoints - pInfo->SpellFocus ) ){
SetFlags( GAMEOBJECT_FLAG_DAMAGED );
SetDisplayId( pInfo->sound4 ); // damaged display id
}
}

CALL_GO_SCRIPT_EVENT( this, OnDamaged )( damage );
}

uint8 animprogress = static_cast< uint8 >( Arcemu::round( hitpoints/ float( maxhitpoints ) ) * 255 );
SetAnimProgress( animprogress );
SendDamagePacket( damage, AttackerGUID, ControllerGUID, SpellID );
}

void GameObject::SendDamagePacket( uint32 damage, uint64 AttackerGUID, uint64 ControllerGUID, uint32 SpellID ){
WorldPacket data( SMSG_DESTRUCTIBLE_BUILDING_DAMAGE, 29 );

data << WoWGuid( GetNewGUID() );
data << WoWGuid( AttackerGUID );
data << WoWGuid( ControllerGUID );
data << uint32( damage );
data << uint32( SpellID );
SendMessageToSet( &data, false, false );
}

void GameObject::Rebuild(){
SetFlags( GetFlags() & uint32( ~( GAMEOBJECT_FLAG_DAMAGED | GAMEOBJECT_FLAG_DESTROYED ) ) );
SetDisplayId( pInfo->DisplayID );
maxhitpoints = pInfo->SpellFocus + pInfo->sound5;
hitpoints = maxhitpoints;
}
@@ -21,6 +21,19 @@
#ifndef WOWSERVER_GAMEOBJECT_H
#define WOWSERVER_GAMEOBJECT_H

enum GO_STATE{
GAMEOBJECT_STATE_OPEN = 0,
GAMEOBJECT_STATE_CLOSED = 1,
GAMEOBJECT_STATE_ALTERNATIVE_OPEN = 2
};

enum GO_FLAGS{
GAMEOBJECT_FLAG_NONSELECTABLE = 0x1,
GAMEOBJECT_FLAG_LOCKED = 0x2,
GAMEOBJECT_FLAG_DAMAGED = 0x200,
GAMEOBJECT_FLAG_DESTROYED = 0x400
};

class Player;
class GameObjectAIScript;
class GameObjectTemplate;
@@ -298,6 +311,82 @@ class SERVER_DECL GameObject : public Object

void SetType(uint8 type) { SetByte(GAMEOBJECT_BYTES_1, 1, type); }
uint8 GetType() { return GetByte(GAMEOBJECT_BYTES_1, 1); }

void SetFlags( uint32 flags ){ SetUInt32Value( GAMEOBJECT_FLAGS, flags ); }
uint32 GetFlags(){ return GetUInt32Value( GAMEOBJECT_FLAGS ); }

bool HasFlags( uint32 flags ){
if( HasFlag( GAMEOBJECT_FLAGS, flags ) != 0 )
return true;
else
return false;
}

void SetArtKit( uint8 artkit ){ SetByte( GAMEOBJECT_BYTES_1, 2, artkit ); }
uint8 GetArtkKit(){ return GetByte( GAMEOBJECT_BYTES_1, 2 ); }
void SetAnimProgress( uint8 progress ){ SetByte( GAMEOBJECT_BYTES_1, 3, progress ); }
uint8 GetAnimProgress(){ return GetByte( GAMEOBJECT_BYTES_1, 3 ); }

//////////////////////////////////////////////////////////////////////////////////////////////////////////
//void Damage( uint32 damage, uint64 AttackerGUID, uint64 ControllerGUID, uint32 SpellID )
// Damages the destructible GameObject with a spell
//
//Parameters
// uint32 damage - The hit points that the GO will lose
// uint64 AttackerGUID - GUID of the caster of the damaging spell
// uint64 ControllerGUID - GUID of the controller of the caster of the damaging spell
// uint32 SpellID - ID of the damaging spell
//
//Return Value
// None
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
void Damage( uint32 damage, uint64 AttackerGUID, uint64 ControllerGUID, uint32 SpellID );

////////////////////////////////////////////////////////////////////////////////////////////////////////
//void Rebuild()
// Rebuilds the damaged/destroyed GameObject.
//
//Parameters
// None
//
//Return Value
// None
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
void Rebuild();


////////////////////////////////////////////////////////////////////////////////////////////////////////
//uint32 GetHP()
// Returns the current hitpoints of the GameObject
//
//Parameters
// None
//
//Return Value
// Returns the current hitpoints of the GameObject
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
uint32 GetHP(){ return hitpoints; }


////////////////////////////////////////////////////////////////////////////////////////////////////////
//uint32 GetMaxHP()
// Returns the maximum hitpoints of the GameObject
//
//Parameters
// None
//
//Return Value
// Returns the maximum hitpoints of the GameObject
//
//
////////////////////////////////////////////////////////////////////////////////////////////////////////
uint32 GetMaxHP(){ return maxhitpoints; }

protected:

@@ -310,6 +399,28 @@ class SERVER_DECL GameObject : public Object

uint32 m_overrides; //See enum GAMEOBJECT_OVERRIDES!


///////////////////////////////////////////////////////////////////////////////////////////////////////
//void SendDamagePacket( uint32 damage, uint64 AttackerGUID, uint64 ControllerGUID, uint32 SpellID )
// Notifies the surrounding clients about the GameObject taking damage
//
//Parameters
// uint32 damage - The hit points that the GO will lose
// uint64 AttackerGUID - GUID of the caster of the damaging spell
// uint64 ControllerGUID - GUID of the controller of the caster of the damaging spell
// uint32 SpellID - ID of the damaging spell
//
//Return Value
// None
//
//
//////////////////////////////////////////////////////////////////////////////////////////////////////
void SendDamagePacket( uint32 damage, uint64 AttackerGUID, uint64 ControllerGUID, uint32 SpellID );


uint32 hitpoints;
uint32 maxhitpoints;

};

#endif
@@ -1040,6 +1040,9 @@ bool ChatHandler::HandleGOInfo(const char* args, WorldSession* m_session)
case GAMEOBJECT_TYPE_FLAGDROP:
strcpy(gotypetxt, "Flag Drop");
break;
case GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING:
strcpy(gotypetxt, "Destructible Building");
break;
default:
strcpy(gotypetxt, "Unknown.");
break;
@@ -1062,6 +1065,10 @@ bool ChatHandler::HandleGOInfo(const char* args, WorldSession* m_session)
SystemMessage(m_session, "%s Parent Rotation O2:%s%f", MSG_COLOR_GREEN, MSG_COLOR_LIGHTBLUE, GObj->GetParentRotation(2));
SystemMessage(m_session, "%s Parent Rotation O3:%s%f", MSG_COLOR_GREEN, MSG_COLOR_LIGHTBLUE, GObj->GetParentRotation(3));

if( GOInfo->Type == GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING ){
SystemMessage(m_session, "%s HP:%s%u/%u", MSG_COLOR_GREEN, MSG_COLOR_LIGHTBLUE, GObj->GetHP(), GObj->GetMaxHP() );
}

return true;
}

@@ -1338,6 +1345,88 @@ bool ChatHandler::HandleGOAnimProgress(const char* args, WorldSession* m_session
return true;
}

bool ChatHandler::HandleGOFactionCommand( const char *args, WorldSession *session ){
GameObject *go = session->GetPlayer()->GetSelectedGo();
if( go == NULL ){
RedSystemMessage( session, "You need to select a GO first!" );
return true;
}

if( *args == '\0' ){
RedSystemMessage( session, "You need to specify a faction!" );
return true;
}

std::stringstream ss( args );
uint32 faction = 0;

ss >> faction;
if( ss.fail() ){
RedSystemMessage( session, "You need to specify a faction!" );
return true;
}

go->SetFaction( faction );

BlueSystemMessage( session, "GameObject faction has been changed to %u", faction );

return true;
}

bool ChatHandler::HandleGODamageCommand( const char *args, WorldSession *session ){
GameObject *go = session->GetPlayer()->GetSelectedGo();
if( go == NULL ){
RedSystemMessage( session, "You need to select a GO first!" );
return true;
}

if( go->GetInfo()->Type != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING ){
RedSystemMessage( session, "The selected GO must be a destructible building!" );
return true;
}

if( *args == '\0' ){
RedSystemMessage( session, "You need to specify how much you want to damage the selected GO!" );
return true;
}

uint32 damage = 0;
std::stringstream ss( args );

ss >> damage;
if( ss.fail() ){
RedSystemMessage( session, "You need to specify how much you want to damage the selected GO!" );
return true;
}

uint64 guid = session->GetPlayer()->GetGUID();

BlueSystemMessage( session, "Attempting to damage GO..." );

go->Damage( damage, guid, guid, 0 );

return true;
}

bool ChatHandler::HandleGORebuildCommand( const char *args, WorldSession *session ){
GameObject *go = session->GetPlayer()->GetSelectedGo();
if( go == NULL ){
RedSystemMessage( session, "You need to select a GO first!" );
return true;
}

if( go->GetInfo()->Type != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING ){
RedSystemMessage( session, "The selected GO must be a destructible building!" );
return true;
}

BlueSystemMessage( session, "Attempting to rebuild building..." );

go->Rebuild();

return true;
}

bool ChatHandler::HandleGOExport(const char* args, WorldSession* m_session)
{
/*if(!m_session->GetPlayer()->m_GM_SelectedGO)
@@ -446,6 +446,8 @@ class SERVER_DECL GameObjectAIScript
virtual void OnDespawn() {}
virtual void OnLootTaken(Player* pLooter, ItemPrototype* pItemInfo) {}
virtual void OnActivate(Player* pPlayer) {}
virtual void OnDamaged( uint32 damage ){}
virtual void OnDestroyed(){}
virtual void AIUpdate() {}
virtual void Destroy() { delete this; }

@@ -1874,6 +1874,7 @@ class SERVER_DECL Spell : public EventableObject
void SpellEffectStuck(uint32 i);
void SpellEffectSummonPlayer(uint32 i);
void SpellEffectActivateObject(uint32 i);
void SpellEffectBuildingDamage(uint32 i);
void SpellEffectEnchantHeldItem(uint32 i);
void SpellEffectSetMirrorName(uint32 i);
void SpellEffectSelfResurrect(uint32 i);
@@ -109,7 +109,7 @@ pSpellEffect SpellEffectsHandler[TOTAL_SPELL_EFFECTS] =
&Spell::SpellEffectStuck, //SPELL_EFFECT_STUCK - 84
&Spell::SpellEffectSummonPlayer, //SPELL_EFFECT_SUMMON_PLAYER - 85
&Spell::SpellEffectActivateObject, //SPELL_EFFECT_ACTIVATE_OBJECT - 86
&Spell::SpellEffectNULL, //SPELL_EFFECT_BUILDING_DAMAGE - 87
&Spell::SpellEffectBuildingDamage, //SPELL_EFFECT_BUILDING_DAMAGE - 87
&Spell::SpellEffectNULL, //SPELL_EFFECT_BUILDING_REPAIR - 88
&Spell::SpellEffectNULL, //SPELL_EFFECT_BUILDING_SWITCH_STATE - 89
&Spell::SpellEffectNULL, //SPELL_EFFECT_KILL_CREDIT_90 - 90
@@ -4058,6 +4058,30 @@ void Spell::SpellEffectActivateObject(uint32 i) // Activate Object
}


void Spell::SpellEffectBuildingDamage(uint32 i){
if( gameObjTarget == NULL )
return;

if( gameObjTarget->GetInfo()->Type != GAMEOBJECT_TYPE_DESTRUCTIBLE_BUILDING )
return;

if( u_caster == NULL )
return;

uint32 damage = m_spellInfo->EffectBasePoints[ i ] + 1;
Unit *controller = NULL;

if( u_caster->GetVehicleComponent() != NULL )
controller = u_caster->GetMapMgr()->GetUnit( u_caster->GetCharmedByGUID() );

if( controller == NULL )
controller = u_caster;

// Baaaam
gameObjTarget->Damage( damage, u_caster->GetGUID(), controller->GetGUID(), m_spellInfo->Id );
}



void Spell::SpellEffectEnchantHeldItem(uint32 i)
{

0 comments on commit d0c3041

Please sign in to comment.
You can’t perform that action at this time.