Core/Players: Improved alcohol handling, weeeeeeeeeeeeeeeee

Closes #7293
This commit is contained in:
Shauren
2012-08-07 17:45:10 +02:00
parent 429130522e
commit f8cd39b2ed
6 changed files with 49 additions and 53 deletions

View File

@@ -1177,7 +1177,7 @@ CREATE TABLE `characters` (
`chosenTitle` int(10) unsigned NOT NULL DEFAULT '0',
`knownCurrencies` bigint(20) unsigned NOT NULL DEFAULT '0',
`watchedFaction` int(10) unsigned NOT NULL DEFAULT '0',
`drunk` smallint(5) unsigned NOT NULL DEFAULT '0',
`drunk` tinyint(3) unsigned NOT NULL DEFAULT '0',
`health` int(10) unsigned NOT NULL DEFAULT '0',
`power1` int(10) unsigned NOT NULL DEFAULT '0',
`power2` int(10) unsigned NOT NULL DEFAULT '0',

View File

@@ -0,0 +1,2 @@
UPDATE characters SET drunk = (drunk / 256) & 0xFF;
ALTER TABLE characters CHANGE drunk drunk tinyint(3) unsigned NOT NULL DEFAULT '0';

View File

@@ -726,7 +726,6 @@ Player::Player(WorldSession* session): Unit(true), m_achievementMgr(this), m_rep
m_MirrorTimerFlagsLast = UNDERWATER_NONE;
m_isInWater = false;
m_drunkTimer = 0;
m_drunk = 0;
m_restTime = 0;
m_deathTimer = 0;
m_deathExpireTime = 0;
@@ -1458,49 +1457,51 @@ void Player::HandleDrowning(uint32 time_diff)
m_MirrorTimerFlagsLast = m_MirrorTimerFlags;
}
///The player sobers by 256 every 10 seconds
///The player sobers by 1% every 9 seconds
void Player::HandleSobering()
{
m_drunkTimer = 0;
uint32 drunk = (m_drunk <= 256) ? 0 : (m_drunk - 256);
uint8 currentDrunkValue = GetDrunkValue();
uint8 drunk = currentDrunkValue ? --currentDrunkValue : 0;
SetDrunkValue(drunk);
}
DrunkenState Player::GetDrunkenstateByValue(uint16 value)
DrunkenState Player::GetDrunkenstateByValue(uint8 value)
{
if (value >= 23000)
if (value >= 90)
return DRUNKEN_SMASHED;
if (value >= 12800)
if (value >= 50)
return DRUNKEN_DRUNK;
if (value & 0xFFFE)
if (value)
return DRUNKEN_TIPSY;
return DRUNKEN_SOBER;
}
void Player::SetDrunkValue(uint16 newDrunkenValue, uint32 itemId)
void Player::SetDrunkValue(uint8 newDrunkValue, uint32 itemId /*= 0*/)
{
uint32 oldDrunkenState = Player::GetDrunkenstateByValue(m_drunk);
bool isSobering = newDrunkValue < GetDrunkValue();
uint32 oldDrunkenState = Player::GetDrunkenstateByValue(GetDrunkValue());
if (newDrunkValue > 100)
newDrunkValue = 100;
// select drunk percent or total SPELL_AURA_MOD_FAKE_INEBRIATE amount, whichever is higher for visibility updates
int32 drunkPercent = newDrunkenValue * 100 / 0xFFFF;
drunkPercent = std::max(drunkPercent, GetTotalAuraModifier(SPELL_AURA_MOD_FAKE_INEBRIATE));
int32 drunkPercent = std::max<int32>(newDrunkValue, GetTotalAuraModifier(SPELL_AURA_MOD_FAKE_INEBRIATE));
if (drunkPercent)
{
m_invisibilityDetect.AddFlag(INVISIBILITY_DRUNK);
m_invisibilityDetect.SetValue(INVISIBILITY_DRUNK, drunkPercent);
}
else if (!HasAuraType(SPELL_AURA_MOD_FAKE_INEBRIATE) && !newDrunkenValue)
else if (!HasAuraType(SPELL_AURA_MOD_FAKE_INEBRIATE) && !newDrunkValue)
m_invisibilityDetect.DelFlag(INVISIBILITY_DRUNK);
m_drunk = newDrunkenValue;
SetUInt32Value(PLAYER_BYTES_3, (GetUInt32Value(PLAYER_BYTES_3) & 0xFFFF0001) | (m_drunk & 0xFFFE));
uint32 newDrunkenState = Player::GetDrunkenstateByValue(m_drunk);
uint32 newDrunkenState = Player::GetDrunkenstateByValue(newDrunkValue);
SetByteValue(PLAYER_BYTES_3, 1, newDrunkValue);
UpdateObjectVisibility();
if (!isSobering)
m_drunkTimer = 0; // reset sobering timer
if (newDrunkenState == oldDrunkenState)
return;
@@ -1508,7 +1509,6 @@ void Player::SetDrunkValue(uint16 newDrunkenValue, uint32 itemId)
data << uint64(GetGUID());
data << uint32(newDrunkenState);
data << uint32(itemId);
SendMessageToSet(&data, true);
}
@@ -1749,11 +1749,10 @@ void Player::Update(uint32 p_time)
m_Last_tick = now;
}
if (m_drunk)
if (GetDrunkValue())
{
m_drunkTimer += p_time;
if (m_drunkTimer > 10*IN_MILLISECONDS)
if (m_drunkTimer > 9 * IN_MILLISECONDS)
HandleSobering();
}
@@ -16748,7 +16747,8 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
SetUInt32Value(PLAYER_BYTES, fields[9].GetUInt32());
SetUInt32Value(PLAYER_BYTES_2, fields[10].GetUInt32());
SetUInt32Value(PLAYER_BYTES_3, (fields[49].GetUInt16() & 0xFFFE) | fields[5].GetUInt8());
SetByteValue(PLAYER_BYTES_3, 0, fields[5].GetUInt8());
SetByteValue(PLAYER_BYTES_3, 1, fields[49].GetUInt8());
SetUInt32Value(PLAYER_FLAGS, fields[11].GetUInt32());
SetInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX, fields[48].GetUInt32());
@@ -17058,13 +17058,11 @@ bool Player::LoadFromDB(uint32 guid, SQLQueryHolder *holder)
// set value, including drunk invisibility detection
// calculate sobering. after 15 minutes logged out, the player will be sober again
float soberFactor;
if (time_diff > 15*MINUTE)
soberFactor = 0;
else
soberFactor = 1-time_diff/(15.0f*MINUTE);
uint16 newDrunkenValue = uint16(soberFactor*(GetUInt32Value(PLAYER_BYTES_3) & 0xFFFE));
SetDrunkValue(newDrunkenValue);
uint8 newDrunkValue = 0;
if (time_diff < GetDrunkValue() * 9)
newDrunkValue = GetDrunkValue() - time_diff / 9;
SetDrunkValue(newDrunkValue);
m_cinematic = fields[18].GetUInt8();
m_Played_time[PLAYED_TIME_TOTAL]= fields[19].GetUInt32();
@@ -18658,7 +18656,7 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setUInt32(index++, GetUInt32Value(PLAYER_CHOSEN_TITLE));
stmt->setUInt64(index++, GetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES));
stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX));
stmt->setUInt16(index++, (uint16)(GetUInt32Value(PLAYER_BYTES_3) & 0xFFFE));
stmt->setUInt8(index++, GetDrunkValue());
stmt->setUInt32(index++, GetHealth());
for (uint32 i = 0; i < MAX_POWERS; ++i)
@@ -18769,7 +18767,7 @@ void Player::SaveToDB(bool create /*=false*/)
stmt->setUInt32(index++, GetUInt32Value(PLAYER_CHOSEN_TITLE));
stmt->setUInt64(index++, GetUInt64Value(PLAYER_FIELD_KNOWN_CURRENCIES));
stmt->setUInt32(index++, GetUInt32Value(PLAYER_FIELD_WATCHED_FACTION_INDEX));
stmt->setUInt16(index++, (uint16)(GetUInt32Value(PLAYER_BYTES_3) & 0xFFFE));
stmt->setUInt8(index++, GetDrunkValue());
stmt->setUInt32(index++, GetHealth());
for (uint32 i = 0; i < MAX_POWERS; ++i)

View File

@@ -2050,9 +2050,9 @@ class Player : public Unit, public GridObject<Player>
inline SpellCooldowns GetSpellCooldowns() const { return m_spellCooldowns; }
void SetDrunkValue(uint16 newDrunkValue, uint32 itemid=0);
uint16 GetDrunkValue() const { return m_drunk; }
static DrunkenState GetDrunkenstateByValue(uint16 value);
void SetDrunkValue(uint8 newDrunkValue, uint32 itemId = 0);
uint8 GetDrunkValue() const { return GetByteValue(PLAYER_BYTES_3, 1); }
static DrunkenState GetDrunkenstateByValue(uint8 value);
uint32 GetDeathTimer() const { return m_deathTimer; }
uint32 GetCorpseReclaimDelay(bool pvp) const;
@@ -2720,7 +2720,6 @@ class Player : public Unit, public GridObject<Player>
time_t m_lastDailyQuestTime;
uint32 m_drunkTimer;
uint16 m_drunk;
uint32 m_weaponChangeTimer;
uint32 m_zoneUpdateId;

View File

@@ -4772,16 +4772,18 @@ void Spell::EffectInebriate(SpellEffIndex /*effIndex*/)
if (!unitTarget || unitTarget->GetTypeId() != TYPEID_PLAYER)
return;
Player* player = (Player*)unitTarget;
uint16 currentDrunk = player->GetDrunkValue();
uint16 drunkMod = damage * 256;
if (currentDrunk + drunkMod > 0xFFFF)
Player* player = unitTarget->ToPlayer();
uint8 currentDrunk = player->GetDrunkValue();
uint8 drunkMod = damage;
if (currentDrunk + drunkMod > 100)
{
currentDrunk = 0xFFFF;
player->CastSpell(player, 67468, false);
currentDrunk = 100;
if (rand_chance() < 25.0f)
player->CastSpell(player, 67468, false); // Drunken Vomit
}
else
currentDrunk += drunkMod;
player->SetDrunkValue(currentDrunk, m_CastItem ? m_CastItem->GetEntry() : 0);
}

View File

@@ -1130,20 +1130,15 @@ public:
static bool HandleModifyDrunkCommand(ChatHandler* handler, const char* args)
{
if (!*args) return false;
if (!*args)
return false;
uint32 drunklevel = (uint32)atoi(args);
uint8 drunklevel = (uint8)atoi(args);
if (drunklevel > 100)
drunklevel = 100;
uint16 drunkMod = drunklevel * 0xFFFF / 100;
Player* target = handler->getSelectedPlayer();
if (!target)
target = handler->GetSession()->GetPlayer();
if (target)
target->SetDrunkValue(drunkMod);
if (Player* target = handler->getSelectedPlayer())
target->SetDrunkValue(drunklevel);
return true;
}