Jump to content
  • Announcements

    • Xmat

      Pravidlo pro postování v TTT

      Do sekce Tipy, triky, tutoriály nepatří žádné dotazy.   Postujte sem vaše návody, tipy a různé další věci jež uznáte za vhodné sdělit zdejšímu osazenstvu, ale veškeré dotazy směřujte do sekce Všeobecná diskuse.
    • Replik

      Seznam návodů a důležitých témat v této sekci

      Pro lepší přehlednost jsem vytvořil tento seznam, který vás, méně zkušené, lépe provede touto sekcí. Věřím, že zde najdete, co hledáte. Vypsané jsou návody, které jsou oficiálně uznané jako návody. Běžné diskuze, které neposkytují postupy a rady zvěřejněny nejsou.   Instalace vlastního MaNGOS Serveru Díky těmto návodům budete (měli by jste být) schopni vytvořit a následně spustit váš vlastní server. Nastavení je pro verze s i bez datadisku.   Instalace MaNGOS Serveru (bez datadisku TBC) - Autor Benny Instalace MaNGOS Serveru (s datadiskem TBC) - Autor Malfik Instalace MaNGOS Serveru v prostředí Linux - Autor charlie Instalace MaNGOS Serveru v prostředí Linux - Autor kupkoid   Chyby a jejich řešení při přihlašování k serveru - Autor Cybe   Zálohování uživatelských dat   Dávkový soubor (BAT soubor) pro vytvoření SQL záloh - Autor Replik   Kompilování - tvoření vlastních release (revizí)   Tvorba kompilací pro Win32 (MangoScript) - Autor bLuma   Ostatní - těžko zařaditelné, ale neznamená to, že nejsou dobré   VIP Systém - Autor charlie Tvorba Webových stránek pro MaNGOS - Autor zahuba Tvorba teleportačních NPC (MangoScript) - Autor Replik Registrační web (původně předělaná SPORA) Funkční pro Antrix i MaNGOS - Autor Replik Nastavení a spuštění Minimanager pro MaNGOS - Autor BlackMartin Nastavení MaNGOS Website - Autor Artorius   Samozřejmě jsou zde i jiné návody, ale tyto jsou nejvíce používané, proto věřím, že vám budou nápomocné. Tuto sekci budeme upravovat podle potřeby. Pokud by jste něco nenašli nebo si nevěděli rady, hledejte na fóru a teprve potom založte vlastní topik. Pokud nějaký autor vytvoří kvalitní návod a chtěl by ho zveřejnit i v tomto seznamu, doporučuji, aby mi napsal zprávu skrze PM.   Díky a přeji hezký den na WoWResource   Replik
    • Aristo

      Příspěvky tam, kde nemají co dělat

      Dodržujte zákaz přispívání do topiků s repaky pokud si to zakladatelé nepřejí!! Opakované psaní příspěvků bude trestáno warnem.
    • Aristo

      Používání spoilerů

      Poslední dobou má většina uživatelů fora zvláštní nutkání postovat extrémně dlouhé texty nebo kódy, které zabírají v nejedenom případu i 80% obsahu celé stránky a hodně tak zvedají nepřehlednost v topiku. Chtěl bych všechny uživatele požádat, aby při postování citací, jakýchkoliv kódů, errorů, atp... delších než 30 řádků používali funkci spoileru.   Funkci vyvoláte příkazem [spoiler] text [/spoiler]   Ukázka:  
Sign in to follow this  
ariczek

Par oprav od zesnuleho serveru :)

Recommended Posts

Ahoj chcel by som sa Opýtať na váš Custom Dungeon či je v c++ alebo lua scripty alebo EventAI a nejaké podrobnosti či je pre ľudí iba full Equiped a zohranostou či iba ľudia s LFG channelu

Share this post


Link to post
Share on other sites

Je to dung jen pres EventAI - komplet v DB. Je to 5man predelanej, ted bych kecal jeden z heroicu co byl u SSC na TBC (tusim Steamvault)- predelan pro lvl 80.

Obtiznosti nekde cca T8. Bossove jsou pojmenovani podle adminu naseho servru, a ability voleny podle oblibene classy daneho cloveka ;)

 

Zabava pro lidi na funku no ;)

Share this post


Link to post
Share on other sites

Ariho vřele doporučuji. Pracuje velmi kvalitně, má smysl pro humor (Vzpomínám na ty spamy na foře s mortimordem, o arim :D ) Tak pokud hledáte kvalitního, developéra, tak jste ho tady našli.

Ps: Já sem vám chtěl pomoct s populaci, ale vy jste mě odfu*** :-)

 

Omyl nehledá post :D Škoda mohli jste mít kvalitního deva.

Edited by Darkal

Share this post


Link to post
Share on other sites

jj tak, ať vystuduješ bez ujmi a ..................... (To bys měl vědět co to je [forum :D ]) Ale stop OT doufám že se někdy setkáme, pracovně.

Edited by Darkal

Share this post


Link to post
Share on other sites

Zdravím. Chtěl bych se zeptat zda uvedený script

system pro zvyseni XP ratu podle played (treba prvni 2 dny played na postave)
by fungoval na Catalysm (SkyFireEmu). Celkem rád bych ho využil na můj budoucí projekt :rolleyes:

Share this post


Link to post
Share on other sites

Neposlal bys mi přes PM na tebe kontakt že by jsme se nějak domluvily? Mám o ten script opravdu zájem. Přibližne asi v příštím týdnu už budu pomalu rozjíždět server tak bych to rád i zkusil jestli to bude fakat :)

Share this post


Link to post
Share on other sites

Midgard Bonus Patch:

 

Kromě XP ratů, umožňuje také všem hráčům poslat poštu :)

Testováno a funkční na revizi 10034 (prehistorická :P )

Obsahuje jeden error o kterem vime - bere to ciste played cas, takze ten bonus maj i DKcka - ovsem to uz by nemelo byt tak tezke opravit :)

Doufám že jsem na nic nezapomněl... přeci jen to máme ve více souborech a dávat dohromady jeden konkrétní script :P

C++ diff

 

# HG changeset patch
# Parent 7b1406907f84c6d48e12cc703012ca9778d05548

diff -r 7b1406907f84 src/server/game/Entities/Creature/GossipDef.cpp
--- a/src/server/game/Entities/Creature/GossipDef.cpp	Sun Oct 03 11:29:27 2010 +0200
+++ b/src/server/game/Entities/Creature/GossipDef.cpp	Tue Oct 05 23:18:23 2010 +0200
@@ -499,7 +499,7 @@
        }

        data << uint32(pQuest->GetRewOrReqMoney());
-        data << uint32(pQuest->XPValue(pSession->GetPlayer())*sWorld.getRate(RATE_XP_QUEST));
+        data << uint32(pQuest->XPValue(pSession->GetPlayer())*(pSession->GetPlayer()->m_BonusRates[bONUS_RATE_XP_QUEST] > sWorld.getRate(RATE_XP_QUEST) ? pSession->GetPlayer()->m_BonusRates[bONUS_RATE_XP_QUEST] : sWorld.getRate(RATE_XP_QUEST)));
    }

    // rewarded honor points. Multiply with 10 to satisfy client
@@ -743,7 +743,7 @@
    }

    data << uint32(pQuest->GetRewOrReqMoney());
-    data << uint32(pQuest->XPValue(pSession->GetPlayer())*sWorld.getRate(RATE_XP_QUEST));
+    data << uint32(pQuest->XPValue(pSession->GetPlayer())*(pSession->GetPlayer()->m_BonusRates[bONUS_RATE_XP_QUEST] > sWorld.getRate(RATE_XP_QUEST) ? pSession->GetPlayer()->m_BonusRates[bONUS_RATE_XP_QUEST] : sWorld.getRate(RATE_XP_QUEST)));

    // rewarded honor points. Multiply with 10 to satisfy client
    data << 10 * Trinity::Honor::hk_honor_at_level(pSession->GetPlayer()->getLevel(), pQuest->GetRewHonorableKills());
diff -r 7b1406907f84 src/server/game/Entities/Player/Player.cpp
--- a/src/server/game/Entities/Player/Player.cpp	Sun Oct 03 11:29:27 2010 +0200
+++ b/src/server/game/Entities/Player/Player.cpp	Tue Oct 05 23:18:23 2010 +0200
@@ -615,6 +615,11 @@
    m_globalCooldowns.clear();

    m_ConditionErrorMsgId = 0;
+
+	for (int i = 0; i < BONUS_MAX_RATES; i++)
+		m_BonusRates[i] = 0;
+	m_ActiveBonusID = 0;
+
}

Player::~Player ()
@@ -814,6 +819,7 @@
    m_Last_tick = time(NULL);
    m_Played_time[PLAYED_TIME_TOTAL] = 0;
    m_Played_time[PLAYED_TIME_LEVEL] = 0;
+    m_Played_time[PLAYED_BONUS_TIME] = 0;

    // base stats and related field values
    InitStatsForLevel();
@@ -933,6 +939,8 @@
        }
    }
    // all item positions resolved
+	_AddNewMidgardBonus(0x0c);
+	_SearchFirstActiveBonusAndActivate();

    return true;
}
@@ -1495,6 +1503,13 @@
        uint32 elapsed = uint32(now - m_Last_tick);
        m_Played_time[PLAYED_TIME_TOTAL] += elapsed;        // Total played time
        m_Played_time[PLAYED_TIME_LEVEL] += elapsed;        // Level played time
+		uint32 last = m_Played_time[PLAYED_BONUS_TIME];
+		m_Played_time[PLAYED_BONUS_TIME] =  m_Played_time[PLAYED_BONUS_TIME] > elapsed ? m_Played_time[PLAYED_BONUS_TIME] - elapsed : 0;        // Bonus played time elapsed
+		if (last && !m_Played_time[PLAYED_BONUS_TIME])
+		{
+			_DeactivateBonus();
+			_SearchFirstActiveBonusAndActivate();
+		}
        m_Last_tick = now;
    }

@@ -4583,6 +4598,7 @@
            trans->PAppend("DELETE FROM character_queststatus_daily WHERE guid = '%u'",guid);
            trans->PAppend("DELETE FROM character_talent WHERE guid = '%u'",guid);
            trans->PAppend("DELETE FROM character_skills WHERE guid = '%u'",guid);
+			trans->PAppend("DELETE FROM character_midgard_bonus WHERE guid = '%u'",guid);

            CharacterDatabase.CommitTransaction(trans);
            break;
@@ -6482,7 +6498,7 @@
                uint32 XP = 0;
                if (diff < -5)
                {
-                    XP = uint32(sObjectMgr.GetBaseXP(getLevel()+5)*sWorld.getRate(RATE_XP_EXPLORE));
+                    XP = uint32(sObjectMgr.GetBaseXP(getLevel()+5)*(m_BonusRates[bONUS_RATE_XP_EXPLORE] > sWorld.getRate(RATE_XP_EXPLORE) ? m_BonusRates[bONUS_RATE_XP_EXPLORE] : sWorld.getRate(RATE_XP_EXPLORE)));
                }
                else if (diff > 5)
                {
@@ -6492,11 +6508,11 @@
                    else if (exploration_percent < 0)
                        exploration_percent = 0;

-                    XP = uint32(sObjectMgr.GetBaseXP(p->area_level)*exploration_percent/100*sWorld.getRate(RATE_XP_EXPLORE));
+                    XP = uint32(sObjectMgr.GetBaseXP(p->area_level)*exploration_percent/100*(m_BonusRates[bONUS_RATE_XP_EXPLORE] > sWorld.getRate(RATE_XP_EXPLORE) ? m_BonusRates[bONUS_RATE_XP_EXPLORE] : sWorld.getRate(RATE_XP_EXPLORE)));
                }
                else
                {
-                    XP = uint32(sObjectMgr.GetBaseXP(p->area_level)*sWorld.getRate(RATE_XP_EXPLORE));
+                    XP = uint32(sObjectMgr.GetBaseXP(p->area_level)*(m_BonusRates[bONUS_RATE_XP_EXPLORE] > sWorld.getRate(RATE_XP_EXPLORE) ? m_BonusRates[bONUS_RATE_XP_EXPLORE] : sWorld.getRate(RATE_XP_EXPLORE)));
                }

                GiveXP(XP, NULL);
@@ -6875,7 +6891,7 @@
        honor_f *= (GetMaxPositiveAuraModifier(SPELL_AURA_MOD_HONOR_GAIN_PCT) + 100) / 100.0f;
    }

-    honor_f *= sWorld.getRate(RATE_HONOR);
+    honor_f *= (m_BonusRates[bONUS_RATE_HONOR] > sWorld.getRate(RATE_HONOR) ? m_BonusRates[bONUS_RATE_HONOR] : sWorld.getRate(RATE_HONOR));
    // Back to int now
    honor = int32(honor_f);
    // honor - for show honor points in log
@@ -14490,7 +14506,7 @@
    QuestStatusData& q_status = mQuestStatus[quest_id];

    // Not give XP in case already completed once repeatable quest
-    uint32 XP = q_status.m_rewarded ? 0 : uint32(pQuest->XPValue(this)*sWorld.getRate(RATE_XP_QUEST));
+    uint32 XP = q_status.m_rewarded ? 0 : uint32(pQuest->XPValue(this)*(m_BonusRates[bONUS_RATE_XP_QUEST] > sWorld.getRate(RATE_XP_QUEST) ? m_BonusRates[bONUS_RATE_XP_QUEST] : sWorld.getRate(RATE_XP_QUEST)));

    // handle SPELL_AURA_MOD_XP_QUEST_PCT auras
    Unit::AuraEffectList const& ModXPPctAuras = GetAuraEffectsByType(SPELL_AURA_MOD_XP_QUEST_PCT);
@@ -15868,7 +15884,7 @@
        matchmakerrating = result->GetUInt32(2);
        SetArenaTeamInfoField(slot, ARENA_TEAM_PERSONAL_RATING, personalrating);
        slot++;
-    } while (result->NextRow());
+	    } while (result->NextRow());
}

void Player::_LoadEquipmentSets(PreparedQueryResult result)
@@ -15900,6 +15916,170 @@
    } while (result->NextRow());
}

+void Player::_LoadMidgardBonus(PreparedQueryResult result)
+{
+    // SetPQuery(PLAYER_LOGIN_QUERY_LOADMIDGARDBONUS,    "SELECT id, bonus, value1, value2 FROM character_midgard_bonus WHERE guid = '%u'", GUID_LOPART(m_guid));
+	if (!result)
+        return;
+
+	uint32 count = 0;
+	MidgardBonus * bonus;
+
+    do
+    {
+		bonus = new MidgardBonus;
+		
+		bonus->id = result->GetUInt16(0);
+		bonus->bonus = result->GetUInt16(1);
+		bonus->value1 = result->GetUInt32(2);
+		bonus->value2 = result->GetString(3);
+		
+		m_MidgardBonusList.push_back(bonus);
+		++count;
+
+    } while (result->NextRow());
+}
+
+void Player::_SaveMidgardBonus(SQLTransaction& trans)
+{
+	trans->PAppend("DELETE FROM character_midgard_bonus WHERE guid='%u'", GetGUIDLow());
+	
+	for (MidgardBonusList::const_iterator itr = m_MidgardBonusList.begin(); itr != m_MidgardBonusList.end(); ++itr)
+	{
+		if ((*itr)->id == m_ActiveBonusID)
+			(*itr)->value1 = m_Played_time[PLAYED_BONUS_TIME];
+		trans->PAppend("INSERT INTO character_midgard_bonus VALUES ('%u', '" UI64FMTD "', '%u', '" UI64FMTD "', '%s')",
+			GetGUIDLow(), (*itr)->id, (*itr)->bonus, (*itr)->value1, (*itr)->value2.c_str());
+	}
+}
+
+void Player::_DeactivateBonus()
+{
+	if (!m_ActiveBonusID || m_MidgardBonusList.empty())
+		return;
+
+	for (MidgardBonusList::const_iterator itr = m_MidgardBonusList.begin(); itr != m_MidgardBonusList.end(); ++itr)
+		if ((*itr)->id == m_ActiveBonusID)
+		{
+			(*itr)->value1 = 0;
+			for (int i = 0; i < BONUS_MAX_RATES; i++)
+				m_BonusRates[i] = 0;
+			m_ActiveBonusID = 0;
+			m_Played_time[PLAYED_BONUS_TIME] = 0;
+			return;
+		}
+}
+
+void Player::_SearchFirstActiveBonusAndActivate()
+{
+	for (MidgardBonusList::const_iterator itr = m_MidgardBonusList.begin(); itr != m_MidgardBonusList.end(); ++itr)
+		if ((*itr)->value1 > 0 && (*itr)->bonus == 0x2)
+		{
+			std::vector<std::string> params = StrSplit((*itr)->value2, ",");
+			
+			if (params.size() == 0)
+				return;
+
+			std::vector<std::string>::iterator iter;
+			for(iter = params.begin(); iter != params.end(); ++iter)
+			{
+				std::vector<std::string> rates = StrSplit((*iter),"=");
+				if (rates.size() == 2)
+				{
+					float value = atof(rates[1].c_str());
+					
+					if (rates[0] == "XP_KILL")
+					{
+						m_BonusRates[bONUS_RATE_XP_KILL] = value;
+						continue;
+					}
+					if (rates[0] == "XP_QUEST")
+					{
+						m_BonusRates[bONUS_RATE_XP_QUEST] = value;
+						continue;
+					}
+					if (rates[0] == "XP_EXPLORE")
+					{
+						m_BonusRates[bONUS_RATE_XP_EXPLORE] = value;
+						continue;
+					}
+					if (rates[0] == "HONOR")
+					{
+						m_BonusRates[bONUS_RATE_HONOR] = value;
+						continue;
+					}
+					if (rates[0] == "REPUTATION")
+					{
+						m_BonusRates[bONUS_RATE_REPUTATION_GAIN] = value;
+						continue;
+					}
+				}
+			}
+			m_Played_time[PLAYED_BONUS_TIME] = (*itr)->value1;
+			m_ActiveBonusID = (*itr)->id;
+			return;
+		}
+}
+
+MidgardBonus * Player::_GetMidgardBonus(uint64 id)
+{
+	for (MidgardBonusList::const_iterator itr = m_MidgardBonusList.begin(); itr != m_MidgardBonusList.end(); ++itr)
+	{
+		if ((*itr)->id == id)
+			return (*itr);
+	}
+	return NULL;
+}
+
+void Player::_AddNewMidgardBonus(uint32 flag)
+{
+	uint32 account_id;
+
+	for (Midgard_BonusList::const_iterator itr = sObjectMgr.m_MidgardBonusList.begin(); itr != sObjectMgr.m_MidgardBonusList.end(); ++itr)
+	{
+		if (((*itr)->bonus == 0x01 || (*itr)->bonus == 0x02) &&  ((*itr)->flag & flag) && _GetMidgardBonus((*itr)->id) == NULL)
+		{
+			//Novy bonus
+			//Kontroluj na pritomnost v account tabulce 
+			if ((*itr)->flag & 0x22)
+			{
+				account_id = sObjectMgr.GetPlayerAccountIdByGUID(GetGUID());
+				QueryResult result = CharacterDatabase.PQuery("SELECT id FROM character_midgard_bonus_acc WHERE accid = '%u' and id = '%u'",account_id,(*itr)->id);
+				if (result)
+					continue;
+			}
+			
+			if ((*itr)->bonus == 0x02)		//Time Bonus
+			{
+				MidgardBonus * bonus = new MidgardBonus();
+				bonus->id = (*itr)->id;
+				bonus->bonus = (*itr)->bonus;
+				bonus->value1 = (*itr)->value1;
+				bonus->value2 = (*itr)->value2;
+				m_MidgardBonusList.push_back(bonus);
+				if ((*itr)->flag & 0x22)
+					CharacterDatabase.PExecute("INSERT INTO character_midgard_bonus_acc (id, accid) VALUES ('%u', '%u')", (*itr)->id, account_id);
+				continue;
+			}
+			
+			if ((*itr)->bonus == 0x01)		//Mail
+			{
+				sObjectMgr.SendMidgardBonusMail((*itr),GetGUID());
+				MidgardBonus * bonus = new MidgardBonus();
+				bonus->id = (*itr)->id;
+				bonus->bonus = (*itr)->bonus;
+				bonus->value1 = (*itr)->value1;
+				bonus->value2 = (*itr)->value2;
+				m_MidgardBonusList.push_back(bonus);
+				if ((*itr)->flag & 0x22)
+					CharacterDatabase.PExecute("INSERT INTO character_midgard_bonus_acc (id, accid) VALUES ('%u', '%u')", (*itr)->id, account_id);
+				continue;
+			}
+		}
+	}
+}
+
+
void Player::_LoadBGData(PreparedQueryResult result)
{
    if (!result)
@@ -16600,8 +16780,11 @@
    m_achievementMgr.CheckAllAchievementCriteria();

    _LoadEquipmentSets(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADEQUIPMENTSETS));
-
-    return true;
+	_LoadMidgardBonus(holder->GetPreparedResult(PLAYER_LOGIN_QUERY_LOADMIDGARDBONUS));
+	_AddNewMidgardBonus(0x30);
+	_SearchFirstActiveBonusAndActivate();
+
+	return true;
}

bool Player::isAllowedToLoot(const Creature* creature)
@@ -17916,6 +18099,8 @@
    if (m_session->isLogingOut() || !sWorld.getBoolConfig(CONFIG_STATS_SAVE_ONLY_ON_LOGOUT))
        _SaveStats(trans);

+	_SaveMidgardBonus(trans);
+
    CharacterDatabase.CommitTransaction(trans);

    // save pet (hunter pet level and experience and all type pets health/mana).
diff -r 7b1406907f84 src/server/game/Entities/Player/Player.h
--- a/src/server/game/Entities/Player/Player.h	Sun Oct 03 11:29:27 2010 +0200
+++ b/src/server/game/Entities/Player/Player.h	Tue Oct 05 23:18:23 2010 +0200
@@ -135,6 +135,16 @@

typedef std::map<uint32, SpellCooldown> SpellCooldowns;

+struct MidgardBonus
+{
+	uint64 id;
+	uint32 bonus;
+	uint64 value1;
+	std::string value2;
+};
+
+typedef std::list<MidgardBonus*> MidgardBonusList;
+
enum TrainerSpellState
{
    TRAINER_SPELL_GREEN = 0,
@@ -752,10 +762,11 @@
enum PlayedTimeIndex
{
    PLAYED_TIME_TOTAL = 0,
-    PLAYED_TIME_LEVEL = 1
+    PLAYED_TIME_LEVEL = 1,
+	PLAYED_BONUS_TIME = 2
};

-#define MAX_PLAYED_TIME_INDEX 2
+#define MAX_PLAYED_TIME_INDEX 3

// used at player loading query list preparing, and later result selection
enum PlayerLoginQueryIndex
@@ -790,7 +801,8 @@
    PLAYER_LOGIN_QUERY_LOADRANDOMBG             = 27,
    PLAYER_LOGIN_QUERY_LOADARENASTATS           = 28,
    PLAYER_LOGIN_QUERY_LOADBANNED               = 29,
-    MAX_PLAYER_LOGIN_QUERY                      = 30
+	PLAYER_LOGIN_QUERY_LOADMIDGARDBONUS		    = 30,
+    MAX_PLAYER_LOGIN_QUERY                      = 31
};

enum PlayerDelayedOperations
@@ -1084,6 +1096,7 @@
        uint32 m_Played_time[MAX_PLAYED_TIME_INDEX];
        uint32 GetTotalPlayedTime() { return m_Played_time[PLAYED_TIME_TOTAL]; }
        uint32 GetLevelPlayedTime() { return m_Played_time[PLAYED_TIME_LEVEL]; }
+        uint32 GetBonusPlayedTime() { return m_Played_time[PLAYED_BONUS_TIME]; }

        void setDeathState(DeathState s);                   // overwrite Unit::setDeathState

@@ -2440,6 +2453,12 @@
        void _LoadArenaTeamInfo(PreparedQueryResult result);
        void _LoadArenaStatsInfo(PreparedQueryResult result);
        void _LoadEquipmentSets(PreparedQueryResult result);
+		void _LoadMidgardBonus(PreparedQueryResult result);
+		void _SaveMidgardBonus(SQLTransaction& trans);
+		void _DeactivateBonus();
+		void _SearchFirstActiveBonusAndActivate();
+		void _AddNewMidgardBonus(uint32 flag);
+		MidgardBonus * _GetMidgardBonus(uint64 id);
        void _LoadBGData(PreparedQueryResult result);
        void _LoadGlyphs(PreparedQueryResult result);
        void _LoadTalents(PreparedQueryResult result);
@@ -2687,7 +2706,11 @@
        uint32 m_timeSyncTimer;
        uint32 m_timeSyncClient;
        uint32 m_timeSyncServer;
-
+		MidgardBonusList m_MidgardBonusList;
+		uint64 m_ActiveBonusID;
+	public:
+		float m_BonusRates[bONUS_MAX_RATES];
+	private:
        LookingForGroup m_LookingForGroup;
};

diff -r 7b1406907f84 src/server/game/Globals/ObjectMgr.cpp
--- a/src/server/game/Globals/ObjectMgr.cpp	Sun Oct 03 11:29:27 2010 +0200
+++ b/src/server/game/Globals/ObjectMgr.cpp	Tue Oct 05 23:18:23 2010 +0200
@@ -49,6 +49,7 @@
#include "ScriptMgr.h"
#include "SpellScript.h"
#include "PoolMgr.h"
+#include "PlayerDump.h"

ScriptMapMap sQuestEndScripts;
ScriptMapMap sQuestStartScripts;
@@ -9018,6 +9019,205 @@
    return sObjectMgr.GetQuestTemplate(entry);
}

+void ObjectMgr::LoadMidgardBonus()
+{
+    if (!m_MidgardBonusList.empty())
+    {
+        for (Midgard_BonusList::const_iterator itr = m_MidgardBonusList.begin(); itr != m_MidgardBonusList.end(); ++itr)
+            delete *itr;
+    }
+    m_MidgardBonusList.clear();
+
+    QueryResult result = CharacterDatabase.Query("SELECT id, bonus, flag, value1, value2 FROM midgard_bonus");
+
+    if (!result)
+    {
+        barGoLink bar(1);
+        bar.step();
+        sLog.outString();
+        sLog.outString(">> Midgard bonus table is empty, no bonus were loaded.");
+        return;
+    }
+
+    uint16 count = 0;
+    barGoLink bar ((*result).GetRowCount());
+    Midgard_Bonus *bonus;
+    do
+    {
+        Field *fields = result->Fetch();
+        bonus = new Midgard_Bonus;
+		bonus->id = fields[0].GetUInt64();
+		bonus->bonus = fields[1].GetUInt32();
+		bonus->flag = fields[2].GetUInt32();
+		bonus->value1 = fields[3].GetUInt64();
+		bonus->value2 = fields[4].GetString();
+        ++count;
+        bar.step();
+
+        m_MidgardBonusList.push_back(bonus);
+
+    } while (result->NextRow());
+}
+
+Midgard_Bonus * ObjectMgr::GetMidgardBonus(uint64 BonusID, uint64 guid)
+{
+	for (Midgard_BonusList::const_iterator itr = m_MidgardBonusList.begin(); itr != m_MidgardBonusList.end(); ++itr)
+	{
+		if((*itr)->id == BonusID)
+			return (*itr);
+	}
+	return NULL;
+}
+
+void ObjectMgr::SendMidgardBonusMail(Midgard_Bonus * Bonus, uint64 guid)
+{
+	typedef std::pair<uint32,uint32> ItemPair;
+    typedef std::list< ItemPair > ItemPairs;
+
+	if (Bonus->bonus != 0x01)
+		return;
+
+	std::vector<std::string> params = StrSplit(Bonus->value2, ",");
+	if (params.size() < 1)
+		return;	
+
+	StrTrim(params[0],'"');
+	StrTrim(params[1]);
+	StrTrim(params[1],'"');
+
+	const char * mailSubject = params[0].c_str();
+	const char * mailtext = params[1].c_str();
+	int32 coin = params.size() >= 3 ? atoi(params[2].c_str()) : 0;
+
+	ItemPairs items;
+
+	for (int i = 3; i < params.size(); i++)
+	{
+		std::vector<std::string> item;
+		item = StrSplit(params[i],":");
+		uint32 item_id = atoi(item[0].c_str());
+		int32 item_count = item.size() > 1 ? atoi(item[1].c_str()) : 1;
+		item_count = item_count > 0 ? item_count : 1;
+
+		if (!item_id)
+			continue;
+					
+		ItemPrototype const* item_proto = sObjectMgr.GetItemPrototype(item_id);
+		if (!item_proto)
+			continue;
+
+		if (item_proto->MaxCount > 0 && item_count > uint32(item_proto->MaxCount))
+			item_count = uint32(item_proto->MaxCount);
+
+		while (item_count > item_proto->GetMaxStackSize() && items.size() < MAX_MAIL_ITEMS)
+		{
+			items.push_back(ItemPair(item_id,item_proto->GetMaxStackSize()));
+     		item_count -= item_proto->GetMaxStackSize();
+		}
+		
+		if (items.size() > MAX_MAIL_ITEMS)
+			break;
+		
+		items.push_back(ItemPair(item_id,item_count));
+		if (items.size() > MAX_MAIL_ITEMS)
+			break;
+	}
+	MailSender sender(MAIL_NORMAL, 0, MAIL_STATIONERY_GM);
+	MailDraft draft(mailSubject, mailtext);
+
+	if (coin > 0)
+		draft.AddMoney(coin);
+
+	SQLTransaction trans = CharacterDatabase.BeginTransaction();
+	for (ItemPairs::const_iterator itr = items.begin(); itr != items.end(); ++itr)
+	{
+		if (Item* item = Item::CreateItem(itr->first,itr->second, 0))
+		{
+			item->SaveToDB(trans);                               // save for prevent lost at next mail load, if send fail then item will deleted
+			draft.AddItem(item);
+		}
+	}
+	
+	draft.SendMailTo(trans,MailReceiver(GUID_LOPART(guid)), MailSender(MAIL_NORMAL, 0, MAIL_STATIONERY_GM));
+	CharacterDatabase.CommitTransaction(trans);
+}
+
+
+
+void ObjectMgr::ExecuteMidgardBonus()
+{
+	typedef std::pair<uint32,uint32> ItemPair;
+    typedef std::list< ItemPair > ItemPairs;
+    
+
+	Midgard_BonusList::const_iterator itr;
+	SQLTransaction trans = CharacterDatabase.BeginTransaction();
+	for (itr = m_MidgardBonusList.begin(); itr != m_MidgardBonusList.end(); ++itr)
+	{
+		if((*itr)->flag & 3)			//Flag nastaven na start serveru
+		{
+			std::vector<std::string> params = StrSplit((*itr)->value2, ",");
+			std::vector<std::string>::iterator iter;
+			
+
+			QueryResult result;
+
+			//provedeni akce
+			switch ((*itr)->bonus)
+			{
+			case 0x01:			//Mail
+				result = CharacterDatabase.Query("SELECT guid FROM characters");
+			    if (!result)
+				{
+					sLog.outString();
+     				sLog.outString(">> characters table is empty, no mails send.");
+					break;
+				}
+				do
+				{
+					Field *fields = result->Fetch();
+					SendMidgardBonusMail((*itr), fields[0].GetUInt64());
+				} while (result->NextRow());
+
+				break;
+
+			case 0x02:			//Time Bonus
+				//Nebudu zatim resit. Plati jen pro prihlasene hrace behem aktivniho bonusu
+				break;
+			case 0x03:			//DELETE
+
+				if (params.size() == 0)
+					break;			//Nejsou vyparsovane jmena
+		
+				for(iter = params.begin(); iter != params.end(); ++iter)
+				{
+					StrTrim((*iter));
+					uint64 character_guid = sObjectMgr.GetPlayerGUIDByName((*iter).c_str());
+					if (character_guid)
+					{
+						uint32 account_id = sObjectMgr.GetPlayerAccountIdByGUID(character_guid);

+						if (sLog.IsOutCharDump())                                // optimize GetPlayerDump call
+						{
+							std::string dump;
+							PlayerDumpWriter().GetDump(GUID_LOPART(character_guid),dump);
+							sLog.outCharDump(dump.c_str(),account_id,GUID_LOPART(character_guid),(*iter).c_str());
+						}
+						Player::DeleteFromDB(character_guid, account_id, true);
+					}
+				}
+		
+				break;
+			}
+			//Deaktivace bonusu (aktivace pri startu serveru)
+			(*itr)->flag &= ~3;
+			
+			trans->PAppend("UPDATE midgard_bonus SET flag='%u' WHERE ID='%u'",(*itr)->flag,(*itr)->id);
+		}
+	}
+	CharacterDatabase.CommitTransaction(trans);
+}
+
+
CreatureBaseStats const* ObjectMgr::GetCreatureBaseStats(uint8 level, uint8 unitClass)
{
    CreatureBaseStatsMap::const_iterator it = m_creatureBaseStatsMap.find(MAKE_PAIR16(level,unitClass));
diff -r 7b1406907f84 src/server/game/Globals/ObjectMgr.h
--- a/src/server/game/Globals/ObjectMgr.h	Sun Oct 03 11:29:27 2010 +0200
+++ b/src/server/game/Globals/ObjectMgr.h	Tue Oct 05 23:18:23 2010 +0200
@@ -354,6 +354,17 @@
    uint32   skill_id;
};

+struct Midgard_Bonus
+{
+	uint64 id;
+	uint32 bonus;
+	uint32 flag;
+	uint64 value1;
+	std::string value2;
+};
+typedef std::list<Midgard_Bonus*> Midgard_BonusList;
+
+
extern LanguageDesc lang_description[LANGUAGES_COUNT];
 LanguageDesc const* GetLanguageDescByID(uint32 lang);

@@ -729,6 +740,10 @@
        bool AddSpellToTrainer(uint32 entry, uint32 spell, Field *fields, std::set<uint32> *skip_trainers, std::set<uint32> *talentIds);
        int  LoadReferenceTrainer(uint32 trainer, int32 spell, std::set<uint32> *skip_trainers, std::set<uint32> *talentIds);

+		void LoadMidgardBonus();
+		void ExecuteMidgardBonus();
+		void SendMidgardBonusMail(Midgard_Bonus * Bonus, uint64 guid);
+		Midgard_Bonus * GetMidgardBonus(uint64 BonusID, uint64 guid);
        std::string GeneratePetName(uint32 entry);
        uint32 GetBaseXP(uint8 level);
        uint32 GetXPForLevel(uint8 level);
@@ -978,6 +993,8 @@
            return GossipMenuItemsMapBoundsNonConst(m_mGossipMenuItemsMap.lower_bound(uiMenuId),m_mGossipMenuItemsMap.upper_bound(uiMenuId));
        }

+		Midgard_BonusList m_MidgardBonusList;
+
        // for wintergrasp only
        GraveYardMap        mGraveYardMap;

diff -r 7b1406907f84 src/server/game/Miscellaneous/Formulas.h
--- a/src/server/game/Miscellaneous/Formulas.h	Sun Oct 03 11:29:27 2010 +0200
+++ b/src/server/game/Miscellaneous/Formulas.h	Tue Oct 05 23:18:23 2010 +0200
@@ -182,7 +182,7 @@
                        gain *= 2;
                }

-                gain = uint32(gain * sWorld.getRate(RATE_XP_KILL));
+				gain = uint32(gain * (pl->m_BonusRates[bONUS_RATE_XP_KILL] > sWorld.getRate(RATE_XP_KILL) ? pl->m_BonusRates[bONUS_RATE_XP_KILL] : sWorld.getRate(RATE_XP_KILL)));
            }

            sScriptMgr.OnGainCalculation(gain, pl, u);
diff -r 7b1406907f84 src/server/game/Reputation/ReputationMgr.cpp
--- a/src/server/game/Reputation/ReputationMgr.cpp	Sun Oct 03 11:29:27 2010 +0200
+++ b/src/server/game/Reputation/ReputationMgr.cpp	Tue Oct 05 23:18:23 2010 +0200
@@ -322,7 +322,7 @@
        if (incremental)
        {
            // int32 *= float cause one point loss?
-            standing = int32(floor((float)standing * sWorld.getRate(RATE_REPUTATION_GAIN) + 0.5));
+            standing = int32(floor((float)standing * (m_player->m_BonusRates[bONUS_RATE_REPUTATION_GAIN] > sWorld.getRate(RATE_REPUTATION_GAIN) ? m_player->m_BonusRates[bONUS_RATE_REPUTATION_GAIN] : sWorld.getRate(RATE_REPUTATION_GAIN)) + 0.5));
            standing += itr->second.Standing + BaseRep;
        }

diff -r 7b1406907f84 src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp
--- a/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp	Sun Oct 03 11:29:27 2010 +0200
+++ b/src/server/game/Server/Protocol/Handlers/CharacterHandler.cpp	Tue Oct 05 23:18:23 2010 +0200
@@ -189,7 +189,11 @@
    stmt->setUInt32(0, lowGuid);
    res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOADBANNED, stmt);

-    return res;
+	stmt = CharacterDatabase.GetPreparedStatement(CHAR_LOAD_PLAYER_MIDGARD_BONUS);
+    stmt->setUInt32(0, lowGuid);
+	res &= SetPreparedQuery(PLAYER_LOGIN_QUERY_LOADMIDGARDBONUS, stmt);
+
+	return res;
}

void WorldSession::HandleCharEnum(QueryResult result)
diff -r 7b1406907f84 src/server/game/Tools/PlayerDump.cpp
--- a/src/server/game/Tools/PlayerDump.cpp	Sun Oct 03 11:29:27 2010 +0200
+++ b/src/server/game/Tools/PlayerDump.cpp	Tue Oct 05 23:18:23 2010 +0200
@@ -26,7 +26,7 @@
#include "ObjectMgr.h"
#include "AccountMgr.h"

-#define DUMP_TABLE_COUNT 26
+#define DUMP_TABLE_COUNT 27
struct DumpTable
{
    char const* name;
@@ -61,6 +61,7 @@
    { "pet_aura",                         DTT_PET_TABLE  },
    { "pet_spell",                        DTT_PET_TABLE  },
    { "pet_spell_cooldown",               DTT_PET_TABLE  },
+    { "character_midgard_bonus",		  DTT_CHAR_TABLE },
};

// Low level functions
diff -r 7b1406907f84 src/server/game/World/World.cpp
--- a/src/server/game/World/World.cpp	Sun Oct 03 11:29:27 2010 +0200
+++ b/src/server/game/World/World.cpp	Tue Oct 05 23:18:23 2010 +0200
@@ -1619,6 +1619,9 @@
    sLog.outString("Loading GM surveys...");
    sTicketMgr.LoadGMSurveys();

+	sLog.outString("Loading Midgard bonus...");
+    sObjectMgr.LoadMidgardBonus();
+
    sLog.outString("Loading client addons...");
    sAddonMgr.LoadFromDB();

@@ -1750,6 +1753,9 @@
    sLog.outString("Calculate random battleground reset time..." );
    InitRandomBGResetTime();

+	sLog.outString("Initialize MidgardBonus...");
+	sObjectMgr.ExecuteMidgardBonus();
+
    // possibly enable db logging; avoid massive startup spam by doing it here.
    if (sLog.GetLogDBLater())
    {
diff -r 7b1406907f84 src/server/game/World/World.h
--- a/src/server/game/World/World.h	Sun Oct 03 11:29:27 2010 +0200
+++ b/src/server/game/World/World.h	Tue Oct 05 23:18:23 2010 +0200
@@ -389,6 +389,17 @@
    MAX_RATES
};

+//Bonus rates
+enum BonusRates
+{
+	BONUS_RATE_XP_KILL = 0,
+	BONUS_RATE_XP_QUEST,
+	BONUS_RATE_XP_EXPLORE,
+	BONUS_RATE_HONOR,
+	BONUS_RATE_REPUTATION_GAIN,
+	BONUS_MAX_RATES
+};
+
/// Can be used in SMSG_AUTH_RESPONSE packet
enum BillingPlanFlags
{
diff -r 7b1406907f84 src/server/shared/Database/Implementation/CharacterDatabase.cpp
--- a/src/server/shared/Database/Implementation/CharacterDatabase.cpp	Sun Oct 03 11:29:27 2010 +0200
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.cpp	Tue Oct 05 23:18:23 2010 +0200
@@ -89,7 +89,8 @@
    PrepareStatement(CHAR_LOAD_PLAYER_MAILITEMS, "SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, item_guid, item_template, owner_guid FROM mail_items JOIN item_instance ON item_guid = guid WHERE mail_id = ?");
    PrepareStatement(CHAR_LOAD_AUCTION_ITEMS, "SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, itemguid, item_template FROM auctionhouse JOIN item_instance ON itemguid = guid");
    PrepareStatement(CHAR_LOAD_GUILD_BANK_ITEMS, "SELECT creatorGuid, giftCreatorGuid, count, duration, charges, flags, enchantments, randomPropertyId, durability, playedTime, text, TabId, SlotId, item_guid, item_entry, guildid FROM guild_bank_item JOIN item_instance ON item_guid = guid");
-    PrepareStatement(CHAR_LOAD_ITEM_REFUNDS, "SELECT player_guid, paidMoney, paidExtendedCost FROM item_refund_instance WHERE item_guid = ? AND player_guid = ? LIMIT 1");
+    PrepareStatement(CHAR_LOAD_PLAYER_MIDGARD_BONUS, "SELECT id, bonus, value1, value2 FROM character_midgard_bonus WHERE guid = ? order by id");
+	PrepareStatement(CHAR_LOAD_ITEM_REFUNDS, "SELECT player_guid, paidMoney, paidExtendedCost FROM item_refund_instance WHERE item_guid = ? AND player_guid = ? LIMIT 1");
    PrepareStatement(CHAR_LOAD_ITEM_BOP_TRADE, "SELECT allowedPlayers FROM item_soulbound_trade_data WHERE itemGuid = ? LIMIT 1");
    PrepareStatement(CHAR_DEL_ITEM_BOP_TRADE, "DELETE FROM item_soulbound_trade_data WHERE itemGuid = ? LIMIT 1");
    PrepareStatement(CHAR_ADD_ITEM_BOP_TRADE, "INSERT INTO item_soulbound_trade_data VALUES (?, ?)");
diff -r 7b1406907f84 src/server/shared/Database/Implementation/CharacterDatabase.h
--- a/src/server/shared/Database/Implementation/CharacterDatabase.h	Sun Oct 03 11:29:27 2010 +0200
+++ b/src/server/shared/Database/Implementation/CharacterDatabase.h	Tue Oct 05 23:18:23 2010 +0200
@@ -95,6 +95,7 @@
    CHAR_LOAD_PLAYER_MAILITEMS,
    CHAR_LOAD_AUCTION_ITEMS,
    CHAR_LOAD_GUILD_BANK_ITEMS,
+	CHAR_LOAD_PLAYER_MIDGARD_BONUS,
    CHAR_LOAD_ITEM_REFUNDS,
    CHAR_LOAD_ITEM_BOP_TRADE,
    CHAR_DEL_ITEM_BOP_TRADE,
diff -r 7b1406907f84 src/server/shared/Utilities/Util.cpp
--- a/src/server/shared/Utilities/Util.cpp	Sun Oct 03 11:29:27 2010 +0200
+++ b/src/server/shared/Utilities/Util.cpp	Tue Oct 05 23:18:23 2010 +0200
@@ -107,6 +107,20 @@
    return r;
}

+void StrTrim(std::string &str, char trim)
+{
+	std::string::size_type pos = str.find_last_not_of(trim);
+	if(pos != std::string::npos) 
+    {
+		str.erase(pos + 1);
+		pos = str.find_first_not_of(trim);
+		if(pos != std::string::npos) 
+			str.erase(0, pos);
+	}
+	else 
+		str.erase(str.begin(), str.end());
+}
+
void stripLineInvisibleChars(std::string &str)
{
    static std::string invChars = " \t\7\n";
diff -r 7b1406907f84 src/server/shared/Utilities/Util.h
--- a/src/server/shared/Utilities/Util.h	Sun Oct 03 11:29:27 2010 +0200
+++ b/src/server/shared/Utilities/Util.h	Tue Oct 05 23:18:23 2010 +0200
@@ -29,6 +29,7 @@
typedef std::vector<std::string> Tokens;

Tokens StrSplit(const std::string &src, const std::string &sep);
+void StrTrim(std::string &str, char trim = ' ');

void stripLineInvisibleChars(std::string &src);

 

 

SQL cast (do characters DB):

 

--
-- Table structure for table `character_midgard_bonus`
--

DROP TABLE IF EXISTS `character_midgard_bonus`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `character_midgard_bonus` (
 `guid` int(11) unsigned NOT NULL,
 `id` smallint(8) unsigned NOT NULL,
 `bonus` smallint(5) unsigned NOT NULL,
 `value1` mediumint(8) unsigned NOT NULL,
 `value2` text collate utf8_czech_ci,
 PRIMARY KEY  (`guid`,`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC;
SET character_set_client = @saved_cs_client;

 

 

 

--
-- Table structure for table `character_midgard_bonus_acc`
--

DROP TABLE IF EXISTS `character_midgard_bonus_acc`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `character_midgard_bonus_acc` (
 `id` smallint(8) unsigned NOT NULL,
 `accid` int(11) unsigned NOT NULL,  
 PRIMARY KEY  (`id`,`accid`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
SET character_set_client = @saved_cs_client;

 

 

 

--
-- Table structure for table `midgard_bonus`
--

DROP TABLE IF EXISTS `midgard_bonus`;
SET @saved_cs_client     = @@character_set_client;
SET character_set_client = utf8;
CREATE TABLE `midgard_bonus` (
 `ID` smallint(8) unsigned NOT NULL default '0',
 `bonus` smallint(5) unsigned NOT NULL default '0',
 `flag` smallint(5) unsigned NOT NULL default '0',
 `value1` mediumint(8) unsigned NOT NULL default '0',
 `value2` text collate utf8_czech_ci,
 PRIMARY KEY  (`ID`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_czech_ci CHECKSUM=1 DELAY_KEY_WRITE=1 ROW_FORMAT=DYNAMIC;
SET character_set_client = @saved_cs_client;

 

 

a příklad naplnění daty, tak jak jsme to meli u nas:

První hodnota - XP raty podle played.

Druhý řádek uvítací mail, který pošle 3 Event Tokeny (ID 90000 itemu)

Třetí pošle pošle všem mailem noncombat peta :)

 

INSERT INTO `midgard_bonus` VALUES 
(1,2,4,172800,'XP_QUEST=2.5, XP_KILL=2'),
(2,1,4,0,'\"Midgard server\", \"Vitame Vas na serveru Midgard a prejeme prijemne hrani. Midgard team\", 0, 90000:3'),
(3,1,20,0,'\"Midgard server\", \"Server Midgard si pro Vas pripravil male prekvapeni, ktere Vam urcite zprijemni hrani. Midgard team\", 0, 49646');

 

 

Případné otázky zodpovím, pokud budu vědět :)

Edited by ariczek

Share this post


Link to post
Share on other sites

Komplet balik pro fun instant server:

 

DB:

http://www.uloz.to/9673199/fun-world-zip
heslo mggp.cz

 

jako zaklad revky slouzi: 422cfec07d5f4701de19bf5735cff2f481185d25 z gitu TC2

 

tak... ted diff:

 

 

diff --git a/src/server/game/Battlegrounds/Battleground.cpp b/src/server/game/Battlegrounds/Battleground.cpp
index 39f1291..1834431 100755
--- a/src/server/game/Battlegrounds/Battleground.cpp
+++ b/src/server/game/Battlegrounds/Battleground.cpp
@@ -874,11 +915,18 @@ void Battleground::EndBattleground(uint32 winner)
            }

            plr->GetAchievementMgr().UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_WIN_BG, 1);
+            RewardQuest(plr);
+			if (isBattleground()) {
+				plr->AddItem(47241,3);
+			}
        }
        else
        {
            if (IsRandom() || BattlegroundMgr::IsBGWeekend(GetTypeID()))
                UpdatePlayerScore(plr, SCORE_BONUS_HONOR, GetBonusHonorFromKill(loser_kills));
+			if (isBattleground()) {
+				plr->AddItem(47241,1);
+			}
        }


@@ -914,6 +962,57 @@ void Battleground::EndBattleground(uint32 winner)
        SendMessageToAll(winmsg_id, CHAT_MSG_BG_SYSTEM_NEUTRAL);
}

+void Battleground::RewardQuest(Player * plr)
+{
+    uint32 entry;
+    switch(GetTypeID())
+    {
+		case BATTLEGROUND_AV:
+            entry = NPC_AV_QUEST_REWARD;
+            break;
+        case BATTLEGROUND_WS:
+            entry = NPC_WS_QUEST_REWARD;
+            break;
+        case BATTLEGROUND_AB:
+            entry = NPC_AB_QUEST_REWARD;
+            break;
+        case BATTLEGROUND_NA:
+            entry = NPC_NA_QUEST_REWARD;
+            break;
+        case BATTLEGROUND_BE:
+            entry = NPC_BE_QUEST_REWARD;
+            break;
+		case BATTLEGROUND_AA:
+            entry = NPC_AA_QUEST_REWARD;
+            break;
+        case BATTLEGROUND_EY:
+            entry = NPC_EY_QUEST_REWARD;
+            break;
+        case BATTLEGROUND_RL:
+            entry = NPC_RL_QUEST_REWARD;
+            break;
+        case BATTLEGROUND_SA:
+            entry = NPC_SA_QUEST_REWARD;
+            break;
+        case BATTLEGROUND_DS:
+            entry = NPC_DS_QUEST_REWARD;
+            break;
+		case BATTLEGROUND_RV:
+            entry = NPC_RV_QUEST_REWARD;
+            break;
+        case BATTLEGROUND_IC:
+            entry = NPC_IC_QUEST_REWARD;
+            break;
+        case BATTLEGROUND_RB:
+            entry = NPC_RB_QUEST_REWARD;
+            break;
+        default:
+            return;
+    }
+	plr->TalkedToCreature(entry,0);
+}
+
+
uint32 Battleground::GetBonusHonorFromKill(uint32 kills) const
{
    //variable kills means how many honorable kills you scored (so we need kills * honor_for_one_kill)
@@ -1812,9 +1920,27 @@ void Battleground::HandleKillPlayer(Player *player, Player *killer)
        {
            Player *plr = sObjectMgr->GetPlayer(itr->first);

-            if (!plr || plr == killer)
+            if (!plr)
                continue;

+			if (!isArena() && plr->GetTeam() == killer->GetTeam()) {
+				BattlegroundScoreMap::const_iterator itrb = m_PlayerScores.find(plr->GetGUID());
+
+				if (itrb != m_PlayerScores.end()) {                // player founded
+					uint32 damage = itrb->second->DamageDone;
+					uint32 heal = itrb->second->HealingDone;
+
+					bool isHealer = (damage*2 < heal);
+
+					if (plr->GetDistance(player) <= 20.0f || (isHealer && plr->GetDistance(player) <= 40.0f) || plr==killer)
+						plr->AddItem(44990,1);
+
+				}
+			}
+
+			if (plr == killer)
+				continue;
+
            if (plr->GetTeam() == killer->GetTeam() && plr->IsAtGroupRewardDistance(player))
                UpdatePlayerScore(plr, SCORE_HONORABLE_KILLS, 1);
        }
diff --git a/src/server/game/Battlegrounds/Battleground.h b/src/server/game/Battlegrounds/Battleground.h
index a1337c2..fc175fa 100755
--- a/src/server/game/Battlegrounds/Battleground.h
+++ b/src/server/game/Battlegrounds/Battleground.h
@@ -70,6 +70,24 @@ enum BattlegroundMarks
    ITEM_SA_MARK_OF_HONOR           = 42425
};

+enum BattleGroundsNpcReward
+{
+    NPC_AV_QUEST_REWARD            = 6000000,
+    NPC_WS_QUEST_REWARD            = 6000001,
+    NPC_AB_QUEST_REWARD            = 6000002,
+    NPC_NA_QUEST_REWARD            = 6000003,
+    NPC_BE_QUEST_REWARD            = 6000004,
+    NPC_AA_QUEST_REWARD            = 6000005,
+    NPC_EY_QUEST_REWARD            = 6000006,
+    NPC_RL_QUEST_REWARD            = 6000007,
+    NPC_SA_QUEST_REWARD            = 6000008,
+    NPC_DS_QUEST_REWARD            = 6000009,
+    NPC_RV_QUEST_REWARD            = 6000010,
+    NPC_IC_QUEST_REWARD            = 6000011,
+    NPC_RB_QUEST_REWARD            = 6000012
+};
+
+
enum BattlegroundMarksCount
{
    ITEM_WINNER_COUNT               = 3,
@@ -479,6 +505,7 @@ class Battleground
        void RemoveAuraOnTeam(uint32 SpellID, uint32 TeamID);
        void RewardHonorToTeam(uint32 Honor, uint32 TeamID);
        void RewardReputationToTeam(uint32 faction_id, uint32 Reputation, uint32 TeamID);
+        void RewardQuest(Player * plr);
        void UpdateWorldState(uint32 Field, uint32 Value);
        void UpdateWorldStateForPlayer(uint32 Field, uint32 Value, Player *Source);
        void EndBattleground(uint32 winner);
diff --git a/src/server/game/Entities/Player/Player.cpp b/src/server/game/Entities/Player/Player.cpp
index 2a664a2..725925c 100755
--- a/src/server/game/Entities/Player/Player.cpp
+++ b/src/server/game/Entities/Player/Player.cpp
@@ -6867,6 +6867,7 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, int32 honor, bool pvpt

    uint64 victim_guid = 0;
    uint32 victim_rank = 0;
+    uint32 rank_diff = 0;

    // need call before fields update to have chance move yesterday data to appropriate fields before today data change.
    UpdateHonorFields();
@@ -6905,22 +6906,52 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, int32 honor, bool pvpt
            //  [15..28] Horde honor titles and player name
            //  [29..38] Other title and player name
            //  [39+]    Nothing
-            uint32 victim_title = pVictim->GetUInt32Value(PLAYER_CHOSEN_TITLE);
-                                                        // Get Killer titles, CharTitlesEntry::bit_index
+    
+            // PLAYER__FIELD_KNOWN_TITLES describe which titles player can use,
+            // so we must find biggest pvp title , even for killer to find extra honor value
+            uint32 vtitle = pVictim->GetUInt32Value(PLAYER__FIELD_KNOWN_TITLES);
+            uint32 victim_title = 0;
+            uint32 ktitle = GetUInt32Value(PLAYER__FIELD_KNOWN_TITLES);
+            uint32 killer_title = 0;
+            if (PLAYER_TITLE_MASK_ALL_PVP & ktitle)
+            {
+                   for (int i = ((GetTeam() == ALLIANCE) ? 1:HKRANKMAX);i!=((GetTeam() == ALLIANCE) ? HKRANKMAX : (2*HKRANKMAX-1));i++)
+                {
+                       if (ktitle & (1<<i))
+                           killer_title = i;
+                }
+            }
+            if (PLAYER_TITLE_MASK_ALL_PVP & vtitle)
+            {
+                   for (int i = ((pVictim->GetTeam() == ALLIANCE) ? 1:HKRANKMAX);i!=((pVictim->GetTeam() == ALLIANCE) ? HKRANKMAX : (2*HKRANKMAX-1));i++)
+                {
+                       if (vtitle & (1<<i))
+                           victim_title = i;
+                }
+            }
            // Ranks:
            //  title[1..14]  -> rank[5..18]
            //  title[15..28] -> rank[5..18]
            //  title[other]  -> 0
            if (victim_title == 0)
                victim_guid = 0;                        // Don't show HK: <rank> message, only log.
-            else if (victim_title < 15)
+            else if (victim_title < HKRANKMAX)
                victim_rank = victim_title + 4;
-            else if (victim_title < 29)
-                victim_rank = victim_title - 14 + 4;
+            else if (victim_title < (2*HKRANKMAX-1))
+                victim_rank = victim_title - (HKRANKMAX-1) + 4;
            else
                victim_guid = 0;                        // Don't show HK: <rank> message, only log.

-            honor_f = ceil(Trinity::Honor::hk_honor_at_level_f(k_level) * (v_level - k_grey) / (k_level - k_grey));
+                       // now find rank difference
+            if (killer_title == 0 && victim_rank>4)
+                   rank_diff = victim_rank - 4;
+            else if (killer_title < HKRANKMAX)
+                   rank_diff = (victim_rank>(killer_title + 4))? (victim_rank - (killer_title + 4)) : 0;
+            else if (killer_title < (2*HKRANKMAX-1))
+                rank_diff = (victim_rank>(killer_title - (HKRANKMAX-1) +4))? (victim_rank - (killer_title - (HKRANKMAX-1) + 4)) : 0;
+
+                       honor_f = ceil(Trinity::Honor::hk_honor_at_level_f(k_level) * (v_level - k_grey) / (k_level - k_grey));
+                       honor_f *= 1 + sWorld->getRate(RATE_PVP_RANK_EXTRA_HONOR)*(((float)rank_diff) / 10.0f);

            // count the number of playerkills in one day
            ApplyModUInt32Value(PLAYER_FIELD_KILLS, 1, true);
@@ -6931,6 +6962,7 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, int32 honor, bool pvpt
            UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HK_RACE, pVictim->getRace());
            UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL_AT_AREA, GetAreaId());
            UpdateAchievementCriteria(ACHIEVEMENT_CRITERIA_TYPE_HONORABLE_KILL, 1, 0, pVictim);
+            UpdateKnownTitles();
        }
        else
        {
@@ -7004,6 +7036,30 @@ bool Player::RewardHonor(Unit *uVictim, uint32 groupsize, int32 honor, bool pvpt
    return true;
}

+void Player::UpdateKnownTitles()
+{
+    uint32 new_title = 0;
+    uint32 honor_kills = GetUInt32Value(PLAYER_FIELD_LIFETIME_HONORABLE_KILLS);
+    uint32 old_title = GetUInt32Value(PLAYER_CHOSEN_TITLE);
+    RemoveFlag64(PLAYER__FIELD_KNOWN_TITLES,PLAYER_TITLE_MASK_ALL_PVP);
+    if (honor_kills < 0)
+        return;
+    bool max_rank = ((honor_kills >= sWorld->pvp_ranks[HKRANKMAX-1]) ? true : false);
+    for (int i = HKRANK01; i != HKRANKMAX; ++i)
+    {
+        if (honor_kills < sWorld->pvp_ranks[i] || (max_rank))
+        {
+            new_title = ((max_rank) ? (HKRANKMAX-1) : (i-1));
+            if (new_title > 0)
+                new_title += ((GetTeam() == ALLIANCE) ? 0 : (HKRANKMAX-1));
+            break;
+        }
+    }
+    SetFlag64(PLAYER__FIELD_KNOWN_TITLES,uint64(1) << new_title);
+    if (old_title > 0 && old_title < (2*HKRANKMAX-1) && new_title > old_title)
+        SetUInt32Value(PLAYER_CHOSEN_TITLE,new_title);
+}
+
void Player::ModifyHonorPoints(int32 value)
{
    if (value < 0)
diff --git a/src/server/game/Entities/Player/Player.h b/src/server/game/Entities/Player/Player.h
index a4f5b42..9ffb0f7 100755
--- a/src/server/game/Entities/Player/Player.h
+++ b/src/server/game/Entities/Player/Player.h
@@ -386,6 +386,27 @@ enum PlayerFlags
    PLAYER_FLAGS_NO_XP_GAIN     = 0x02000000
};

+#define PLAYER_TITLE_MASK_ALLIANCE_PVP             \
+    (PLAYER_TITLE_PRIVATE | PLAYER_TITLE_CORPORAL |  \
+      PLAYER_TITLE_SERGEANT_A | PLAYER_TITLE_MASTER_SERGEANT | \
+      PLAYER_TITLE_SERGEANT_MAJOR | PLAYER_TITLE_KNIGHT | \
+      PLAYER_TITLE_KNIGHT_LIEUTENANT | PLAYER_TITLE_KNIGHT_CAPTAIN | \
+      PLAYER_TITLE_KNIGHT_CHAMPION | PLAYER_TITLE_LIEUTENANT_COMMANDER | \
+      PLAYER_TITLE_COMMANDER | PLAYER_TITLE_MARSHAL | \
+      PLAYER_TITLE_FIELD_MARSHAL | PLAYER_TITLE_GRAND_MARSHAL)
+
+#define PLAYER_TITLE_MASK_HORDE_PVP                           \
+    (PLAYER_TITLE_SCOUT | PLAYER_TITLE_GRUNT |  \
+      PLAYER_TITLE_SERGEANT_H | PLAYER_TITLE_SENIOR_SERGEANT | \
+      PLAYER_TITLE_FIRST_SERGEANT | PLAYER_TITLE_STONE_GUARD | \
+      PLAYER_TITLE_BLOOD_GUARD | PLAYER_TITLE_LEGIONNAIRE | \
+      PLAYER_TITLE_CENTURION | PLAYER_TITLE_CHAMPION | \
+      PLAYER_TITLE_LIEUTENANT_GENERAL | PLAYER_TITLE_GENERAL | \
+      PLAYER_TITLE_WARLORD | PLAYER_TITLE_HIGH_WARLORD)
+
+#define PLAYER_TITLE_MASK_ALL_PVP  \
+    (PLAYER_TITLE_MASK_ALLIANCE_PVP | PLAYER_TITLE_MASK_HORDE_PVP)
+
// used for PLAYER__FIELD_KNOWN_TITLES field (uint64), (1<<bit_index) without (-1)
// can't use enum for uint64 values
#define PLAYER_TITLE_DISABLED              UI64LIT(0x0000000000000000)
@@ -1961,6 +1984,7 @@ class Player : public Unit, public GridObject<Player>
        void ModifyHonorPoints(int32 value);
        void ModifyArenaPoints(int32 value);
        uint32 GetMaxPersonalArenaRatingRequirement(uint32 minarenaslot);
+        void UpdateKnownTitles();
        void SetHonorPoints(uint32 value)
        {
            SetUInt32Value(PLAYER_FIELD_HONOR_CURRENCY, value);
diff --git a/src/server/game/Scripting/ScriptLoader.cpp b/src/server/game/Scripting/ScriptLoader.cpp
index cb1b2c8..a3f1688 100755
--- a/src/server/game/Scripting/ScriptLoader.cpp
+++ b/src/server/game/Scripting/ScriptLoader.cpp
@@ -17,7 +17,6 @@

#include "ScriptLoader.h"

-
//examples
void AddSC_example_creature();
void AddSC_example_escort();
@@ -1203,6 +1202,9 @@ void AddBattlegroundScripts()

#ifdef SCRIPTS
/* This is where custom scripts' loading functions should be declared. */
+void AddSC_npc_at_beastmaster();
+void AddSC_custom_npc_doctor();

#endif

@@ -1210,6 +1212,8 @@ void AddCustomScripts()
{
#ifdef SCRIPTS
    /* This is where custom scripts should be added. */
-
+        AddSC_npc_at_beastmaster();
+        AddSC_custom_npc_doctor();
#endif
}
diff --git a/src/server/game/World/World.cpp b/src/server/game/World/World.cpp
index ab5071a..2724a7c 100755
--- a/src/server/game/World/World.cpp
+++ b/src/server/game/World/World.cpp
@@ -818,6 +818,19 @@ void World::LoadConfigSettings(bool reload)
        m_int_configs[CONFIG_START_ARENA_POINTS] = m_int_configs[CONFIG_MAX_ARENA_POINTS];
    }

+    rate_values[RATE_PVP_RANK_EXTRA_HONOR] = sConfig->GetFloatDefault("PvPRank.Rate.ExtraHonor", 1);
+    std::string s_pvp_ranks = sConfig->GetStringDefault("PvPRank.HKPerRank", "10,50,100,200,450,750,1300,2000,3500,6000,9500,15000,21000,30000");
+    char *c_pvp_ranks = const_cast<char*>(s_pvp_ranks.c_str());
+    for (int i = 0; i !=HKRANKMAX; i++)
+    {
+        if (i==0)
+            pvp_ranks[0] = 0;
+        else if (i==1)
+            pvp_ranks[1] = atoi(strtok (c_pvp_ranks, ","));
+        else
+            pvp_ranks[i] = atoi(strtok (NULL, ","));
+    }
+
    m_int_configs[CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL] = sConfig->GetIntDefault("RecruitAFriend.MaxLevel", 60);
    if (m_int_configs[CONFIG_MAX_RECRUIT_A_FRIEND_BONUS_PLAYER_LEVEL] > m_int_configs[CONFIG_MAX_PLAYER_LEVEL])
    {
diff --git a/src/server/game/World/World.h b/src/server/game/World/World.h
index 7e052ed..0a08c2c 100755
--- a/src/server/game/World/World.h
+++ b/src/server/game/World/World.h
@@ -378,10 +378,32 @@ enum Rates
    RATE_DURABILITY_LOSS_PARRY,
    RATE_DURABILITY_LOSS_ABSORB,
    RATE_DURABILITY_LOSS_BLOCK,
+    RATE_PVP_RANK_EXTRA_HONOR,
    RATE_MOVESPEED,
    MAX_RATES
};

+enum HonorKillPvPRank
+{
+    HKRANK00,
+    HKRANK01,
+    HKRANK02,
+    HKRANK03,
+    HKRANK04,
+    HKRANK05,
+    HKRANK06,
+    HKRANK07,
+    HKRANK08,
+    HKRANK09,
+    HKRANK10,
+    HKRANK11,
+    HKRANK12,
+    HKRANK13,
+    HKRANK14,
+    HKRANKMAX
+};
+
+
/// Can be used in SMSG_AUTH_RESPONSE packet
enum BillingPlanFlags
{
@@ -627,6 +649,8 @@ class World
        void SendZoneMessage(uint32 zone, WorldPacket *packet, WorldSession *self = 0, uint32 team = 0);
        void SendZoneText(uint32 zone, const char *text, WorldSession *self = 0, uint32 team = 0);
        void SendServerMessage(ServerMessageType type, const char *text = "", Player* player = NULL);
+        
+        uint32 pvp_ranks[HKRANKMAX];

        /// Are we in the middle of a shutdown?
        bool IsShutdowning() const { return m_ShutdownTimer > 0; }
diff --git a/src/server/scripts/Custom/CMakeLists.txt b/src/server/scripts/Custom/CMakeLists.txt
index 0dec843..3a7c5aa 100644
--- a/src/server/scripts/Custom/CMakeLists.txt
+++ b/src/server/scripts/Custom/CMakeLists.txt
@@ -1,5 +1,8 @@
set(scripts_STAT_SRCS
  ${scripts_STAT_SRCS}
+	Custom/beastmaster.cpp
+	Custom/doctor.cpp
)

message("  -> Prepared: Custom")
diff --git a/src/server/worldserver/worldserver.conf.dist b/src/server/worldserver/worldserver.conf.dist
index d0ccc61..4c15f75 100644
--- a/src/server/worldserver/worldserver.conf.dist
+++ b/src/server/worldserver/worldserver.conf.dist
@@ -2745,3 +2745,23 @@ LevelReq.Mail = 1

#
###################################################################################################
+###################################################################################################################
+# PVP RANK / TITLE SYSTEM
+#
+# PvPRank.Rate.ExtraHonor
+# Rate of honor bonus for killing higher pvp ranked players
+# Default: 1 - 10% more honor per rank difference
+# 2 - 20%
+# 0 - off
+#
+# PvPRank.HKPerRank
+# Honor Kills needed for each rank, use "," between values.
+# Whole string must be enclosed with " "
+# Always specify 14 values, for 14 ranks
+# Default: "10,50,100,200,450,750,1300,2000,3500,6000,9500,15000,21000,30000"
+#
+##################################################################################################################
+ 
+PvPRank.Rate.ExtraHonor = 2
+PvPRank.HKPerRank = "10,50,100,200,450,750,1300,2000,3500,6000,9500,15000,21000,30000"
+

 

 

odkazuji se na skripty od Hkarty: http://www.wowresource.eu/index.php?showtopic=18039 a Cäshe http://www.wowresource.eu/index.php?showtopic=18355

z tech staci jen doplnit soubory:

Custom/beastmaster.cpp
Custom/doctor.cpp

zbytek uz je v diffu...

 

jmeno skriptu u doctora nutno zmenit na npc_doctore

 

Par lidi to po me chtelo, treba to nekomu pomuze ;)

 

Pro plnou funcknost je treba pomerne dost poeditovat config, ale to necham jako domaci cviceni :P

 

Aribeth

Edited by ariczek
  • Upvote 1

Share this post


Link to post
Share on other sites

Ano spolupracoval, nejdrive jsme hejskovi poskytli utociste, pak jsme spojili loginy, pak rekneme po vymene nazoru jsme nenasli spolecnou cestu, takze Hejsek s onyxiusem zase odesel... a ten zaklad funu co zde postuji je tak, jak jsme ho udelali my, nikoli hejskova verze.

Share this post


Link to post
Share on other sites

Tak přidám asi poslední skript do sbírky, spíš pro lidi zběhlejší v C++ ... když budete prosit hodně, třeba to Wolf přepíše, nebo něko podobnej

(mě to wolf slibuje od 1.5.2011 :innocent: )

 

Wintergrasp: opět testováno a "funkční v rámci možností" na TC2 revizi 10034 - prehistorická :blink:

 

http://pastebin.com/weB0isvZ

 

Dávám na pastebin, tady mi to hlásí že příspěvek moc dlouhej :o !

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this  

×