forked from SoDOff-Project/sodoff
166 lines
7.5 KiB
C#
166 lines
7.5 KiB
C#
using sodoff.Model;
|
|
using sodoff.Schema;
|
|
using sodoff.Util;
|
|
using System.Reflection;
|
|
using System.Xml;
|
|
using System.Xml.Linq;
|
|
|
|
namespace sodoff.Services;
|
|
public class RoomService {
|
|
|
|
private readonly DBContext ctx;
|
|
|
|
public RoomService(DBContext ctx) {
|
|
this.ctx = ctx;
|
|
}
|
|
|
|
public void CreateRoom(Viking viking, string roomId) {
|
|
viking.Rooms.Add(new Room { RoomId = roomId });
|
|
ctx.SaveChanges();
|
|
}
|
|
|
|
public Tuple<int[], UserItemState[]> CreateItems(UserItemPositionSetRequest[] roomItemRequest, Room room) {
|
|
List<int> ids = new();
|
|
List<UserItemState> states = new();
|
|
foreach (var itemRequest in roomItemRequest) {
|
|
// TODO: Remove item from inventory (using CommonInventoryID)
|
|
InventoryItem? i = room.Viking?.Inventory.InventoryItems.FirstOrDefault(x => x.Id == itemRequest.UserInventoryCommonID);
|
|
if (i != null) i.Quantity--;
|
|
RoomItem roomItem = new RoomItem {
|
|
RoomItemData = XmlUtil.SerializeXml<UserItemPosition>(itemRequest).Replace(" xsi:type=\"UserItemPositionSetRequest\"", "") // NOTE: No way to avoid this hack when we're serializing a child class into a base class
|
|
};
|
|
|
|
room.Items.Add(roomItem);
|
|
ctx.SaveChanges();
|
|
ids.Add(roomItem.Id);
|
|
if (itemRequest.Item.ItemStates.Count > 0) {
|
|
ItemState defaultState = itemRequest.Item.ItemStates.Find(x => x.Order == 1)!;
|
|
UserItemState userDefaultState = new UserItemState {
|
|
CommonInventoryID = (int)itemRequest.UserInventoryCommonID!,
|
|
UserItemPositionID = roomItem.Id,
|
|
ItemID = (int)itemRequest.Item.ItemID,
|
|
ItemStateID = defaultState.ItemStateID,
|
|
StateChangeDate = DateTime.Now
|
|
};
|
|
states.Add(userDefaultState);
|
|
itemRequest.UserItemState = userDefaultState;
|
|
roomItem.RoomItemData = XmlUtil.SerializeXml<UserItemPosition>(itemRequest).Replace(" xsi:type=\"UserItemPositionSetRequest\"", "");
|
|
ctx.SaveChanges();
|
|
}
|
|
}
|
|
return new(ids.ToArray(), states.ToArray());
|
|
}
|
|
|
|
public UserItemState[] UpdateItems(UserItemPositionSetRequest[] roomItemRequest, Room room) {
|
|
List<UserItemState> state = new();
|
|
foreach (var itemRequest in roomItemRequest) {
|
|
RoomItem? item = room.Items.FirstOrDefault(x => x.Id == itemRequest.UserItemPositionID);
|
|
if (item is null) continue;
|
|
|
|
UserItemPosition itemPosition = XmlUtil.DeserializeXml<UserItemPosition>(item.RoomItemData);
|
|
|
|
if (itemRequest.Uses != null) itemPosition.Uses = itemRequest.Uses;
|
|
itemPosition.InvLastModifiedDate = itemRequest.InvLastModifiedDate;
|
|
if (itemRequest.UserItemState != null) itemPosition.UserItemState = itemRequest.UserItemState;
|
|
if (itemRequest.UserItemAttributes != null) itemPosition.UserItemAttributes = itemRequest.UserItemAttributes;
|
|
if (itemRequest.UserItemStat != null) itemPosition.UserItemStat = itemRequest.UserItemStat;
|
|
if (itemRequest.Item != null) itemPosition.Item = itemRequest.Item;
|
|
if (itemRequest.PositionX != null) itemPosition.PositionX = itemRequest.PositionX;
|
|
if (itemRequest.PositionY != null) itemPosition.PositionY = itemRequest.PositionY;
|
|
if (itemRequest.PositionZ != null) itemPosition.PositionZ = itemRequest.PositionZ;
|
|
if (itemRequest.RotationX != null) itemPosition.RotationX = itemRequest.RotationX;
|
|
if (itemRequest.RotationY != null) itemPosition.RotationY = itemRequest.RotationY;
|
|
if (itemRequest.RotationZ != null) itemPosition.RotationZ = itemRequest.RotationZ;
|
|
if (itemRequest.ParentID != null) itemPosition.ParentID = itemRequest.ParentID;
|
|
|
|
item.RoomItemData = XmlUtil.SerializeXml(itemPosition);
|
|
if (itemPosition.UserItemState != null) state.Add(itemPosition.UserItemState);
|
|
}
|
|
|
|
ctx.SaveChanges();
|
|
return state.ToArray();
|
|
}
|
|
|
|
public void DeleteItems(int[] itemIds, Room room) {
|
|
for (int i = 0; i < itemIds.Length; i++) {
|
|
RoomItem? ri = room.Items.FirstOrDefault(x => x.Id == itemIds[i]);
|
|
if (ri is null) continue;
|
|
UserItemPosition itemPosition = XmlUtil.DeserializeXml<UserItemPosition>(ri.RoomItemData);
|
|
room.Items.Remove(ri);
|
|
InventoryItem? invItem = room.Viking?.Inventory.InventoryItems.FirstOrDefault(x => x.Id == itemPosition.UserInventoryCommonID);
|
|
if (invItem != null) invItem.Quantity++;
|
|
}
|
|
ctx.SaveChanges();
|
|
}
|
|
|
|
public UserItemPositionList GetUserItemPositionList(Room room) {
|
|
List<UserItemPosition> itemPosition = new();
|
|
foreach (var item in room.Items) {
|
|
UserItemPosition data = XmlUtil.DeserializeXml<UserItemPosition>(item.RoomItemData);
|
|
data.UserItemPositionID = item.Id;
|
|
data.ItemID = data.Item.ItemID;
|
|
itemPosition.Add(data);
|
|
}
|
|
return new UserItemPositionList { UserItemPosition = itemPosition.ToArray() };
|
|
}
|
|
|
|
public SetNextItemStateResult NextItemState(RoomItem item, bool speedup) {
|
|
SetNextItemStateResult response = new SetNextItemStateResult {
|
|
Success = true,
|
|
ErrorCode = ItemStateChangeError.Success
|
|
};
|
|
UserItemPosition pos = XmlUtil.DeserializeXml<UserItemPosition>(item.RoomItemData);
|
|
|
|
int nextStateID = GetNextStateID(pos, speedup);
|
|
DateTime stateChange = DateTime.Now;
|
|
if (nextStateID == -1) {
|
|
nextStateID = pos.UserItemState.ItemStateID;
|
|
stateChange = pos.UserItemState.StateChangeDate;
|
|
ctx.RoomItems.Remove(item);
|
|
ctx.SaveChanges();
|
|
}
|
|
|
|
response.UserItemState = new UserItemState {
|
|
CommonInventoryID = (int)pos.UserInventoryCommonID!,
|
|
UserItemPositionID = item.Id,
|
|
ItemID = pos.Item.ItemID,
|
|
ItemStateID = nextStateID,
|
|
StateChangeDate = stateChange
|
|
};
|
|
|
|
if (nextStateID != -1) {
|
|
pos.UserItemState = response.UserItemState;
|
|
item.RoomItemData = XmlUtil.SerializeXml<UserItemPosition>(pos);
|
|
ctx.SaveChanges();
|
|
}
|
|
|
|
return response;
|
|
}
|
|
|
|
private int GetNextStateID(UserItemPosition pos, bool speedup) {
|
|
if (pos.UserItemState == null)
|
|
return pos.Item.ItemStates.Find(x => x.Order == 1)!.ItemStateID;
|
|
|
|
ItemState currState = pos.Item.ItemStates.Find(x => x.ItemStateID == pos.UserItemState.ItemStateID)!;
|
|
if (speedup)
|
|
return ((ItemStateCriteriaSpeedUpItem)currState.Rule.Criterias.Find(x => x.Type == ItemStateCriteriaType.SpeedUpItem)!).EndStateID;
|
|
|
|
ItemStateCriteriaExpiry? expiry = (ItemStateCriteriaExpiry?)currState.Rule.Criterias.Find(x => x.Type == ItemStateCriteriaType.StateExpiry);
|
|
if (expiry != null) {
|
|
DateTime start = pos.UserItemState.StateChangeDate;
|
|
if (start.AddSeconds(expiry.Period) <= DateTime.Now)
|
|
return expiry.EndStateID;
|
|
}
|
|
|
|
switch (currState.Rule.CompletionAction.Transition) {
|
|
default:
|
|
return pos.Item.ItemStates.Find(x => x.Order == currState.Order + 1)!.ItemStateID;
|
|
case StateTransition.InitialState:
|
|
return pos.Item.ItemStates.Find(x => x.Order == 1)!.ItemStateID;
|
|
case StateTransition.Deletion:
|
|
return -1;
|
|
|
|
}
|
|
}
|
|
}
|