Merge pull request #820 from nolt/feature-bots

(cherry picked from commit b10de0645a869485fbb5771a739abd06b5708c2d)
This commit is contained in:
sven-n
2026-07-16 22:01:57 +02:00
committed by Acentech Dev
parent 8baf329654
commit d04cbecae3
58 changed files with 14856 additions and 62 deletions

View File

@@ -263,18 +263,7 @@ public class MoveItemAction
if (itemDefinition.ItemSlot.ItemSlots.Contains(toSlot) &&
player.CompliesRequirements(item))
{
static bool IsOneHandedOrShield(ItemDefinition definition) =>
(definition.ItemSlot!.ItemSlots.Contains(RightHandSlot) && definition.ItemSlot.ItemSlots.Contains(LeftHandSlot)) || definition.Group == 6;
var rightHandItemDefinition = storage.GetItem(RightHandSlot)?.Definition!;
if ((toSlot == LeftHandSlot
&& itemDefinition.Width >= 2
&& rightHandItemDefinition != null
&& !rightHandItemDefinition.IsAmmunition)
|| (toSlot == RightHandSlot
&& IsOneHandedOrShield(itemDefinition)
&& storage.GetItem(LeftHandSlot)?.Definition!.Width >= 2))
if (itemDefinition.ConflictsWithEquippedHands(storage, toSlot))
{
// Attempting to equip a two-handed item to the left hand slot when a shield is in the right hand slot,
// or trying to equip a one-handed weapon or shield to the right hand slot when a two-handed item is in the left hand slot.

View File

@@ -99,6 +99,10 @@ public class EnterMiniGameAction
var entrance = miniGameDefinition.Entrance ?? throw new InvalidOperationException("mini game entrance not defined");
var miniGame = await player.GameContext.GetMiniGameAsync(miniGameDefinition, player).ConfigureAwait(false);
// Snapshot before entering: an event which disallows parties (Chaos Castle) kicks the
// entering player out of its party below, losing the knowledge of who was going to follow.
var partyBots = Bots.BotMiniGameHandler.SnapshotPartyBots(player);
var enterResult = await miniGame.TryEnterAsync(player).ConfigureAwait(false);
if (enterResult == EnterResult.Success)
{
@@ -125,6 +129,10 @@ public class EnterMiniGameAction
await player.RemoveSummonAsync().ConfigureAwait(false);
await player.MagicEffectList.ClearEffectsAfterDeathAsync().ConfigureAwait(false);
await player.WarpToAsync(entrance).ConfigureAwait(false);
// The bots of the entering party leader follow them in (each checked against the same
// entry restrictions, no ticket needed - the leader's own ticket legitimizes the visit).
Bots.BotMiniGameHandler.BringPartyBotsAlong(player, partyBots, miniGameDefinition, miniGame);
}
else
{

View File

@@ -28,7 +28,12 @@ public class PartyRequestAction
if (toRequest.Party != null || toRequest.LastPartyRequester != null)
{
if (toRequest.Party != null && Equals(toRequest.Party.PartyMaster, toRequest))
// A server-side bot is asked as well when it is a plain member of its (bot) party: a living
// player takes precedence over the bot's own company, so it leaves that party and joins the
// inviter (see BotPartyHandler). Everyone else keeps the original rule - only the master of a
// party can answer an invitation.
var isBot = toRequest.Account?.IsBot == true;
if (toRequest.Party != null && (isBot || Equals(toRequest.Party.PartyMaster, toRequest)))
{
if (await PartyRequestHandler.TryAutoAcceptPartyRequestAsync(toRequest, player).ConfigureAwait(false))
{