Skip to content

Commit

Permalink
Scripts: Implement SCRIPT_COMMAND_RECALL_OR_RESPAWN_ACCESSORIES
Browse files Browse the repository at this point in the history
  • Loading branch information
killerwife committed Jan 27, 2024
1 parent 2b71c05 commit ce715ca
Show file tree
Hide file tree
Showing 5 changed files with 128 additions and 16 deletions.
5 changes: 5 additions & 0 deletions doc/script_commands.txt
Original file line number Diff line number Diff line change
Expand Up @@ -445,3 +445,8 @@ Defining a buddy could be done in several way:
* datalong = string_id id
* apply = 0 remove, 1 add

56 SCRIPT_COMMAND_RECALL_OR_RESPAWN_ACCESSORIES Recalls or respawns source vehicle accessories
* datalong = 0x1 recall, 0x2 respawn, 0x3 recall and respawn
* datalong2 = max distance for recall, of 0 any distance
* dataint = seat index for recall or respawn, if -1, all seats per vehicle accessory template

32 changes: 32 additions & 0 deletions src/game/DBScripts/ScriptMgr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -948,6 +948,18 @@ void ScriptMgr::LoadScripts(ScriptMapType scriptType)
}
break;
}
case SCRIPT_COMMAND_RECALL_OR_RESPAWN_ACCESSORIES: // 56
if (tmp.recallOrRespawnPassenger.recallRespawnFlag > 0x3)
{
sLog.outErrorDb("Table `%s` has invalid recall respawn flags assigned %u", tablename, tmp.recallOrRespawnPassenger.recallRespawnFlag);
continue;
}
if (tmp.textId[0] >= MAX_VEHICLE_SEAT || tmp.textId[0] < -1)
{
sLog.outErrorDb("Table `%s` has seat index assigned %d", tablename, tmp.textId[0]);
continue;
}
break;
default:
{
sLog.outErrorDb("Table `%s` unknown command %u, skipping.", tablename, tmp.command);
Expand Down Expand Up @@ -3278,6 +3290,26 @@ bool ScriptAction::ExecuteDbscriptCommand(WorldObject* pSource, WorldObject* pTa
pSource->SetStringId(m_script->stringId.stringId, m_script->stringId.apply);
break;
}
case SCRIPT_COMMAND_RECALL_OR_RESPAWN_ACCESSORIES:
{
if (LogIfNotUnit(pSource))
break;

if (!static_cast<Unit*>(pSource)->IsVehicle())
{
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u source is not vehicle.",
m_table, m_script->id, m_script->command);
}
uint32 flags = m_script->recallOrRespawnPassenger.recallRespawnFlag;
int32 seatIndex = m_script->textId[0];
if (flags == 1)
static_cast<Unit*>(pSource)->GetVehicleInfo()->RecallAccessories(m_script->recallOrRespawnPassenger.searchRadius, seatIndex);
else if (flags == 2)
static_cast<Unit*>(pSource)->GetVehicleInfo()->RespawnAccessories(seatIndex);
else if (flags == 3)
static_cast<Unit*>(pSource)->GetVehicleInfo()->RecallAndRespawnAccessories(m_script->recallOrRespawnPassenger.searchRadius, seatIndex);
break;
}
default:
sLog.outErrorDb(" DB-SCRIPTS: Process table `%s` id %u, command %u unknown command used.",
m_table, m_script->id, m_script->command);
Expand Down
7 changes: 7 additions & 0 deletions src/game/DBScripts/ScriptMgr.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,7 @@ enum ScriptCommand // resSource, resTar
SCRIPT_COMMAND_SET_WORLDSTATE = 53, // dataint = worldstate id, dataint2 = new value,
SCRIPT_COMMAND_SET_SHEATHE = 54, // dataint = worldstate id, dataint2 = new value,
SCRIPT_COMMAND_SET_STRING_ID = 55, // datalong = string_id id, datalong2 = 0 unapply, 1 apply
SCRIPT_COMMAND_RECALL_OR_RESPAWN_ACCESSORIES = 56 // datalong = 0x1 recall, 0x2 respawn, 0x3 recall and respawn, datalong2 = search radius for recall
};

#define MAX_TEXT_ID 4 // used for SCRIPT_COMMAND_TALK, SCRIPT_COMMAND_EMOTE, SCRIPT_COMMAND_CAST_SPELL, SCRIPT_COMMAND_TERMINATE_SCRIPT
Expand Down Expand Up @@ -483,6 +484,12 @@ struct ScriptInfo
uint32 apply; // datalong2
} stringId;

struct // SCRIPT_COMMAND_RECALL_OR_RESPAWN_ACCESSORIES (56)
{
uint32 recallRespawnFlag; // datalong
uint32 searchRadius; // datalong2
} recallOrRespawnPassenger;

struct
{
uint32 data[3];
Expand Down
86 changes: 74 additions & 12 deletions src/game/Entities/Vehicle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,9 @@ void VehicleInfo::Initialize()
SQLMultiStorage::SQLMSIteratorBounds<VehicleAccessory> bounds = sVehicleAccessoryStorage.getBounds<VehicleAccessory>(m_overwriteNpcEntry);
for (SQLMultiStorage::SQLMultiSIterator<VehicleAccessory> itr = bounds.first; itr != bounds.second; ++itr)
{
if (Creature* summoned = m_owner->SummonCreature(itr->passengerEntry, m_owner->GetPositionX(), m_owner->GetPositionY(), m_owner->GetPositionZ(), 2 * m_owner->GetOrientation(), TEMPSPAWN_DEAD_DESPAWN, 0))
{
DEBUG_LOG("VehicleInfo(of %s)::Initialize: Load vehicle accessory %s onto seat %u", m_owner->GetGuidStr().c_str(), summoned->GetGuidStr().c_str(), itr->seatId);
m_accessoryGuids.insert(summoned->GetObjectGuid());
int32 basepoint0 = itr->seatId + 1;
summoned->CastCustomSpell((Unit*)m_owner, SPELL_RIDE_VEHICLE_HARDCODED, &basepoint0, nullptr, nullptr, TRIGGERED_OLD_TRIGGERED);
}
Position pos = m_owner->GetPosition();
pos.o *= 2;
SummonPassenger(itr->passengerEntry, pos, itr->seatId);
}
}

Expand Down Expand Up @@ -251,6 +247,17 @@ void VehicleInfo::Initialize()
m_isInitialized = true;
}

void VehicleInfo::SummonPassenger(uint32 entry, Position const& pos, uint8 seatId)
{
if (Creature* summoned = m_owner->SummonCreature(entry, pos.x, pos.y, pos.z, pos.o, TEMPSPAWN_DEAD_DESPAWN, 0))
{
DEBUG_LOG("VehicleInfo(of %s)::Initialize: Load vehicle accessory %s onto seat %u", m_owner->GetGuidStr().c_str(), summoned->GetGuidStr().c_str(), seatId);
m_accessoryGuids.insert(summoned->GetObjectGuid());
int32 basepoint0 = seatId + 1;
summoned->CastCustomSpell((Unit*)m_owner, SPELL_RIDE_VEHICLE_HARDCODED, &basepoint0, nullptr, nullptr, TRIGGERED_OLD_TRIGGERED);
}
}

/**
* This function will board a passenger onto a vehicle
*
Expand Down Expand Up @@ -487,7 +494,7 @@ void VehicleInfo::UnBoard(Unit* passenger, bool changeVehicle)
passenger->m_movementInfo.ClearTransportData();
}

if (passenger->GetTypeId() == TYPEID_PLAYER)
if (passenger->IsPlayer())
{
Player* pPlayer = (Player*)passenger;
pPlayer->ResummonPetTemporaryUnSummonedIfAny();
Expand Down Expand Up @@ -525,13 +532,12 @@ void VehicleInfo::UnBoard(Unit* passenger, bool changeVehicle)
init.SetExitVehicle();
init.Launch();

// Despawn if passenger was accessory
if (passenger->GetTypeId() == TYPEID_UNIT && m_accessoryGuids.find(passenger->GetObjectGuid()) != m_accessoryGuids.end())
// Remove from list if passenger was accessory
if (passenger->IsCreature() && m_accessoryGuids.find(passenger->GetObjectGuid()) != m_accessoryGuids.end())
{
Creature* cPassenger = static_cast<Creature*>(passenger);
m_accessoryGuids.erase(passenger->GetObjectGuid());

// Note: Most of the creature accessories have to stay on the map if unboarded; despawn events are handled by Creauture_Linking_Template if needed
m_unboardedAccessories.emplace_back(passenger->GetObjectGuid(), seat);
}
}

Expand Down Expand Up @@ -647,6 +653,62 @@ void VehicleInfo::TeleportPassengers(uint32 mapId)
}
}

void VehicleInfo::RecallAndRespawnAccessories(float distance, int32 seatIndex)
{
RecallAccessories(distance, seatIndex);
RespawnAccessories(seatIndex);
}

void VehicleInfo::RespawnAccessories(int32 seatIndex)
{
SQLMultiStorage::SQLMSIteratorBounds<VehicleAccessory> bounds = sVehicleAccessoryStorage.getBounds<VehicleAccessory>(m_overwriteNpcEntry);
for (SQLMultiStorage::SQLMultiSIterator<VehicleAccessory> itr = bounds.first; itr != bounds.second; ++itr)
{
if (seatIndex != -1 && seatIndex != itr->seatId)
continue;
Position pos = m_owner->GetPosition();
pos.o *= 2;
SummonPassenger(itr->passengerEntry, pos, itr->seatId);
}
}

void VehicleInfo::RecallAccessories(float distance, int32 seatIndex)
{
for (auto itr = m_unboardedAccessories.begin(); itr != m_unboardedAccessories.end();)
{
ObjectGuid guid = itr->first;
uint8 seat = itr->second;
if (seatIndex != -1 && seat != seatIndex)
{
++itr;
continue;
}
if (Creature* creature = m_owner->GetMap()->GetCreature(guid))
{
if (!creature->IsAlive())
{
itr = m_unboardedAccessories.erase(itr);
continue;
}
if (distance != 0.f && creature->GetDistance(m_owner, true, DIST_CALC_NONE) > distance * distance)
{
++itr;
continue;
}
if (!IsSeatAvailableFor(creature, seat))
{
++itr;
continue;
}
m_accessoryGuids.insert(creature->GetObjectGuid());
int32 basepoint0 = seat;
creature->CastCustomSpell(static_cast<Unit*>(m_owner), SPELL_RIDE_VEHICLE_HARDCODED, &basepoint0, nullptr, nullptr, TRIGGERED_OLD_TRIGGERED);
itr = m_unboardedAccessories.erase(itr);
}
else ++itr;
}
}

/* ************************************************************************************************
* Helper function for seat control
* ***********************************************************************************************/
Expand Down
14 changes: 10 additions & 4 deletions src/game/Entities/Vehicle.h
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ class VehicleInfo : public TransportBase
explicit VehicleInfo(Unit* owner, VehicleEntry const* vehicleEntry, uint32 overwriteNpcEntry);
void Initialize(); ///< Initializes the accessories
bool IsInitialized() const { return m_isInitialized; }
void SummonPassenger(uint32 entry, Position const& pos, uint8 seatId);

~VehicleInfo();

Expand All @@ -102,6 +103,10 @@ class VehicleInfo : public TransportBase

void DisableAccessoryInit() { m_disabledAccessoryInit = true; }

void RecallAndRespawnAccessories(float distance = 0.f, int32 seatIndex = -1);
void RespawnAccessories(int32 seatIndex = -1);
void RecallAccessories(float distance = 0.f, int32 seatIndex = -1);

private:
// Internal use to calculate the boarding position
void CalculateBoardingPositionOf(float gx, float gy, float gz, float go, float& lx, float& ly, float& lz, float& lo) const;
Expand All @@ -122,15 +127,16 @@ class VehicleInfo : public TransportBase
void RemoveSeatMods(Unit* passenger, uint32 seatFlags);

VehicleEntry const* m_vehicleEntry;
VehicleSeatMap m_vehicleSeats; ///< Stores the available seats of the vehicle (filled in constructor)
uint8 m_creatureSeats; ///< Mask that stores which seats are avaiable for creatures
uint8 m_playerSeats; ///< Mask that stores which seats are avaiable for players
VehicleSeatMap m_vehicleSeats; // Stores the available seats of the vehicle (filled in constructor)
uint8 m_creatureSeats; // Mask that stores which seats are avaiable for creatures
uint8 m_playerSeats; // Mask that stores which seats are avaiable for players

uint32 m_overwriteNpcEntry; // Internal use to store the entry with which the vehicle-accessories are fetched
bool m_isInitialized; // Internal use to store if the accessory is initialized
bool m_disabledAccessoryInit;
uint32 m_originalFaction; // Internal use to store the original unit faction before taking control of the unit
GuidSet m_accessoryGuids; ///< Stores the summoned accessories of this vehicle
GuidSet m_accessoryGuids; // Stores the summoned accessories of this vehicle
std::vector<std::pair<ObjectGuid, uint8>> m_unboardedAccessories; // Stores unboarded accessories for purpose of recall
};

#endif
Expand Down

0 comments on commit ce715ca

Please sign in to comment.