public void init(int divisionsOverWidth) { for (int i = 0; i < managedDivisions.Length; i++) { managedDivisions[i] = new CollisionDivision(); } width = chart.getAIMesh().getWidth(); height = chart.getAIMesh().getHeight(); // Get the square root of the division count. This is why it requires to be squared. (It's a map of 3x3 by default) //CORE_INFO("CollisionHandler has %d divisions.", divisionsOverWidth*divisionsOverWidth); divisionCount = divisionsOverWidth; // Setup the division dimensions for (int y = 0; y < divisionsOverWidth; y++) { for (int x = 0; x < divisionsOverWidth; x++) { managedDivisions[y * divisionsOverWidth + x].min.X = x * (width / divisionsOverWidth); managedDivisions[y * divisionsOverWidth + x].min.Y = y * (height / divisionsOverWidth); managedDivisions[y * divisionsOverWidth + x].max.X = (x + 1) * (width / divisionsOverWidth); managedDivisions[y * divisionsOverWidth + x].max.Y = (y + 1) * (height / divisionsOverWidth); managedDivisions[y * divisionsOverWidth + x].objectCount = 0; } } }
public void addObject(GameObject obj) { if (divisionCount == -1) // If we have not initialised.. { Logger.LogCoreError("Tried to add an object before we initialised the CollisionHandler!"); return; } var map = obj.GetGame().GetMap(); if (map != null && map != chart) { Logger.LogCoreInfo("Map is adding an object that is not healthy. His map pointer is " + obj.GetGame().GetMap() + " (not " + chart + "). Not adding it."); return; } float divX = obj.getPosition().X / (float)(width / divisionCount); // Get the division position. float divY = obj.getPosition().Y / (float)(height / divisionCount); int divi = (int)divY * divisionCount + (int)divX; if (divX < 0 || divX > divisionCount || divY < 0 || divY > divisionCount) // We're not inside the map! Add to the unmanaged objects. { Logger.LogCoreError("Object spawned outside of map. (" + obj.getPosition().X + ", " + obj.getPosition().Y + ")"); //addUnmanagedObject(object); } else { addToDivision(obj, (int)divX, (int)divY); CollisionDivision curDiv = managedDivisions[divi]; bool a = false, b = false; if (Math.Abs(obj.getPosition().X - curDiv.max.X) < obj.getCollisionRadius()) // Are we in the one to the right? { addToDivision(obj, (int)divX + 1, (int)divY); // Add it there too. } if (Math.Abs(obj.getPosition().X - curDiv.min.X) < obj.getCollisionRadius()) // Maybe on the left? { a = true; addToDivision(obj, (int)divX - 1, (int)divY); } if (Math.Abs(obj.getPosition().Y - curDiv.max.Y) < obj.getCollisionRadius()) // Are we touching below us? { addToDivision(obj, (int)divX, (int)divY + 1); } if (Math.Abs(obj.getPosition().Y - curDiv.min.Y) < obj.getCollisionRadius()) // Or above? { b = true; addToDivision(obj, (int)divX, (int)divY - 1); } if (a && b) // If we are touching all four, add the left-upper one. { b = true; addToDivision(obj, (int)divX - 1, (int)divY - 1); } } }
private void correctDivisions(int pos) { CollisionDivision curDiv = managedDivisions[pos]; for (int j = 0; j < curDiv.objects.Count; j++) // For all objects inside this division { var o = curDiv.objects[j]; if (o != null) //if (o->isMovementUpdated()) // Only check if they moved around. { while (_game.Map.Id != chart.Id) { _logger.LogCoreWarning(string.Format( "I have found an object that is not healthy. " + "His map pointer is {0} (not {1}). " + "Removing it from the database ({2}/{3} in div {4}).", _game.Map.Id, chart.Id, j, curDiv.objects.Count, pos )); removeObject(o); if (j < curDiv.objects.Count) { o = curDiv.objects[j]; } else { break; } } // If they are no longer in this division.. if ((o.X - o.CollisionRadius > curDiv.max.X || o.Y - o.CollisionRadius > curDiv.max.Y || o.X + o.CollisionRadius < curDiv.min.X || o.Y + o.CollisionRadius < curDiv.min.Y)) { removeFromDivision(o, pos); // Remove them from it. addObject(o); // Reset in what divisions this object is. } // If they've entered another division, but not left this one yet.. else if ((o.X + o.CollisionRadius > curDiv.max.X || o.Y + o.CollisionRadius > curDiv.max.Y || o.X - o.CollisionRadius < curDiv.min.X || o.Y - o.CollisionRadius < curDiv.min.Y)) { addObject(o); // Reset in what divisions this object is. } } } }
private void correctDivisions(int pos) { CollisionDivision curDiv = managedDivisions[pos]; for (int j = 0; j < curDiv.objects.Count; j++) // For all objects inside this division { var o = curDiv.objects[j]; if (o != null) //if (o->isMovementUpdated()) // Only check if they moved around. { while (o.GetGame().GetMap().GetId() != chart.GetId()) { Logger.LogCoreWarning("I have found an object that is not healthy. His map pointer is " + o.GetGame().GetMap().GetId() + " (not " + chart.GetId() + "). Removing it from the database (" + j + "/" + curDiv.objects.Count + " in div " + pos + ")."); removeObject(o); if (j < curDiv.objects.Count) { o = curDiv.objects[j]; } else { break; } } // If they are no longer in this division.. if ((o.getPosition().X - o.getCollisionRadius() > curDiv.max.X || o.getPosition().Y - o.getCollisionRadius() > curDiv.max.Y || o.getPosition().X + o.getCollisionRadius() < curDiv.min.X || o.getPosition().Y + o.getCollisionRadius() < curDiv.min.Y)) { removeFromDivision(o, pos); // Remove them from it. addObject(o); // Reset in what divisions this object is. } // If they've entered another division, but not left this one yet.. else if ((o.getPosition().X + o.getCollisionRadius() > curDiv.max.X || o.getPosition().Y + o.getCollisionRadius() > curDiv.max.Y || o.getPosition().X - o.getCollisionRadius() < curDiv.min.X || o.getPosition().Y - o.getCollisionRadius() < curDiv.min.Y)) { addObject(o); // Reset in what divisions this object is. } } } }
public void addObject(GameObject obj) { if (divisionCount == -1) // If we have not initialised.. { _logger.LogCoreError("Tried to add an object before we initialised the CollisionHandler!"); return; } var map = _game.Map; if (map != null && map != chart) { _logger.LogCoreInfo(string.Format( "Map is adding an object that is not healthy. His map pointer is {0} (not {1}). Not adding it.", _game.Map, chart )); return; } float divX = obj.X / (float)(width / divisionCount); // Get the division position. float divY = obj.Y / (float)(height / divisionCount); int divi = (int)divY * divisionCount + (int)divX; // We're not inside the map! Add to the unmanaged objects. if (divX < 0 || divX > divisionCount || divY < 0 || divY > divisionCount) { _logger.LogCoreError(string.Format( "Object spawned outside of map. ({0}, {1})", obj.X, obj.Y )); //addUnmanagedObject(object); } else { addToDivision(obj, (int)divX, (int)divY); CollisionDivision curDiv = managedDivisions[divi]; bool a = false, b = false; // Are we in the one to the right? if (Math.Abs(obj.X - curDiv.max.X) < obj.CollisionRadius) { addToDivision(obj, (int)divX + 1, (int)divY); // Add it there too. } // Maybe on the left? if (Math.Abs(obj.X - curDiv.min.X) < obj.CollisionRadius) { a = true; addToDivision(obj, (int)divX - 1, (int)divY); } // Are we touching below us? if (Math.Abs(obj.Y - curDiv.max.Y) < obj.CollisionRadius) { addToDivision(obj, (int)divX, (int)divY + 1); } // Or above? if (Math.Abs(obj.Y - curDiv.min.Y) < obj.CollisionRadius) { b = true; addToDivision(obj, (int)divX, (int)divY - 1); } // If we are touching all four, add the left-upper one. if (a && b) { b = true; addToDivision(obj, (int)divX - 1, (int)divY - 1); } } }