mirror of
https://github.com/mangosfour/server.git
synced 2025-12-13 22:37:03 +00:00
[11558] Fixes and way work chnages for GO lock/interact state
* Not reset lock/interact state in instances (so until instance reset) * Do unti-cheating checks for use attempts locked/non-intareactive GOs * Implement SCRIPT_COMMAND_GO_LOCK_STATE for control lock/interact state of GOs from scripts. Signed-off-by: VladimirMangos <vladimir@getmangos.com>
This commit is contained in:
parent
4a087e6bda
commit
0de4e302b3
8 changed files with 98 additions and 10 deletions
|
|
@ -218,9 +218,8 @@ spell_scripts
|
|||
* datalong3 = creature search radius
|
||||
* data_flags = flag_original_source_as_target = 0x02
|
||||
flag_buddy_as_target = 0x04 (When this flag is not set, buddy will be the attacker when buddy is defined)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
27 SCRIPT_COMMAND_GO_LOCK_STATE source or target must be WorldObject
|
||||
* datalong = flag_go_lock = 0x01, flag_go_unlock = 0x02,
|
||||
flag_go_nonInteract = 0x04, flag_go_interact = 0x08
|
||||
* datalong2 = go entry (searching closest to source (if worldobject) or target
|
||||
* datalong3 = go search radius
|
||||
|
|
|
|||
|
|
@ -398,7 +398,10 @@ void GameObject::Update(uint32 update_diff, uint32 /*p_time*/)
|
|||
if (GetGOInfo()->IsDespawnAtAction() || GetGoAnimProgress() > 0)
|
||||
{
|
||||
SendObjectDeSpawnAnim(GetObjectGuid());
|
||||
//reset flags
|
||||
// reset flags: In Instances do not restore GO_FLAG_LOCKED or GO_FLAG_NO_INTERACT
|
||||
if (GetMap()->Instanceable())
|
||||
SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags & ~(GO_FLAG_LOCKED | GO_FLAG_NO_INTERACT));
|
||||
else
|
||||
SetUInt32Value(GAMEOBJECT_FLAGS, GetGOInfo()->flags);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2869,6 +2869,42 @@ void Map::ScriptsProcess()
|
|||
sLog.outError("SCRIPT_COMMAND_ATTACK_START (script id %u) unexpected error, attacker or victim could not be found, no action.", step.script->id);
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_GO_LOCK_STATE:
|
||||
{
|
||||
if ((!source || !source->isType(TYPEMASK_WORLDOBJECT)) && (!target || !target->isType(TYPEMASK_WORLDOBJECT)))
|
||||
{
|
||||
sLog.outError("SCRIPT_COMMAND_GO_LOCK_STATE (script id %u) call for non-worldobject (TypeIdSource: %u)(TypeIdTarget: %u), skipping.", step.script->id, source ? source->GetTypeId() : 0, target ? target->GetTypeId() : 0);
|
||||
break;
|
||||
}
|
||||
|
||||
WorldObject* pSearcher = source && source->isType(TYPEMASK_WORLDOBJECT) ? (WorldObject*)source : (WorldObject*)target;
|
||||
GameObject* pGo = NULL;
|
||||
|
||||
MaNGOS::NearestGameObjectEntryInObjectRangeCheck u_check(*pSearcher, step.script->goLockState.goEntry, step.script->goLockState.searchRadius);
|
||||
MaNGOS::GameObjectLastSearcher<MaNGOS::NearestGameObjectEntryInObjectRangeCheck> searcher(pGo, u_check);
|
||||
|
||||
Cell::VisitGridObjects(pSearcher, searcher, step.script->goLockState.searchRadius);
|
||||
|
||||
/* flag lockState
|
||||
* go_lock 0x01
|
||||
* go_unlock 0x02
|
||||
* go_nonInteract 0x04
|
||||
* go_Interact 0x08
|
||||
*/
|
||||
if (pGo)
|
||||
{
|
||||
// Lock or Unlock
|
||||
if (step.script->goLockState.lockState & 0x01)
|
||||
pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
|
||||
else if (step.script->goLockState.lockState & 0x02)
|
||||
pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_LOCKED);
|
||||
// Set Non Interactable or Set Interactable
|
||||
if (step.script->goLockState.lockState & 0x04)
|
||||
pGo->SetFlag(GAMEOBJECT_FLAGS, GO_FLAG_NO_INTERACT);
|
||||
else if (step.script->goLockState.lockState & 0x08)
|
||||
pGo->RemoveFlag(GAMEOBJECT_FLAGS, GO_FLAG_NO_INTERACT);
|
||||
}
|
||||
}
|
||||
default:
|
||||
sLog.outError("Unknown SCRIPT_COMMAND_ %u called for script id %u.",step.script->command, step.script->id);
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -533,6 +533,32 @@ void ScriptMgr::LoadScripts(ScriptMapMap& scripts, const char* tablename)
|
|||
}
|
||||
break;
|
||||
}
|
||||
case SCRIPT_COMMAND_GO_LOCK_STATE:
|
||||
{
|
||||
if (!ObjectMgr::GetGameObjectInfo(tmp.goLockState.goEntry))
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` has datalong2 = %u in SCRIPT_COMMAND_GO_LOCK_STATE for script id %u, but this gameobject_template does not exist.", tablename, tmp.goLockState.goEntry, tmp.id);
|
||||
continue;
|
||||
}
|
||||
if (!tmp.goLockState.searchRadius)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` has invalid search radius (datalong3 = %u) in SCRIPT_COMMAND_GO_LOCK_STATE for script id %u.", tablename, tmp.goLockState.searchRadius, tmp.id);
|
||||
continue;
|
||||
}
|
||||
if (// lock(0x01) and unlock(0x02) together
|
||||
((tmp.goLockState.lockState & 0x01) && (tmp.goLockState.lockState & 0x02)) ||
|
||||
// non-interact (0x4) and interact (0x08) together
|
||||
((tmp.goLockState.lockState & 0x04) && (tmp.goLockState.lockState & 0x08)) ||
|
||||
// no setting
|
||||
!tmp.goLockState.lockState ||
|
||||
// invalid number
|
||||
tmp.goLockState.lockState >= 0x10)
|
||||
{
|
||||
sLog.outErrorDb("Table `%s` has invalid lock state (datalong = %u) in SCRIPT_COMMAND_GO_LOCK_STATE for script id %u.", tablename, tmp.goLockState.lockState, tmp.id);
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (scripts.find(tmp.id) == scripts.end())
|
||||
|
|
|
|||
|
|
@ -92,6 +92,9 @@ enum eScriptCommand
|
|||
// datalong2=creature entry, datalong3=search radius
|
||||
SCRIPT_COMMAND_ATTACK_START = 26, // source = Creature (or WorldObject when creature entry are defined), target = Player
|
||||
// datalong2 = creature entry (searching for a buddy, closest to source), datalong3 = creature search radius
|
||||
SCRIPT_COMMAND_GO_LOCK_STATE = 27, // source or target must be WorldObject
|
||||
// datalong= 1=lock, 2=unlock, 4=set not-interactable, 8=set interactable
|
||||
// datalong2= go entry, datalong3= go search radius
|
||||
};
|
||||
|
||||
#define MAX_TEXT_ID 4 // used for SCRIPT_COMMAND_TALK
|
||||
|
|
@ -284,6 +287,13 @@ struct ScriptInfo
|
|||
uint32 flags; // data_flags
|
||||
} attack;
|
||||
|
||||
struct // SCRIPT_COMMAND_GO_LOCK_STATE (27)
|
||||
{
|
||||
uint32 lockState; // datalong
|
||||
uint32 goEntry; // datalong2
|
||||
uint32 searchRadius; // datalong3
|
||||
} goLockState;
|
||||
|
||||
struct
|
||||
{
|
||||
uint32 data[9];
|
||||
|
|
|
|||
|
|
@ -1258,7 +1258,7 @@ enum GameObjectFlags
|
|||
GO_FLAG_LOCKED = 0x00000002, //require key, spell, event, etc to be opened. Makes "Locked" appear in tooltip
|
||||
GO_FLAG_INTERACT_COND = 0x00000004, //cannot interact (condition to interact)
|
||||
GO_FLAG_TRANSPORT = 0x00000008, //any kind of transport? Object can transport (elevator, boat, car)
|
||||
GO_FLAG_UNK1 = 0x00000010, //
|
||||
GO_FLAG_NO_INTERACT = 0x00000010, //players cannot interact with this go (often need to remove flag in event)
|
||||
GO_FLAG_NODESPAWN = 0x00000020, //never despawn, typically for doors, they just change state
|
||||
GO_FLAG_TRIGGERED = 0x00000040, //typically, summoned objects. Triggered by spell or other events
|
||||
GO_FLAG_UNK_8 = 0x00000080,
|
||||
|
|
|
|||
|
|
@ -289,6 +289,13 @@ void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data )
|
|||
if(!obj)
|
||||
return;
|
||||
|
||||
// Additional check preventing exploits (ie loot despawned chests)
|
||||
if (!obj->isSpawned())
|
||||
{
|
||||
sLog.outError("HandleGameObjectUseOpcode: CMSG_GAMEOBJ_USE for despawned GameObject (Entry %u), didn't expect this to happen.", obj->GetEntry());
|
||||
return;
|
||||
}
|
||||
|
||||
// Never expect this opcode for some type GO's
|
||||
if (obj->GetGoType() == GAMEOBJECT_TYPE_GENERIC)
|
||||
{
|
||||
|
|
@ -296,6 +303,13 @@ void WorldSession::HandleGameObjectUseOpcode( WorldPacket & recv_data )
|
|||
return;
|
||||
}
|
||||
|
||||
// Never expect this opcode for non intractable GO's
|
||||
if (obj->HasFlag(GAMEOBJECT_FLAGS, GO_FLAG_NO_INTERACT))
|
||||
{
|
||||
sLog.outError("HandleGameObjectUseOpcode: CMSG_GAMEOBJ_USE for GameObject (Entry %u) with non intractable flag (Flags %u), didn't expect this to happen.", obj->GetEntry(), obj->GetUInt32Value(GAMEOBJECT_FLAGS));
|
||||
return;
|
||||
}
|
||||
|
||||
obj->Use(_player);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
#ifndef __REVISION_NR_H__
|
||||
#define __REVISION_NR_H__
|
||||
#define REVISION_NR "11557"
|
||||
#define REVISION_NR "11558"
|
||||
#endif // __REVISION_NR_H__
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue