Commit 1b2aac41 authored by Kenix Whisperwind's avatar Kenix Whisperwind

RegionManager is now a non-static class member of World.

parent 5a3a0ed8
package com.openrsc.server.plugins.commands;
import com.openrsc.server.Server;
import com.openrsc.server.constants.Constants;
import com.openrsc.server.constants.ItemId;
import com.openrsc.server.constants.Skills;
import com.openrsc.server.event.SingleEvent;
......@@ -25,7 +26,6 @@ import com.openrsc.server.model.entity.update.Damage;
import com.openrsc.server.model.snapshot.Chatlog;
import com.openrsc.server.model.world.World;
import com.openrsc.server.model.world.region.Region;
import com.openrsc.server.model.world.region.RegionManager;
import com.openrsc.server.model.world.region.TileValue;
import com.openrsc.server.net.rsc.ActionSender;
import com.openrsc.server.plugins.Functions;
......@@ -100,12 +100,12 @@ public final class Admins implements CommandListener {
player.message(messagePrefix + "Saved " + count + " players on server!");
} else if (cmd.equalsIgnoreCase("cleanregions")) {
Server.getServer().submitTask(() -> {
final int HORIZONTAL_PLANES = (World.MAX_WIDTH / RegionManager.REGION_SIZE) + 1;
final int VERTICAL_PLANES = (World.MAX_HEIGHT / RegionManager.REGION_SIZE) + 1;
final int HORIZONTAL_PLANES = (World.MAX_WIDTH / Constants.REGION_SIZE) + 1;
final int VERTICAL_PLANES = (World.MAX_HEIGHT / Constants.REGION_SIZE) + 1;
for (int x = 0; x < HORIZONTAL_PLANES; ++x) {
for (int y = 0; y < VERTICAL_PLANES; ++y) {
Region r = RegionManager.getRegion(x * RegionManager.REGION_SIZE,
y * RegionManager.REGION_SIZE);
Region r = player.getWorld().getRegionManager().getRegion(x * Constants.REGION_SIZE,
y * Constants.REGION_SIZE);
if (r != null) {
r.getPlayers().removeIf(Entity::isRemoved);
}
......
package com.openrsc.server.plugins.misc;
import com.openrsc.server.Server;
import com.openrsc.server.event.SingleEvent;
import com.openrsc.server.constants.ItemId;
import com.openrsc.server.constants.NpcId;
import com.openrsc.server.model.Point;
import com.openrsc.server.constants.Skills;
import com.openrsc.server.event.SingleEvent;
import com.openrsc.server.model.Point;
import com.openrsc.server.model.entity.GameObject;
import com.openrsc.server.model.entity.npc.Npc;
import com.openrsc.server.model.entity.player.Player;
import com.openrsc.server.model.world.region.RegionManager;
import com.openrsc.server.plugins.listeners.action.ObjectActionListener;
import com.openrsc.server.plugins.listeners.executive.ObjectActionExecutiveListener;
import com.openrsc.server.util.rsc.DataConversions;
import static com.openrsc.server.plugins.Functions.createGroundItem;
import static com.openrsc.server.plugins.Functions.delayedSpawnObject;
import static com.openrsc.server.plugins.Functions.displayTeleportBubble;
import static com.openrsc.server.plugins.Functions.message;
import static com.openrsc.server.plugins.Functions.registerObject;
import static com.openrsc.server.plugins.Functions.removeObject;
import static com.openrsc.server.plugins.Functions.sleep;
import static com.openrsc.server.plugins.Functions.spawnNpc;
import static com.openrsc.server.plugins.Functions.*;
public class StrangeBarrels implements ObjectActionListener, ObjectActionExecutiveListener {
......@@ -126,7 +118,7 @@ public class StrangeBarrels implements ObjectActionListener, ObjectActionExecuti
public void action() {
int newObjectX = DataConversions.random(467, 476);
int newObjectY = DataConversions.random(3699, 3714);
if (RegionManager.getRegion(Point.location(newObjectX, newObjectY)).getGameObject(Point.location(newObjectX, newObjectY)) != null) {
if (p.getWorld().getRegionManager().getRegion(Point.location(newObjectX, newObjectY)).getGameObject(Point.location(newObjectX, newObjectY)) != null) {
registerObject(new GameObject(obj.getWorld(), obj.getLoc()));
} else {
registerObject(new GameObject(obj.getWorld(), Point.location(newObjectX, newObjectY), 1178, 0, 0));
......
......@@ -10,7 +10,6 @@ import com.openrsc.server.model.entity.GroundItem;
import com.openrsc.server.model.entity.npc.Npc;
import com.openrsc.server.model.entity.player.Player;
import com.openrsc.server.model.world.World;
import com.openrsc.server.model.world.region.RegionManager;
import com.openrsc.server.plugins.QuestInterface;
import com.openrsc.server.plugins.listeners.action.*;
import com.openrsc.server.plugins.listeners.executive.*;
......@@ -171,13 +170,13 @@ public class ClockTower implements QuestInterface, TalkToNpcListener,
GameObject dynGate, statGate, newGate;
boolean correctSetup = false;
if (obj.getID() == 373) {
dynGate = RegionManager.getRegion(Point.location(594, 3475)).getGameObject(Point.location(594, 3475));
statGate = RegionManager.getRegion(Point.location(590, 3475)).getGameObject(Point.location(590, 3475));
dynGate = p.getWorld().getRegionManager().getRegion(Point.location(594, 3475)).getGameObject(Point.location(594, 3475));
statGate = p.getWorld().getRegionManager().getRegion(Point.location(590, 3475)).getGameObject(Point.location(590, 3475));
//outer gate was open + inner gate is open
correctSetup = (dynGate.getID() == 372) && (statGate.getID() == 372);
} else {
dynGate = RegionManager.getRegion(Point.location(590, 3475)).getGameObject(Point.location(590, 3475));
statGate = RegionManager.getRegion(Point.location(594, 3475)).getGameObject(Point.location(594, 3475));
dynGate = p.getWorld().getRegionManager().getRegion(Point.location(590, 3475)).getGameObject(Point.location(590, 3475));
statGate = p.getWorld().getRegionManager().getRegion(Point.location(594, 3475)).getGameObject(Point.location(594, 3475));
//inner gate was closed + outer gate is closed
correctSetup = (dynGate.getID() == 371) && (statGate.getID() == 371);
}
......
......@@ -10,7 +10,6 @@ import com.openrsc.server.model.entity.GroundItem;
import com.openrsc.server.model.entity.npc.Npc;
import com.openrsc.server.model.entity.player.Player;
import com.openrsc.server.model.world.World;
import com.openrsc.server.model.world.region.RegionManager;
import com.openrsc.server.net.rsc.ActionSender;
import com.openrsc.server.plugins.QuestInterface;
import com.openrsc.server.plugins.listeners.action.ObjectActionListener;
......@@ -175,7 +174,7 @@ public class DwarfCannon
int cannonX = p.getCache().getInt("cannon_x");
int cannonY = p.getCache().getInt("cannon_y");
GameObject cannon = RegionManager.getRegion(cannonX, cannonY).getGameObject(cannonX, cannonY);
GameObject cannon = p.getWorld().getRegionManager().getRegion(cannonX, cannonY).getGameObject(cannonX, cannonY);
// does not exist or the object there is not a cannon.
if (cannon == null || !DataConversions.inArray(Cannon.cannonObjectIDs, cannon.getID())) {
message(p, "the dwarf gives you a new cannon");
......
......@@ -6,7 +6,6 @@ import com.openrsc.server.model.Point;
import com.openrsc.server.model.entity.GameObject;
import com.openrsc.server.model.entity.npc.Npc;
import com.openrsc.server.model.entity.player.Player;
import com.openrsc.server.model.world.region.RegionManager;
import com.openrsc.server.plugins.listeners.action.ObjectActionListener;
import com.openrsc.server.plugins.listeners.action.TalkToNpcListener;
import com.openrsc.server.plugins.listeners.executive.ObjectActionExecutiveListener;
......@@ -207,7 +206,7 @@ public class LegendsQuestGuildGuard implements TalkToNpcListener, TalkToNpcExecu
}
private void openGates(Player p) {
GameObject the_gate = RegionManager.getRegion(Point.location(512, 550)).getGameObject(Point.location(512, 550));
GameObject the_gate = p.getWorld().getRegionManager().getRegion(Point.location(512, 550)).getGameObject(Point.location(512, 550));
replaceObjectDelayed(the_gate, 2500, 181);
p.teleport(513, 549);
}
......
......@@ -2,11 +2,11 @@ package com.openrsc.server.plugins.quests.members.legendsquest.obstacles;
import com.openrsc.server.Server;
import com.openrsc.server.constants.ItemId;
import com.openrsc.server.constants.NpcId;
import com.openrsc.server.constants.Quests;
import com.openrsc.server.constants.Skills;
import com.openrsc.server.event.SingleEvent;
import com.openrsc.server.external.EntityHandler;
import com.openrsc.server.constants.NpcId;
import com.openrsc.server.model.Point;
import com.openrsc.server.model.container.Item;
import com.openrsc.server.model.entity.GameObject;
......@@ -14,7 +14,6 @@ import com.openrsc.server.model.entity.GroundItem;
import com.openrsc.server.model.entity.npc.Npc;
import com.openrsc.server.model.entity.player.Player;
import com.openrsc.server.model.world.World;
import com.openrsc.server.model.world.region.RegionManager;
import com.openrsc.server.plugins.listeners.action.InvUseOnObjectListener;
import com.openrsc.server.plugins.listeners.action.ObjectActionListener;
import com.openrsc.server.plugins.listeners.executive.InvUseOnObjectExecutiveListener;
......@@ -631,7 +630,7 @@ public class LegendsQuestGameObjects implements ObjectActionListener, ObjectActi
replaceObject(obj, new GameObject(obj.getWorld(), obj.getLocation(), CRAFTED_TOTEM_POLE, obj.getDirection(), obj.getType(), p.getUsername()));
Server.getServer().getGameEventHandler().add(new SingleEvent(null, 60000, "Legends Quest Craft Totem Pole") {
public void action() {
GameObject whatObject = RegionManager.getRegion(Point.location(objectX, objectY)).getGameObject(Point.location(objectX, objectY));
GameObject whatObject = p.getWorld().getRegionManager().getRegion(Point.location(objectX, objectY)).getGameObject(Point.location(objectX, objectY));
if (whatObject != null && whatObject.getID() == CRAFTED_TOTEM_POLE) {
World.getWorld().registerGameObject(new GameObject(obj.getWorld(), obj.getLocation(), FERTILE_EARTH, obj.getDirection(), obj.getType()));
}
......@@ -650,7 +649,7 @@ public class LegendsQuestGameObjects implements ObjectActionListener, ObjectActi
replaceObject(obj, new GameObject(obj.getWorld(), obj.getLocation(), TRIMMED_YOMMI_TREE, obj.getDirection(), obj.getType(), p.getUsername()));
Server.getServer().getGameEventHandler().add(new SingleEvent(null, 60000, "Legend Quest Trim Yommi Tree") {
public void action() {
GameObject whatObject = RegionManager.getRegion(Point.location(objectX, objectY)).getGameObject(Point.location(objectX, objectY));
GameObject whatObject = p.getWorld().getRegionManager().getRegion(Point.location(objectX, objectY)).getGameObject(Point.location(objectX, objectY));
if (whatObject != null && whatObject.getID() == TRIMMED_YOMMI_TREE) {
World.getWorld().registerGameObject(new GameObject(obj.getWorld(), obj.getLocation(), FERTILE_EARTH, obj.getDirection(), obj.getType()));
}
......@@ -668,7 +667,7 @@ public class LegendsQuestGameObjects implements ObjectActionListener, ObjectActi
replaceObject(obj, new GameObject(obj.getWorld(), obj.getLocation(), CHOPPED_YOMMI_TREE, obj.getDirection(), obj.getType(), p.getUsername()));
Server.getServer().getGameEventHandler().add(new SingleEvent(null, 60000, "Legend Quest Chop Yommi Tree") {
public void action() {
GameObject whatObject = RegionManager.getRegion(Point.location(objectX, objectY)).getGameObject(Point.location(objectX, objectY));
GameObject whatObject = p.getWorld().getRegionManager().getRegion(Point.location(objectX, objectY)).getGameObject(Point.location(objectX, objectY));
if (whatObject != null && whatObject.getID() == CHOPPED_YOMMI_TREE) {
World.getWorld().registerGameObject(new GameObject(obj.getWorld(), obj.getLocation(), FERTILE_EARTH, obj.getDirection(), obj.getType()));
}
......@@ -696,7 +695,7 @@ public class LegendsQuestGameObjects implements ObjectActionListener, ObjectActi
replaceObject(obj, new GameObject(obj.getWorld(), obj.getLocation(), GROWN_YOMMI_TREE, obj.getDirection(), obj.getType(), p.getUsername()));
Server.getServer().getGameEventHandler().add(new SingleEvent(null, 15000, "Legend Quest Water Yommi Tree") {
public void action() {
GameObject whatObject = RegionManager.getRegion(Point.location(objectX, objectY)).getGameObject(Point.location(objectX, objectY));
GameObject whatObject = p.getWorld().getRegionManager().getRegion(Point.location(objectX, objectY)).getGameObject(Point.location(objectX, objectY));
if (whatObject != null && whatObject.getID() == GROWN_YOMMI_TREE) {
World.getWorld().registerGameObject(new GameObject(obj.getWorld(), obj.getLocation(), ROTTEN_YOMMI_TREE, obj.getDirection(), obj.getType()));
if (p.isLoggedIn()) {
......@@ -745,7 +744,7 @@ public class LegendsQuestGameObjects implements ObjectActionListener, ObjectActi
replaceObject(obj, new GameObject(obj.getWorld(), obj.getLocation(), YOMMI_TREE, obj.getDirection(), obj.getType()));
Server.getServer().getGameEventHandler().add(new SingleEvent(null, 15000, "Legends Quest Grow Yommi Tree") {
public void action() {
GameObject whatObject = RegionManager.getRegion(Point.location(objectX, objectY)).getGameObject(Point.location(objectX, objectY));
GameObject whatObject = p.getWorld().getRegionManager().getRegion(Point.location(objectX, objectY)).getGameObject(Point.location(objectX, objectY));
if (whatObject != null && whatObject.getID() == YOMMI_TREE) {
World.getWorld().registerGameObject(new GameObject(obj.getWorld(), obj.getLocation(), DEAD_YOMMI_TREE, obj.getDirection(), obj.getType(), p.getUsername()));
if (p.isLoggedIn()) {
......
......@@ -75,6 +75,10 @@ public final class Constants {
* Maximum hit for Crumble Undead (Magic) spell. (Against undead)
*/
public static final int CRUMBLE_UNDEAD_MAX = 12;
/**
* Size of Regions in RegionManager
*/
public static final int REGION_SIZE = 48;
//public static final class Skillcapes {
// public static final int ATTACK_CAPE = 2111;
......
......@@ -8,7 +8,6 @@ import com.openrsc.server.model.entity.player.Player;
import com.openrsc.server.model.entity.update.ChatMessage;
import com.openrsc.server.model.world.Area;
import com.openrsc.server.model.world.World;
import com.openrsc.server.model.world.region.RegionManager;
import com.openrsc.server.net.rsc.ActionSender;
import com.openrsc.server.util.SimpleSubscriber;
import com.openrsc.server.util.rsc.DataConversions;
......@@ -388,7 +387,7 @@ public class FishingTrawler extends DelayedEvent {
/* The ship is leaking hardcore. */
if (freeLeakIndex == -1) {
break;
} else if (RegionManager.getRegion(x, y).getGameObject(x, y) != null) {
} else if (World.getWorld().getRegionManager().getRegion(x, y).getGameObject(x, y) != null) {
continue;
}
int southSide = currentStage == State.FIRST_SHIP ? spawnLocation.getY() - 1 : shipAreaWaterSpawn.getY() - 1;
......
......@@ -5,7 +5,6 @@ import com.openrsc.server.model.entity.GroundItem;
import com.openrsc.server.model.entity.Mob;
import com.openrsc.server.model.entity.npc.Npc;
import com.openrsc.server.model.entity.player.Player;
import com.openrsc.server.model.world.region.RegionManager;
import java.util.Collection;
......@@ -19,19 +18,19 @@ public class ViewArea {
}
public Collection<GameObject> getGameObjectsInView() {
return RegionManager.getLocalObjects(mob);
return mob.getWorld().getRegionManager().getLocalObjects(mob);
}
public Collection<GroundItem> getItemsInView() {
return RegionManager.getLocalGroundItems(mob);
return mob.getWorld().getRegionManager().getLocalGroundItems(mob);
}
public Collection<Npc> getNpcsInView() {
return RegionManager.getLocalNpcs(mob);
return mob.getWorld().getRegionManager().getLocalNpcs(mob);
}
public Collection<Player> getPlayersInView() {
return RegionManager.getLocalPlayers(mob);
return mob.getWorld().getRegionManager().getLocalPlayers(mob);
}
public GameObject getGameObject(Point location) {
......
......@@ -6,7 +6,6 @@ import com.openrsc.server.model.entity.npc.Npc;
import com.openrsc.server.model.entity.player.Player;
import com.openrsc.server.model.world.World;
import com.openrsc.server.model.world.region.Region;
import com.openrsc.server.model.world.region.RegionManager;
import com.openrsc.server.model.world.region.TileValue;
import com.openrsc.server.util.rsc.CollisionFlag;
......@@ -186,7 +185,7 @@ public class WalkingQueue {
}
private boolean isMobBlocking(int x, int y) {
Region region = RegionManager.getRegion(Point.location(x, y));
Region region = mob.getWorld().getRegionManager().getRegion(Point.location(x, y));
if (mob.getX() == x && mob.getY() == y)
return false;
......
......@@ -4,7 +4,6 @@ import com.openrsc.server.model.Point;
import com.openrsc.server.model.entity.player.Player;
import com.openrsc.server.model.world.World;
import com.openrsc.server.model.world.region.Region;
import com.openrsc.server.model.world.region.RegionManager;
import java.util.ArrayList;
import java.util.HashMap;
......@@ -152,7 +151,7 @@ public abstract class Entity {
}
public void updateRegion() {
Region newRegion = RegionManager.getRegion(getLocation());
Region newRegion = getWorld().getRegionManager().getRegion(getLocation());
if (!newRegion.equals(getRegion())) {
if (getRegion() != null) {
region.get().removeEntity(this);
......
......@@ -73,7 +73,7 @@ public final class World implements SimpleSubscriber<FishingTrawler> {
public static boolean WORLD_TELEGRAB_TOGGLE = false;
private static World worldInstance;
//private final RegionManager regionManager;
private final RegionManager regionManager;
private final EntityList<Npc> npcs;
private final EntityList<Player> players;
private final List<QuestInterface> quests;
......@@ -111,6 +111,7 @@ public final class World implements SimpleSubscriber<FishingTrawler> {
tiles = new TileValue[MAX_WIDTH][MAX_HEIGHT];
snapshots = new LinkedList<Snapshot>();
worldLoader = new WorldLoader(this);
regionManager = new RegionManager(this);
}
public static synchronized World getWorld() {
......@@ -415,8 +416,8 @@ public final class World implements SimpleSubscriber<FishingTrawler> {
public void registerGameObject(GameObject o) {
Point objectCoordinates = Point.location(o.getLoc().getX(), o.getLoc().getY());
GameObject collidingGameObject = RegionManager.getRegion(objectCoordinates).getGameObject(objectCoordinates);
GameObject collidingWallObject = RegionManager.getRegion(objectCoordinates).getWallGameObject(objectCoordinates, o.getLoc().getDirection());
GameObject collidingGameObject = getRegionManager().getRegion(objectCoordinates).getGameObject(objectCoordinates);
GameObject collidingWallObject = getRegionManager().getRegion(objectCoordinates).getWallGameObject(objectCoordinates, o.getLoc().getDirection());
if (collidingGameObject != null && o.getType() == 0) {
unregisterGameObject(collidingGameObject);
}
......@@ -938,4 +939,8 @@ public final class World implements SimpleSubscriber<FishingTrawler> {
public static IPTracker<String> getWildernessIPTracker() {
return wildernessIPTracker;
}
public RegionManager getRegionManager() {
return regionManager;
}
}
package com.openrsc.server.model.world.region;
import com.openrsc.server.Server;
import com.openrsc.server.constants.Constants;
import com.openrsc.server.model.Point;
import com.openrsc.server.model.entity.Entity;
import com.openrsc.server.model.entity.GameObject;
......@@ -16,15 +17,18 @@ import java.util.LinkedHashSet;
public class RegionManager {
public static final int REGION_SIZE = 48;
private static final int HORIZONTAL_PLANES = (World.MAX_WIDTH / Constants.REGION_SIZE) + 1;
private static final int HORIZONTAL_PLANES = (World.MAX_WIDTH / REGION_SIZE) + 1;
private static final int VERTICAL_PLANES = (World.MAX_HEIGHT / Constants.REGION_SIZE) + 1;
private static final int VERTICAL_PLANES = (World.MAX_HEIGHT / REGION_SIZE) + 1;
private final Region[][] regions;
private static final Region[][] regions = new Region[HORIZONTAL_PLANES][VERTICAL_PLANES];
private final World world;
public RegionManager(World world) {
this.world = world;
regions = new Region[HORIZONTAL_PLANES][VERTICAL_PLANES];
static {
for (int x = 0; x < HORIZONTAL_PLANES; x++) {
for (int y = 0; y < VERTICAL_PLANES; y++) {
regions[x][y] = new Region();
......@@ -38,7 +42,7 @@ public class RegionManager {
* @param entity The entity.
* @return The collection of local players.
*/
public static Collection<Player> getLocalPlayers(final Entity entity) {
public Collection<Player> getLocalPlayers(final Entity entity) {
LinkedHashSet<Player> localPlayers = new LinkedHashSet<Player>();
for (Region region : getSurroundingRegions(entity.getLocation())) {
for (Player player : region.getPlayers()) {
......@@ -56,7 +60,7 @@ public class RegionManager {
* @param entity The entity.
* @return The collection of local NPCs.
*/
public static Collection<Npc> getLocalNpcs(Entity entity) {
public Collection<Npc> getLocalNpcs(Entity entity) {
LinkedHashSet<Npc> localNpcs = new LinkedHashSet<Npc>();
for (Region region : getSurroundingRegions(entity.getLocation())) {
for (Npc npc : region.getNpcs()) {
......@@ -68,7 +72,7 @@ public class RegionManager {
return localNpcs;
}
public static Collection<GameObject> getLocalObjects(Mob entity) {
public Collection<GameObject> getLocalObjects(Mob entity) {
LinkedHashSet<GameObject> localObjects = new LinkedHashSet<GameObject>();
for (Iterator<Region> region = getSurroundingRegions(entity.getLocation()).iterator(); region.hasNext(); ) {
for (Iterator<GameObject> o = region.next().getGameObjects().iterator(); o.hasNext(); ) {
......@@ -82,7 +86,7 @@ public class RegionManager {
return localObjects;
}
public static Collection<GroundItem> getLocalGroundItems(Mob entity) {
public Collection<GroundItem> getLocalGroundItems(Mob entity) {
LinkedHashSet<GroundItem> localItems = new LinkedHashSet<GroundItem>();
for (Region region : getSurroundingRegions(entity.getLocation())) {
for (GroundItem o : region.getGroundItems()) {
......@@ -100,9 +104,9 @@ public class RegionManager {
* @param location The location.
* @return The regions surrounding the location.
*/
public static LinkedHashSet<Region> getSurroundingRegions(Point location) {
int regionX = location.getX() / REGION_SIZE;
int regionY = location.getY() / REGION_SIZE;
public LinkedHashSet<Region> getSurroundingRegions(Point location) {
int regionX = location.getX() / Constants.REGION_SIZE;
int regionY = location.getY() / Constants.REGION_SIZE;
LinkedHashSet<Region> surrounding = new LinkedHashSet<Region>();
surrounding.add(regions[regionX][regionY]);
......@@ -117,21 +121,21 @@ public class RegionManager {
return surrounding;
}
private static Region getRegionFromSectorCoordinates(int regionX, int regionY) {
private Region getRegionFromSectorCoordinates(int regionX, int regionY) {
if (regionX < 0 || regionY < 0 || regionX >= regions.length || regionY >= regions[regionX].length) {
return null;
}
return regions[regionX][regionY];
}
public static Region getRegion(int x, int y) {
int regionX = x / REGION_SIZE;
int regionY = y / REGION_SIZE;
public Region getRegion(int x, int y) {
int regionX = x / Constants.REGION_SIZE;
int regionY = y / Constants.REGION_SIZE;
return regions[regionX][regionY];
}
public static Region getRegion(Point objectCoordinates) {
public Region getRegion(Point objectCoordinates) {
return getRegion(objectCoordinates.getX(), objectCoordinates.getY());
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment