mirror of
https://github.com/raphaelcheung/zircon-legend-server.git
synced 2026-10-21 00:45:52 +08:00
267 lines
8.9 KiB
C#
267 lines
8.9 KiB
C#
using System;
|
|
using System.Linq;
|
|
using Library;
|
|
using Library.Network;
|
|
using S = Library.Network.ServerPackets;
|
|
using Server.DBModels;
|
|
using Server.Envir;
|
|
using Zircon.Server.Models.Monsters;
|
|
using System.Security.Principal;
|
|
using System.Text;
|
|
using System.Numerics;
|
|
|
|
namespace Zircon.Server.Models
|
|
{
|
|
public sealed class ItemObject : MapObject
|
|
{
|
|
public override ObjectType Race {get{return ObjectType.Item;}}
|
|
public override bool Blocking { get { return false; } }
|
|
|
|
public DateTime ExpireTime { get; set; } = DateTime.MaxValue;
|
|
|
|
public UserItem? Item { get; set; }
|
|
public List<CharacterInfo> OwnerList { get; } = new List<CharacterInfo>();
|
|
public DateTime OwnerExpire { get; set; } = DateTime.MaxValue;
|
|
|
|
public bool MonsterDrop { get; set; }
|
|
|
|
public bool CharacterContain(CharacterInfo character)
|
|
{
|
|
return OwnerList.Any(c => c.CharacterName == character.CharacterName);
|
|
}
|
|
|
|
public string GetCharacterListString()
|
|
{
|
|
StringBuilder sb = new();
|
|
foreach (CharacterInfo character in OwnerList)
|
|
{
|
|
if (sb.Length <= 0) sb.Append(character.CharacterName);
|
|
else sb.Append($"、{character.CharacterName}");
|
|
}
|
|
|
|
return sb.ToString();
|
|
}
|
|
|
|
public override void Process()
|
|
{
|
|
base.Process();
|
|
|
|
if (SEnvir.Now > ExpireTime)
|
|
{
|
|
Despawn();
|
|
Item?.Delete();
|
|
Item = null;
|
|
return;
|
|
}
|
|
|
|
if (SEnvir.Now > OwnerExpire)
|
|
OwnerList.Clear();
|
|
}
|
|
|
|
public override void OnDespawned()
|
|
{
|
|
base.OnDespawned();
|
|
|
|
if (Item?.UserTask != null)
|
|
{
|
|
Item.UserTask.Objects.Remove(this);
|
|
Item.UserTask = null;
|
|
Item.Flags &= ~UserItemFlags.QuestItem;
|
|
}
|
|
|
|
Item = null;
|
|
OwnerList.Clear();
|
|
}
|
|
|
|
public override void OnSafeDespawn()
|
|
{
|
|
base.OnSafeDespawn();
|
|
|
|
|
|
if (Item?.UserTask != null)
|
|
{
|
|
Item.UserTask.Objects.Remove(this);
|
|
Item.UserTask = null;
|
|
Item.Flags &= ~UserItemFlags.QuestItem;
|
|
}
|
|
|
|
Item = null;
|
|
OwnerList.Clear();
|
|
}
|
|
|
|
public bool PickUpItem(PlayerObject ob)
|
|
{
|
|
if (OwnerList.Count > 0 && !OwnerList.Contains(ob.Character))
|
|
{
|
|
ob.Connection.ReceiveChat($"无法捡拾他人掉落的物品 【{Item.Info.ItemName}】", MessageType.System);
|
|
return false;
|
|
}
|
|
|
|
long amount = 0;
|
|
|
|
if (OwnerList.Count > 0 && Item.Info.Effect == ItemEffect.Gold && ob.Character.Account.GuildMember != null && ob.Character.Account.GuildMember.Guild.GuildTax > 0)
|
|
amount = (long)Math.Ceiling(Item.Count * ob.Character.Account.GuildMember.Guild.GuildTax);
|
|
|
|
ItemCheck check = new ItemCheck(Item, Item.Count - amount, Item.Flags, Item.ExpireTime);
|
|
|
|
if (ob.CanGainItems(false, check))
|
|
{
|
|
if (amount > 0 && ob.Character.Account.GuildMember != null)
|
|
{
|
|
Item.Count -= amount;
|
|
|
|
ob.Character.Account.GuildMember.Guild.GuildFunds += amount;
|
|
ob.Character.Account.GuildMember.Guild.DailyGrowth += amount;
|
|
|
|
ob.Character.Account.GuildMember.Guild.DailyContribution += amount;
|
|
ob.Character.Account.GuildMember.Guild.TotalContribution += amount;
|
|
|
|
ob.Character.Account.GuildMember.DailyContribution += amount;
|
|
ob.Character.Account.GuildMember.TotalContribution += amount;
|
|
|
|
if ((ob.Character.Account.GuildMember.Guild?.Members ?? null) != null)
|
|
foreach (GuildMemberInfo member in ob.Character.Account.GuildMember.Guild.Members)
|
|
{
|
|
if ((member.Account.Connection?.Player ?? null) == null) continue;
|
|
|
|
member.Account.Connection.Enqueue(new S.GuildMemberContribution { Index = ob.Character.Account.GuildMember.Index, Contribution = amount, ObserverPacket = false });
|
|
}
|
|
}
|
|
|
|
Item.UserTask?.Objects?.Remove(this);
|
|
|
|
ob.GainItem(Item);
|
|
Despawn();
|
|
return true;
|
|
}
|
|
|
|
//Get Max Carry of type
|
|
//Reduce Amount by type.
|
|
//Send updated floor counts
|
|
//Gain New / partial items
|
|
return false;
|
|
}
|
|
public void PickUpItem(Companion ob)
|
|
{
|
|
//SEnvir.Log($"尝试捡拾道具:{Name} 属主:{GetCharacterListString()} 共{OwnerList.Count}个");
|
|
|
|
if (OwnerList.Count > 0 && !OwnerList.Contains(ob.CompanionOwner.Character)) return;
|
|
long amount = 0;
|
|
|
|
if (OwnerList.Count > 0 && Item.Info.Effect == ItemEffect.Gold && ob.CompanionOwner.Character.Account.GuildMember != null && ob.CompanionOwner.Character.Account.GuildMember.Guild.GuildTax > 0)
|
|
amount = (long)Math.Ceiling(Item.Count * ob.CompanionOwner.Character.Account.GuildMember.Guild.GuildTax);
|
|
|
|
ItemCheck check = new ItemCheck(Item, Item.Count - amount, Item.Flags, Item.ExpireTime);
|
|
|
|
if (ob.CanGainItems(false, check))
|
|
{
|
|
if (amount > 0)
|
|
{
|
|
Item.Count -= amount;
|
|
|
|
if (ob.CompanionOwner.Character.Account.GuildMember != null)
|
|
{
|
|
ob.CompanionOwner.Character.Account.GuildMember.Guild.GuildFunds += amount;
|
|
ob.CompanionOwner.Character.Account.GuildMember.Guild.DailyGrowth += amount;
|
|
|
|
ob.CompanionOwner.Character.Account.GuildMember.Guild.DailyContribution += amount;
|
|
ob.CompanionOwner.Character.Account.GuildMember.Guild.TotalContribution += amount;
|
|
|
|
ob.CompanionOwner.Character.Account.GuildMember.DailyContribution += amount;
|
|
ob.CompanionOwner.Character.Account.GuildMember.TotalContribution += amount;
|
|
|
|
if ((ob.CompanionOwner.Character.Account.GuildMember.Guild?.Members ?? null) != null)
|
|
foreach (GuildMemberInfo member in ob.CompanionOwner.Character.Account.GuildMember.Guild.Members)
|
|
{
|
|
if ((member.Account.Connection?.Player ?? null) == null) continue;
|
|
|
|
member.Account.Connection.Enqueue(new S.GuildMemberContribution { Index = ob.CompanionOwner.Character.Account.GuildMember.Index, Contribution = amount, ObserverPacket = false });
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
Item.UserTask?.Objects?.Remove(this);
|
|
|
|
ob.GainItem(Item);
|
|
Despawn();
|
|
return;
|
|
}
|
|
|
|
//Get Max Carry of type
|
|
//Reduce Amount by type.
|
|
//Send updated floor counts
|
|
//Gain New / partial items
|
|
return;
|
|
}
|
|
|
|
|
|
public override void ProcessHPMP()
|
|
{
|
|
}
|
|
public override void ProcessNameColour()
|
|
{
|
|
}
|
|
public override void ProcessBuff()
|
|
{
|
|
}
|
|
public override void ProcessPoison()
|
|
{
|
|
}
|
|
|
|
public override bool CanBeSeenBy(PlayerObject ob)
|
|
{
|
|
if (Item == null) return false;
|
|
if (!Config.CanSeeOthersDropped && OwnerList.Count > 0 && !OwnerList.Contains(ob.Character)) return false;
|
|
|
|
if ((Item.UserTask?.Quest?.Character ?? ob.Character) != ob.Character) return false;
|
|
|
|
return base.CanBeSeenBy(ob);
|
|
}
|
|
|
|
public override void Activate()
|
|
{
|
|
if (Activated) return;
|
|
|
|
Activated = true;
|
|
SEnvir.ActiveObjects.Add(this);
|
|
}
|
|
public override void DeActivate()
|
|
{
|
|
return;
|
|
}
|
|
|
|
protected override void OnSpawned()
|
|
{
|
|
base.OnSpawned();
|
|
|
|
ExpireTime = SEnvir.Now + Config.DropDuration;
|
|
|
|
AddAllObjects();
|
|
|
|
Activate();
|
|
}
|
|
public override Packet GetInfoPacket(PlayerObject ob)
|
|
{
|
|
return new S.ObjectItem
|
|
{
|
|
ObjectID = ObjectID,
|
|
Item = Item.ToClientInfo(),
|
|
Location = CurrentLocation,
|
|
};
|
|
}
|
|
public override Packet GetDataPacket(PlayerObject ob)
|
|
{
|
|
return new S.DataObjectItem
|
|
{
|
|
ObjectID = ObjectID,
|
|
|
|
MapIndex = CurrentMap.Info.Index,
|
|
CurrentLocation = CurrentLocation,
|
|
|
|
ItemIndex = Item.Info.Index,
|
|
};
|
|
}
|
|
}
|
|
}
|