*Use setcharmedby and removecharmedby in enter/exit vehicle functions.

*Fix build.

--HG--
branch : trunk
This commit is contained in:
megamage
2009-06-03 13:51:05 -05:00
parent e861df8795
commit c70e6a003e
7 changed files with 115 additions and 101 deletions
+3 -2
View File
@@ -16664,8 +16664,6 @@ void Player::RemovePet(Pet* pet, PetSaveMode mode, bool returnreagent)
void Player::StopCastingCharm() void Player::StopCastingCharm()
{ {
ExitVehicle();
Unit* charm = GetCharm(); Unit* charm = GetCharm();
if(!charm) if(!charm)
return; return;
@@ -16674,6 +16672,8 @@ void Player::StopCastingCharm()
{ {
if(((Creature*)charm)->HasSummonMask(SUMMON_MASK_PUPPET)) if(((Creature*)charm)->HasSummonMask(SUMMON_MASK_PUPPET))
((Puppet*)charm)->UnSummon(); ((Puppet*)charm)->UnSummon();
else if(((Creature*)charm)->isVehicle())
ExitVehicle();
} }
if(GetCharmGUID()) if(GetCharmGUID())
{ {
@@ -16685,6 +16685,7 @@ void Player::StopCastingCharm()
if(GetCharmGUID()) if(GetCharmGUID())
{ {
sLog.outCrash("Player %s is not able to uncharm unit (Entry: %u, Type: %u)", GetName(), charm->GetEntry(), charm->GetTypeId()); sLog.outCrash("Player %s is not able to uncharm unit (Entry: %u, Type: %u)", GetName(), charm->GetEntry(), charm->GetTypeId());
assert(false);
} }
} }
+6 -3
View File
@@ -4659,6 +4659,7 @@ SpellCastResult Spell::CheckCast(bool strict)
} }
case SPELL_AURA_MOD_POSSESS: case SPELL_AURA_MOD_POSSESS:
case SPELL_AURA_MOD_CHARM: case SPELL_AURA_MOD_CHARM:
//case SPELL_AURA_MOD_POSSESS_PET:
{ {
if(m_caster->GetPetGUID()) if(m_caster->GetPetGUID())
return SPELL_FAILED_ALREADY_HAVE_SUMMON; return SPELL_FAILED_ALREADY_HAVE_SUMMON;
@@ -4669,13 +4670,15 @@ SpellCastResult Spell::CheckCast(bool strict)
if(m_caster->GetCharmerGUID()) if(m_caster->GetCharmerGUID())
return SPELL_FAILED_CHARMED; return SPELL_FAILED_CHARMED;
if(!m_targets.getUnitTarget()) Unit *target = m_targets.getUnitTarget();
if(!target || target->GetTypeId() == TYPEID_UNIT
&& ((Creature*)target)->isVehicle())
return SPELL_FAILED_BAD_IMPLICIT_TARGETS; return SPELL_FAILED_BAD_IMPLICIT_TARGETS;
if(m_targets.getUnitTarget()->GetCharmerGUID()) if(target->GetCharmerGUID())
return SPELL_FAILED_CHARMED; return SPELL_FAILED_CHARMED;
if(int32(m_targets.getUnitTarget()->getLevel()) > CalculateDamage(i,m_targets.getUnitTarget())) if(int32(target->getLevel()) > CalculateDamage(i, target))
return SPELL_FAILED_HIGHLEVEL; return SPELL_FAILED_HIGHLEVEL;
break; break;
+10 -10
View File
@@ -532,12 +532,12 @@ AreaAuraEffect::AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * curre
case SPELL_EFFECT_APPLY_AREA_AURA_PARTY: case SPELL_EFFECT_APPLY_AREA_AURA_PARTY:
m_areaAuraType = AREA_AURA_PARTY; m_areaAuraType = AREA_AURA_PARTY;
if(m_target->GetTypeId() == TYPEID_UNIT && ((Creature*)m_target)->isTotem()) if(m_target->GetTypeId() == TYPEID_UNIT && ((Creature*)m_target)->isTotem())
const_cast<AuraType>(m_auraName) = SPELL_AURA_NONE; (AuraType)m_auraName = SPELL_AURA_NONE;
break; break;
case SPELL_EFFECT_APPLY_AREA_AURA_RAID: case SPELL_EFFECT_APPLY_AREA_AURA_RAID:
m_areaAuraType = AREA_AURA_RAID; m_areaAuraType = AREA_AURA_RAID;
if(m_target->GetTypeId() == TYPEID_UNIT && ((Creature*)m_target)->isTotem()) if(m_target->GetTypeId() == TYPEID_UNIT && ((Creature*)m_target)->isTotem())
const_cast<AuraType>(m_auraName) = SPELL_AURA_NONE; (AuraType)m_auraName = SPELL_AURA_NONE;
break; break;
case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND: case SPELL_EFFECT_APPLY_AREA_AURA_FRIEND:
m_areaAuraType = AREA_AURA_FRIEND; m_areaAuraType = AREA_AURA_FRIEND;
@@ -545,7 +545,7 @@ AreaAuraEffect::AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * curre
case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY: case SPELL_EFFECT_APPLY_AREA_AURA_ENEMY:
m_areaAuraType = AREA_AURA_ENEMY; m_areaAuraType = AREA_AURA_ENEMY;
if(m_target == caster_ptr) if(m_target == caster_ptr)
const_cast<AuraType>(m_auraName) = SPELL_AURA_NONE; // Do not do any effect on self (AuraType)m_auraName = SPELL_AURA_NONE; // Do not do any effect on self
break; break;
case SPELL_EFFECT_APPLY_AREA_AURA_PET: case SPELL_EFFECT_APPLY_AREA_AURA_PET:
m_areaAuraType = AREA_AURA_PET; m_areaAuraType = AREA_AURA_PET;
@@ -553,7 +553,7 @@ AreaAuraEffect::AreaAuraEffect(Aura * parentAura, uint32 effIndex, int32 * curre
case SPELL_EFFECT_APPLY_AREA_AURA_OWNER: case SPELL_EFFECT_APPLY_AREA_AURA_OWNER:
m_areaAuraType = AREA_AURA_OWNER; m_areaAuraType = AREA_AURA_OWNER;
if(m_target == caster_ptr) if(m_target == caster_ptr)
const_cast<AuraType>(m_auraName) = SPELL_AURA_NONE; (AuraType)m_auraName = SPELL_AURA_NONE;
break; break;
default: default:
sLog.outError("Wrong spell effect in AreaAura constructor"); sLog.outError("Wrong spell effect in AreaAura constructor");
@@ -6906,10 +6906,10 @@ void AuraEffect::HandleModPossess(bool apply, bool Real, bool /*changeAmount*/)
if(m_target->getLevel() > m_amount) if(m_target->getLevel() > m_amount)
return; return;
m_target->SetCharmedOrPossessedBy(caster, true); m_target->SetCharmedBy(caster, CHARM_TYPE_POSSESS);
} }
else else
m_target->RemoveCharmedOrPossessedBy(caster); m_target->RemoveCharmedBy(caster);
} }
void AuraEffect::HandleModPossessPet(bool apply, bool Real, bool /*changeAmount*/) void AuraEffect::HandleModPossessPet(bool apply, bool Real, bool /*changeAmount*/)
@@ -6926,11 +6926,11 @@ void AuraEffect::HandleModPossessPet(bool apply, bool Real, bool /*changeAmount*
if(caster->GetGuardianPet() != m_target) if(caster->GetGuardianPet() != m_target)
return; return;
m_target->SetCharmedOrPossessedBy(caster, true); m_target->SetCharmedBy(caster, CHARM_TYPE_POSSESS);
} }
else else
{ {
m_target->RemoveCharmedOrPossessedBy(caster); m_target->RemoveCharmedBy(caster);
// Reinitialize the pet bar and make the pet come back to the owner // Reinitialize the pet bar and make the pet come back to the owner
((Player*)caster)->PetSpellInitialize(); ((Player*)caster)->PetSpellInitialize();
@@ -6954,10 +6954,10 @@ void AuraEffect::HandleModCharm(bool apply, bool Real, bool /*changeAmount*/)
if(int32(m_target->getLevel()) > m_amount) if(int32(m_target->getLevel()) > m_amount)
return; return;
m_target->SetCharmedOrPossessedBy(caster, false); m_target->SetCharmedBy(caster, CHARM_TYPE_CHARM);
} }
else else
m_target->RemoveCharmedOrPossessedBy(caster); m_target->RemoveCharmedBy(caster);
} }
void AuraEffect::HandlePhase(bool apply, bool Real, bool /*changeAmount*/) void AuraEffect::HandlePhase(bool apply, bool Real, bool /*changeAmount*/)
+2 -2
View File
@@ -332,7 +332,7 @@ void Puppet::InitStats(uint32 duration)
void Puppet::InitSummon() void Puppet::InitSummon()
{ {
Minion::InitSummon(); Minion::InitSummon();
SetCharmedOrPossessedBy(m_owner, true); SetCharmedBy(m_owner, CHARM_TYPE_POSSESS);
} }
void Puppet::Update(uint32 time) void Puppet::Update(uint32 time)
@@ -351,6 +351,6 @@ void Puppet::RemoveFromWorld()
if(!IsInWorld()) if(!IsInWorld())
return; return;
RemoveCharmedOrPossessedBy(NULL); RemoveCharmedBy(NULL);
Minion::RemoveFromWorld(); Minion::RemoveFromWorld();
} }
+83 -67
View File
@@ -13525,12 +13525,13 @@ void Unit::SetConfused(bool apply)
((Player*)this)->SetClientControl(this, !apply); ((Player*)this)->SetClientControl(this, !apply);
} }
void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess) void Unit::SetCharmedBy(Unit* charmer, CharmType type)
{ {
if(!charmer) if(!charmer)
return; return;
assert(!possess || charmer->GetTypeId() == TYPEID_PLAYER); assert(type != CHARM_TYPE_POSSESS || charmer->GetTypeId() == TYPEID_PLAYER);
assert(type != CHARM_TYPE_VEHICLE || GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isVehicle());
if(this == charmer) if(this == charmer)
return; return;
@@ -13581,50 +13582,57 @@ void Unit::SetCharmedOrPossessedBy(Unit* charmer, bool possess)
} }
// Pets already have a properly initialized CharmInfo, don't overwrite it. // Pets already have a properly initialized CharmInfo, don't overwrite it.
if(GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT if(type != CHARM_TYPE_VEHICLE && !GetCharmInfo())
&& !((Creature*)this)->HasSummonMask(SUMMON_MASK_GUARDIAN))
{ {
CharmInfo *charmInfo = InitCharmInfo(); CharmInfo *charmInfo = InitCharmInfo();
if(possess) if(type == CHARM_TYPE_POSSESS)
charmInfo->InitPossessCreateSpells(); charmInfo->InitPossessCreateSpells();
else else
charmInfo->InitCharmCreateSpells(); charmInfo->InitCharmCreateSpells();
} }
//Set possessed if(charmer->GetTypeId() == TYPEID_PLAYER)
if(possess)
{ {
addUnitState(UNIT_STAT_POSSESSED); switch(type)
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
((Player*)charmer)->SetClientControl(this, 1);
((Player*)charmer)->SetViewpoint(this, true);
charmer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
}
// Charm demon
else if(GetTypeId() == TYPEID_UNIT && charmer->GetTypeId() == TYPEID_PLAYER && charmer->getClass() == CLASS_WARLOCK)
{
CreatureInfo const *cinfo = ((Creature*)this)->GetCreatureInfo();
if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
{ {
//to prevent client crash case CHARM_TYPE_VEHICLE:
//SetFlag(UNIT_FIELD_BYTES_0, 2048); ((Player*)charmer)->SetViewpoint(this, true);
((Player*)charmer)->VehicleSpellInitialize();
break;
case CHARM_TYPE_POSSESS:
addUnitState(UNIT_STAT_POSSESSED);
SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
charmer->SetFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
((Player*)charmer)->SetClientControl(this, 1);
((Player*)charmer)->SetViewpoint(this, true);
((Player*)charmer)->PossessSpellInitialize();
break;
case CHARM_TYPE_CHARM:
if(GetTypeId() == TYPEID_UNIT && charmer->getClass() == CLASS_WARLOCK)
{
CreatureInfo const *cinfo = ((Creature*)this)->GetCreatureInfo();
if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
{
//to prevent client crash
//SetFlag(UNIT_FIELD_BYTES_0, 2048);
//just to enable stat window //just to enable stat window
if(GetCharmInfo()) if(GetCharmInfo())
GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true); GetCharmInfo()->SetPetNumber(objmgr.GeneratePetNumber(), true);
//if charmed two demons the same session, the 2nd gets the 1st one's name //if charmed two demons the same session, the 2nd gets the 1st one's name
SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL)); SetUInt32Value(UNIT_FIELD_PET_NAME_TIMESTAMP, time(NULL));
}
}
((Player*)charmer)->CharmSpellInitialize();
break;
default:
break;
} }
} }
if(possess)
((Player*)charmer)->PossessSpellInitialize();
else if(charmer->GetTypeId() == TYPEID_PLAYER)
((Player*)charmer)->CharmSpellInitialize();
} }
void Unit::RemoveCharmedOrPossessedBy(Unit *charmer) void Unit::RemoveCharmedBy(Unit *charmer)
{ {
if(!isCharmed()) if(!isCharmed())
return; return;
@@ -13634,7 +13642,13 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
else if(charmer != GetCharmer()) // one aura overrides another? else if(charmer != GetCharmer()) // one aura overrides another?
return; return;
bool possess = hasUnitState(UNIT_STAT_POSSESSED); CharmType type;
if(hasUnitState(UNIT_STAT_POSSESSED))
type = CHARM_TYPE_POSSESS;
else if(this == charmer->m_Vehicle)
type = CHARM_TYPE_VEHICLE;
else
type = CHARM_TYPE_CHARM;
CastStop(); CastStop();
CombatStop(); //TODO: CombatStop(true) may cause crash (interrupt spells) CombatStop(); //TODO: CombatStop(true) may cause crash (interrupt spells)
@@ -13643,7 +13657,7 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
RestoreFaction(); RestoreFaction();
GetMotionMaster()->InitDefault(); GetMotionMaster()->InitDefault();
if(possess) if(type == CHARM_TYPE_POSSESS)
{ {
clearUnitState(UNIT_STAT_POSSESSED); clearUnitState(UNIT_STAT_POSSESSED);
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24); RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_UNK_24);
@@ -13651,20 +13665,18 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
if(GetTypeId() == TYPEID_UNIT) if(GetTypeId() == TYPEID_UNIT)
{ {
if(!((Creature*)this)->isPet())
RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_PVP_ATTACKABLE);
((Creature*)this)->AI()->OnCharmed(false); ((Creature*)this)->AI()->OnCharmed(false);
if(isAlive() && ((Creature*)this)->IsAIEnabled) if(isAlive() && charmer && !IsFriendlyTo(charmer))
((Creature*)this)->AddThreat(charmer, 10000.0f);
/*if(isAlive() && ((Creature*)this)->IsAIEnabled)
{ {
if(charmer && !IsFriendlyTo(charmer)) if(charmer && !IsFriendlyTo(charmer))
{ {
((Creature*)this)->AddThreat(charmer, 10000.0f);
((Creature*)this)->AI()->AttackStart(charmer); ((Creature*)this)->AI()->AttackStart(charmer);
} }
else else
((Creature*)this)->AI()->EnterEvadeMode(); ((Creature*)this)->AI()->EnterEvadeMode();
} }*/
} }
else else
((Player*)this)->SetClientControl(this, 1); ((Player*)this)->SetClientControl(this, 1);
@@ -13673,42 +13685,46 @@ void Unit::RemoveCharmedOrPossessedBy(Unit *charmer)
if(!charmer) if(!charmer)
return; return;
assert(!possess || charmer->GetTypeId() == TYPEID_PLAYER); assert(type != CHARM_TYPE_POSSESS || charmer->GetTypeId() == TYPEID_PLAYER);
assert(type != CHARM_TYPE_VEHICLE || GetTypeId() == TYPEID_UNIT && ((Creature*)this)->isVehicle());
charmer->SetCharm(this, false); charmer->SetCharm(this, false);
if(possess)
if(charmer->GetTypeId() == TYPEID_PLAYER)
{ {
((Player*)charmer)->SetClientControl(charmer, 1); switch(type)
((Player*)charmer)->SetViewpoint(this, false);
charmer->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
}
// restore UNIT_FIELD_BYTES_0
else if(GetTypeId() == TYPEID_UNIT && charmer->GetTypeId() == TYPEID_PLAYER && charmer->getClass() == CLASS_WARLOCK)
{
CreatureInfo const *cinfo = ((Creature*)this)->GetCreatureInfo();
if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
{ {
if(GetCharmInfo()) case CHARM_TYPE_VEHICLE:
GetCharmInfo()->SetPetNumber(0, true); ((Player*)charmer)->SetViewpoint(this, false);
else break;
sLog.outError("Aura::HandleModCharm: target="UI64FMTD" with typeid=%d has a charm aura but no charm info!", GetGUID(), GetTypeId()); case CHARM_TYPE_POSSESS:
((Player*)charmer)->SetClientControl(charmer, 1);
((Player*)charmer)->SetViewpoint(this, false);
charmer->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_DISABLE_MOVE);
break;
case CHARM_TYPE_CHARM:
if(GetTypeId() == TYPEID_UNIT && charmer->getClass() == CLASS_WARLOCK)
{
CreatureInfo const *cinfo = ((Creature*)this)->GetCreatureInfo();
if(cinfo && cinfo->type == CREATURE_TYPE_DEMON)
{
if(GetCharmInfo())
GetCharmInfo()->SetPetNumber(0, true);
else
sLog.outError("Aura::HandleModCharm: target="UI64FMTD" with typeid=%d has a charm aura but no charm info!", GetGUID(), GetTypeId());
}
}
break;
default:
break;
} }
} }
//a guardian should always have charminfo //a guardian should always have charminfo
if(GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT if(charmer->GetTypeId() == TYPEID_PLAYER && this != charmer->GetFirstControlled())
&& !((Creature*)this)->HasSummonMask(SUMMON_MASK_GUARDIAN)) ((Player*)charmer)->SendRemoveControlBar();
{ else if(GetTypeId() == TYPEID_PLAYER || GetTypeId() == TYPEID_UNIT && !((Creature*)this)->isGuardian())
DeleteCharmInfo(); DeleteCharmInfo();
}
if(possess || charmer->GetTypeId() == TYPEID_PLAYER)
{
// Remove pet spell action bar
WorldPacket data(SMSG_PET_SPELLS, 8);
data << uint64(0);
((Player*)charmer)->GetSession()->SendPacket(&data);
}
} }
void Unit::RestoreFaction() void Unit::RestoreFaction()
+9 -2
View File
@@ -885,6 +885,13 @@ struct CharmSpellEntry
typedef std::list<Player*> SharedVisionList; typedef std::list<Player*> SharedVisionList;
enum CharmType
{
CHARM_TYPE_CHARM,
CHARM_TYPE_POSSESS,
CHARM_TYPE_VEHICLE,
};
enum ActionBarIndex enum ActionBarIndex
{ {
ACTION_BAR_INDEX_START = 0, ACTION_BAR_INDEX_START = 0,
@@ -1340,8 +1347,8 @@ class TRINITY_DLL_SPEC Unit : public WorldObject
void SetMinion(Minion *minion, bool apply); void SetMinion(Minion *minion, bool apply);
void SetCharm(Unit* target, bool apply); void SetCharm(Unit* target, bool apply);
Unit* GetNextRandomRaidMemberOrPet(float radius); Unit* GetNextRandomRaidMemberOrPet(float radius);
void SetCharmedOrPossessedBy(Unit* charmer, bool possess); void SetCharmedBy(Unit* charmer, CharmType type);
void RemoveCharmedOrPossessedBy(Unit* charmer); void RemoveCharmedBy(Unit* charmer);
void RestoreFaction(); void RestoreFaction();
ControlList m_Controlled; ControlList m_Controlled;
+2 -15
View File
@@ -247,14 +247,7 @@ bool Vehicle::AddPassenger(Unit *unit, int8 seatId)
//ChatHandler(player).PSendSysMessage("Enter seat %u %u", veSeat->m_ID, seat->first); //ChatHandler(player).PSendSysMessage("Enter seat %u %u", veSeat->m_ID, seat->first);
if(seat->first == 0 && seat->second.seatInfo->IsUsable()) // not right if(seat->first == 0 && seat->second.seatInfo->IsUsable()) // not right
{ SetCharmedBy(unit, CHARM_TYPE_VEHICLE);
setFaction(unit->getFaction());
AI()->OnCharmed(true);
GetMotionMaster()->MoveIdle();
((Player*)unit)->SetCharm(this, true);
((Player*)unit)->SetViewpoint(this, true);
((Player*)unit)->VehicleSpellInitialize();
}
((Player*)unit)->BuildTeleportAckMsg(&data, unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetOrientation()); ((Player*)unit)->BuildTeleportAckMsg(&data, unit->GetPositionX(), unit->GetPositionY(), unit->GetPositionZ(), unit->GetOrientation());
((Player*)unit)->GetSession()->SendPacket(&data); ((Player*)unit)->GetSession()->SendPacket(&data);
@@ -294,13 +287,7 @@ void Vehicle::RemovePassenger(Unit *unit)
//SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK); //SetFlag(UNIT_NPC_FLAGS, UNIT_NPC_FLAG_SPELLCLICK);
if(unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.seatInfo->IsUsable()) if(unit->GetTypeId() == TYPEID_PLAYER && seat->first == 0 && seat->second.seatInfo->IsUsable())
{ RemoveCharmedBy(unit);
RestoreFaction();
AI()->OnCharmed(false);
((Player*)unit)->SetCharm(this, false);
((Player*)unit)->SetViewpoint(this, false);
((Player*)unit)->SendRemoveControlBar();
}
// only for flyable vehicles? // only for flyable vehicles?
//CastSpell(this, 45472, true); // Parachute //CastSpell(this, 45472, true); // Parachute