Skip to content

Commit

Permalink
[10855] Add TARGET_AREAEFFECT_GO_AROUND_DEST(52) (renamed from TARGET…
Browse files Browse the repository at this point in the history
…_AREAEFFECT_CUSTOM_2)

Target selects all gameobject around destination, limited by adding spell with a corresponding gameobject entry in database table spell_script_target.

Signed-off-by: NoFantasy <nofantasy@nf.no>
  • Loading branch information
NoFantasy committed Dec 11, 2010
1 parent d026482 commit f121f4e
Show file tree
Hide file tree
Showing 6 changed files with 100 additions and 6 deletions.
62 changes: 62 additions & 0 deletions src/game/GridNotifiers.h
Expand Up @@ -687,6 +687,68 @@ namespace MaNGOS
NearestGameObjectEntryInObjectRangeCheck(NearestGameObjectEntryInObjectRangeCheck const&);
};

// Success at gameobject in range of xyz, range update for next check (this can be use with GameobjectLastSearcher to find nearest GO)
class NearestGameObjectEntryInPosRangeCheck
{
public:
NearestGameObjectEntryInPosRangeCheck(WorldObject const& obj, uint32 entry, float x, float y, float z, float range)
: i_obj(obj), i_x(x), i_y(y), i_z(z), i_entry(entry), i_range(range) {}

WorldObject const& GetFocusObject() const { return i_obj; }

bool operator()(GameObject* go)
{
if (go->GetEntry() == i_entry && go->IsWithinDist3d(i_x, i_y, i_z, i_range))
{
// use found GO range as new range limit for next check
i_range = go->GetDistance(i_x,i_y,i_z);
return true;
}

return false;
}

float GetLastRange() const { return i_range; }

private:
WorldObject const& i_obj;
uint32 i_entry;
float i_x, i_y, i_z;
float i_range;

// prevent clone this object
NearestGameObjectEntryInPosRangeCheck(NearestGameObjectEntryInPosRangeCheck const&);
};

// Success at gameobject with entry in range of provided xyz
class GameObjectEntryInPosRangeCheck
{
public:
GameObjectEntryInPosRangeCheck(WorldObject const& obj, uint32 entry, float x, float y, float z, float range)
: i_obj(obj), i_x(x), i_y(y), i_z(z), i_entry(entry), i_range(range) {}

WorldObject const& GetFocusObject() const { return i_obj; }

bool operator()(GameObject* go)
{
if (go->GetEntry() == i_entry && go->IsWithinDist3d(i_x, i_y, i_z, i_range))
return true;

return false;
}

float GetLastRange() const { return i_range; }

private:
WorldObject const& i_obj;
uint32 i_entry;
float i_x, i_y, i_z;
float i_range;

// prevent clone this object
GameObjectEntryInPosRangeCheck(GameObjectEntryInPosRangeCheck const&);
};

class GameObjectWithDbGUIDCheck
{
public:
Expand Down
2 changes: 1 addition & 1 deletion src/game/SharedDefines.h
Expand Up @@ -1076,7 +1076,7 @@ enum Targets
TARGET_DYNAMIC_OBJECT_BEHIND = 48,
TARGET_DYNAMIC_OBJECT_LEFT_SIDE = 49,
TARGET_DYNAMIC_OBJECT_RIGHT_SIDE = 50,
TARGET_AREAEFFECT_CUSTOM_2 = 52,
TARGET_AREAEFFECT_GO_AROUND_DEST = 52, // gameobject around destination, select by spell_script_target
TARGET_CURRENT_ENEMY_COORDINATES = 53, // set unit coordinates as dest, only 16 target B imlemented
TARGET_LARGE_FRONTAL_CONE = 54,
TARGET_ALL_RAID_AROUND_CASTER = 56,
Expand Down
32 changes: 31 additions & 1 deletion src/game/Spell.cpp
Expand Up @@ -1588,7 +1588,6 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
case TARGET_TOTEM_FIRE:
case TARGET_SELF:
case TARGET_SELF2:
case TARGET_AREAEFFECT_CUSTOM_2:
targetUnitMap.push_back(m_caster);
break;
case TARGET_RANDOM_ENEMY_CHAIN_IN_AREA:
Expand Down Expand Up @@ -1891,6 +1890,37 @@ void Spell::SetTargetMap(SpellEffectIndex effIndex, uint32 targetMode, UnitList&
}
break;
}
case TARGET_AREAEFFECT_GO_AROUND_DEST:
{
// It may be possible to fill targets for some spell effects
// automatically (SPELL_EFFECT_WMO_REPAIR(88) for example) but
// for some/most spells we clearly need/want to limit with spell_target_script

// Some spells untested, for affected GO type 33. May need further adjustments for spells related.

SpellScriptTargetBounds bounds = sSpellMgr.GetSpellScriptTargetBounds(m_spellInfo->Id);

std::list<GameObject*> tempTargetGOList;

for(SpellScriptTarget::const_iterator i_spellST = bounds.first; i_spellST != bounds.second; ++i_spellST)
{
if (i_spellST->second.type == SPELL_TARGET_TYPE_GAMEOBJECT)
{
// search all GO's with entry, within range of m_destN
MaNGOS::GameObjectEntryInPosRangeCheck go_check(*m_caster, i_spellST->second.targetEntry, m_targets.m_destX, m_targets.m_destY, m_targets.m_destZ, radius);
MaNGOS::GameObjectListSearcher<MaNGOS::GameObjectEntryInPosRangeCheck> checker(tempTargetGOList, go_check);
Cell::VisitGridObjects(m_caster, checker, radius);
}
}

if (!tempTargetGOList.empty())
{
for(std::list<GameObject*>::iterator iter = tempTargetGOList.begin(); iter != tempTargetGOList.end(); ++iter)
AddGOTarget(*iter, effIndex);
}

break;
}
case TARGET_ALL_ENEMY_IN_AREA_INSTANT:
{
// targets the ground, not the units in the area
Expand Down
4 changes: 3 additions & 1 deletion src/game/SpellMgr.cpp
Expand Up @@ -2964,7 +2964,9 @@ void SpellMgr::LoadSpellScriptTarget()
spellProto->EffectImplicitTargetA[i] == TARGET_AREAEFFECT_INSTANT ||
spellProto->EffectImplicitTargetB[i] == TARGET_AREAEFFECT_INSTANT ||
spellProto->EffectImplicitTargetA[i] == TARGET_AREAEFFECT_CUSTOM ||
spellProto->EffectImplicitTargetB[i] == TARGET_AREAEFFECT_CUSTOM)
spellProto->EffectImplicitTargetB[i] == TARGET_AREAEFFECT_CUSTOM ||
spellProto->EffectImplicitTargetA[i] == TARGET_AREAEFFECT_GO_AROUND_DEST ||
spellProto->EffectImplicitTargetB[i] == TARGET_AREAEFFECT_GO_AROUND_DEST)
{
targetfound = true;
break;
Expand Down
4 changes: 2 additions & 2 deletions src/game/SpellMgr.h
Expand Up @@ -266,7 +266,7 @@ inline bool IsCasterSourceTarget(uint32 target)
case TARGET_TOTEM_WATER:
case TARGET_TOTEM_AIR:
case TARGET_TOTEM_FIRE:
case TARGET_AREAEFFECT_CUSTOM_2:
case TARGET_AREAEFFECT_GO_AROUND_DEST:
case TARGET_ALL_RAID_AROUND_CASTER:
case TARGET_SELF2:
case TARGET_DIRECTLY_FORWARD:
Expand Down Expand Up @@ -358,7 +358,7 @@ inline bool IsAreaEffectTarget( Targets target )
case TARGET_ALL_PARTY:
case TARGET_ALL_PARTY_AROUND_CASTER_2:
case TARGET_AREAEFFECT_PARTY:
case TARGET_AREAEFFECT_CUSTOM_2:
case TARGET_AREAEFFECT_GO_AROUND_DEST:
case TARGET_ALL_RAID_AROUND_CASTER:
case TARGET_AREAEFFECT_PARTY_AND_CLASS:
case TARGET_IN_FRONT_OF_CASTER_30:
Expand Down
2 changes: 1 addition & 1 deletion src/shared/revision_nr.h
@@ -1,4 +1,4 @@
#ifndef __REVISION_NR_H__
#define __REVISION_NR_H__
#define REVISION_NR "10854"
#define REVISION_NR "10855"
#endif // __REVISION_NR_H__

7 comments on commit f121f4e

@wolfiestyle
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this target mode is used mostly by siege damage spells (like 56350, 61766), is it correct to limit it to spell_script_target?

@NoFantasy
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just because "most" are related to certain spell effects doesn't mean we can allow all spells to handle any gameobject.

@rsa
Copy link
Contributor

@rsa rsa commented on f121f4e Dec 11, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

case m_targets.m_targetMask & TARGET_FLAG_SOURCE_LOCATION
lost in this implement :(

@rsa
Copy link
Contributor

@rsa rsa commented on f121f4e Dec 11, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just counting GameObject type 33 and spells with effect 87 gives the need to add 1,575 records in spell_script_target. Are you sure that's a good idea?

@NoFantasy
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you are really-really bored, yes. If not, i would ask myself: "why would I do such a thing when I don't know how this will work for spell effect 87 yet."

The commit does not state anywhere it will work for any kinds of spell effects, nor does it say anywhere the target mode if 100% completed for all spells under any circumstance. In fact, the code contain comments to tell those who bother to read it, that the target mode can not be considered complete. Mangos is a kind of a project where the progression often comes before "100% working, everything implemented zomfg". As far as I can see, there is nothing wrong in the above. Sure, like the code comments already say, there must be room for further improvement, just to avoid adding thousands of spells to database. You can speak of "lost", but the fact is, more spells can work with this commit and I'm happy they can. Next week maybe someone who also care will implement more parts, related to this target mode.

@kbz
Copy link

@kbz kbz commented on f121f4e Dec 11, 2010

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually i think it should be the other way around, if given spell doesnt have spell_script_target then use any GO around, otherwise do an exclusive search with the spell_script_target (maybe)

@wolfiestyle
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What i meant, there are generic spells that meant to hit ANY gameobject, not just predefined ones in spell_script_target.

Please sign in to comment.