Changeset 1514
Author: ATracer
(2010/03/14 12:30) Almost 2 years ago
Instances refactoring. Players should be able to rejoin group instance. Relog should place player in the same instance or move to instance's entry point (same for ascension quest). Added Fire Temple instance support (Morheim entry only)
# Saving of player data for one player could upto 1sec# With 500 player online saving can be upto 10 seconds# with 500 player online it can be upto 10 minutes# (it depends on hardware, changes in item locations, new acquisitions etc)# (it depends on changes in item locations, new acquisitions etc)WorldMapInstance newInstance = player.getPosition().getWorld().getNextAvailableInstance(310010000);WorldMapInstance newInstance = instanceService.getNextAvailableInstance(310010000, 60 * 20);newInstance.setDestroyTime(60 * 20);instanceService.registerPlayerWithInstance(newInstance, player);{{int instanceId = player.getInstanceId();if(player.getWorldId() != 310010000)WorldMap worldMap = world.getWorldMap(310010000);int id = -1;if (worldMap != null)id = worldMap.getWorldMapScriptInstanceIdByPlyerObjId(player.getObjectId());if(id == -1 || player.getWorldId() != 310010000){{teleportService.teleportTo(player, 210010000, 1, 244f, 1639f, 100.5f, 1000);else if(id != instanceId)teleportService.changeChannel(player, id-1);{{WorldMapInstance newInstance = player.getPosition().getWorld().getNextAvailableInstance(320010000);WorldMapInstance newInstance = instanceService.getNextAvailableInstance(320010000, 60 * 20);newInstance.setDestroyTime(60 * 20); // 20 mininstanceService.registerPlayerWithInstance(newInstance, player);{{int instanceId = player.getInstanceId();{{{{WorldMap worldMap = world.getWorldMap(320010000);if(player.getWorldId() != 320010000)int id = -1;if (worldMap != null)id = worldMap.getWorldMapScriptInstanceIdByPlyerObjId(player.getObjectId());if(id == -1 || player.getWorldId() != 320010000){{teleportService.teleportTo(player, 220010000, 1, 378.9f, 1895.39f, 330.0f, 1000);else if(id != instanceId)teleportService.changeChannel(player, id-1);{{WorldMapInstance newInstance = player.getPosition().getWorld().getNextAvailableInstance(310010000);WorldMapInstance newInstance = instanceService.getNextAvailableInstance(310010000, 60 * 5);newInstance.setDestroyTime(60 * 5);<portal_templates><?xml version="1.0" encoding="UTF-8"?><portal npcid="700414" mapid="300030000" x="600" y="700" z="327.165" instance="true" minlevel="25" maxlevel="28" group="true"/><portal_templates xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:noNamespaceSchemaLocation="portal_template.xsd"><!-- Nochsana Training Camp --><portal npcid="700414" instance="true" minlevel="25" maxlevel="28" group="true" race="ASMODIANS"><entrypoint mapid="400010000" x="876.7211" y="3079.2874" z="1644.5786"/><exitpoint mapid="300030000" x="600" y="700" z="327.165"/></portal><!-- Fire Temple --><portal npcid="730047" instance="true" minlevel="25" maxlevel="50" group="true"><entrypoint mapid="220020000" x="1592.178" y="977.2572" z="140.75"/><exitpoint mapid="320100000" x="148.256" y="460.857" z="141.713"/></portal><!-- Pernos [Ascension quest]--><portal npcid="790001" instance="true"><entrypoint mapid="210010000" x="241.094" y="1639.461" z="100.38"/><exitpoint mapid="310010000" x="52" y="174" z="229"/></portal><!-- Munin [Ascension quest]--><portal npcid="203550" instance="true"><entrypoint mapid="220010000" x="378.9" y="1895.39" z="330.0"/><exitpoint mapid="310010000" x="52" y="174" z="229"/></portal><xs:attribute name="instance" type="xs:boolean" /><xs:attribute name="npcid" type="xs:int" /></xs:complexType><xs:complexType name="EntryPoint"><xs:attribute name="mapid" type="xs:int" /><xs:attribute name="x" type="xs:float" /><xs:attribute name="y" type="xs:float" /><xs:attribute name="x" type="xs:float" /><xs:attribute name="z" type="xs:float" /><xs:attribute name="mapid" type="xs:int" /><xs:attribute name="npcid" type="xs:int" />*{{private PortalData portalData;private PortalData portalData;@Injectprivate PortalTemplate portalTemplate;private InstanceService instanceService;private PortalTemplate portalTemplate;{{public void onDialogRequest(final Player player){{if(portalTemplate.isInstance() && CustomConfig.ENABLE_INSTANCES)portGroup(player);elseport(player);}ThreadPoolManager.getInstance().schedule(new Runnable(){{{{{{{private void port(Player player)private void port(Player requester){{Collection<Player> players = Collections.singletonList(player);Collection<Player> players = Collections.singletonList(requester);transfer(player, players);WorldMapInstance instance = instanceService.getNextAvailableInstance(portalTemplate.getExitPoint().getMapId());instanceService.registerPlayerWithInstance(instance, requester);transfer(requester, instance);private void portGroup(Player player)private void portGroup(Player requester){{PlayerGroup group = player.getPlayerGroup();PlayerGroup group = requester.getPlayerGroup();if(group == null || group.getGroupLeader().getObjectId() != player.getObjectId())if(group == null || group.getGroupLeader().getObjectId() != requester.getObjectId()){PacketSendUtility.sendMessage(requester, "You are not group leader");}transfer(player, players);WorldMapInstance instance = instanceService.getNextAvailableInstance(portalTemplate.getExitPoint().getMapId());instanceService.registerGroupWithInstance(instance, group);for(Player player : players){transfer(player, instance);}private void transfer(final Player leader, final Collection<Player> players)private void transfer(Player player, WorldMapInstance instance){{final int defaultUseTime = 3000;ExitPoint exitPoint = portalTemplate.getExitPoint();PacketSendUtility.sendPacket(leader, new SM_USE_OBJECT(leader.getObjectId(),sp.getTeleportService().teleportTo(player, exitPoint.getMapId(), instance.getInstanceId(),getOwner().getObjectId(), defaultUseTime, 1));exitPoint.getX(), exitPoint.getY(), exitPoint.getZ(), 0);PacketSendUtility.broadcastPacket(leader, new SM_EMOTION(leader, 37, 0, getOwner().getObjectId()), true);ThreadPoolManager.getInstance().schedule(new Runnable(){@Overridepublic void run(){PacketSendUtility.sendPacket(leader, new SM_USE_OBJECT(leader.getObjectId(),getOwner().getObjectId(), defaultUseTime, 0));WorldMapInstance newInstance = sp.getWorld().getNextAvailableInstance(portalTemplate.getMapId());newInstance.setDestroyTime(60 * 30);for(Player player : players){sp.getTeleportService().teleportTo(player, portalTemplate.getMapId(), newInstance.getInstanceId(),portalTemplate.getX(), portalTemplate.getY(), portalTemplate.getZ(), 0);}}}, defaultUseTime);{{{{{{{{public PortalTemplate getPortalTemplate(int id)/**** @param npcId* @return*/public PortalTemplate getPortalTemplate(int npcId){{return portalData.get(id);return portalData.get(npcId);{{{{{* {@inheritDoc}* {@inheritDoc}{{{{{@XmlAttribute(name = "mapid")protected int mapId;@XmlAttribute(name = "x")protected float x;@XmlAttribute(name = "y")protected float y;@XmlAttribute(name = "z")protected float z;@XmlAttribute(name = "item_id")@XmlAttribute(name = "group")* @return the mapId*/public int getMapId(){return mapId;}/*** @return the x*/public float getX(){return x;}/*** @return the y*/public float getY(){return y;}/*** @return the z*/public float getZ(){return z;}/**{{{{{{{player.getController().startProtectionActiveTask();client.sendPacket(new SM_CHANNEL_INFO(player.getPosition())); // ?? unknwonplayerService.playerLoggedIn(player);client.sendPacket(new SM_CHANNEL_INFO(player.getPosition()));playerService.playerLoggedIn(player);private PlayerControllerFactory controllerFactory;DuelService duelService, PlayerStatsData playerStatsData, PlayerInitialData playerInitialData)DuelService duelService, PlayerStatsData playerStatsData, PlayerInitialData playerInitialData,InstanceService instanceService){{{{//analyze current instanceinstanceService.onPlayerLogin(player);{{if(player.getInstanceId() != instanceId || player.getWorldId() != worldId){world.getWorldMap(player.getWorldId()).getWorldMapInstanceById(player.getInstanceId()).removePlayer(player.getObjectId());world.getWorldMap(worldId).getWorldMapInstanceById(instanceId).addPlayer(player.getObjectId());}{{if(player.getInstanceId() != 1 || player.getWorldId() != worldId)world.setPosition(player, worldId, 1, x, y, z, player.getHeading());{world.getWorldMap(player.getWorldId()).getWorldMapInstanceById(player.getInstanceId()).removePlayer(player.getObjectId());world.getWorldMap(worldId).getWorldMapInstanceById(1).addPlayer(player.getObjectId());}world.setPosition(player, worldId, x, y, z, player.getHeading());{{parent.onEnter(object);{{parent.onLeave(object);import com.aionemu.gameserver.spawnengine.SpawnEngine;@Injectprivate SpawnEngine spawnEngine;* @return the spawnEngine*/public SpawnEngine getSpawnEngine(){return spawnEngine;}/**throw new WorldMapNotExistException("Map: " + id + " not exist!");throw new WorldMapNotExistException("Map: " + id + " not exist!");/**** @param worldId* @return WorldMapInstance*/public WorldMapInstance getNextAvailableInstance(int worldId){WorldMap map = worldMaps.get(worldId);return map.getNextFreeInstance();}public void destroyInstance(int worldId, int instanceId){WorldMap map = worldMaps.get(worldId);map.removeWorldMapInstance(instanceId);}{{/*** dummy method to initialize World.*/public static void init(){}import org.apache.log4j.Logger;{{private static Logger log = Logger.getLogger(WorldMap.class);/*** Will create new instance if there are not free yet and spawn according to xml data* //TODO limit* @return WorldMapInstance*/public synchronized WorldMapInstance getNextFreeInstance(){if (!worldMapTemplate.isInstance()){for(WorldMapInstance instance : instances.values()){if(!instance.isInUse())return instance;}}log.info("Creating new instance: " + worldMapTemplate.getMapId() + " " + nextInstanceId );if (worldMapTemplate.isInstance())addInstance(nextInstanceId, new WorldMapScriptInstance(this, nextInstanceId));elseaddInstance(nextInstanceId, new WorldMapInstance(this, nextInstanceId));world.getSpawnEngine().spawnInstance(worldMapTemplate.getMapId(), nextInstanceId-1);return instances.get(nextInstanceId-1);}**{{/**//TODO Balance players into instances.* twin map - balance playersreturn getWorldMapInstance(1);*/if(worldMapTemplate.getTwinCount() != 0){/*** Balance players into instances.*/int i = 1;while(i <= worldMapTemplate.getTwinCount()){WorldMapInstance inst = getWorldMapInstance(i);i++;// TODO! user count etc..return inst;}// TODO! whats now?return getWorldMapInstance(worldMapTemplate.getTwinCount());}elsereturn getWorldMapInstance(1);* @return WorldMapInstance/public WorldMapInstance removeWorldMapInstance(int instanceId)public void removeWorldMapInstance(int instanceId){{WorldMapInstance instance = instances.get(instanceId);instances.remove(instanceId);if (instance != null){instance.destroyInstance();return instances.remove(instanceId);}return null;public int getWorldMapScriptInstanceIdByPlyerObjId(int objId)/*** Add instance to map and increases pointer to nextInstanceId** @param instanceId* @param instance*/public void addInstance(int instanceId, WorldMapInstance instance){{for (WorldMapInstance instance : instances.values()){if (instance.isInInstance(objId))return instance.getInstanceId();}return -1;}private void addInstance(int instanceId, WorldMapInstance instance){{{{{{public static final int regionSize = 500;public static final int regionSize = 500;private static final int maxWorldSize = 10000;private static final int maxWorldSize = 10000;private final WorldMap parent;* List of active regions.* Map of active regions.private final Map<Integer, MapRegion> regions = new HashMap<Integer, MapRegion>();private final Map<Integer, MapRegion> regions = new HashMap<Integer, MapRegion>();* Current player count in this instance* All objects spawned in this world map instanceprivate int currentPlayerCount;private final Map<Integer, VisibleObject> worldMapObjects = new ConcurrentHashMap<Integer, VisibleObject>();private int instanceId;public WorldMapInstance(WorldMap parent, int instanceId){{{{* @return the currentPlayerCount* @param objectpublic int getCurrentPlayerCount()public void addObject(VisibleObject object){{return currentPlayerCount;if(worldMapObjects.put(object.getObjectId(), object) != null)throw new DuplicateAionObjectException();if(object instanceof Player)worldMapPlayers.put(object.getObjectId(), (Player) object);public void onEnter(VisibleObject object)/**** @param object*/public void removeObject(AionObject object){{if (object instanceof Player)worldMapObjects.remove(object.getObjectId());currentPlayerCount++;if(object instanceof Player)worldMapPlayers.remove(object.getObjectId());public void onLeave(VisibleObject object){if (object instanceof Player)currentPlayerCount--;}public boolean isInUse(){return currentPlayerCount > 0;}{{return false;return worldMapPlayers.containsKey(objId);public void setDestroyTime(int sec)/**{* @return the destroyTask*/public Future<?> getDestroyTask(){return destroyTask;public void destroyInstance()/*** @param destroyTask the destroyTask to set*/public void setDestroyTask(Future<?> destroyTask){{public void addPlayer(int objId)/*** @return*/public Iterator<VisibleObject> objectIterator(){{{{public void removePlayer(int objId)/*** @param objectId* @return*/public boolean isRegistered(int objectId){{