Index: ascent-world.conf =================================================================== --- ascent-world.conf (revision 3645) +++ ascent-world.conf (working copy) @@ -227,7 +227,9 @@ # by this value in order to get his xp gain. # # RestXP: -# Value is the amount of rest XP a player will recieve per minute of rest time. +# Amount of hours needed to get one *ubble rested XP ( one bubble is 5% of the complete XP bar) +# Default is 8 hrs rest for one bubble, lowering this rate is earning RestedXP faster +# (Note that resting in a resting area goes 4 times faster.) # # Drop(Color): # These values will be multiplied by the drop percentages of the items for creatures @@ -267,7 +269,7 @@ Compression="1" XP="1" QuestXP="1" - RestXP="1" + RestXP="8" DropGrey="1" DropWhite="1" DropGreen="1" Index: ascent-world/CharacterHandler.cpp =================================================================== --- ascent-world/CharacterHandler.cpp (revision 3645) +++ ascent-world/CharacterHandler.cpp (working copy) @@ -876,27 +876,20 @@ } } - // Calculate rested experience if there is time between lastlogoff and now - uint32 currenttime = (uint32)UNIXTIME; - uint32 timediff = currenttime - plr->m_timeLogoff; + + //Set current RestState + if( plr->m_isResting) // We are resting at an inn , turn on Zzz + plr->ApplyPlayerRestState(true); - if(plr->m_timeLogoff > 0 && plr->GetUInt32Value(UNIT_FIELD_LEVEL) < plr->GetUInt32Value(PLAYER_FIELD_MAX_LEVEL)) // if timelogoff = 0 then it's the first login + //Calculate rest bonus if there is time between lastlogoff and now + if( plr->m_timeLogoff > 0 && plr->GetUInt32Value(UNIT_FIELD_LEVEL) < plr->GetUInt32Value(PLAYER_FIELD_MAX_LEVEL)) // if timelogoff = 0 then it's the first login { - if(plr->m_isResting) - { - // We are resting at an inn, calculate XP and add it. - uint32 RestXP = plr->CalculateRestXP((uint32)timediff); - plr->AddRestXP(RestXP); - sLog.outDebug("REST: Added %d of rest XP.", RestXP); - plr->ApplyPlayerRestState(true); - } - else if(timediff > 0) - { - // We are resting in the wilderness at a slower rate. - uint32 RestXP = plr->CalculateRestXP((uint32)timediff); - RestXP >>= 2; // divide by 4 because its at 1/4 of the rate - plr->AddRestXP(RestXP); - } + uint32 currenttime = (uint32)UNIXTIME; + uint32 timediff = currenttime - plr->m_timeLogoff; + + //Calculate rest bonus + if( timediff > 0 ) + plr->AddCalculatedRestXP(timediff); } #ifdef CLUSTERING Index: ascent-world/Level2.cpp =================================================================== --- ascent-world/Level2.cpp (revision 3645) +++ ascent-world/Level2.cpp (working copy) @@ -909,7 +909,7 @@ if(plr->GetInstanceID() == m_session->GetPlayer()->GetInstanceID()) plr->RemoteRevive(); else - sEventMgr.AddEvent(plr, &layer::RemoteRevive, EVENT_PLAYER_REST, 1, 1,0); + sEventMgr.AddEvent(plr, &layer::RemoteRevive, EVENT_PLAYER_UPDATE, 1, 1,0); GreenSystemMessage(m_session, "Revived player %s.", args); } else { Index: ascent-world/Player.cpp =================================================================== --- ascent-world/Player.cpp (revision 3645) +++ ascent-world/Player.cpp (working copy) @@ -142,8 +142,6 @@ for ( int aX = 0; aX < 8; aX++ ) m_Tutorials[ aX ] = 0x00; - m_lastRestUpdate = 0; - m_lootGuid = 0; m_banned = false; @@ -1175,22 +1173,19 @@ if(at->ZoneId != 0 && m_zoneId != at->ZoneId) ZoneUpdate(at->ZoneId); + bool rest_on = false; // Check for a restable area if(at->AreaFlags & AREA_CITY_AREA || at->AreaFlags & AREA_CITY) { // check faction if((at->category == AREAC_ALLIANCE_TERRITORY && GetTeam() == 0) || (at->category == AREAC_HORDE_TERRITORY && GetTeam() == 1) ) { - if(!m_isResting) ApplyPlayerRestState(true); + rest_on = true; } - else if(at->category != AREAC_ALLIANCE_TERRITORY && at->category != AREAC_HORDE_TERRITORY) + else if(at->category != AREAC_ALLIANCE_TERRITORY && at->category != AREAC_HORDE_TERRITORY) { - if(!m_isResting) ApplyPlayerRestState(true); + rest_on = true; } - else - { - if(m_isResting) ApplyPlayerRestState(false); - } } else { @@ -1201,30 +1196,35 @@ if(at2 && at2->AreaFlags & AREA_CITY_AREA || at2 && at2->AreaFlags & AREA_CITY) { if((at2->category == AREAC_ALLIANCE_TERRITORY && GetTeam() == 0) || (at2->category == AREAC_HORDE_TERRITORY && GetTeam() == 1) ) - { - if(!m_isResting) ApplyPlayerRestState(true); - } - else if(at2->category != AREAC_ALLIANCE_TERRITORY && at2->category != AREAC_HORDE_TERRITORY) - { - if(!m_isResting) ApplyPlayerRestState(true); - } - else - { - if(m_isResting) ApplyPlayerRestState(false); - } + { + rest_on = true; + } + else if(at2->category != AREAC_ALLIANCE_TERRITORY && at2->category != AREAC_HORDE_TERRITORY) + { + rest_on = true; + } } - else - { - if(m_isResting) - ApplyPlayerRestState(false); - } - } - else - { - if(m_isResting) ApplyPlayerRestState(false); - } + } } + if (rest_on) + { + if(!m_isResting) ApplyPlayerRestState(true); + } + else + { + if(m_isResting) + { +#ifdef COLLISION + const LocationVector & loc = GetPosition(); + if(!CollideInterface.IsIndoor(GetMapId(), loc.x, loc.y, loc.z + 2.0f)) + ApplyPlayerRestState(false); +#else + ApplyPlayerRestState(false); +#endif + } + } + if( !(currFields & val) && !GetTaxiState() && !m_TransporterGUID)//Unexplored Area // bur: we dont want to explore new areas when on taxi { SetUInt32Value(offset, (uint32)(currFields | val)); @@ -1345,8 +1345,9 @@ if(getLevel() >= GetUInt32Value(PLAYER_FIELD_MAX_LEVEL)) return; - uint32 restxp = xp; + uint32 restxp = 0; + //add reststate bonus (except for quests) if(m_restState == RESTSTATE_RESTED && allowbonus) { restxp = SubtractRestXP(xp); @@ -4681,66 +4682,51 @@ CalcDamage(); } -void Player::AddRestXP(uint32 amount) -{ - if(GetUInt32Value(UNIT_FIELD_LEVEL) >= GetUInt32Value(PLAYER_FIELD_MAX_LEVEL)) // Save CPU, don't waste time on this if you're >= 60 - return; - m_restAmount += amount; - SetUInt32Value(PLAYER_REST_STATE_EXPERIENCE, (uint32)(m_restAmount*0.5)); - UpdateRestState(); -} - uint32 Player::SubtractRestXP(uint32 amount) { - if(GetUInt32Value(UNIT_FIELD_LEVEL) >= GetUInt32Value(PLAYER_FIELD_MAX_LEVEL)) // Save CPU, don't waste time on this if you're >= 70 - return 0; - uint32 amt = amount; - int32 tmp = m_restAmount - amount; - int32 pos = m_restAmount - (amount*2); - if(pos < 0) pos = 0; + if(GetUInt32Value(UNIT_FIELD_LEVEL) >= GetUInt32Value(PLAYER_FIELD_MAX_LEVEL)) // Save CPU, don't waste time on this if you've reached max_level + amount = 0; - if(tmp < 0) - { - amt = m_restAmount; + int32 restAmount = m_restAmount - (amount << 1); // remember , we are dealing with xp without restbonus, so multiply by 2 + + if( restAmount < 0) m_restAmount = 0; - } else - m_restAmount -= amount; + m_restAmount = restAmount; - - SetUInt32Value(PLAYER_REST_STATE_EXPERIENCE, pos); - UpdateRestState(); - return amt; + Log.Debug("REST","Subtracted %d rest XP to a total of %d", amount, m_restAmount); + UpdateRestState(); // Update clients interface with new values. + return amount; } -uint32 Player::CalculateRestXP(uint32 seconds) +void Player::AddCalculatedRestXP(uint32 seconds) { - float rate = sWorld.getRate(RATE_RESTXP); - float xp = 0; - if(seconds < 60) - { - xp = 1 * rate; - } - else - { - xp = ((seconds / 60) * rate); - } - return uint32(xp); -} + // At level one, players will all start in the normal tier. + // When a player rests in a city or at an inn they will gain rest bonus at a very slow rate. + // Eight hours of rest will be needed for a player to gain one "bubble" of rest bonus. + // At any given time, players will be able to accumulate a maximum of 30 "bubbles" worth of rest bonus which + // translates into approximately 1.5 levels worth of rested play (before your character returns to normal rest state). + // Thanks to the comforts of a warm bed and a hearty meal, players who rest or log out at an Inn will + // accumulate rest credit four times faster than players logged off outside of an Inn or City. + // Players who log out anywhere else in the world will earn rest credit four times slower. + // http://www.worldofwarcraft.com/info/basics/resting.html -void Player::EventPlayerRest() -{ - if(GetUInt32Value(UNIT_FIELD_LEVEL) >= GetUInt32Value(PLAYER_FIELD_MAX_LEVEL)) // Save CPU, don't waste time on this if you're >= 70 - { - EventMgr::getSingleton().RemoveEvents(this, EVENT_PLAYER_REST); - return; - } - // Rest timer - uint32 diff = (uint32)UNIXTIME - m_lastRestUpdate; - m_lastRestUpdate = (uint32)UNIXTIME; - uint32 RestXP = CalculateRestXP((uint32)diff); - sLog.outDebug("REST: Adding %d rest XP for %.0f seconds of rest time", RestXP, diff); - AddRestXP(RestXP); + float bubblerate = sWorld.getRate(RATE_RESTXP); + uint32 xp_to_lvl = uint32(lvlinfo->XPToNextLevel); // Define xp for a full bar ( = 20 bubbles) + uint32 rested_xp = uint32(0.05f * xp_to_lvl * ( seconds / (3600 * bubblerate ))); // One bubble (5% of xp_to_level) for every <bubblerate> hours logged out. + // bubblerate is multiplier RestXP from ascent.config default is 8hrs/bubble. + + if (m_isResting) // we are at a resting area rest_XP goes 4 times faster (one bubble every 2 hrs) + rested_xp <<= 2; + + m_restAmount += rested_xp; // Add result to accumulated rested XP + + if (m_restAmount > xp_to_lvl + xp_to_lvl >> 1) // and set limit to be max 30 bubbles (1.5 * xp_to_level) + m_restAmount = xp_to_lvl + xp_to_lvl >> 1; + + Log.Debug("REST","Add %d rest XP to a total of %d, RestState %d", rested_xp, m_restAmount,m_isResting); + + UpdateRestState(); // Update clients interface with new values. } void Player::UpdateRestState() @@ -4750,8 +4736,11 @@ else m_restState = RESTSTATE_NORMAL; - // Update needle position + // Update RestState 100%/200% SetUInt32Value(PLAYER_*YTES_2, ((GetUInt32Value(PLAYER_*YTES_2) & 0x00FFFFFF) | (m_restState << 24))); + + //update needle (weird, works at 1/2 rate) + SetUInt32Value(PLAYER_REST_STATE_EXPERIENCE, m_restAmount >> 1); } void Player::ApplyPlayerRestState(bool apply) @@ -4760,23 +4749,14 @@ { m_restState = RESTSTATE_RESTED; m_isResting = true; - SetFlag(PLAYER_FLAGS, PLAYER_FLAG_RESTING); //put zzz icon - - UpdateRestState(); - m_lastRestUpdate = (uint32)UNIXTIME; - - if(GetUInt32Value(UNIT_FIELD_LEVEL) >= GetUInt32Value(PLAYER_FIELD_MAX_LEVEL)) // Save CPU, don't waste time on this if you're >= 70 - return; - sEventMgr.AddEvent(this, &layer::EventPlayerRest, EVENT_PLAYER_REST, (uint32)60000, 0, EVENT_FLAG_DO_NOT_EXECUTE_IN_WORLD_CONTEXT); } else { m_isResting = false; RemoveFlag(PLAYER_FLAGS,PLAYER_FLAG_RESTING); //remove zzz icon - sEventMgr.RemoveEvents(this, EVENT_PLAYER_REST); - UpdateRestState(); } + UpdateRestState(); } void Player::UpdateCooldowns() Index: ascent-world/Player.h =================================================================== --- ascent-world/Player.h (revision 3645) +++ ascent-world/Player.h (working copy) @@ -1344,11 +1344,8 @@ //*ase stats calculations //void Calc*aseStats(); // Rest - void AddRestXP(uint32 amount); uint32 SubtractRestXP(uint32 amount); - uint32 CalculateRestXP(uint32 seconds); - uint32 m_lastRestUpdate; - void EventPlayerRest(); + void AddCalculatedRestXP(uint32 seconds); void ApplyPlayerRestState(bool apply); void UpdateRestState(); //falling? Index: ascent-world/World.cpp =================================================================== --- ascent-world/World.cpp (revision 3645) +++ ascent-world/World.cpp (working copy) @@ -7832,7 +7832,7 @@ setRate(RATE_DROP5,Config.MainConfig.GetFloatDefault("Rates", "DropOrange",1)); setRate(RATE_DROP6,Config.MainConfig.GetFloatDefault("Rates", "DropArtifact",1)); setRate(RATE_XP,Config.MainConfig.GetFloatDefault("Rates", "XP",1)); - setRate(RATE_RESTXP,Config.MainConfig.GetFloatDefault("Rates", "RestXP", 1)); + setRate(RATE_RESTXP,Config.MainConfig.GetFloatDefault("Rates", "RestXP", 8)); setRate(RATE_QUESTXP,Config.MainConfig.GetFloatDefault("Rates", "QuestXP", 1)); setIntRate(INTRATE_SAVE, Config.MainConfig.GetIntDefault("Rates", "Save", 1)); setRate(RATE_MONEY, Config.MainConfig.GetFloatDefault("Rates", "DropMoney", 1.0f)); |