Jump to content

Syreldar

Premium
  • Posts

    1298
  • Joined

  • Last visited

  • Days Won

    38
  • Feedback

    100%

Posts posted by Syreldar

  1. 3 hours ago, Ropen said:

     

    if i used  mysql_direct_query like that

    local name = input();
    mysql_direct_query("UPDATE player.player SET block_map = '1' WHERE name = "..name..""); 

     

    could i use mysql_direct_query to get block_map value ? and relying on it block the player like that ?

    local myname = pc.get_name() ;
    local results, ret = mysql_direct_query(string.format("SELECT `block_map` FROM `player`.`player` WHERE `name` = '%s' LIMIT 1;", myname));
    			
    if (results > 0) then
    	say ("u can't enter")
    else
    	pc.warp( 947100 , 169800 )
    end -- if/else

    Is it an effective method ? or will there be problems ?

    Why? You check with the flag still no reason to use a query to check it.

  2. quest test begin
    	state start begin
    		when 10581.chat."Block Player" with pc.is_gm() begin
    			say_event_title(string.format("%s:[ENTER]", mob_name(10581)))
    			say("Type the name of the player whom you want to")
    			say("lock out of accessing this map.[ENTER]")
    			local player_name = input();
    			-- yield
    			say_event_title(string.format("%s:[ENTER]", mob_name(10581)))
    			local player_vid = find_pc_by_name(player_name);
    			if (player_vid == 0) then
      				return say_reward(string.format("The player `%s` is offline or in another core.", player_name));
      			end -- if
    
      			local old_vid = pc.select(player_vid, player_vid);
      			pc.setf("map_control", "cannot_enter", 1);
    			pc.select(old_vid, old_vid);
    			say("Operation complete.[ENTER]")
    		end -- when
    	end -- state
    end -- quest

     

    The quest is limited due to the fact that if the player is offline or in a separate core you won't be able to reach out to him to assign the flag.

    This can be solved via query, i'll give you a rough example of the code using @ martysama0134's mysql_direct_query function, you can find it here paired with other useful functions: https://www.elitepvpers.com/forum/metin2-pserver-guides-strategies/3327940-release-mysql_direct_query-get_table_postfix-mysql_escape_string-written-c-lua.html

    Keep in mind that this code works but you'll still have to properly escape the string on the input in order to avoid possible sqli.

    local results, ret = mysql_direct_query(string.format("SELECT `id` FROM `player`.`player` WHERE `name` = '%s' LIMIT 1;", player_name));
    if (results > 0) then
    	mysql_direct_query(string.format("INSERT INTO `player`.`quest`(`dwPID`, `szName`, `szState`, `lValue`) VALUES (%d, 'map_control', 'cannot_enter', 1) ON DUPLICATE KEY UPDATE `lValue` = 1;", ret[1].id))
    else
    	say_reward(string.format("The player `%s` was not found.[ENTER]", player_name))
    end -- if/else
  3. Quote

    They have also added a new group in the "dragon_soul_table.txt" parser file but for what I understood, it's just another probability table.
    I didn't find it necessary to follow their logic because the "ApplyNumSettings" group already has probabilities of 0 to 3 for adding additional bonuses.

     

    The mentioned table for reference:

    # ¿ëÈ¥¼® ¼Ó¼ºº¯°æ AddÈ®·ü Å×À̺í (¿¬°ü Å×À̺í : ApplyNumSettings)
    Group ChangeAttrStepTables
    {
    	Group GRADE_MYTH
    	{
    		#--#	STEP	0	1	2	3
    		STEP_LOWEST	500	400	8	1
    		STEP_LOW	500	400	16	5
    		STEP_MID	500	400	40	10
    		STEP_HIGH	500	400	100	30
    		STEP_HIGHEST	500	400	300	150
    	}
    }

    So the way it works is it renders that specific probability, x% more likely to happen.

    As Owsap mentioned, it is not supported by the system by default.

    • Good 2
  4. 9 hours ago, CaptainLucifer said:

    What do you think about it. 

    Trash that makes 0 sense. That's what I think about it.

    7 hours ago, VegaS™ said:
    • Srcs/game/src/pvp.cpp
    bool CPVPManager::CanAttack(LPCHARACTER pkChr, LPCHARACTER pkVictim)
    {
    	[...]
    	if (pkChr && pkVictim && (pkChr->GetMountVnum() && pkVictim->GetMountVnum()))
    		return false;
    	[...]
    }
    • Srcs/Client/InstanceBase.cpp
    bool CInstanceBase::IsAttackableInstance(CInstanceBase& rkInstVictim)
    {
    	[...]
    	if (IsMountingHorse() && rkInstVictim.IsMountingHorse())
    		return false;
    	[...]
    }

    I don't really understand why you want to do this, but this is what you asked for.
    You can ignore the client part if you just want a server-side solution to not do damage.

    They meant for when the player attacks other players while on a mount, so not if both the player and the victim are on a mount.

  5. ActorInstanceSync.cpp:

    Search for:

    if (IsResistFallen())
    	return;

    Move this check just above this line:

    if (!IsUsingSkill())

     

    ActorInstanceBattle.cpp: (Fix by @ martysama0134)

    Search for:

    		// VICTIM_COLLISION_TEST
    		const D3DXVECTOR3& kVictimPos = rVictim.GetPosition();
    		rVictim.m_PhysicsObject.IncreaseExternalForce(kVictimPos, c_rAttackData.fExternalForce); //*nForceRatio/100.0f);
    		// VICTIM_COLLISION_TEST_END

    Substitute with:

    		// VICTIM_COLLISION_TEST
    		const D3DXVECTOR3& kVictimPos = rVictim.GetPosition();
    		float fExternalForceRatio = 1.0f;
    		if (rVictim.IsResistFallen())
    			fExternalForceRatio *= 0.75f;
    		rVictim.m_PhysicsObject.IncreaseExternalForce(kVictimPos, c_rAttackData.fExternalForce * fExternalForceRatio); //*nForceRatio/100.0f);
    		// VICTIM_COLLISION_TEST_END

     

  6. 1. Open ActorInstanceSync.cpp:

    Search for:

    if (IsResistFallen())
    	return;

    Take that snippet and move it just above this check:

    if (!IsUsingSkill())

     

    2. Open ActorInstanceBattle.cpp: (Fix by @ martysama0134)

    Search for:

    rVictim.m_PhysicsObject.IncreaseExternalForce(kVictimPos, c_rAttackData.fExternalForce); //*nForceRatio/100.0f);

    Substitute it with:

    float fExternalForceRatio = 1.0f;
    if (rVictim.IsResistFallen())
    	fExternalForceRatio *= 0.75f;
    rVictim.m_PhysicsObject.IncreaseExternalForce(kVictimPos, c_rAttackData.fExternalForce * fExternalForceRatio); //*nForceRatio/100.0f);

     

    This allows the Push distance to still be reduced on Mental Warriors, while allowing the __Push function's SetBlendingPosition() to be executed, fixing this little desync issue.

  7. 20 minutes ago, CaptainLucifer said:

     

    But we have pc.is_pvp and pc.is_mount, pc.unmound quest functions?

    Okay? How do you plan on blocking the player from actually hitting another player with those?

    Even assuming you wanted to apply a solution as dirty as "If they hit a player while on mount, they dismount", no such trigger exists by default in Metin2's sources.

    If you had it, you could write:

    quest mount_dismount_pvp begin
    	state start begin
    		when damage with npc.is_pc() begin
    			if (pc.is_mount()) then
      				pc.unmount();
    			end -- if
    			
    			pc.setqf("last_pc_damage_time", get_time());
    		end -- when
    	end -- state
    end -- quest

    And then, in your mount quest:

    --
    	--
    		when MOUNTSEAL_VNUM.use begin
    				local last_pc_damage_time = pc.getf("mount_dismount_pvp", "last_pc_damage_time");
    				local cur_time, time_to_wait = get_time(), 3;
    				if (cur_time - last_pc_damage_time < time_to_wait) then
      					return syschat(string.format("You gotta wait %d more seconds to mount after damaging another character.", last_pc_damage_time + time_to_wait - cur_time));
      				end -- if
    
    				pc.mount(vnum, mount_duration);
    				pc.mount_bonus(apply_id, apply_vnum, apply_duration)
    		end -- when
    	--
    --

    But this solution is so bad I don't even want to look at it.. and I wrote it, lol.

    Also, this doesn't prevent damage at all, it just prevents players being on a mount while hitting other players after the first hit.

  8. Hello.

    Here's a list of useful globals you can use in your quests.

    You can add them to your questlib.lua or make a separate *.lua file and load it via dofile().

    This is the hidden content, please

     

    25/04/2023:

    1. Added SELECT_YES, SELECT_ENTER, SELECT_NO;
    2. Added EMPIRES;
    3. Added ARMED_HORSE_LEVEL, MILITARY_HORSE_LEVEL;
    4. Added STATUS_VIT, STATUS_INT, STATUS_STR, STATUS_DEX;
    5. Added ITEM_TYPES, ITEM_SUB_TYPES;
    6. Added AFFECT;
    7. Updated APPLY;
    8. Added JOB_TO_RACE, RACE_TO_JOB, RACE_TO_SEX;
    9. Changed RACE_NAME_LIST;
    10. Added PC_RACE_LIST, PC2_RACE_LIST, PC3_RACE_LIST;
    11. Added MALE_RACE_LIST, FEMALE_RACE_LIST;
    12. Added SEX_NAME_LIST
    13. Added STATUS_NAME_LIST;
    14. Added EMPIRE_NAME_LIST;

    11/05/2023:

    1. Improvements to the overall structure of the globals.
    2. Added POINTS

    31/08/2023:

    1. Structural update for ITEMS and DUNGEON_DATA.
    • Metin2 Dev 88
    • kekw 2
    • Good 17
    • Love 4
    • Love 29
    1. Select the run/walk animation of your mount.
    2. Open it in granny
    3. Click "view in detail"
    4. Profit.

    spacer.png

    spacer.png

    spacer.png

    granny_real32 Duration = MotionDuration

    granny_real32 LoopTranslation = Accumulation

    Update the relative .msa file if they don't match with the .gr2's data:

    MotionDuration           0.666667
    Accumulation             0.00	-300.00	0.00

    Make sure it's also correct in the share/data folder in your server.

    Make sure the value in the mob_proto column `folder` is also correct (or in the .txt if you're using .txt protos).

    • Metin2 Dev 2
    • Good 1
    • Love 1
    • Love 5
  9. 1 minute ago, WeedHex said:

    Ehhhm sorry I'm not LUA addict ahaha.

    I did with c++ an other way (based on what I need to check) because happened some guys exploit the begin_other_pc_block in some server. (With change channel and shits like that)

    Of course if is only for level you can check it again in the dungeon and kick him out, but better to be careful in big servers about these things.

     

    PS. WTF only I see my messages x2? 

    I can assure you that if they can bug it you made a mistake in the quest. There's no reason to use C++ whatsoever.

  10. local pc_data = {};
    for _, pid in ipairs({party.get_member_pids()}) do
    	q.begin_other_pc_block(pid);
    	--
    	table.insert(pc_data, {["name"] = pc.get_name(), ["level"] = pc.get_level()});
    	--
    	q.end_other_pc_block();
    end -- for
    
    for index, data in ipairs(pc_data) do
    	say(string.format("%d. %s's level is %d.", index, data["name"], data["level"]))
    end -- for

     

  11. Two things @ Owsap.

    1.  For sure an overlook, this should be self.newTooltip.AddItemData(itemIndex, metinSlot)
    RM99Zgg.png

     

    2. You forgot to tell them to add this line:
     

    self.newToolTip.SetPosition(15 + self.oldToolTip.GetWidth() + 45, 38)

    Before if localeInfo.IsARABIC():

    • Good 1
    • Love 1
  12. 2 hours ago, WeedHex said:

    Hmmm, it's not properly a bug. It's happening because you are not making any movement in the victim.

    Anyway thanks to this thread, after some check, I figured out that may be this the problem:

     

    File ActorInstanceSync.cpp:

    Replace the function

    void CActorInstance::__Push(int x, int y)
    {
    	const D3DXVECTOR3& c_rv3Src=GetPosition();
    	const D3DXVECTOR3 c_v3Dst=D3DXVECTOR3(x, -y, c_rv3Src.z);
    	const D3DXVECTOR3 c_v3Delta=c_v3Dst-c_rv3Src;
    
    	const auto LoopValue = 100;
    	const D3DXVECTOR3 inc = c_v3Delta / LoopValue;
    
    	D3DXVECTOR3 v3Movement(0.0f, 0.0f, 0.0f);
    
    	IPhysicsWorld* pWorld = IPhysicsWorld::GetPhysicsWorld();
    	if (!pWorld)
    		return;
    
    	for (int i = 0; i < LoopValue; ++i)
    	{
    		if (pWorld->isPhysicalCollision(c_rv3Src + v3Movement))
    		{
    			ResetBlendingPosition();
    			return;
    		}
    		v3Movement += inc;
    	}
    
    	SetBlendingPosition(c_v3Dst);
    
    	if (IsResistFallen())
    		return;
    
    	if (!IsUsingSkill())
    	{
    		const int len = sqrt(c_v3Delta.x*c_v3Delta.x+c_v3Delta.y*c_v3Delta.y);
    		if (len > 150.0f)
    		{
    			InterceptOnceMotion(CRaceMotionData::NAME_DAMAGE_FLYING);
    			PushOnceMotion(CRaceMotionData::NAME_STAND_UP);
    		}
    	}
    }

     

    Yep, as you can see I just moved the order of execution of a statement. I leave the theory to you.

    That'll also fix the issue. But based on what I see here, it means the target will also be pushed way farther than intended while usually targets with Immunity to Fall (mental warriors) get pushed way less.

  13. 4 minutes ago, CaptainLucifer said:

    This is not a solution. 😞

    Even when the mental warrior is standing still, his coordinate must be transmitted to the opposite side when he is pushed.

     

    We really need help on this issue.

    Is there really no one on this forum who knows how to fix it?

    This solution fixes the issue that you presented. So it's the appropriate solution. 

    If it generates another bug, post it and we'll try to fix it, else, don't look for something that doesn't exist.

×
×
  • 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.