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 },
View
@@ -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; }
View
@@ -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)
{
Oops, something went wrong.

0 comments on commit d0c3041

Please sign in to comment.