/*
* This file is part of aion-unique <aion-unique.org>.
*
* aion-unique is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* aion-unique is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with aion-unique. If not, see <http://www.gnu.org/licenses/>.
*/
package com.aionemu.gameserver.model.templates.spawn;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlTransient;
import javax.xml.bind.annotation.XmlType;
import com.aionemu.commons.utils.Rnd;
import com.aionemu.gameserver.model.gameobjects.VisibleObject;
import com.aionemu.gameserver.spawnengine.SpawnHandlerType;
/**
* @author ATracer
*
*/
@XmlAccessorType(XmlAccessType.FIELD)
@XmlType(name = "spawn")
public class SpawnGroup
{
/**
* XML attributes
* Order should be reversed to XML attributes order
*/
@XmlAttribute(name = "time")
private SpawnTime spawnTime;
@XmlAttribute(name = "anchor")
private String anchor;
@XmlAttribute(name = "handler")
private SpawnHandlerType handler;
@XmlAttribute(name = "interval")
private int interval;
@XmlAttribute(name = "pool")
private int pool;
@XmlAttribute(name = "npcid")
private int npcid;
@XmlAttribute(name = "map")
private int mapid;
@XmlElement(name = "object")
private List<SpawnTemplate> objects;
/**
* Real-time properties
*/
@XmlTransient
private Map<Integer, Integer> lastSpawnedTemplate = new HashMap<Integer, Integer>();
/**
* Constructor used by unmarshaller
*/
public SpawnGroup()
{
}
/**
* Constructor used to create new spawns not defined in xml
*
* @param mapid
* @param npcid
* @param interval
* @param pool
*/
public SpawnGroup(int mapid, int npcid, int interval, int pool)
{
super();
this.mapid = mapid;
this.npcid = npcid;
this.interval = interval;
this.pool = pool;
}
/**
* @return the mapid
*/
public int getMapid()
{
return mapid;
}
/**
* @return the npcid
*/
public int getNpcid()
{
return npcid;
}
/**
* @return the interval
*/
public int getInterval()
{
return interval;
}
/**
* @return the pool
*/
public int getPool()
{
return pool;
}
/**
* @return the objects
*/
public List<SpawnTemplate> getObjects()
{
if(this.objects == null)
this.objects = new ArrayList<SpawnTemplate>();
return this.objects;
}
/**
* @return the handler
*/
public SpawnHandlerType getHandler()
{
return handler;
}
/**
* @return the anchor
*/
public String getAnchor()
{
return anchor;
}
/**
* @return the dayTime
*/
public SpawnTime getSpawnTime()
{
return spawnTime;
}
/**
* Returns next template to spawn
*
* @param instance
* @return SpawnTemplate
*/
public SpawnTemplate getNextAvailableTemplate(int instance)
{
for(int i = 0; i < getObjects().size(); i++)
{
Integer lastSpawnCounter = lastSpawnedTemplate.get(instance);
int nextSpawnCounter = lastSpawnCounter == null ? 0 : lastSpawnCounter + 1;
if(nextSpawnCounter >= objects.size())
nextSpawnCounter = 0;
SpawnTemplate nextSpawn = objects.get(nextSpawnCounter);
if(nextSpawn.isSpawned(instance))
continue;
lastSpawnedTemplate.put(instance, nextSpawnCounter);
return nextSpawn;
}
return null;
}
public int size()
{
return getObjects().size();
}
/**
*
*/
public SpawnTemplate getNextRandomTemplate()
{
return objects.get(Rnd.get(0, size() - 1));
}
/**
* Last spawn counter will be reseted during instance respawn
*
* @param instanceIndex
*/
public void resetLastSpawnCounter(int instanceIndex)
{
if(lastSpawnedTemplate.containsKey(instanceIndex))
lastSpawnedTemplate.remove(instanceIndex);
}
/**
* Check whether pool size is equal to number of defined objects
* For such pools no exchange template should be done
*
* @return
*/
public boolean isFullPool()
{
return pool == objects.size();
}
/**
* @param visibleObject
*/
public synchronized void exchangeSpawn(VisibleObject visibleObject)
{
if(isFullPool())
return;
int instanceId = visibleObject.getInstanceId();
SpawnTemplate nextSpawn = getNextAvailableTemplate(instanceId);
if(nextSpawn != null)
visibleObject.setSpawn(nextSpawn);
}
}