package fakes;
import fakes.dao.PhantomDAO;
import fakes.handlers.admincommand.AdminPhantom;
import fakes.holders.PhantomColorHolder;
import fakes.holders.PhantomPhrasesHolder;
import fakes.holders.PhantomsHolder;
import fakes.objects.PhantomPartyObject;
import fakes.parsers.ClassAIParser;
import fakes.parsers.PartyAIParser;
import fakes.parsers.PhantomSpawnParser;
import fakes.parsers.reworked.*;
import fakes.tasks.PhantomTask;
import fakes.utils.PhantomInitUtil;
import l2p.gameserver.Config;
import l2p.gameserver.ThreadPoolManager;
import l2p.gameserver.commons.util.Rnd;
import l2p.gameserver.handler.admincommands.AdminCommandHandler;
import l2p.gameserver.model.GameObjectsStorage;
import l2p.gameserver.model.Player;
import l2p.gameserver.model.party.Party;
import l2p.gameserver.model.pledge.Clan;
import l2p.gameserver.model.pledge.SubUnit;
import l2p.gameserver.model.pledge.UnitMember;
import l2p.gameserver.tables.ClanTable;
import l2p.gameserver.utils.Location;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.Iterator;
import java.util.concurrent.ConcurrentLinkedQueue;
public class PhantomsEngine
{
private static final Logger _log = LoggerFactory.getLogger(PhantomsEngine.class);
// список_заспавненных
private static ConcurrentLinkedQueue<Player> _fakes = new ConcurrentLinkedQueue<Player>();
// список заспавненных для групп (чтобы не повторялись ИД при поиске по профам)
private static ConcurrentLinkedQueue<Integer> _all_party_obj_id = new ConcurrentLinkedQueue<>();
private static PhantomsEngine _instance;
public static PhantomsEngine getInstance() {
return _instance;
}
public static void init() {
_instance = new PhantomsEngine();
_instance.load();
}
public void load()
{
AdminCommandHandler.getInstance().registerAdminCommandHandler(new AdminPhantom());
PhantomDAO.getInstance().loadClans(); // загружаем в память все ИД фантомовских кланов
if(Config.ALLOW_FAKE_PLAYERS_PLUS)
{
PhantomAccessoryParser.getInstance().allParse();
PhantomArmorParser.getInstance().allParse();
PhantomJewelParser.getInstance().allParse();
PhantomShieldParser.getInstance().allParse();
PhantomUnderwearParser.getInstance().allParse();
PhantomBuffParser.getInstance().allParse();
PhantomColorHolder.load();
PhantomPhrasesHolder.load();
ClassAIParser.getInstance().allParse();
PhantomSpawnParser.getInstance().allParse();
PhantomsHolder.load();
PartyAIParser.getInstance().allParse();
if(PhantomsHolder.isFakesReady()) // если есть боты, то запускаем первую волну спавна
ThreadPoolManager.getInstance().schedule(new PhantomTask(), Config.FAKE_PLAYERS_DELAY_BEFORE_FIRST_WAVE_SPAWN);
restoreFakeParties(); // спаун партийных ботов
}
}
public void restoreFakeParties()
{
Player phantom;
int count_p = 0;
try
{
_log.info("Party spawn: 0");
for(PhantomPartyObject party : PartyAIParser.getInstance().getAllParties())
{
_log.info("Party spawn: 1");
if(!party.isSpawnEnabled()) // если спавн выключен
continue;
_log.info("Party spawn: 2");
for(int i = 0; i < party.getObjIds().length; i++)
{ _log.info("Party spawn: 2.1");
int obj_id = party.getObjIds();
if(obj_id == 0) // если пати не полная
continue;
_log.info("Party spawn: 2.2");
String ai_type = PhantomInitUtil.getAIbyClassId(party.getClassList());
_log.info("Party spawn: 2.3");
// Если фантом заспавнен, то деспавним его.
if(PhantomsEngine.getInstance().isPhantomAlreadySpawned(obj_id))
{
phantom = GameObjectsStorage.get(obj_id).getPlayer();
phantom.phantom_params.getPhantomAI().abortAITask();
despawnPhantom(phantom);
phantom.setOnlineStatus(false);
phantom.kick();
}
_log.info("Party spawn: 2.4");
// Создаем фантома заного
phantom = PhantomInitUtil.restoreFake(obj_id, ai_type);
_log.info("Party spawn: 2.5");
if(phantom == null)
continue;
Location loc = party.getAnySpawnLocation();
phantom.setXYZ(loc.x + (Rnd.chance(50) ? 1 : -1) * Rnd.get(Config.FAKE_SPAWN_COLLISION_X), loc.y + (Rnd.chance(50) ? 1 : -1) * Rnd.get(Config.FAKE_SPAWN_COLLISION_Y), loc.z);
_log.info("Party spawn: 2.6");
if(party.getPartyLeader() == null)
{
party.setPartyLeader(phantom);
party.getPartyLeader().setParty(new Party(party.getPartyLeader(), 1));
}
_log.info("Party spawn: 2.7");
phantom.phantom_params.setPhantomPartyAI(party); // добавляем фейку аи группы
party.addPartyMember(phantom);
phantom.setHandicapAttack(party.getHandicapAttack());
phantom.setHandicapDefence(party.getHandicapDefence());
}
_log.info("Party spawn: 3");
// Ресторим сначало их клан
Clan clan = ClanTable.getInstance().getClan(party.getClanId());
_log.info("Party spawn: 4");
// заключаем их всех в пати
for(Player member : party.getAllMembers())
{
if(member != party.getPartyLeader())
party.getPartyLeader().getParty().addPartyMember(member);
// даем всем клан
if(party.getClanId() != -1 && clan != null)
{
SubUnit subUnit = clan.getSubUnit(0);
if(subUnit == null)
return;
UnitMember u_member = new UnitMember(clan, member.getName(), member.getTitle(), member.getLevel(), member.getClassId().getId(), member.getObjectId(), 0, member.getPowerGrade(), member.getApprentice(), member.getSex(), Clan.SUBUNIT_NONE);
subUnit.addUnitMember(u_member);
member.setPledgeType(0);
member.setClan(clan);
member.setPowerGrade(6);
member.setLvlJoinedAcademy(0);
member.setApprentice(0);
PhantomDAO.getInstance().setClanToPhantom(member.getObjectId());
if(party.getClanId() != 0)
member.setClan(ClanTable.getInstance().getClan(party.getClanId()));
}
member.phantom_params.getPhantomAI().startAITask(500);
}
_log.info("Party spawn: 5");
// делаем спаун пати
party.spawnPartyBattle();
party.changePartyState(1);
party.startAITask(5000);
count_p++;
}
}
catch (Exception e) {
e.printStackTrace();
}
_log.info("PhantomsEngine: spawned " + count_p + " parties.");
}
public boolean isPhantomAlreadySpawned(int obj_id) {
return _fakes.contains(obj_id);
}
public void addPhantom(Player phantom) {
_fakes.add(phantom);
}
public void despawnPhantom(Player phantom) {
_fakes.remove(phantom);
}
public Player getPhantom(int objId)
{
for(Player p : _fakes)
if(p.getObjectId() == objId)
return p;
return null;
}
public void despawnPhantom(int id)
{
Iterator iter = _fakes.iterator();
while(iter.hasNext())
{
Player p = (Player)iter.next();
if(p.getObjectId() == id)
{
iter.remove();
break;
}
}
}
public ConcurrentLinkedQueue<Integer> getAllPartyObjID() {
return _all_party_obj_id;
}
}