*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:
megamage
2009-08-19 23:05:36 -05:00
parent 411902af03
commit cf9022aa16
6 changed files with 137 additions and 20 deletions
@@ -17,19 +17,43 @@
#include "precompiled.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)
{
if (pCreature->isQuestGiver())
pPlayer->PrepareQuestMenu(pCreature->GetGUID());
if (pPlayer->HasAura(SPELL_CORPORAL))
pPlayer->ADD_GOSSIP_ITEM(GOSSIP_ICON_CHAT, "Build catapult.", GOSSIP_SENDER_MAIN, GOSSIP_ACTION_INFO_DEF);
else if (pPlayer->HasAura(SPELL_LIEUTENANT))
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);
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);
if (pPlayer->HasAura(SPELL_CORPORAL))
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);
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());
return true;
@@ -54,6 +78,7 @@ void AddSC_wintergrasp()
newscript = new Script;
newscript->Name = "npc_demolisher_engineerer";
newscript->GetAI = &GetAI_npc_demolisher_engineerer;
newscript->pGossipHello = &GossipHello_npc_demolisher_engineerer;
newscript->pGossipSelect = &GossipSelect_npc_demolisher_engineerer;
newscript->RegisterSelf();
+2 -3
View File
@@ -584,7 +584,6 @@ void OutdoorPvP::OnGameObjectCreate(GameObject *go, bool add)
if(go->GetGoType() != GAMEOBJECT_TYPE_CAPTURE_POINT)
return;
OutdoorPvP::OPvPCapturePointMap::iterator itr = m_capturePoints.find(go->GetDBTableGUIDLow());
if(itr != m_capturePoints.end())
itr->second->m_capturePoint = add ? go : NULL;
if(OPvPCapturePoint *cp = GetCapturePoint(go->GetDBTableGUIDLow()))
cp->m_capturePoint = add ? go : NULL;
}
+8
View File
@@ -226,6 +226,14 @@ protected:
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);
bool HasPlayer(Player *plr) const;
void TeamCastSpell(TeamId team, int32 spellId);
+2
View File
@@ -57,6 +57,8 @@ class TRINITY_DLL_SPEC UnitAI
// Pass parameters between AI
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 uint64 GetGUID(int32 id = 0) { return 0; }
+69 -8
View File
@@ -74,7 +74,7 @@ typedef std::list<const AreaPOIEntry *> AreaPOIList;
SiegeWorkshop::SiegeWorkshop(OPvPWintergrasp *opvp, BuildingState *state)
: 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);
if(entry != m_engineer->GetEntry() || !m_engineer->isAlive())
{
m_engineer->Respawn(true);
DespawnAllVehicles();
}
}
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()
{
m_defender = TeamId(rand()%2);
@@ -277,11 +286,13 @@ bool OPvPWintergrasp::SetupOutdoorPvP()
workshop->m_engEntry = const_cast<uint32*>(&creData->id);
const_cast<CreatureData*>(creData)->displayid = 0;
workshop->AddGO(0, guid, goData->id);
workshop->m_workshopGuid = guid;
workshop->m_engGuid = engGuid;
//workshop->AddGO(0, guid, goData->id);
//workshop->AddCre(0, engGuid, creData->id);
//sLog.outDebug("Demolisher Engineerer lowguid %u is linked to workshop lowguid %u.", engGuid, guid);
AddCapturePoint(workshop);
m_buildingStates[guid]->type = BUILDING_WORKSHOP;
workshop->SetStateByBuildingState();
}
}while(result->NextRow());
@@ -322,6 +333,10 @@ void OPvPWintergrasp::ProcessEvent(GameObject *obj, uint32 eventId)
else
itr->second->damageState = DAMAGE_DESTROYED;
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 28312:
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
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)
{
for(OutdoorPvP::OPvPCapturePointMap::iterator itr = m_capturePoints.begin(); itr != m_capturePoints.end(); ++itr)
if(SiegeWorkshop *workshop = dynamic_cast<SiegeWorkshop*>(itr->second))
if(workshop->m_engGuid == id)
return itr->first;
// if can build more vehicles
if(SiegeWorkshop *workshop = GetWorkshopByEngGuid(id))
return workshop->m_vehicles.size() < MAX_VEHICLE_PER_WORKSHOP ? 1 : 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
View File
@@ -58,6 +58,11 @@ enum OutdoorPvP_WG_Sounds
*/
};
enum DataId
{
DATA_ENGINEER_DIE,
};
enum OutdoorPvP_WG_KeepStatus
{
OutdoorPvP_WG_KEEP_TYPE_NEUTRAL = 0,
@@ -69,6 +74,13 @@ enum OutdoorPvP_WG_KeepStatus
OutdoorPvP_WG_KEEP_STATUS_HORDE_OCCUPIED = 4
};
enum BuildingType
{
BUILDING_WALL,
BUILDING_WORKSHOP,
BUILDING_TOWER,
};
enum DamageState
{
DAMAGE_INTACT,
@@ -83,13 +95,14 @@ struct BuildingState
explicit BuildingState(uint32 _worldState, TeamId _team, bool asDefault)
: worldState(_worldState), health(0)
, defaultTeam(asDefault ? _team : OTHER_TEAM(_team)), team(_team), damageState(DAMAGE_INTACT)
, building(NULL)
, building(NULL), type(BUILDING_WALL)
{}
uint32 worldState;
uint32 health;
TeamId team, defaultTeam;
DamageState damageState;
GameObject *building;
BuildingType type;
void SendUpdate(Player *player)
{
@@ -104,12 +117,15 @@ struct BuildingState
typedef std::map<uint32, uint32> TeamPairMap;
class SiegeWorkshop;
typedef std::set<Vehicle*> VehicleSet;
class OPvPWintergrasp : public OutdoorPvP
{
protected:
typedef std::map<uint32, BuildingState *> BuildingStateMap;
typedef std::set<Creature*> CreatureSet;
typedef std::set<Vehicle*> VehicleSet;
typedef std::set<GameObject*> GameObjectSet;
public:
explicit OPvPWintergrasp() : m_tenacityStack(0) {}
@@ -148,6 +164,10 @@ class OPvPWintergrasp : public OutdoorPvP
bool m_wartime;
uint32 m_timer;
SiegeWorkshop *GetWorkshop(uint32 lowguid) const;
SiegeWorkshop *GetWorkshopByEngGuid(uint32 lowguid) const;
SiegeWorkshop *GetWorkshopByGOGuid(uint32 lowguid) const;
void ChangeDefender();
void UpdateTenacityStack();
@@ -171,10 +191,12 @@ class SiegeWorkshop : public OPvPCapturePoint
explicit SiegeWorkshop(OPvPWintergrasp *opvp, BuildingState *state);
void SetStateByBuildingState();
void ChangeState();
uint32 m_vehNum;
void DespawnAllVehicles();
uint32 *m_engEntry;
uint32 m_engGuid;
Creature *m_engineer;
uint32 m_workshopGuid;
VehicleSet m_vehicles;
protected:
BuildingState *m_buildingState;
OPvPWintergrasp *m_wintergrasp;