//---------------------------------------------------------------------------------------------------------------------------------------------------
//
// Copyright (C)2007 DarkWynter Studios. All rights reserved.
//
//---------------------------------------------------------------------------------------------------------------------------------------------------
// {Contact : darkwynter.com for licensing information
//---------------------------------------------------------------------------------------------------------------------------------------------------
namespace ElementalGame.GameObjects
{
#region Using Statements
using System;
using System.Collections;
using System.Collections.Generic;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Storage;
using System.Xml;
using System.Diagnostics;
using Physics;
using Globals;
#endregion
public class LookupMap
{
#region Attributes
private LinkedList[,] lookupMap;
private LinkedList[,] playerMap;
private LinkedList returnList;
private List dynamicList;
private int mapWidth;
private int mapHeight;
#endregion
#region Methods
public LookupMap() { }
public LookupMap(int width, int height)
{
mapWidth = width;
mapHeight = height;
lookupMap = new LinkedList[mapWidth, mapHeight];
for (int x = 0; x < mapWidth; x++)
{
for (int z = 0; z < mapHeight; z++)
{
lookupMap[x, z] = new LinkedList();
}
}
playerMap = new LinkedList[mapWidth, mapWidth];
for (int x = 0; x < mapWidth; x++)
{
for (int z = 0; z < mapHeight; z++)
{
playerMap[x, z] = new LinkedList();
}
}
returnList = new LinkedList();
dynamicList = new List();
}
private bool UpdatePosition(Mass mass)
{
if (((int)mass.currentPosition.X / Statics.terrainScaleFactor != (int)mass.lastPosition.X / Statics.terrainScaleFactor) ||
((int)mass.currentPosition.Z / Statics.terrainScaleFactor != (int)mass.lastPosition.Z / Statics.terrainScaleFactor))
{
RemoveLast(mass);
RemoveCurrent(mass);
switch (mass.objectType)
{
case Enums.ObjectType.PLAYER:
{
playerMap[(int)mass.currentPosition.X / Statics.terrainScaleFactor,
(int)mass.currentPosition.Z / Statics.terrainScaleFactor].AddLast(mass);
break;
}
default:
{
lookupMap[(int)mass.currentPosition.X / Statics.terrainScaleFactor,
(int)mass.currentPosition.Z / Statics.terrainScaleFactor].AddLast(mass);
break;
}
}
return true;
}
return false;
}
public LinkedList GetCollisionObjects(Mass mass)
{
// Get Min and Max search area positions
int xMin = (int)mass.currentPosition.X / Statics.terrainScaleFactor - Statics.GameSettings.collisionSearchArea;
int zMin = (int)mass.currentPosition.Z / Statics.terrainScaleFactor - Statics.GameSettings.collisionSearchArea;
int xMax = (int)mass.currentPosition.X / Statics.terrainScaleFactor + Statics.GameSettings.collisionSearchArea;
int zMax = (int)mass.currentPosition.Z / Statics.terrainScaleFactor + Statics.GameSettings.collisionSearchArea;
// Bound Checking
if (xMin < 0) { xMin = 0; }
if (xMax >= mapWidth) { xMax = mapWidth - 1; }
if (zMin < 0) { zMin = 0; }
if (zMax >= mapHeight) { zMax = mapHeight - 1; }
returnList.Clear();
// Concatenate a list of objects within the search area
for (int currentX = xMin; currentX <= xMax; currentX++)
{
for (int currentZ = zMin; currentZ <= zMax; currentZ++)
{
if (lookupMap[currentX, currentZ].Count > 0)
{
foreach (Mass massObj in lookupMap[currentX, currentZ])
{
if (massObj != null && massObj.gameObjectPointer != null && massObj != mass)
{
returnList.AddLast(massObj);
}
}
}
if (playerMap[currentX, currentZ].Count > 0)
{
foreach (Mass massObj in playerMap[currentX, currentZ])
{
if (massObj != null && massObj.gameObjectPointer != null && massObj != mass)
{
Player player = (Player)massObj.gameObjectPointer;
if (player.IsAlive())
{
returnList.AddLast(massObj);
}
}
}
}
}
}
// Don't return the object being checked for
//while (returnList.Contains(mass))
//{
// returnList.Remove(mass);
//}
// Return the list of local objects
return returnList;
}
public void GetDrawObjects(Mass mass, LinkedList drawList)
{
// Get Min and Max search area positions
int xMin = (int)mass.currentPosition.X / Statics.terrainScaleFactor - Statics.GameSettings.drawSearchArea;
int zMin = (int)mass.currentPosition.Z / Statics.terrainScaleFactor - Statics.GameSettings.drawSearchArea;
int xMax = (int)mass.currentPosition.X / Statics.terrainScaleFactor + Statics.GameSettings.drawSearchArea;
int zMax = (int)mass.currentPosition.Z / Statics.terrainScaleFactor + Statics.GameSettings.drawSearchArea;
// Bound Checking
if (xMin < 0) { xMin = 0; }
if (xMax >= mapWidth) { xMax = mapWidth - 1; }
if (zMin < 0) { zMin = 0; }
if (zMax >= mapHeight) { zMax = mapHeight - 1; }
drawList.Clear();
// Concatenate a list of objects within the search area
for (int currentX = xMin; currentX <= xMax; currentX++)
{
for (int currentZ = zMin; currentZ <= zMax; currentZ++)
{
if (lookupMap[currentX, currentZ].Count > 0)
{
foreach (Mass massObj in lookupMap[currentX, currentZ])
{
if (massObj != null && massObj.gameObjectPointer != null && massObj != mass)
{
#if !XBOX360
if (massObj.objectType == Enums.ObjectType.GPU_OBJECT ||
massObj.objectType == Enums.ObjectType.PROP ||
massObj.objectType == Enums.ObjectType.KEY||
massObj.objectType == Enums.ObjectType.PORTAL||
massObj.objectType == Enums.ObjectType.PARTICLE)
{
continue;
}
#endif
drawList.AddLast(massObj);
}
}
}
if (playerMap[currentX, currentZ].Count > 0)
{
foreach (Mass massObj in playerMap[currentX, currentZ])
{
if (massObj != null && massObj.gameObjectPointer != null && massObj != mass)
{
Player player = (Player)massObj.gameObjectPointer;
if (player.IsAlive())
{
drawList.AddLast(massObj);
}
}
}
}
}
}
// Don't return the object being checked for
//while (drawList.Contains(mass))
//{
// drawList.Remove(mass);
//}
//// Return the list of local objects
//return returnList;
}
// Return the number of objects in the list
private int Count()
{
int count = 0;
for (int i = 0; i < mapWidth; i++)
{
for (int j = 0; j < mapHeight; j++)
{
if (playerMap[i, j].Count > 0)
{
count += playerMap[i, j].Count;
}
}
}
return count;
}
public void RemoveCurrent(Mass mass)
{
switch (mass.objectType)
{
case Enums.ObjectType.PLAYER:
{
while (playerMap[(int)mass.currentPosition.X / Statics.terrainScaleFactor,
(int)mass.currentPosition.Z / Statics.terrainScaleFactor].Contains(mass))
{
playerMap[(int)mass.currentPosition.X / Statics.terrainScaleFactor,
(int)mass.currentPosition.Z / Statics.terrainScaleFactor].Remove(mass);
}
break;
}
default:
{
while (lookupMap[(int)mass.currentPosition.X / Statics.terrainScaleFactor,
(int)mass.currentPosition.Z / Statics.terrainScaleFactor].Contains(mass))
{
lookupMap[(int)mass.currentPosition.X / Statics.terrainScaleFactor,
(int)mass.currentPosition.Z / Statics.terrainScaleFactor].Remove(mass);
}
break;
}
}
}
public void RemoveLast(Mass mass)
{
switch (mass.objectType)
{
case Enums.ObjectType.PLAYER:
{
while (playerMap[(int)mass.lastPosition.X / Statics.terrainScaleFactor,
(int)mass.lastPosition.Z / Statics.terrainScaleFactor].Contains(mass))
{
playerMap[(int)mass.lastPosition.X / Statics.terrainScaleFactor,
(int)mass.lastPosition.Z / Statics.terrainScaleFactor].Remove(mass);
}
break;
}
default:
{
while (lookupMap[(int)mass.lastPosition.X / Statics.terrainScaleFactor,
(int)mass.lastPosition.Z / Statics.terrainScaleFactor].Contains(mass))
{
lookupMap[(int)mass.lastPosition.X / Statics.terrainScaleFactor,
(int)mass.lastPosition.Z / Statics.terrainScaleFactor].Remove(mass);
}
break;
}
}
}
public void SetPosition(Mass mass)
{
switch (mass.objectType)
{
case Enums.ObjectType.PLAYER:
{
if (!playerMap[(int)mass.lastPosition.X / Statics.terrainScaleFactor,
(int)mass.lastPosition.Z / Statics.terrainScaleFactor].Contains(mass))
{
playerMap[(int)mass.lastPosition.X / Statics.terrainScaleFactor,
(int)mass.lastPosition.Z / Statics.terrainScaleFactor].AddLast(mass);
}
break;
}
default:
{
lookupMap[(int)mass.lastPosition.X / Statics.terrainScaleFactor,
(int)mass.lastPosition.Z / Statics.terrainScaleFactor].AddLast(mass);
break;
}
}
}
public LinkedList GetListXZ(int x, int z)
{
return lookupMap[x, z];
}
public void AddDynamic(Mass mass)
{
if (!dynamicList.Contains(mass))
{
dynamicList.Add(mass);
}
}
public void RemoveDynamic(Mass mass)
{
while (dynamicList.Contains(mass))
{
dynamicList.Remove(mass);
}
}
public List GetDynamicList()
{
return dynamicList;
}
public void UpdateDynamic(ObjectLibrary objectLibrary)
{
for (int i = 0; i < dynamicList.Count; i++)
{
if (dynamicList[i].gameObjectPointer == null)
{
RemoveDynamic(dynamicList[i]);
i--;
continue;
}
dynamicList[i].gameObjectPointer.Update(ref objectLibrary);
if (!dynamicList[i].isMoving)
{
RemoveDynamic(dynamicList[i]);
i--;
}
else
{
UpdatePosition(dynamicList[i]);
}
}
}
public void AddRange(List newMasses)
{
dynamicList.AddRange(newMasses);
}
public bool DynamicContains(Mass mass)
{
if (dynamicList.Contains(mass))
{
return true;
}
return false;
}
#endregion
}
}