Fix PvP conflict

This commit is contained in:
HungDK
2026-02-24 16:59:51 +07:00
parent cab2c0af45
commit 7996bed176
4 changed files with 45 additions and 2680 deletions
@@ -386,9 +386,11 @@ namespace BrewMonster
UnityGameSession.c2s_CmdSelectTarget(m_iObjectId);
m_pHost.m_idSelTarget = m_iObjectId;
}
if (m_pHost.AttackableJudge(m_iObjectId, m_bForceAttack) == 1)
// Duel: always send PVP/force mask when target is duel opponent so server accepts the attack
bool bUseForceAttack = m_bForceAttack || (m_pHost.IsInDuel() && m_iObjectId == m_pHost.GetDuelOpponentId());
if (m_pHost.AttackableJudge(m_iObjectId, bUseForceAttack) == 1)
{
byte byPVPMask = EC_Utility.glb_BuildPVPMask(m_bForceAttack);
byte byPVPMask = EC_Utility.glb_BuildPVPMask(bUseForceAttack);
UnityGameSession.c2s_CmdNormalAttack(byPVPMask);
m_pHost.m_bPrepareFight = true;
bActionDone = true;
@@ -148,6 +148,9 @@ namespace BrewMonster
CECPlayer pPlayer = EC_ManMessageMono.Instance.EC_ManPlayer.GetPlayer(idObject);
if (pPlayer != null && !pPlayer.IsDead())
{
// Duel: so AttackableJudge and server get PVP mask
if (IsInDuel() && idObject == m_pvp.idDuelOpp)
bForceAttack = true;
// Already selected: allow trace (attack/talk). Or in duel: first click on duel opp = attack.
bool alreadySelected = (m_idSelTarget == idObject);
bool duelOppFirstClick = !alreadySelected && IsInDuel() && idObject == m_pvp.idDuelOpp && AttackableJudge(idObject, bForceAttack) == 1;
@@ -314,6 +317,9 @@ namespace BrewMonster
// In duel: first click on duel opp = attack (no prior select needed).
if (pPlayer != null && !pPlayer.IsDead())
{
// Duel: so AttackableJudge and server get PVP mask
if (IsInDuel() && idObject == m_pvp.idDuelOpp)
bForceAttack = true;
bool alreadySelected = (m_idSelTarget == idObject);
bool duelOppFirstClick = !alreadySelected && IsInDuel() && idObject == m_pvp.idDuelOpp && AttackableJudge(idObject, bForceAttack) == 1;
if (alreadySelected || duelOppFirstClick)
@@ -382,6 +388,14 @@ namespace BrewMonster
return;
}*/
// Duel fallback: if duel opp is already selected and we clicked (e.g. on ground or ray missed), treat as attack
if (idTraceTarget == 0 && IsInDuel() && m_idSelTarget == m_pvp.idDuelOpp && AttackableJudge(m_pvp.idDuelOpp, true) == 1)
{
idTraceTarget = m_pvp.idDuelOpp;
iTraceReason = CECHPWorkTrace.Trace_reason.TRACE_ATTACK;
bForceAttack = true;
}
// Handle trace target / Handle trace target
if (idTraceTarget != 0)
{
@@ -393,6 +407,8 @@ namespace BrewMonster
// Trace a object / Trace a object
if (iTraceReason == CECHPWorkTrace.Trace_reason.TRACE_ATTACK)
{
// So CanDo(CANDO_MELEE) passes: it requires m_idSelTarget set to the attack target
m_idSelTarget = idTraceTarget;
if (!CanDo(ActionCanDo.CANDO_MELEE))
return;
// When attacking duel opponent, send force/PVP so server accepts (origin: duel = attack but not kill)
+15 -70
View File
@@ -1,4 +1,4 @@
using BrewMonster.Managers;
using BrewMonster.Managers;
using BrewMonster.Network;
using BrewMonster.Scripts;
using BrewMonster.Scripts.World;
@@ -828,75 +828,16 @@ namespace BrewMonster
}
}
}
// TO DO: fix later
//else if (GPDataTypeHelper.ISPLAYERID(idTarget))
//{
// // Check duel at first
// if (m_pvp.iDuelState == Duel_state.DUEL_ST_INDUEL && m_pvp.idDuelOpp == idTarget)
// return 1;
// else if (m_pvp.iDuelState == Duel_state.DUEL_ST_STOPPING && m_pvp.idDuelOpp == idTarget)
// return 0;
// // In sanctuary we cannot attack other players
// if (m_bInSanctuary)
// return 0;
// //ASSERT(pObject.GetClassID() == CECObject::OCID_ELSEPLAYER);
// EC_ElsePlayer pPlayer = (EC_ElsePlayer)pObject;
// ROLEBASICPROP bp = pPlayer.GetBasicProps();
// EC_GAME_SETTING gs = g_pGame.GetConfigs().GetGameSettings();
// if (m_pvp.bFreePVP)
// {
// if (IsTeamMember(idTarget))
// return 0;
// // In free pvp mode, for example, host is in arena.
// if (bForceAttack)
// iRet = 1;
// else if (gs.bAtk_NoMafia && IsFactionMember(pPlayer.GetFactionID()))
// iRet = 0;
// else if (gs.bAtk_NoWhite && !pPlayer.IsInvader() && !pPlayer.IsPariah())
// iRet = 0;
// else if (gs.bAtk_NoAlliance && g_pGame.GetFactionMan().IsFactionAlliance(pPlayer.GetFactionID()))
// iRet = 0;
// else if (gs.bAtk_NoForce && GetForce() > 0 && GetForce() == pPlayer.GetForce())
// iRet = 0;
// else
// iRet = 1;
// }
// else if (m_iBattleCamp != GP_BATTLE_CAMP_NONE)
// {
// // Host is in battle
// int iCamp = pPlayer.GetBattleCamp();
// if (iCamp != GP_BATTLE_CAMP_NONE && iCamp != m_iBattleCamp)
// iRet = 1;
// else
// iRet = 0;
// }
// else // Normal mode
// {
// if (IsTeamMember(idTarget))
// return 0;
// if (!IsPVPOpen() || !pPlayer.IsPVPOpen() || m_BasicProps.iLevel < EC_MAXNOPKLEVEL || bp.iLevel < EC_MAXNOPKLEVEL)
// iRet = 0;
// else if (bForceAttack)
// iRet = 1;
// else if (!gs.bAtk_Player)
// iRet = 0;
// else if (gs.bAtk_NoMafia && IsFactionMember(pPlayer.GetFactionID()))
// iRet = 0;
// else if (gs.bAtk_NoWhite && !pPlayer.IsInvader() && !pPlayer.IsPariah())
// iRet = 0;
// else if (gs.bAtk_NoAlliance && g_pGame.GetFactionMan().IsFactionAlliance(pPlayer.GetFactionID()))
// iRet = 0;
// else if (gs.bAtk_NoForce && GetForce() > 0 && GetForce() == pPlayer.GetForce())
// iRet = 0;
// else
// iRet = 1;
// }
//}
else if (GPDataTypeHelper.ISPLAYERID(idTarget))
{
// Duel: allow attack only on duel opponent while in duel
if (IsInDuel() && m_pvp.idDuelOpp == idTarget)
return 1;
if (m_pvp.iDuelState == Duel_state.DUEL_ST_STOPPING && m_pvp.idDuelOpp == idTarget)
return 0;
// Other player PVP not implemented here; treat as not attackable
return 0;
}
else
{
return -1;
@@ -952,6 +893,10 @@ namespace BrewMonster
else
bForceAttack = iForceAtk > 0 ? true : false;
// Duel: server accepts attack on opponent only with PVP/force mask
if (IsInDuel() && idTarget == m_pvp.idDuelOpp)
bForceAttack = true;
if (AttackableJudge(idTarget, bForceAttack) != 1)
return false;
File diff suppressed because it is too large Load Diff