Jump to content

Arena manager from target


caanmasu

Recommended Posts

Hi

 

This feature allows you to make an arena with a player from the target, not just from the NPC.
The position of where they start the battle is also saved so that they return to the same place and not always next to Yu-Hwan.

The code communicates quest/lua with client (python), and server (C++) with quest.

 

GIF:

https://metin2.download/video/XKptZ6CY5jnSnp6v1F5yr04Dq6XxHWnw/.mp4

 

Feature created by Camilo (caanmasu)

https://i.gyazo.com/d0859862714c81271a8cfeca3071d5d1.mp4

This feature allows you to make an arena with a player from the target, not just from the NPC.
The position of where they start the battle is also saved so that they return to the same place and not always next to Yu-Hwan.

The code communicates quest/lua with Python, and server (C++) with quest.


Clientside

root:

constinfo.py

ENABLE_ARENA_MANAGER_TARGET = True
if ENABLE_ARENA_MANAGER_TARGET:
	QUEST_arena_manager_INDEX = 0
	QUEST_arena_manager_TARGET = 0

game.py

1:
Above:

		self.serverCommander=stringCommander.Analyzer()
		
Add:

		if constInfo.ENABLE_ARENA_MANAGER_TARGET:
			serverCommandList.update({"StartArenaManager" : self.QUEST_arena_manager})
			serverCommandList.update({"GetTargetArenaManager" : self.QUEST_get_target_arena_manager})
			
2:
Add this functions:

	if constInfo.ENABLE_ARENA_MANAGER_TARGET:
		def QUEST_arena_manager(self, quest_index):
			constInfo.QUEST_arena_manager_INDEX = quest_index

		def QUEST_get_target_arena_manager(self):
			net.SendQuestInputStringPacket(str(constInfo.QUEST_arena_manager_TARGET))

uitarget.py

1:

import event

2:

Above:

GRADE_NAME =	{

Add:

	if constInfo.ENABLE_ARENA_MANAGER_TARGET:
		BUTTON_NAME_LIST.append(localeInfo.TARGET_BUTTON_ARENA_MANAGER)
		
3:

Above:

		self.buttonDict["VOTE_BLOCK_CHAT"].SetEvent(ui.__mem_func__(self.__OnVoteBlockChat))

Add:

		if constInfo.ENABLE_ARENA_MANAGER_TARGET:
			self.buttonDict[localeInfo.TARGET_BUTTON_ARENA_MANAGER].SAFE_SetEvent(self.__OnArena)
			
4:

Above:

		if player.IsPartyMember(self.vid):
		
Add:

		if constInfo.ENABLE_ARENA_MANAGER_TARGET:
			if player.GetStatus(player.LEVEL) >= constInfo.PVPMODE_PROTECTED_LEVEL:
				self.__ShowButton(localeInfo.TARGET_BUTTON_ARENA_MANAGER)

5:

Add this function:

	if constInfo.ENABLE_ARENA_MANAGER_TARGET:
		def __OnArena(self):
			constInfo.QUEST_arena_manager_TARGET = chr.GetNameByVID(self.vid)
			event.QuestButtonClick(int(constInfo.QUEST_arena_manager_INDEX))


locale_game.txt

TARGET_BUTTON_ARENA_MANAGER	Arena


If you do not have input ignore, then do it:


constinfo.py

Add anywhere:

INPUT_IGNORE = 0

game.py

1:

Find this function:

	def OpenQuestWindow(self, skin, idx):
		self.interface.OpenQuestWindow(skin, idx)

Replace for:

	def OpenQuestWindow(self, skin, idx):
		if constInfo.INPUT_IGNORE == 1:
			return
		else:
			self.interface.OpenQuestWindow(skin, idx)
			
2:

Below of:

			# PRIVATE_SHOP_PRICE_LIST
			"MyShopPriceList"		: self.__PrivateShop_PriceList,
			# END_OF_PRIVATE_SHOP_PRICE_LIST
			
Add:

			"quest_input_ignore"		: self.questInputIgnore,
			
Add this function:

	def questInputIgnore(self, var):
		constInfo.INPUT_IGNORE = int(var)
		
interfacemondule.py

Find:

	def OpenQuestWindow(self, skin, idx):
		wnds = ()
		
Replace for:

	def OpenQuestWindow(self, skin, idx):
		if constInfo.INPUT_IGNORE == 1:
			return
		else:
			wnds = ()
			

Quest:

arena_manager.cpp

1:
Add those when:

		when login begin
			cmdchat(string.format("StartArenaManager %s", q.currentquestindex()))
		end
		
		when logout begin --
			if pc.get_map_index() == 112 then
				pc.delqf("saved_x")
				pc.delqf("saved_y")
			end
		end
		
		when button begin
		
			--clientside related
			cmdchat("quest_input_ignore 1") --Note: If you set my input_ignore then this is correct. If you already had your own input_ignore, put the correct command.
			local victim_name = input(cmdchat("GetTargetArenaManager"))
			cmdchat("quest_input_ignore 0")
			--
			
			if game.get_event_flag("arena_close") > 0 then
				say(gameforge.arena_manager._30_say) --token 42
				return
			end
			
			local useMinLevel = game.get_event_flag("arena_use_min_level")

			if useMinLevel == 0 then
				useMinLevel = 25 ;
			end

			if pc.get_level() < useMinLevel then
				say(string.format(gameforge.arena_manager._50_say, useMinLevel)) --token 44
				return
			else
				local sname = victim_name
				local opp_vid = find_pc_by_name(sname)
				local old = pc.select(opp_vid , opp_vid)
				local opp_level = pc.level
				-- Save the position (opponent) from where the arena was started
				pc.setf("arena_manager", "saved_x", pc.x) --BUG FIXED: si no se especifica el nombre de la quest, se tomará la quest del id anterior (la quest que se compiló antes de ésta en el quest_list)
				pc.setf("arena_manager", "saved_y", pc.y) --
				pc.select(old, old)
				if opp_level < useMinLevel then
					say(string.format(gameforge.arena_manager._110_say, useMinLevel)) --token 28
					return
				end

				local a = arena.is_in_arena(opp_vid)
				if a == 0 then
					say_reward(string.format(gameforge.arena_manager._130_say, sname)) --token 30
					return
				end
				chat(string.format(gameforge.arena_manager._85_say, pc.name, sname)) --token 48
				local agree = confirm(opp_vid, string.format(gameforge.arena_manager._87_say, sname, pc.name), 30) --token 49 (text very long)
				if agree!= CONFIRM_OK then
					say(string.format(gameforge.arena_manager._150_say, sname)) --token 32
					return
				end
				-- Save the position (current player) from where the arena was started
				pc.setqf("saved_x", pc.x) --
				pc.setqf("saved_y", pc.y) --
				local s = arena.start_duel(sname, 3)
				if s == 0 then
					say(gameforge.arena_manager._160_say) --token 33
				elseif s == 2 then
					say(gameforge.arena_manager._170_say) --token 34
				elseif s == 3 then
					say(gameforge.arena_manager._180_say) --token 35
				end
			end
		end
		
2:

Find:

				if table.getn(arena_observer) >= s then

Add:

				-- Save the position (observer player) from where the arena was started
					pc.setqf("saved_x", pc.x) --
					pc.setqf("saved_y", pc.y) --
					
					
Serverside

arena.cpp

1. 

Find:

	LPCHARACTER playerB = GetPlayerB();
	
Add:

	quest::PC* pPC_A = quest::CQuestManager::instance().GetPC(playerA->GetPlayerID());
	quest::PC* pPC_B = quest::CQuestManager::instance().GetPC(playerB->GetPlayerID());

	int saved_A_x = pPC_A->GetFlag("arena_manager.saved_x");
	int saved_A_y = pPC_A->GetFlag("arena_manager.saved_y");

	int saved_B_x = pPC_B->GetFlag("arena_manager.saved_x");
	int saved_B_y = pPC_B->GetFlag("arena_manager.saved_y");

2: 

Find:

		playerA->WarpSet(ARENA_RETURN_POINT_X(playerA->GetEmpire()), ARENA_RETURN_POINT_Y(playerA->GetEmpire()));

Replace for:

		if (saved_A_x != 0 && saved_A_y != 0)
			playerA->WarpSet(saved_A_x*100, saved_A_y*100);
		else
			playerA->WarpSet(ARENA_RETURN_POINT_X(playerA->GetEmpire()), ARENA_RETURN_POINT_Y(playerA->GetEmpire()));
			
3:

Find:

	playerB->WarpSet(ARENA_RETURN_POINT_X(playerB->GetEmpire()), ARENA_RETURN_POINT_Y(playerB->GetEmpire()));

Replace for:

		if (saved_B_x != 0 && saved_B_y != 0)
			playerB->WarpSet(saved_B_x*100, saved_B_y*100);
		else
			playerB->WarpSet(ARENA_RETURN_POINT_X(playerB->GetEmpire()), ARENA_RETURN_POINT_Y(playerB->GetEmpire()));
			
4:

Find:

		LPCHARACTER pChar = CHARACTER_MANAGER::instance().FindByPID(iter->first);
		if (pChar != NULL)
		{
			pChar->WarpSet(ARENA_RETURN_POINT_X(pChar->GetEmpire()), ARENA_RETURN_POINT_Y(pChar->GetEmpire()));
		}
		
Replace for:

		LPCHARACTER pChar = CHARACTER_MANAGER::instance().FindByPID(iter->first);
		if (pChar != NULL)
		{
			
			quest::PC* pPC = quest::CQuestManager::instance().GetPC(pChar->GetPlayerID());
			
			int saved_x = pPC->GetFlag("arena_manager.saved_x");
			int saved_y = pPC->GetFlag("arena_manager.saved_y");
			if (saved_x != 0 && saved_y != 0)
				pChar->WarpSet(saved_x*100, saved_y*100);
			else
				pChar->WarpSet(ARENA_RETURN_POINT_X(pChar->GetEmpire()), ARENA_RETURN_POINT_Y(pChar->GetEmpire()));
		}


 

Regards.

  • Metin2 Dev 2
  • Lmao 1
  • Good 1
Link to comment
Share on other sites

2 hours ago, Erexo said:

Is it possible to make command for gm? Like /create_arena name1 name2? And it will teleport players and gm to arena? 

 

I make this code (NO TESTED) as guide.

 

This may be the beginning of what you want to do. Does not include the observer mode part.

 

cmd_gm.cpp

ACMD(do_start_arena)
{
	char arg1[256], arg2[256];
	two_arguments(argument, arg1, sizeof(arg1), arg2, sizeof(arg2));

	if (!*arg1 && !*arg2)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, "Usage: start_arena <name1> <name2>");
		return;
	}

	LPCHARACTER ch1 = CHARACTER_MANAGER::instance().FindPC(arg1);
	LPCHARACTER ch2 = CHARACTER_MANAGER::instance().FindPC(arg2);
	if (!ch1 || !ch2)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, "At least one player is offline.");
		return;
	}
	
	if ( CArenaManager::instance().IsMember(ch1->GetMapIndex(), ch1->GetPlayerID()) != MEMBER_NO ||
			CArenaManager::instance().IsMember(ch2->GetMapIndex(), ch2->GetPlayerID()) != MEMBER_NO	)
	{
		ch->ChatPacket(CHAT_TYPE_INFO, "At least one player is on arena.");
		return;
	}
	
	if (!(ch1->GetArena()) || ch1->GetArenaObserverMode())
	{
		if (CArenaManager::instance().IsMember(ch1->GetMapIndex(), ch1->GetPlayerID()) == MEMBER_DUELIST)
		{
			ch->ChatPacket(CHAT_TYPE_INFO, "At least one player is on arena.");
			return;
		}
	}
	
	if (!(ch2->GetArena()) || ch2->GetArenaObserverMode())
	{
		if (CArenaManager::instance().IsMember(ch2->GetMapIndex(), ch2->GetPlayerID()) == MEMBER_DUELIST)
		{
			ch->ChatPacket(CHAT_TYPE_INFO, "At least one player is on arena.");
			return;
		}
	}
	
	if (ch1->IsHorseRiding())
	{
		ch1->StopRiding();
		ch1->HorseSummon(false);
	}

	if (ch2->IsHorseRiding())
	{
		ch2->StopRiding();
		ch2->HorseSummon(false);
	}
	
	if (!(CArenaManager::instance().StartDuel(ch1, ch2, 3)))
	{
		ch->ChatPacket(CHAT_TYPE_INFO, "An error has occurred");
		return;
	}
}

 

  • Love 1
Link to comment
Share on other sites

  • 5 months later...

Announcements



×
×
  • Create New...

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.