Jump to content
Maintenance ×
×
×
  • Create New...

Easy ThreeWay War System


Recommended Posts

  • Bot

threeway_war.cpp

#include "stdafx.h"
#include "threeway_war.h"
#include "../../common/length.h"
#include "../../common/tables.h"
#include "p2p.h"
#include "locale_service.h"
#include "packet.h"
#include "char.h"
#include "questmanager.h"
#include "questlua.h"
#include "start_position.h"
#include "char_manager.h"
#include "sectree_manager.h"
#include "regen.h"
#include "log.h"

extern int test_server;
extern int passes_per_sec;

CThreeWayWar::CThreeWayWar()
{
	Initialize();
}

CThreeWayWar::~CThreeWayWar()
{
	RegisterUserMap_.clear();
	ReviveTokenMap_.clear();
}

void CThreeWayWar::Initialize()
{
	RegenFlag_ = 0;
	memset( KillScore_, 0, sizeof(KillScore_) );
	RegisterUserMap_.clear();
	ReviveTokenMap_.clear();
}

int CThreeWayWar::GetKillScore( BYTE empire ) const
{
	if( empire <= 0 || empire >= EMPIRE_MAX_NUM )
	{
		sys_err("ThreeWayWar::GetKillScore Wrong Empire variable");
		return 0;
	}

	return KillScore_[empire-1];
}

void CThreeWayWar::SetKillScore( BYTE empire, int count )
{
	if( empire <= 0 || empire >= EMPIRE_MAX_NUM )
	{
		sys_err("ThreeWayWar::SetKillScore Wrong Empire variable");
		return;
	}

	KillScore_[empire-1] = count;
}

void CThreeWayWar::SetReviveTokenForPlayer(DWORD PlayerID, int count)
{
	if (0 == PlayerID)
		return;

	ReviveTokenMap_[PlayerID] = count;
}

int CThreeWayWar::GetReviveTokenForPlayer(DWORD PlayerID)
{
	if (0 == PlayerID)
		return 0;

	return ReviveTokenMap_[PlayerID];
}

void CThreeWayWar::DecreaseReviveTokenForPlayer(DWORD PlayerID)
{
	if (0 == PlayerID)
		return;

	ReviveTokenMap_[PlayerID] = ReviveTokenMap_[PlayerID] - 1;
}

bool CThreeWayWar::LoadSetting(const char* szFileName)
{
	char szPath[1024];
	snprintf( szPath, sizeof(szPath), "%s/%s", LocaleService_GetBasePath().c_str(), szFileName);

	FILE* pf = fopen( szPath, "r" );

	if (NULL == pf)
	{
		sys_err("[ThreeWayWar] Cannot open file: <%s>", szPath );
		return false;
	}

	char szLine[256];
	char szSungziName[128];
	char szPassName[3][128];

	while( NULL != fgets(szLine, 256, pf) )
	{
		if (0 == strncmp(szLine, "sungzi:", 7))
		{
			struct ForkedSungziMapInfo sungziinfo;

			sscanf( szLine+7, "%d %d %d %d %d %d %d %s",
					&sungziinfo.m_iForkedSung,
					&sungziinfo.m_iForkedSungziStartPosition[0][0], &sungziinfo.m_iForkedSungziStartPosition[0][1],
					&sungziinfo.m_iForkedSungziStartPosition[1][0], &sungziinfo.m_iForkedSungziStartPosition[1][1],
					&sungziinfo.m_iForkedSungziStartPosition[2][0], &sungziinfo.m_iForkedSungziStartPosition[2][1],
					szSungziName);

			sungziinfo.m_stMapName = static_cast<std::string>(szSungziName);

			SungZiInfoMap_.push_back( sungziinfo );

			MapIndexSet_.insert( sungziinfo.m_iForkedSung );
		}
		else if (0 == strncmp(szLine, "pass:", 5))
		{
			struct ForkedPassMapInfo passinfo;

			sscanf( szLine+5, "%d %d %d %s %d %d %d %s %d %d %d %s",
					&passinfo.m_iForkedPass[0],
					&passinfo.m_iForkedPassStartPosition[0][0], &passinfo.m_iForkedPassStartPosition[0][1], szPassName[0],
					&passinfo.m_iForkedPass[1],
					&passinfo.m_iForkedPassStartPosition[1][0], &passinfo.m_iForkedPassStartPosition[1][1], szPassName[1],
					&passinfo.m_iForkedPass[2],
					&passinfo.m_iForkedPassStartPosition[2][0], &passinfo.m_iForkedPassStartPosition[2][1], szPassName[2] );

			passinfo.m_stMapName[0] = static_cast<std::string>(szPassName[0]);
			passinfo.m_stMapName[1] = static_cast<std::string>(szPassName[1]);
			passinfo.m_stMapName[2] = static_cast<std::string>(szPassName[2]);

			PassInfoMap_.push_back( passinfo );

			MapIndexSet_.insert( passinfo.m_iForkedPass[0] );
			MapIndexSet_.insert( passinfo.m_iForkedPass[1] );
			MapIndexSet_.insert( passinfo.m_iForkedPass[2] );
		}
	}

	fclose(pf);

	return true;
}

const ForkedPassMapInfo& CThreeWayWar::GetEventPassMapInfo() const
{
	const size_t idx = quest::CQuestManager::instance().GetEventFlag( "threeway_war_pass_idx" );

	return PassInfoMap_[idx];
}

const ForkedSungziMapInfo& CThreeWayWar::GetEventSungZiMapInfo() const
{
	const size_t idx = quest::CQuestManager::instance().GetEventFlag( "threeway_war_sungzi_idx" );

	return SungZiInfoMap_[idx];
}

bool CThreeWayWar::IsThreeWayWarMapIndex(int iMapIndex) const
{
	return MapIndexSet_.find(iMapIndex) != MapIndexSet_.end();
}

bool CThreeWayWar::IsSungZiMapIndex(int iMapIndex) const
{
	std::vector<ForkedSungziMapInfo>::const_iterator it = SungZiInfoMap_.begin();

	for( ; it != SungZiInfoMap_.end() ; ++it )
	{
		if (iMapIndex == it->m_iForkedSung)
		{
			return true;
		}
	}

	return false;
}

void CThreeWayWar::RandomEventMapSet()
{
	const size_t pass_idx = number( 0, PassInfoMap_.size()-1 );
	const size_t sung_idx = number( 0, SungZiInfoMap_.size()-1 );

	quest::CQuestManager::instance().RequestSetEventFlag( "threeway_war_sungzi_idx", sung_idx );
	quest::CQuestManager::instance().RequestSetEventFlag( "threeway_war_pass_idx", pass_idx );
}

bool CThreeWayWar::IsRegisteredUser(DWORD PlayerID) const
{
	boost::unordered_map<DWORD, DWORD>::const_iterator iter = RegisterUserMap_.find(PlayerID);

	if (iter == RegisterUserMap_.end())
	{
		return false;
	}

	return true;
}

void CThreeWayWar::RegisterUser(DWORD PlayerID)
{
	if (0 == PlayerID)
		return;

	RegisterUserMap_.insert( std::make_pair(PlayerID, PlayerID) );
}

void CThreeWayWar::onDead(LPCHARACTER pChar, LPCHARACTER pkKiller)
{
	if (!pChar->IsPC())
		return;
	if (GetRegenFlag() == -1)
		return;
	DecreaseReviveTokenForPlayer( pChar->GetPlayerID() );
	if (!IsSungZiMapIndex(pChar->GetMapIndex()))
		return;
	if (NULL == pkKiller || !pkKiller->IsPC())
		return;
	if (pChar->GetEmpire() == pkKiller->GetEmpire())
		return;
	int nKillScore = GetKillScore(pkKiller->GetEmpire());
	if (nKillScore >= 0)
	{
		nKillScore += 1;
		SetKillScore(pkKiller->GetEmpire(), nKillScore);
	}
	const int nVictoryScore = quest::CQuestManager::instance().GetEventFlag("threeway_war_kill_count");
	if (GetRegenFlag() == 0)
	{
		if (nKillScore != 0 && (nKillScore % 5) == 0)
		{
			char szBuf[80 + 1];
			snprintf(szBuf, sizeof(szBuf), "Shinsoo: [%d/%d]  -  Chunjo: [%d/%d]  -  Jinno: [%d/%d]", 
			GetKillScore(1), nVictoryScore, GetKillScore(2), nVictoryScore, GetKillScore(3), nVictoryScore);
			SendNoticeMap(szBuf, GetSungziMapIndex(), false);
		}
		int nEliminatedEmpireCount = 0;
		BYTE bLoseEmpire = 0;
		for (int n = 1; n < 4; ++n)
		{
			if (GetKillScore(n) < nVictoryScore)
			{
				++nEliminatedEmpireCount;
				bLoseEmpire = n;
			}
		}
		if (nEliminatedEmpireCount == 1) {
			SetKillScore(1, 0);
			SetKillScore(2, 0);
			SetKillScore(3, 0);
			SetKillScore(bLoseEmpire, -1);
			quest::warp_all_to_map_my_empire_event_info *info;
			info = AllocEventInfo<quest::warp_all_to_map_my_empire_event_info>();
			info->m_lMapIndexFrom	= GetSungziMapIndex();
			info->m_lMapIndexTo		= EMPIRE_START_MAP(bLoseEmpire);
			info->m_x				= EMPIRE_START_X(bLoseEmpire);
			info->m_y				= EMPIRE_START_Y(bLoseEmpire);
			info->m_bEmpire			= bLoseEmpire;
			event_create(quest::warp_all_to_map_my_empire_event, info, PASSES_PER_SEC(5));
			const std::string Nation(EMPIRE_NAME(bLoseEmpire));
			char szNotice[512+1];
			snprintf(szNotice, sizeof(szNotice), "<EmpireWar> The empire %s has lost the war.", Nation.c_str());
			BroadcastNotice(szNotice);
			char szBuf[80 + 1];
			snprintf(szBuf, sizeof(szBuf), "[%s] You'll be teleported to your own village...", Nation.c_str());
			SendNoticeMap(szBuf, GetSungziMapIndex(), false);
			SetRegenFlag(1);
		}
	}
	else if (GetRegenFlag() == 1)
	{
		if (nKillScore != 0 && (nKillScore % 2) == 0)
		{
			char szBuf[80 + 1];
			if (GetKillScore(1) != -1 && GetKillScore(2) != -1 && GetKillScore(3) == -1) {
				snprintf(szBuf, sizeof(szBuf), "Shinsoo: [%d/%d]  -  Chunjo: [%d/%d]", 
				GetKillScore(1), nVictoryScore, GetKillScore(2), nVictoryScore);
			}else if (GetKillScore(1) != -1 && GetKillScore(2) == -1 && GetKillScore(3) != -1) {
				snprintf(szBuf, sizeof(szBuf), "Shinsoo: [%d/%d]  -  Jinno: [%d/%d]", 
				GetKillScore(1), nVictoryScore, GetKillScore(3), nVictoryScore);
			}else if (GetKillScore(1) == -1 && GetKillScore(2) != -1 && GetKillScore(3) != -1) {
				snprintf(szBuf, sizeof(szBuf), "Chunjo: [%d/%d]  -  Jinno: [%d/%d]", 
				GetKillScore(2), nVictoryScore, GetKillScore(3), nVictoryScore);
			}
			SendNoticeMap(szBuf, GetSungziMapIndex(), false);
		}
		int nVictoryEmpireIndex = 0;
		for (int n = 1; n < 4; ++n)
		{
			nKillScore = GetKillScore(n);
			if (nKillScore == -1)
				continue;
			if (nKillScore >= nVictoryScore)
			{
				nVictoryEmpireIndex = n;
				break;
			}
		}
		if (nVictoryEmpireIndex == 0)
			return;
		for (int n = 1; n < 4; ++n)
		{
			if (n != nVictoryEmpireIndex && GetKillScore(n) != -1)
			{
				BYTE bLoseEmpire = n;
				quest::warp_all_to_map_my_empire_event_info * info;
				info = AllocEventInfo<quest::warp_all_to_map_my_empire_event_info>();
				info->m_lMapIndexFrom	= GetSungziMapIndex();
				info->m_lMapIndexTo		= EMPIRE_START_MAP(bLoseEmpire);
				info->m_x				= EMPIRE_START_X(bLoseEmpire);
				info->m_y				= EMPIRE_START_Y(bLoseEmpire);
				info->m_bEmpire			= bLoseEmpire;
				event_create(quest::warp_all_to_map_my_empire_event, info, PASSES_PER_SEC(5));
				const std::string LoseNation(EMPIRE_NAME(bLoseEmpire));
				char szBuf[80 + 1];
				snprintf(szBuf, sizeof(szBuf), "[%s] You'll be teleported to your own village...", LoseNation.c_str());
				SendNoticeMap(szBuf, GetSungziMapIndex(), false);
			}
		}
		const std::string EmpireName(EMPIRE_NAME(nVictoryEmpireIndex));
		char szNotice3[512+1];
		snprintf(szNotice3, sizeof(szNotice3), "<EmpireWar> The war was won by %s!", EmpireName.c_str());
		BroadcastNotice(szNotice3);
		char szBuf[160 + 1];
		snprintf(szBuf, sizeof(szBuf), "[%s] Congrats guys, you win the war. You'll be teleported to your own village!", EmpireName.c_str());
		SendNoticeMap(szBuf, GetSungziMapIndex(), false);
		SetRegenFlag(-1);
		quest::CQuestManager::instance().EraseEventFlag("threeway_war");
		quest::CQuestManager::instance().EraseEventFlag("threeway_war_dead_count");
		quest::CQuestManager::instance().EraseEventFlag("threeway_war_kill_count");
		quest::CQuestManager::instance().EraseEventFlag("threeway_war_open_gate1");
		quest::CQuestManager::instance().EraseEventFlag("threeway_war_open_gate2");
		quest::CQuestManager::instance().EraseEventFlag("threeway_war_open_gate3");
		quest::CQuestManager::instance().EraseEventFlag("threeway_war_pass_idx");
		quest::CQuestManager::instance().EraseEventFlag("threeway_war_sungzi_idx");
		quest::warp_all_to_map_my_empire_event_info * info;
		info = AllocEventInfo<quest::warp_all_to_map_my_empire_event_info>();
		info->m_lMapIndexFrom	= GetSungziMapIndex();
		info->m_lMapIndexTo		= EMPIRE_START_MAP(nVictoryEmpireIndex);
		info->m_x				= EMPIRE_START_X(nVictoryEmpireIndex);
		info->m_y				= EMPIRE_START_Y(nVictoryEmpireIndex);
		info->m_bEmpire			= nVictoryEmpireIndex;
		event_create(quest::warp_all_to_map_my_empire_event, info, PASSES_PER_SEC(30));
	}
}

struct FDestroyAllEntity
{
	void operator() (LPENTITY ent)
	{
		if (true == ent->IsType(ENTITY_CHARACTER))
		{
			LPCHARACTER ch = static_cast<LPCHARACTER>(ent);

			if (false == ch->IsPC())
			{
				ch->Dead();
			}
		}
	}
};

void CThreeWayWar::RemoveAllMonstersInThreeWay() const
{
	std::set<int>::const_iterator iter = MapIndexSet_.begin();

	while( iter != MapIndexSet_.end() )
	{
		LPSECTREE_MAP pSecMap = SECTREE_MANAGER::instance().GetMap( *iter );

		if (NULL != pSecMap)
		{
			FDestroyAllEntity f;

			pSecMap->for_each( f );
		}

		++iter;
	}
}

const char* GetSungziMapPath()
{
	static char s_szMapPath[128];

	snprintf(s_szMapPath, sizeof(s_szMapPath), "%s/map/%s/",
		   	LocaleService_GetBasePath().c_str(),
		   	CThreeWayWar::instance().GetEventSungZiMapInfo().m_stMapName.c_str());

	return s_szMapPath;
}

const char* GetPassMapPath( BYTE bEmpire )
{
	if (bEmpire > 0 && bEmpire < EMPIRE_MAX_NUM)
	{
		static char s_szMapPath[128];

		snprintf(s_szMapPath, sizeof(s_szMapPath), "%s/map/%s/",
				LocaleService_GetBasePath().c_str(),
				CThreeWayWar::instance().GetEventPassMapInfo().m_stMapName[bEmpire-1].c_str());

		return s_szMapPath;
	}

	return NULL;
}

int GetPassMapIndex( BYTE bEmpire )
{
	if (bEmpire > 0 && bEmpire < EMPIRE_MAX_NUM)
	{
		return CThreeWayWar::instance().GetEventPassMapInfo().m_iForkedPass[bEmpire-1];
	}

	return 0;
}

int GetPassStartX( BYTE bEmpire )
{
	if (bEmpire > 0 && bEmpire < EMPIRE_MAX_NUM)
	{
		return CThreeWayWar::instance().GetEventPassMapInfo().m_iForkedPassStartPosition[bEmpire-1][0];
	}

	return 0;
}

int GetPassStartY( BYTE bEmpire ) 
{
	if (bEmpire > 0 && bEmpire < EMPIRE_MAX_NUM)
	{
		return CThreeWayWar::instance().GetEventPassMapInfo().m_iForkedPassStartPosition[bEmpire-1][1];
	}

	return 0;
}

int GetSungziMapIndex()
{
	return CThreeWayWar::instance().GetEventSungZiMapInfo().m_iForkedSung;
}

int GetSungziStartX( BYTE bEmpire )
{
	if (bEmpire > 0 && bEmpire < EMPIRE_MAX_NUM)
	{
		return CThreeWayWar::instance().GetEventSungZiMapInfo().m_iForkedSungziStartPosition[bEmpire-1][0];
	}

	return 0;
}

int GetSungziStartY( BYTE bEmpire )
{
	if (bEmpire > 0 && bEmpire < EMPIRE_MAX_NUM)
	{
		return CThreeWayWar::instance().GetEventSungZiMapInfo().m_iForkedSungziStartPosition[bEmpire-1][1];
	}

	return 0;
}

threeway_war.h

#ifndef THREE_WAY_WAR_EVENT_
#define THREE_WAY_WAR_EVENT_

#include <boost/unordered_map.hpp>

#include "../../common/stl.h"

struct ForkedSungziMapInfo
{
	int m_iForkedSung;
	int m_iForkedSungziStartPosition[3][2];
	std::string m_stMapName;
};

struct ForkedPassMapInfo
{
	int m_iForkedPass[3];
	int m_iForkedPassStartPosition[3][2];
	std::string m_stMapName[3];
};

class CThreeWayWar : public singleton<CThreeWayWar>
{
	public:
		CThreeWayWar ();
		virtual ~CThreeWayWar ();

		void Initialize ();
		bool LoadSetting (const char* szFileName);

		int GetKillScore (BYTE empire) const;
		void SetKillScore (BYTE empire, int count);

		void SetReviveTokenForPlayer (DWORD PlayerID, int count);
		int GetReviveTokenForPlayer (DWORD PlayerID);
		void DecreaseReviveTokenForPlayer (DWORD PlayerID);

		const ForkedPassMapInfo& GetEventPassMapInfo () const;
		const ForkedSungziMapInfo& GetEventSungZiMapInfo () const;

		bool IsThreeWayWarMapIndex (int iMapIndex) const;
		bool IsSungZiMapIndex (int iMapIndex) const;

		void RandomEventMapSet ();

		void RegisterUser (DWORD PlayerID);
		bool IsRegisteredUser (DWORD PlayerID) const;

		void onDead (LPCHARACTER pChar, LPCHARACTER pKiller);

		void SetRegenFlag (int flag) { RegenFlag_ = flag; }
		int GetRegenFlag () const { return RegenFlag_; }

		void RemoveAllMonstersInThreeWay () const;

	private:
		int KillScore_[3];
		int RegenFlag_;

		std::set<int>	MapIndexSet_;
		std::vector<ForkedPassMapInfo>	PassInfoMap_;
		std::vector<ForkedSungziMapInfo>	SungZiInfoMap_;

		boost::unordered_map<DWORD, DWORD>	RegisterUserMap_;
		boost::unordered_map<DWORD, int>	ReviveTokenMap_;
};

const char* GetSungziMapPath();
const char* GetPassMapPath( BYTE bEmpire );
int GetPassMapIndex( BYTE bEmpire );
int GetSungziMapIndex();

int GetSungziStartX( BYTE bEmpire );
int GetSungziStartY( BYTE bEmpire );
int GetPassStartX( BYTE bEmpire );
int GetPassStartY( BYTE bEmpire );

#endif /* THREE_WAY_WAR_EVENT_ */

Implement the ERASEEVENTFLAG FUNCTION!

FORKEDMAPINDEX.txt

#sungzi: mapindex startposX startposY startposX startposY startposX startposY
#pass: mapindex1 startposX startposY mapindex2 startposX startposY mapindex3 startposX startposY
sungzi: 114 948100 36500 937100 22000 953200 18500 metin2_map_sungzi
pass: 118 1150400 182400 metin2_map_sungzi_flame_hill_01 119 1150400 284800 metin2_map_sungzi_flame_hill_02 120 1150400 387200 metin2_map_sungzi_flame_hill_03

TO LET THE SYSTEM WORKING WITHOUT PROBLEM, YOUR NPC THAT START THE WAR MUST BE IN CH99!

  • Love 1

english_banner.gif

Link to comment
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
  • Recently Browsing   0 members

    • No registered users viewing this page.


  • Activity

    1. 1

      Metin2 TitleBar Move Frezze

    2. 1

      Metin2 TitleBar Move Frezze

    3. 0

      Navicat "Trial" Reset

    4. 13

      Item ToolTip Width Fix

    5. 0

      Guild icon wrong position

    6. 3

      Monster health

    7. 4

      Luffy Pet

    8. 38

      Core X → Top Metin2 & Metin2 Download → Changelogs

Important Information

Terms of Use / Privacy Policy / Guidelines / We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.