Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using JoyLib.Code.Entities;
- using JoyLib.Code.Entities.AI;
- using JoyLib.Code.Entities.Items;
- using JoyLib.Code.Helpers;
- using JoyLib.Code.IO;
- using JoyLib.Code.Managers;
- using JoyLib.Code.States;
- using Microsoft.Xna.Framework;
- using Newtonsoft.Json;
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Threading;
- namespace JoyLib.Code.World
- {
- public class WorldInstance
- {
- protected WorldTile[,] m_Tiles;
- protected int[,] m_Light;
- protected bool[,] m_Discovered;
- protected int m_PlayerIndex;
- protected readonly WorldType m_Type;
- //Worlds and where to access them
- //[JsonConverter(typeof(AreaConverter))]
- protected Dictionary<string, WorldInstance> m_Areas;
- [JsonIgnore]
- protected WorldInstance m_Parent;
- protected List<Entity> m_Entities;
- protected List<BaseJoyObject> m_Objects;
- [JsonConverter(typeof(PointConverter))]
- protected Point m_SpawnPoint;
- protected static DateTime s_DateTime;
- public WorldInstance(WorldTile[,] tiles, Dictionary<string, WorldInstance> areas, List<Entity> entities,
- List<BaseJoyObject> objects, WorldType type, string name)
- {
- this.name = name;
- worldType = type;
- m_Tiles = tiles;
- m_Areas = areas;
- m_Entities = entities;
- m_Objects = objects;
- GUID = GUIDManager.AssignGUID();
- m_Discovered = new bool[m_Tiles.GetLength(0), m_Tiles.GetLength(1)];
- m_Type = type;
- CalculatePlayerIndex();
- m_Light = new int[m_Tiles.GetLength(0), m_Tiles.GetLength(1)];
- }
- public void SetDateTime(DateTime dateTime)
- {
- s_DateTime = dateTime;
- }
- protected void CalculatePlayerIndex()
- {
- for (int i = 0; i < m_Entities.Count; i++)
- {
- if (m_Entities[i].playerControlled)
- {
- m_PlayerIndex = i;
- return;
- }
- }
- }
- protected void CalculateLightLevels()
- {
- m_Light = new int[m_Light.GetLength(0), m_Light.GetLength(1)];
- //Do objects first
- List<BaseJoyObject> objects = m_Objects.ToList();
- for(int i = 0; i < objects.Count; i++)
- {
- if (objects[i] is ItemInstance == false)
- continue;
- ItemInstance item = (ItemInstance)objects[i];
- int xMin, xMax;
- int yMin, yMax;
- xMin = Math.Max(0, item.position.X - (item.lightLevel));
- xMax = Math.Min(m_Light.GetLength(0) - 1, item.position.X + (item.lightLevel));
- yMin = Math.Max(0, item.position.Y - (item.lightLevel));
- yMax = Math.Min(m_Light.GetLength(1) - 1, item.position.Y + (item.lightLevel));
- if(item.lightLevel > 0)
- {
- for(int x = xMin; x < xMax; x++)
- {
- for(int y = yMin; y < yMax; y++)
- {
- m_Light[x, y] = (int)Math.Max(0, (item.lightLevel - Vector2.Distance(item.position.ToVector2(), new Point(x, y).ToVector2())));
- }
- }
- }
- }
- //Then the objects used by entities
- List<Entity> entities = m_Entities.ToList();
- for(int i = 0; i < entities.Count; i++)
- {
- Entity entity = entities[i];
- for(int j = 0; j < entity.backpack.Count; j++)
- {
- ItemInstance item = entity.backpack[j];
- int xMin, xMax;
- int yMin, yMax;
- xMin = Math.Max(0, entity.position.X - (item.lightLevel));
- xMax = Math.Min(m_Light.GetLength(0) - 1, entity.position.X + (item.lightLevel));
- yMin = Math.Max(0, entity.position.Y - (item.lightLevel));
- yMax = Math.Min(m_Light.GetLength(1) - 1, entity.position.Y + (item.lightLevel));
- if (item.lightLevel > 0)
- {
- for (int x = xMin; x < xMax; x++)
- {
- for (int y = yMin; y < yMax; y++)
- {
- m_Light[x, y] += (int)Math.Max(0, (item.lightLevel - Vector2.Distance(entity.position.ToVector2(), new Point(x, y).ToVector2())));
- m_Light[x, y] = Math.Min(16, m_Light[x, y]);
- }
- }
- }
- }
- }
- }
- public void AddObject(BaseJoyObject objectRef)
- {
- lock(m_Objects)
- {
- m_Objects.Add(objectRef);
- }
- }
- public void RemoveObject(Point positionRef)
- {
- lock(m_Objects)
- {
- for (int i = 0; i < m_Objects.Count; i++)
- {
- if (m_Objects[i].position == positionRef)
- {
- m_Objects.RemoveAt(i);
- return;
- }
- }
- }
- }
- public BaseJoyObject GetObject(Point position)
- {
- for(int i = 0; i < m_Objects.Count; i++)
- {
- if (m_Objects[i].position == position)
- {
- return m_Objects[i];
- }
- }
- return null;
- }
- public void Tick()
- {
- DateTime oldTime = s_DateTime;
- if (worldType != WorldType.Overworld)
- {
- s_DateTime = s_DateTime.AddSeconds(6.0);
- }
- else
- {
- s_DateTime = s_DateTime.AddHours(1.0);
- }
- }
- public void Update()
- {
- foreach(Entity entity in m_Entities)
- {
- Thread childThread = new Thread(new ThreadStart(entity.Update));
- childThread.Start();
- }
- CalculateLightLevels();
- }
- public List<NeedAIData> SearchForObjects(Entity entityRef, string objectType, Intent intentRef)
- {
- List<NeedAIData> data = new List<NeedAIData>();
- if (entityRef.vision.GetLength(0) == 1)
- return data;
- //Special cases
- //Ownable objects
- if(objectType.Equals("Ownable"))
- {
- for(int i = 0; i < m_Objects.Count; i++)
- {
- if (!entityRef.vision[m_Objects[i].position.X, m_Objects[i].position.Y])
- continue;
- if (!m_Objects[i].GetType().Equals(typeof(ItemInstance)))
- continue;
- NeedAIData tempData = new NeedAIData();
- tempData.intent = intentRef;
- tempData.target = m_Objects[i];
- data.Add(tempData);
- }
- }
- for(int i = 0; i < m_Objects.Count; i++)
- {
- if(entityRef.vision[m_Objects[i].position.X, m_Objects[i].position.Y])
- {
- if (m_Objects[i].baseType.Equals(objectType))
- {
- NeedAIData tempData = new NeedAIData();
- tempData.intent = intentRef;
- tempData.target = m_Objects[i];
- data.Add(tempData);
- }
- }
- }
- return data;
- }
- public List<NeedAIData> SearchForEntities(Entity searcher, string entityTypeRef, Intent intentRef)
- {
- List<NeedAIData> data = new List<NeedAIData>();
- //Special cases
- //Non-sentient entities
- if (entityTypeRef.Equals("Entities-ns"))
- {
- List<Entity> entities = m_Entities.Where(x => x.sentient == false).ToList();
- for (int i = 0; i < entities.Count; i++)
- {
- if (searcher.vision[entities[i].position.X, entities[i].position.Y] && searcher.GUID != entities[i].GUID)
- {
- NeedAIData tempData = new NeedAIData();
- tempData.intent = intentRef;
- tempData.target = entities[i];
- data.Add(tempData);
- }
- }
- return data;
- }
- //Sentient entities
- else if (entityTypeRef.Equals("Entities-s"))
- {
- List<Entity> entities = m_Entities.Where(x => x.sentient).ToList();
- for (int i = 0; i < entities.Count; i++)
- {
- if (searcher.vision[entities[i].position.X, entities[i].position.Y] && searcher.GUID != entities[i].GUID)
- {
- NeedAIData tempData = new NeedAIData();
- tempData.intent = intentRef;
- tempData.target = entities[i];
- data.Add(tempData);
- }
- }
- return data;
- }
- //All entities
- else if(entityTypeRef.Equals("Entities"))
- {
- List<NeedAIData> dataList = new List<NeedAIData>();
- for(int i = 0; i < m_Entities.Count; i++)
- {
- if(searcher.vision[m_Entities[i].position.X, m_Entities[i].position.Y] && searcher.GUID != m_Entities[i].GUID)
- {
- NeedAIData tempData = new NeedAIData();
- tempData.intent = intentRef;
- tempData.target = m_Entities[i];
- dataList.Add(tempData);
- }
- }
- return dataList;
- }
- else
- {
- for (int i = 0; i < m_Entities.Count; i++)
- {
- if (searcher.vision[m_Entities[i].position.X, m_Entities[i].position.Y])
- {
- if ((m_Entities[i].baseType.Equals(entityTypeRef) ||
- m_Entities[i].creatureType.Equals(entityTypeRef)) &&
- searcher.GUID != entities[i].GUID)
- {
- NeedAIData tempData = new NeedAIData();
- tempData.intent = intentRef;
- tempData.target = entities[i];
- data.Add(tempData);
- }
- }
- }
- return data;
- }
- }
- public NeedAIData SearchForEntities(Entity entityRef, List<int> GUIDs, Intent intentRef)
- {
- NeedAIData data = new NeedAIData();
- data.intent = intentRef;
- Dictionary<int, Entity> chosenEntities = m_Entities.Where(x => GUIDs.Contains(x.GUID)).ToDictionary(x => x.GUID, x => x);
- List<Entity> visibleEntities = new List<Entity>();
- foreach(Entity entity in chosenEntities.Values)
- {
- if(entityRef.vision[entity.position.X, entity.position.Y] && entity.GUID != entityRef.GUID)
- {
- visibleEntities.Add(entity);
- }
- }
- if (visibleEntities.Count > 0)
- {
- data.target = visibleEntities[RNG.Roll(0, visibleEntities.Count - 1)];
- }
- return data;
- }
- public NeedAIData SearchForMate(Entity entityRef)
- {
- NeedAIData data = new NeedAIData();
- data.intent = Intent.Interact;
- List<Entity> validPartners = new List<Entity>();
- if (entityRef.sexuality == Sexuality.Heterosexual)
- {
- validPartners = m_Entities.Where(x => x.gender != entityRef.gender && x.sentient == entityRef.sentient &&
- (x.sexuality == Sexuality.Heterosexual || x.sexuality == Sexuality.Bisexual) && x.creatureType.Equals(entityRef.creatureType) &&
- x.needs[NeedIndex.Sex].contributingHappiness == false).ToList();
- }
- else if(entityRef.sexuality == Sexuality.Homosexual)
- {
- validPartners = m_Entities.Where(x => x.gender == entityRef.gender && x.sentient == entityRef.sentient &&
- (x.sexuality == Sexuality.Homosexual || x.sexuality == Sexuality.Bisexual) && x.creatureType.Equals(entityRef.creatureType) &&
- x.needs[NeedIndex.Sex].contributingHappiness == false).ToList();
- }
- else if(entityRef.sexuality == Sexuality.Bisexual)
- {
- validPartners = m_Entities.Where(x => x.sentient == entityRef.sentient &&
- (x.sexuality == Sexuality.Heterosexual || x.sexuality == Sexuality.Bisexual) && x.creatureType.Equals(entityRef.creatureType) &&
- x.needs[NeedIndex.Sex].contributingHappiness == false).ToList();
- }
- List<Entity> visiblePartners = new List<Entity>();
- for(int i = 0; i < validPartners.Count; i++)
- {
- if (validPartners[i].GUID == entityRef.GUID)
- continue;
- if (entityRef.vision[validPartners[i].position.X, validPartners[i].position.Y])
- visiblePartners.Add(validPartners[i]);
- }
- if (visiblePartners.Count > 0)
- data.target = visiblePartners[RNG.Roll(0, visiblePartners.Count - 1)];
- return data;
- }
- public Entity GetRandomSentient()
- {
- List<Entity> sentients = m_Entities.Where(x => x.sentient).ToList();
- if (sentients.Count > 0)
- return sentients[RNG.Roll(0, sentients.Count - 1)];
- else
- return null;
- }
- public Entity GetRandomSentientWorldWide()
- {
- List<WorldInstance> worlds = GetWorlds(WorldState.overworld);
- int result = RNG.Roll(0, worlds.Count - 1);
- Entity entity = worlds[result].GetRandomSentient();
- while (entity == null)
- {
- result = RNG.Roll(0, worlds.Count - 1);
- entity = worlds[result].GetRandomSentient();
- }
- return entity;
- }
- public List<WorldInstance> GetWorlds(WorldInstance parent)
- {
- List<WorldInstance> worlds = new List<WorldInstance>();
- worlds.Add(parent);
- for(int i = 0; i < worlds.Count; i++)
- {
- foreach(WorldInstance world in worlds[i].m_Areas.Values)
- {
- List<WorldInstance> newWorlds = GetWorlds(world);
- for(int j = 0; j < newWorlds.Count; j++)
- {
- if (!worlds.Contains(newWorlds[j]))
- worlds.Add(newWorlds[j]);
- }
- }
- }
- return worlds;
- }
- public void SwapPosition(Entity left, Entity right)
- {
- Point tempPosition = right.position;
- right.Move(left.position);
- left.Move(tempPosition);
- }
- public void PickUpObject(Entity entityRef)
- {
- ItemInstance item = (ItemInstance)GetObject(entityRef.position);
- if (item != null)
- {
- item.ownerGUID = entityRef.GUID;
- entityRef.AddItem(item);
- lock (m_Objects)
- {
- m_Objects.Remove(item);
- }
- }
- }
- public void TradeObjects(Entity leftEntity, ItemInstance leftItem, Entity rightEntity, ItemInstance rightItem)
- {
- if(leftItem != null)
- {
- leftEntity.RemoveItemFromBackpack(leftItem);
- rightEntity.AddItem(leftItem);
- }
- if(rightItem != null)
- {
- rightEntity.RemoveItemFromBackpack(rightItem);
- leftEntity.AddItem(rightItem);
- }
- }
- public bool[,] GetVision(Entity entityRef)
- {
- bool[,] vision = new bool[m_Tiles.GetLength(0), m_Tiles.GetLength(1)];
- vision = DiscoverTiles(entityRef.position, entityRef, vision);
- if (entityRef.playerControlled)
- {
- m_Discovered = DiscoverTiles(entityRef.position, entityRef, m_Discovered);
- }
- return vision;
- }
- protected bool[,] DiscoverTiles(Point pointRef, Entity entityRef, bool[,] visionRef)
- {
- bool[,] vision = visionRef;
- float entityPerceptionMod = entityRef.statistics[StatisticIndex.Perception] / 10 + 1;
- lock(m_Objects)
- {
- List<BaseJoyObject> wallsUnsorted = m_Objects.Where(x => x.baseType.Equals("Wall")).ToList();
- Dictionary<Point, BaseJoyObject> walls = wallsUnsorted.ToDictionary(x => x.position, x => x);
- walls = walls.Where(x => x.Key.X <= pointRef.X + entityPerceptionMod &&
- x.Key.X >= pointRef.X - entityPerceptionMod &&
- x.Key.Y <= pointRef.Y + entityPerceptionMod &&
- x.Key.Y >= pointRef.Y - entityPerceptionMod).ToDictionary(x => x.Key, x => x.Value);
- for (int i = 0; i < 360; i++)
- {
- float x = (float)Math.Cos(i * 0.01745f);
- float y = (float)Math.Sin(i * 0.01745f);
- vision = DiscoverTile(x, y, entityRef, entityPerceptionMod, walls, vision);
- }
- }
- return vision;
- }
- protected bool[,] DiscoverTile(float x, float y, Entity entityRef, float perceptionMod,
- Dictionary<Point, BaseJoyObject> walls, bool[,] visionRef)
- {
- bool[,] vision = visionRef;
- float oX, oY;
- oX = entityRef.position.X + 0.5f;
- oY = entityRef.position.Y + 0.5f;
- for (int i = 0; i < perceptionMod; i++)
- {
- if (oX < 0.0f || oY < 0.0f || oX >= vision.GetLength(0) || oY >= vision.GetLength(1))
- return vision;
- if (m_Light[(int)oX, (int)oY] == 0 && entityRef.visionType != VisionType.Nocturnal)
- return vision;
- vision[(int)oX, (int)oY] = true;
- if (walls.ContainsKey(new Point((int)oX, (int)oY)))
- return vision;
- oX += x;
- oY += y;
- }
- return vision;
- }
- public void AddEntity(Entity entityRef)
- {
- m_Entities.Add(entityRef);
- CalculatePlayerIndex();
- }
- public void RemoveEntity(Point positionRef)
- {
- for (int i = 0; i < m_Entities.Count; i++)
- {
- if (m_Entities[i].position.Equals(positionRef))
- {
- m_Entities.RemoveAt(i);
- break;
- }
- }
- CalculatePlayerIndex();
- }
- public Entity GetEntity(Point positionRef)
- {
- for (int i = 0; i < m_Entities.Count; i++)
- {
- if (m_Entities[i].position.Equals(positionRef))
- {
- return m_Entities[i];
- }
- }
- return null;
- }
- public Entity GetEntityRecursive(int GUID)
- {
- for(int i = 0; i < m_Entities.Count; i++)
- {
- if(m_Entities[i].GUID == GUID)
- {
- return m_Entities[i];
- }
- }
- List<WorldInstance> worlds = m_Areas.Values.ToList();
- for(int i = 0; i < worlds.Count; i++)
- {
- Entity entity = worlds[i].GetEntityRecursive(GUID);
- if(entity != null)
- {
- return entity;
- }
- }
- return null;
- }
- public WorldInstance GetWorldOfEntity(int GUID)
- {
- for(int i = 0; i < m_Entities.Count; i++)
- {
- if(m_Entities[i].GUID == GUID)
- {
- return this;
- }
- }
- List<WorldInstance> worlds = m_Areas.Values.ToList();
- for(int i = 0; i < worlds.Count; i++)
- {
- WorldInstance world = worlds[i].GetWorldOfEntity(GUID);
- if(world != null)
- {
- return world;
- }
- }
- return null;
- }
- public Sector GetSectorFromPoint(Point point)
- {
- int xCentreBegin, xRightBegin;
- int yCentreBegin, yBottomBegin;
- xCentreBegin = m_Tiles.GetLength(0) / 3;
- xRightBegin = xCentreBegin * 2;
- yCentreBegin = m_Tiles.GetLength(1) / 3;
- yBottomBegin = yCentreBegin * 2;
- int sectorX;
- int sectorY;
- if (point.X < xCentreBegin)
- sectorX = 0;
- else if (point.X < xRightBegin)
- sectorX = 1;
- else
- sectorX = 2;
- if (point.Y < yCentreBegin)
- sectorY = 0;
- else if (point.Y < yBottomBegin)
- sectorY = 1;
- else
- sectorY = 2;
- switch(sectorX)
- {
- case 0:
- switch(sectorY)
- {
- case 0:
- return Sector.NorthWest;
- case 1:
- return Sector.North;
- case 2:
- return Sector.NorthEast;
- }
- break;
- case 1:
- switch(sectorY)
- {
- case 0:
- return Sector.West;
- case 1:
- return Sector.Centre;
- case 2:
- return Sector.East;
- }
- break;
- case 2:
- switch (sectorY)
- {
- case 0:
- return Sector.SouthWest;
- case 1:
- return Sector.South;
- case 2:
- return Sector.SouthEast;
- }
- break;
- }
- return Sector.Centre;
- }
- public WorldTile[,] tiles
- {
- get
- {
- return m_Tiles;
- }
- }
- public bool[,] discoveredTiles
- {
- get
- {
- return m_Discovered;
- }
- }
- public Dictionary<Point, BaseJoyObject> GetObjectsOfType(string type)
- {
- Dictionary<Point, BaseJoyObject> objects = new Dictionary<Point, BaseJoyObject>();
- foreach (BaseJoyObject joyObject in m_Objects)
- {
- if (joyObject.baseType.Equals(type))
- {
- objects.Add(joyObject.position, joyObject);
- }
- }
- return objects;
- }
- public void AddArea(string key, WorldInstance value)
- {
- value.parent = this;
- m_Areas.Add(key, value);
- }
- public string GetLocalAreaInfo(Entity entityRef)
- {
- if (m_Type == WorldType.Interior)
- {
- int result = RNG.Roll(0, 100);
- if (result <= 50)
- {
- int numberOfLevels = 1;
- numberOfLevels = WorldConversationDataHelper.GetNumberOfFloors(numberOfLevels, this);
- if (numberOfLevels == 1)
- return "This place only has " + numberOfLevels + " floor to it.";
- else
- return "This place has at least " + numberOfLevels + " floors.";
- }
- else if (result > 50)
- {
- int exactNumber = WorldConversationDataHelper.GetNumberOfCreatures(entityRef, this);
- int roughNumber = 0;
- if (exactNumber % 10 < 6)
- {
- roughNumber = exactNumber - (exactNumber % 10);
- }
- else
- {
- roughNumber = exactNumber + (exactNumber % 10);
- }
- return "There are around " + roughNumber + " " + entityRef.creatureType + "s here.";
- }
- }
- return "I don't know much about this place, sorry.";
- }
- //[JsonConverter(typeof(AreaConverter))]
- public Dictionary<string, WorldInstance> areas
- {
- get
- {
- return m_Areas;
- }
- }
- public List<Entity> entities
- {
- get
- {
- Entity[] newEntities = new Entity[m_Entities.Count];
- m_Entities.CopyTo(newEntities);
- return newEntities.ToList();
- }
- set
- {
- m_Entities = value;
- }
- }
- public List<BaseJoyObject> objects
- {
- get
- {
- return m_Objects;
- }
- }
- [JsonConverter(typeof(PointConverter))]
- public Point spawnPoint
- {
- get
- {
- return m_SpawnPoint;
- }
- set
- {
- m_SpawnPoint = value;
- }
- }
- [JsonIgnore]
- public WorldInstance parent
- {
- get
- {
- return m_Parent;
- }
- set
- {
- m_Parent = value;
- }
- }
- public int GUID
- {
- get;
- protected set;
- }
- public string name
- {
- get;
- protected set;
- }
- public Entity player
- {
- get
- {
- if (!m_Entities.Any(x => x.playerControlled))
- return null;
- return m_Entities[m_PlayerIndex];
- }
- }
- public WorldType worldType
- {
- get;
- protected set;
- }
- public int[,] lightLevels
- {
- get
- {
- return m_Light;
- }
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement