package handling.world;
import client.MapleBuffStat;
import client.MapleCharacter;
import client.MapleCoolDownValueHolder;
import client.MapleDiseaseValueHolder;
import client.inventory.MapleInventoryType;
import client.inventory.MaplePet;
import client.inventory.PetDataFactory;
import client.status.MonsterStatusEffect;
import handling.channel.ChannelServer;
import java.util.ArrayList;
import java.util.List;
import server.Timer.WorldTimer;
import server.life.MapleMonster;
import server.maps.MapleMap;
import server.maps.MapleMapItem;
import tools.MaplePacketCreator;
import tools.packet.PetPacket;
public class WorldRespawnService {
private static final int CHANNELS_PER_THREAD = 3;
public static WorldRespawnService getInstance() {
return SingletonHolder.instance;
}
private WorldRespawnService() {
Integer[] chs = (Integer[]) ChannelServer.getAllInstance().toArray(new Integer[0]);
for (int i = 0; i < chs.length; i += 3) {
WorldTimer.getInstance().register(new Respawn(chs, i), 4000);
}
}
public static void handleMap(MapleMap map, int numTimes, int size, long now) {
if (map.getItemsSize() > 0) {
for (MapleMapItem item : map.getAllItemsThreadsafe()) {
if (item.shouldExpire(now)) {
item.expire(map);
} else if (item.shouldFFA(now)) {
item.setDropType((byte) 2);
}
}
}
if (map.getCharactersSize() > 0 || map.getId() == 931000500) {
if (map.canSpawn(now)) {
map.respawn(false, now);
}
boolean hurt = map.canHurt(now);
boolean canrune = true;
for (MapleCharacter chr : map.getCharactersThreadsafe()) {
handleCooldowns(chr, numTimes, hurt, now);
}
if (map.getMobsSize() > 0) {
for (MapleMonster mons : map.getAllMonstersThreadsafe()) {
if (mons.getStats().isBoss()) {
canrune = false;
}
if ((mons.isAlive()) && (mons.shouldKill(now))) {
map.killMonster(mons);
} else if ((mons.isAlive()) && (mons.shouldDrop(now))) {
mons.doDropItem(now);
} else if ((mons.isAlive()) && (mons.getStatiSize() > 0)) {
for (MonsterStatusEffect mse : mons.getAllBuffs()) {
if (mse.shouldCancel(now)) {
mons.cancelSingleStatus(mse);
}
}
}
}
}
}
}
/**
* 可以创建定时技能
*
* @param chr
* @param numTimes
* @param hurt
* @param now
*/
public static void handleCooldowns(MapleCharacter chr, int numTimes, boolean hurt, long now) {
if (chr == null) {
return;
}
if (chr.getCooldownSize() > 0) {
for (MapleCoolDownValueHolder m : chr.getCooldowns()) {
if (m.startTime + m.length < now) {
int skillId = m.skillId;
chr.removeCooldown(skillId);
chr.getClient().getSession().write(MaplePacketCreator.skillCooldown(skillId, 0));
}
}
}
if (chr.isAlive()) {
if (((chr.getJob() == 131) || (chr.getJob() == 132)) && (chr.canBlood(now))) {
chr.doDragonBlood();
}
if (chr.canRecover(now)) {
chr.doRecovery();
}
if (chr.canHPRecover(now)) {
chr.addHP((int) chr.getStat().getHealHP());
}
if (chr.canMPRecover(now)) {
chr.addMP((int) chr.getStat().getHealMP());
if ((chr.getJob() == 3111) || (chr.getJob() == 3112)) {
chr.addDemonMp((int) chr.getStat().getHealMP());
}
}
if (chr.canFairy(now)) {
chr.doFairy();
}
if (chr.canDOT(now)) {
chr.doDOT();
}
if (chr.canExpiration(now)) {
chr.expirationTask();
}
}
if (chr.getDiseaseSize() > 0) {
for (MapleDiseaseValueHolder m : chr.getAllDiseases()) {
if ((m != null) && (m.startTime + m.length < now)) {
chr.dispelDebuff(m.disease);
}
}
}
if ((numTimes % 7 == 0) && (chr.getMount() != null) && (chr.getMount().canTire(now))) {
chr.getMount().increaseFatigue();
}
if (numTimes % 13 == 0) {
chr.doFamiliarSchedule(now);
for (MaplePet pet : chr.getSummonedPets()) {
if ((pet.getPetItemId() == 5000054) && (pet.getSecondsLeft() > 0)) {
pet.setSecondsLeft(pet.getSecondsLeft() - 1);
if (pet.getSecondsLeft() <= 0) {
chr.unequipSpawnPet(pet, true, true);
return;
}
}
int newFullness = pet.getFullness() - PetDataFactory.getHunger(pet.getPetItemId());
if (newFullness <= 5) {
pet.setFullness(15);
chr.unequipSpawnPet(pet, true, true);
} else {
pet.setFullness(newFullness);
chr.getClient().getSession().write(PetPacket.updatePet(pet, chr.getInventory(MapleInventoryType.CASH).getItem(pet.getInventoryPosition()), false));
}
}
}
if ((hurt) && (chr.isAlive())) {
if (chr.getInventory(MapleInventoryType.EQUIPPED).findById(chr.getMap().getHPDecProtect()) == null) {
// 雪域自动扣血
if (chr.getMapId() >= 211000000 && chr.getMapId()<=211999999) {
if (chr.getBuffedValue(MapleBuffStat.HP减少无效) == null) {
chr.addHP(-(chr.getMap().getHPDec()));
}
} else {
chr.addHP(-(chr.getMap().getHPDec()));
}
}
}
}
private static class SingletonHolder {
protected static final WorldRespawnService instance = new WorldRespawnService();
}
private static class Respawn implements Runnable {
private int numTimes = 0;
private final List<ChannelServer> cservs = new ArrayList(3);
public Respawn(Integer[] chs, int c) {
// StringBuilder s = new StringBuilder("[Respawn Worker] Registered for channels ");
for (int i = 1; (i <= CHANNELS_PER_THREAD) && (chs.length >= c + i); i++) {
this.cservs.add(ChannelServer.getInstance(c + i));
// s.append(c + i).append(" ");
}
// FileoutputUtil.log(s.toString());
}
@Override
public void run() {
numTimes++;
long now = System.currentTimeMillis();
for (ChannelServer cserv : this.cservs) {
if (!cserv.hasFinishedShutdown()) {
for (MapleMap map : cserv.getMapFactory().getAllLoadedMaps()) {
WorldRespawnService.handleMap(map, numTimes, map.getCharactersSize(), now);
}
}
}
}
}
}