*Wintergrasp: only allow a workshop to build 4 vehicles.
*remove all existing vehicles when workshop is destroyed or captured. --HG-- branch : trunk
This commit is contained in:
@@ -17,19 +17,43 @@
|
|||||||
#include "precompiled.h"
|
#include "precompiled.h"
|
||||||
#include "Wintergrasp.h"
|
#include "Wintergrasp.h"
|
||||||
|
|
||||||
|
|
||||||
|
struct TRINITY_DLL_DECL npc_demolisher_engineererAI : public ScriptedAI
|
||||||
|
{
|
||||||
|
npc_demolisher_engineererAI(Creature* pCreature) : ScriptedAI(pCreature) {}
|
||||||
|
|
||||||
|
/*
|
||||||
|
void JustDied(Unit *killer)
|
||||||
|
{
|
||||||
|
if(me->GetZoneScript())
|
||||||
|
me->GetZoneScript()->SetData(DATA_ENGINEER_DIE, me->GetDBTableGUIDLow());
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
};
|
||||||
|
|
||||||
|
CreatureAI* GetAI_npc_demolisher_engineerer(Creature* pCreature)
|
||||||
|
{
|
||||||
|
return new npc_demolisher_engineererAI (pCreature);
|
||||||
|
}
|
||||||
|
|
||||||
bool GossipHello_npc_demolisher_engineerer(Player* pPlayer, Creature* pCreature)
|
bool GossipHello_npc_demolisher_engineerer(Player* pPlayer, Creature* pCreature)
|
||||||
{
|
{
|
||||||
if (pCreature->isQuestGiver())
|
if (pCreature->isQuestGiver())
|
||||||
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
|
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
|
||||||
|
|
||||||
if (pPlayer->HasAura(SPELL_CORPORAL))
|
if(pPlayer->isGameMaster() || pCreature->GetZoneScript() && pCreature->GetZoneScript()->GetData(pCreature->GetDBTableGUIDLow()))
|
||||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Build catapult.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
|
||||||
else if (pPlayer->HasAura(SPELL_LIEUTENANT))
|
|
||||||
{
|
{
|
||||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Build catapult.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
if (pPlayer->HasAura(SPELL_CORPORAL))
|
||||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Build demolisher.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Build catapult.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||||
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Build siege engine.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
|
else if (pPlayer->HasAura(SPELL_LIEUTENANT))
|
||||||
|
{
|
||||||
|
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Build catapult.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
|
||||||
|
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Build demolisher.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+1);
|
||||||
|
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Build siege engine.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "I cannot build more!", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF+9);
|
||||||
|
|
||||||
pPlayer->SEND_GOSSIP_MENU(pCreature->GetNpcTextId(), pCreature->GetGUID());
|
pPlayer->SEND_GOSSIP_MENU(pCreature->GetNpcTextId(), pCreature->GetGUID());
|
||||||
return true;
|
return true;
|
||||||
@@ -54,6 +78,7 @@ void AddSC_wintergrasp()
|
|||||||
|
|
||||||
newscript = new Script;
|
newscript = new Script;
|
||||||
newscript->Name = "npc_demolisher_engineerer";
|
newscript->Name = "npc_demolisher_engineerer";
|
||||||
|
newscript->GetAI = &GetAI_npc_demolisher_engineerer;
|
||||||
newscript->pGossipHello = &GossipHello_npc_demolisher_engineerer;
|
newscript->pGossipHello = &GossipHello_npc_demolisher_engineerer;
|
||||||
newscript->pGossipSelect = &GossipSelect_npc_demolisher_engineerer;
|
newscript->pGossipSelect = &GossipSelect_npc_demolisher_engineerer;
|
||||||
newscript->RegisterSelf();
|
newscript->RegisterSelf();
|
||||||
|
|||||||
@@ -584,7 +584,6 @@ void OutdoorPvP::OnGameObjectCreate(GameObject *go, bool add)
|
|||||||
if(go->GetGoType() != GAMEOBJECT_TYPE_CAPTURE_POINT)
|
if(go->GetGoType() != GAMEOBJECT_TYPE_CAPTURE_POINT)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
OutdoorPvP::OPvPCapturePointMap::iterator itr = m_capturePoints.find(go->GetDBTableGUIDLow());
|
if(OPvPCapturePoint *cp = GetCapturePoint(go->GetDBTableGUIDLow()))
|
||||||
if(itr != m_capturePoints.end())
|
cp->m_capturePoint = add ? go : NULL;
|
||||||
itr->second->m_capturePoint = add ? go : NULL;
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -226,6 +226,14 @@ protected:
|
|||||||
m_capturePoints[cp->m_CapturePointGUID] = cp;
|
m_capturePoints[cp->m_CapturePointGUID] = cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OPvPCapturePoint * GetCapturePoint(uint32 lowguid) const
|
||||||
|
{
|
||||||
|
OutdoorPvP::OPvPCapturePointMap::const_iterator itr = m_capturePoints.find(lowguid);
|
||||||
|
if(itr != m_capturePoints.end())
|
||||||
|
return itr->second;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void RegisterZone(uint32 zoneid);
|
void RegisterZone(uint32 zoneid);
|
||||||
bool HasPlayer(Player *plr) const;
|
bool HasPlayer(Player *plr) const;
|
||||||
void TeamCastSpell(TeamId team, int32 spellId);
|
void TeamCastSpell(TeamId team, int32 spellId);
|
||||||
|
|||||||
@@ -57,6 +57,8 @@ class TRINITY_DLL_SPEC UnitAI
|
|||||||
|
|
||||||
// Pass parameters between AI
|
// Pass parameters between AI
|
||||||
virtual void DoAction(const int32 param = 0) {}
|
virtual void DoAction(const int32 param = 0) {}
|
||||||
|
virtual uint32 GetData(uint32 id = 0) { return 0; }
|
||||||
|
virtual void SetData(uint32 id, uint32 value) {}
|
||||||
virtual void SetGUID(const uint64 &guid, int32 id = 0) {}
|
virtual void SetGUID(const uint64 &guid, int32 id = 0) {}
|
||||||
virtual uint64 GetGUID(int32 id = 0) { return 0; }
|
virtual uint64 GetGUID(int32 id = 0) { return 0; }
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ typedef std::list<const AreaPOIEntry *> AreaPOIList;
|
|||||||
|
|
||||||
SiegeWorkshop::SiegeWorkshop(OPvPWintergrasp *opvp, BuildingState *state)
|
SiegeWorkshop::SiegeWorkshop(OPvPWintergrasp *opvp, BuildingState *state)
|
||||||
: OPvPCapturePoint(opvp), m_buildingState(state), m_wintergrasp(opvp)
|
: OPvPCapturePoint(opvp), m_buildingState(state), m_wintergrasp(opvp)
|
||||||
, m_vehNum(0), m_engineer(NULL), m_engGuid(0)
|
, m_engineer(NULL), m_engGuid(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -133,12 +133,21 @@ void SiegeWorkshop::ChangeState()
|
|||||||
{
|
{
|
||||||
m_engineer->SetOriginalEntry(entry);
|
m_engineer->SetOriginalEntry(entry);
|
||||||
if(entry != m_engineer->GetEntry() || !m_engineer->isAlive())
|
if(entry != m_engineer->GetEntry() || !m_engineer->isAlive())
|
||||||
|
{
|
||||||
m_engineer->Respawn(true);
|
m_engineer->Respawn(true);
|
||||||
|
DespawnAllVehicles();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
sLog.outDebug("Wintergrasp workshop now belongs to %u.", (uint32)m_buildingState->team);
|
sLog.outDebug("Wintergrasp workshop now belongs to %u.", (uint32)m_buildingState->team);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void SiegeWorkshop::DespawnAllVehicles()
|
||||||
|
{
|
||||||
|
while(!m_vehicles.empty())
|
||||||
|
(*m_vehicles.begin())->Dismiss();
|
||||||
|
}
|
||||||
|
|
||||||
bool OPvPWintergrasp::SetupOutdoorPvP()
|
bool OPvPWintergrasp::SetupOutdoorPvP()
|
||||||
{
|
{
|
||||||
m_defender = TeamId(rand()%2);
|
m_defender = TeamId(rand()%2);
|
||||||
@@ -277,11 +286,13 @@ bool OPvPWintergrasp::SetupOutdoorPvP()
|
|||||||
|
|
||||||
workshop->m_engEntry = const_cast<uint32*>(&creData->id);
|
workshop->m_engEntry = const_cast<uint32*>(&creData->id);
|
||||||
const_cast<CreatureData*>(creData)->displayid = 0;
|
const_cast<CreatureData*>(creData)->displayid = 0;
|
||||||
workshop->AddGO(0, guid, goData->id);
|
workshop->m_workshopGuid = guid;
|
||||||
workshop->m_engGuid = engGuid;
|
workshop->m_engGuid = engGuid;
|
||||||
|
//workshop->AddGO(0, guid, goData->id);
|
||||||
//workshop->AddCre(0, engGuid, creData->id);
|
//workshop->AddCre(0, engGuid, creData->id);
|
||||||
//sLog.outDebug("Demolisher Engineerer lowguid %u is linked to workshop lowguid %u.", engGuid, guid);
|
//sLog.outDebug("Demolisher Engineerer lowguid %u is linked to workshop lowguid %u.", engGuid, guid);
|
||||||
AddCapturePoint(workshop);
|
AddCapturePoint(workshop);
|
||||||
|
m_buildingStates[guid]->type = BUILDING_WORKSHOP;
|
||||||
workshop->SetStateByBuildingState();
|
workshop->SetStateByBuildingState();
|
||||||
}
|
}
|
||||||
}while(result->NextRow());
|
}while(result->NextRow());
|
||||||
@@ -322,6 +333,10 @@ void OPvPWintergrasp::ProcessEvent(GameObject *obj, uint32 eventId)
|
|||||||
else
|
else
|
||||||
itr->second->damageState = DAMAGE_DESTROYED;
|
itr->second->damageState = DAMAGE_DESTROYED;
|
||||||
BroadcastStateChange(itr->second);
|
BroadcastStateChange(itr->second);
|
||||||
|
|
||||||
|
if(itr->second->type == BUILDING_WORKSHOP)
|
||||||
|
if(SiegeWorkshop *workshop = GetWorkshop(obj->GetDBTableGUIDLow()))
|
||||||
|
workshop->DespawnAllVehicles();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -359,6 +374,25 @@ void OPvPWintergrasp::OnCreatureCreate(Creature *creature, bool add)
|
|||||||
case 28094:
|
case 28094:
|
||||||
case 28312:
|
case 28312:
|
||||||
case 32627:
|
case 32627:
|
||||||
|
if(uint32 engLowguid = GUID_LOPART(creature->GetOwnerGUID()))
|
||||||
|
{
|
||||||
|
if(SiegeWorkshop *workshop = GetWorkshopByEngGuid(engLowguid))
|
||||||
|
{
|
||||||
|
if(add)
|
||||||
|
{
|
||||||
|
if(workshop->m_vehicles.size() >= MAX_VEHICLE_PER_WORKSHOP)
|
||||||
|
{
|
||||||
|
creature->setDeathState(DEAD);
|
||||||
|
creature->SetRespawnTime(DAY);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
workshop->m_vehicles.insert((Vehicle*)creature);
|
||||||
|
}
|
||||||
|
// TODO: now you have to wait until the corpse of vehicle disappear to build a new one
|
||||||
|
else if(!workshop->m_vehicles.erase((Vehicle*)creature))
|
||||||
|
sLog.outError("OPvPWintergrasp::OnCreatureCreate: a vehicle is removed but it does not have record in workshop!");
|
||||||
|
}
|
||||||
|
}
|
||||||
//case 28366: tower
|
//case 28366: tower
|
||||||
if(add)
|
if(add)
|
||||||
{
|
{
|
||||||
@@ -723,16 +757,43 @@ void OPvPWintergrasp::EndBattle()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void OPvPWintergrasp::SetData(uint32 id, uint32 value)
|
||||||
|
{
|
||||||
|
if(id == DATA_ENGINEER_DIE)
|
||||||
|
if(SiegeWorkshop *workshop = GetWorkshopByEngGuid(value))
|
||||||
|
workshop->DespawnAllVehicles();
|
||||||
|
}
|
||||||
|
|
||||||
uint32 OPvPWintergrasp::GetData(uint32 id)
|
uint32 OPvPWintergrasp::GetData(uint32 id)
|
||||||
{
|
{
|
||||||
for(OutdoorPvP::OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
|
// if can build more vehicles
|
||||||
if(SiegeWorkshop *workshop = dynamic_cast<SiegeWorkshop*>(itr->second))
|
if(SiegeWorkshop *workshop = GetWorkshopByEngGuid(id))
|
||||||
if(workshop->m_engGuid == id)
|
return workshop->m_vehicles.size() < MAX_VEHICLE_PER_WORKSHOP ? 1 : 0;
|
||||||
return itr->first;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void OPvPWintergrasp::SetData(uint32 id, uint32 value)
|
SiegeWorkshop *OPvPWintergrasp::GetWorkshop(uint32 lowguid) const
|
||||||
{
|
{
|
||||||
|
if(OPvPCapturePoint *cp = GetCapturePoint(lowguid))
|
||||||
|
return dynamic_cast<SiegeWorkshop*>(cp);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SiegeWorkshop *OPvPWintergrasp::GetWorkshopByEngGuid(uint32 lowguid) const
|
||||||
|
{
|
||||||
|
for(OutdoorPvP::OPvPCapturePointMap::const_iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
|
||||||
|
if(SiegeWorkshop *workshop = dynamic_cast<SiegeWorkshop*>(itr->second))
|
||||||
|
if(workshop->m_engGuid == lowguid)
|
||||||
|
return workshop;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
SiegeWorkshop *OPvPWintergrasp::GetWorkshopByGOGuid(uint32 lowguid) const
|
||||||
|
{
|
||||||
|
for(OutdoorPvP::OPvPCapturePointMap::const_iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
|
||||||
|
if(SiegeWorkshop *workshop = dynamic_cast<SiegeWorkshop*>(itr->second))
|
||||||
|
if(workshop->m_workshopGuid == lowguid)
|
||||||
|
return workshop;
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|||||||
+25
-3
@@ -58,6 +58,11 @@ enum OutdoorPvP_WG_Sounds
|
|||||||
*/
|
*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum DataId
|
||||||
|
{
|
||||||
|
DATA_ENGINEER_DIE,
|
||||||
|
};
|
||||||
|
|
||||||
enum OutdoorPvP_WG_KeepStatus
|
enum OutdoorPvP_WG_KeepStatus
|
||||||
{
|
{
|
||||||
OutdoorPvP_WG_KEEP_TYPE_NEUTRAL = 0,
|
OutdoorPvP_WG_KEEP_TYPE_NEUTRAL = 0,
|
||||||
@@ -69,6 +74,13 @@ enum OutdoorPvP_WG_KeepStatus
|
|||||||
OutdoorPvP_WG_KEEP_STATUS_HORDE_OCCUPIED = 4
|
OutdoorPvP_WG_KEEP_STATUS_HORDE_OCCUPIED = 4
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum BuildingType
|
||||||
|
{
|
||||||
|
BUILDING_WALL,
|
||||||
|
BUILDING_WORKSHOP,
|
||||||
|
BUILDING_TOWER,
|
||||||
|
};
|
||||||
|
|
||||||
enum DamageState
|
enum DamageState
|
||||||
{
|
{
|
||||||
DAMAGE_INTACT,
|
DAMAGE_INTACT,
|
||||||
@@ -83,13 +95,14 @@ struct BuildingState
|
|||||||
explicit BuildingState(uint32 _worldState, TeamId _team, bool asDefault)
|
explicit BuildingState(uint32 _worldState, TeamId _team, bool asDefault)
|
||||||
: worldState(_worldState), health(0)
|
: worldState(_worldState), health(0)
|
||||||
, defaultTeam(asDefault ? _team : OTHER_TEAM(_team)), team(_team), damageState(DAMAGE_INTACT)
|
, defaultTeam(asDefault ? _team : OTHER_TEAM(_team)), team(_team), damageState(DAMAGE_INTACT)
|
||||||
, building(NULL)
|
, building(NULL), type(BUILDING_WALL)
|
||||||
{}
|
{}
|
||||||
uint32 worldState;
|
uint32 worldState;
|
||||||
uint32 health;
|
uint32 health;
|
||||||
TeamId team, defaultTeam;
|
TeamId team, defaultTeam;
|
||||||
DamageState damageState;
|
DamageState damageState;
|
||||||
GameObject *building;
|
GameObject *building;
|
||||||
|
BuildingType type;
|
||||||
|
|
||||||
void SendUpdate(Player *player)
|
void SendUpdate(Player *player)
|
||||||
{
|
{
|
||||||
@@ -104,12 +117,15 @@ struct BuildingState
|
|||||||
|
|
||||||
typedef std::map<uint32, uint32> TeamPairMap;
|
typedef std::map<uint32, uint32> TeamPairMap;
|
||||||
|
|
||||||
|
class SiegeWorkshop;
|
||||||
|
|
||||||
|
typedef std::set<Vehicle*> VehicleSet;
|
||||||
|
|
||||||
class OPvPWintergrasp : public OutdoorPvP
|
class OPvPWintergrasp : public OutdoorPvP
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
typedef std::map<uint32, BuildingState *> BuildingStateMap;
|
typedef std::map<uint32, BuildingState *> BuildingStateMap;
|
||||||
typedef std::set<Creature*> CreatureSet;
|
typedef std::set<Creature*> CreatureSet;
|
||||||
typedef std::set<Vehicle*> VehicleSet;
|
|
||||||
typedef std::set<GameObject*> GameObjectSet;
|
typedef std::set<GameObject*> GameObjectSet;
|
||||||
public:
|
public:
|
||||||
explicit OPvPWintergrasp() : m_tenacityStack(0) {}
|
explicit OPvPWintergrasp() : m_tenacityStack(0) {}
|
||||||
@@ -148,6 +164,10 @@ class OPvPWintergrasp : public OutdoorPvP
|
|||||||
bool m_wartime;
|
bool m_wartime;
|
||||||
uint32 m_timer;
|
uint32 m_timer;
|
||||||
|
|
||||||
|
SiegeWorkshop *GetWorkshop(uint32 lowguid) const;
|
||||||
|
SiegeWorkshop *GetWorkshopByEngGuid(uint32 lowguid) const;
|
||||||
|
SiegeWorkshop *GetWorkshopByGOGuid(uint32 lowguid) const;
|
||||||
|
|
||||||
void ChangeDefender();
|
void ChangeDefender();
|
||||||
|
|
||||||
void UpdateTenacityStack();
|
void UpdateTenacityStack();
|
||||||
@@ -171,10 +191,12 @@ class SiegeWorkshop : public OPvPCapturePoint
|
|||||||
explicit SiegeWorkshop(OPvPWintergrasp *opvp, BuildingState *state);
|
explicit SiegeWorkshop(OPvPWintergrasp *opvp, BuildingState *state);
|
||||||
void SetStateByBuildingState();
|
void SetStateByBuildingState();
|
||||||
void ChangeState();
|
void ChangeState();
|
||||||
uint32 m_vehNum;
|
void DespawnAllVehicles();
|
||||||
uint32 *m_engEntry;
|
uint32 *m_engEntry;
|
||||||
uint32 m_engGuid;
|
uint32 m_engGuid;
|
||||||
Creature *m_engineer;
|
Creature *m_engineer;
|
||||||
|
uint32 m_workshopGuid;
|
||||||
|
VehicleSet m_vehicles;
|
||||||
protected:
|
protected:
|
||||||
BuildingState *m_buildingState;
|
BuildingState *m_buildingState;
|
||||||
OPvPWintergrasp *m_wintergrasp;
|
OPvPWintergrasp *m_wintergrasp;
|
||||||
|
|||||||
Reference in New Issue
Block a user