This commit is contained in:
111
trunk/dist/game/data/scripts/ai/fantasy_isle/HandysBlockCheckerEvent.java
vendored
Normal file
111
trunk/dist/game/data/scripts/ai/fantasy_isle/HandysBlockCheckerEvent.java
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.fantasy_isle;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.instancemanager.HandysBlockCheckerManager;
|
||||
import com.l2jserver.gameserver.model.ArenaParticipantsHolder;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.quest.Quest;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExCubeGameChangeTimeToStart;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExCubeGameRequestReady;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExCubeGameTeamList;
|
||||
|
||||
/**
|
||||
* Handys Block Checker Event AI.
|
||||
* @authors BiggBoss, Gigiikun
|
||||
*/
|
||||
public class HandysBlockCheckerEvent extends Quest
|
||||
{
|
||||
// Arena Managers
|
||||
private static final int A_MANAGER_1 = 32521;
|
||||
private static final int A_MANAGER_2 = 32522;
|
||||
private static final int A_MANAGER_3 = 32523;
|
||||
private static final int A_MANAGER_4 = 32524;
|
||||
|
||||
public HandysBlockCheckerEvent()
|
||||
{
|
||||
super(-1, HandysBlockCheckerEvent.class.getSimpleName(), "Handy's Block Checker Event");
|
||||
addFirstTalkId(A_MANAGER_1, A_MANAGER_2, A_MANAGER_3, A_MANAGER_4);
|
||||
HandysBlockCheckerManager.getInstance().startUpParticipantsQueue();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if ((npc == null) || (player == null))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final int arena = npc.getId() - A_MANAGER_1;
|
||||
if (eventIsFull(arena))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.YOU_CANNOT_REGISTER_BECAUSE_CAPACITY_HAS_BEEN_EXCEEDED);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (HandysBlockCheckerManager.getInstance().arenaIsBeingUsed(arena))
|
||||
{
|
||||
player.sendPacket(SystemMessageId.THE_MATCH_IS_BEING_PREPARED_PLEASE_TRY_AGAIN_LATER);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (HandysBlockCheckerManager.getInstance().addPlayerToArena(player, arena))
|
||||
{
|
||||
ArenaParticipantsHolder holder = HandysBlockCheckerManager.getInstance().getHolder(arena);
|
||||
|
||||
final ExCubeGameTeamList tl = new ExCubeGameTeamList(holder.getRedPlayers(), holder.getBluePlayers(), arena);
|
||||
|
||||
player.sendPacket(tl);
|
||||
|
||||
int countBlue = holder.getBlueTeamSize();
|
||||
int countRed = holder.getRedTeamSize();
|
||||
int minMembers = Config.MIN_BLOCK_CHECKER_TEAM_MEMBERS;
|
||||
|
||||
if ((countBlue >= minMembers) && (countRed >= minMembers))
|
||||
{
|
||||
holder.updateEvent();
|
||||
holder.broadCastPacketToTeam(new ExCubeGameRequestReady());
|
||||
holder.broadCastPacketToTeam(new ExCubeGameChangeTimeToStart(10));
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean eventIsFull(int arena)
|
||||
{
|
||||
return HandysBlockCheckerManager.getInstance().getHolder(arena).getAllPlayers().size() == 12;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
if (Config.ENABLE_BLOCK_CHECKER_EVENT)
|
||||
{
|
||||
new HandysBlockCheckerEvent();
|
||||
_log.info("Handy's Block Checker Event is enabled");
|
||||
}
|
||||
else
|
||||
{
|
||||
_log.info("Handy's Block Checker Event is disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
517
trunk/dist/game/data/scripts/ai/fantasy_isle/MC_Show.java
vendored
Normal file
517
trunk/dist/game/data/scripts/ai/fantasy_isle/MC_Show.java
vendored
Normal file
@@ -0,0 +1,517 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.fantasy_isle;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Map;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.GameTimeController;
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
||||
|
||||
/**
|
||||
* MC Show AI.
|
||||
* @author Kerberos
|
||||
*/
|
||||
public class MC_Show extends AbstractNpcAI
|
||||
{
|
||||
private static int MC = 32433;
|
||||
// @formatter:off
|
||||
private static int[] SINGERS =
|
||||
{
|
||||
32431, 32432
|
||||
};
|
||||
private static int[] CIRCUS =
|
||||
{
|
||||
32442, 32443, 32444, 32445, 32446
|
||||
};
|
||||
private static int[] INDIVIDUALS =
|
||||
{
|
||||
32439, 32440, 32441
|
||||
};
|
||||
private static int[] SHOWSTUFF =
|
||||
{
|
||||
32424, 32425, 32426, 32427, 32428
|
||||
};
|
||||
// @formatter:on
|
||||
private static boolean IS_STARTED = false;
|
||||
private static NpcStringId[] MESSAGES =
|
||||
{
|
||||
NpcStringId.LADIES_AND_GENTLEMEN_THE_SHOW_IS_ABOUT_TO_BEGIN,
|
||||
NpcStringId.MAY_I_HAVE_YOUR_ATTENTION_PLEASE,
|
||||
NpcStringId.THANK_YOU_ALL_FOR_COMING_HERE_TONIGHT,
|
||||
NpcStringId.IT_IS_AN_HONOR_TO_HAVE_YOU_ALL_IN_ATTENDANCE_THIS_EVENING,
|
||||
NpcStringId.FANTASY_ISLE_TAKES_GREAT_PRIDE_IN_PROVIDING_THE_VERY_BEST_IN_ENTERTAINMENT,
|
||||
NpcStringId.NOW_I_D_LIKE_TO_INTRODUCE_THE_MOST_BEAUTIFUL_SINGER_IN_ADEN_PLEASE_WELCOME_LEYLA_MIRA,
|
||||
NpcStringId.PERFORMING_HER_LATEST_HIT,
|
||||
NpcStringId.THANK_YOU_VERY_MUCH_LEYLA,
|
||||
NpcStringId.NOW_WE_RE_IN_FOR_A_REAL_TREAT,
|
||||
NpcStringId.JUST_BACK_FROM_THEIR_WORLD_TOUR_PUT_YOUR_HANDS_TOGETHER_FOR_THE_FANTASY_ISLE_CIRCUS,
|
||||
NpcStringId.EVERYONE_GIVE_THEM_A_HAND,
|
||||
NpcStringId.IMPRESSIVE_NO_A_VERY_TALENTED_GROUP,
|
||||
NpcStringId.NOW_WE_HAVE_A_SPECIAL_REQUEST_FROM_SOME_FOLKS_WHO_WISH_TO_PERFORM,
|
||||
NpcStringId.LET_S_WELCOME_OUR_FIRST_VOLUNTEER,
|
||||
NpcStringId.AH,
|
||||
NpcStringId.MOVING_ON_LET_S_WELCOME_OUR_NEXT_VOLUNTEER,
|
||||
NpcStringId.I_M_SURE_THEY_HAVE_SOMETHING_MUCH_MORE_EXCITING,
|
||||
NpcStringId.REALLY,
|
||||
NpcStringId.THAT_WAS_JUST_SUPER_AND_NOW_FOR_OUR_LAST_VOLUNTEER,
|
||||
NpcStringId.SIGH_AND_THAT_S_OUR_SHOW_FOLKS,
|
||||
NpcStringId.I_HOPE_EVERYONE_ENJOYED_THE_SHOW,
|
||||
NpcStringId.PLEASE_REMEMBER_THAT_FANTASY_ISLE_IS_ALWAYS_PLANNING_A_LOT_OF_GREAT_SHOWS_FOR_YOU,
|
||||
NpcStringId.WELL_WE_WISH_WE_COULD_KEEP_THIS_PARTY_GOING_BUT_WE_MUST_TAKE_A_BREAK_THANK_YOU,
|
||||
NpcStringId.WE_LOVE_YOU_ALL
|
||||
};
|
||||
|
||||
private class ShoutInfo
|
||||
{
|
||||
private final NpcStringId _npcStringId;
|
||||
private final String _nextEvent;
|
||||
private final int _time;
|
||||
|
||||
public ShoutInfo(NpcStringId npcStringId, String nextEvent, int time)
|
||||
{
|
||||
_npcStringId = npcStringId;
|
||||
_nextEvent = nextEvent;
|
||||
_time = time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the _npcStringId
|
||||
*/
|
||||
public NpcStringId getNpcStringId()
|
||||
{
|
||||
return _npcStringId;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the _nextEvent
|
||||
*/
|
||||
public String getNextEvent()
|
||||
{
|
||||
return _nextEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the _time
|
||||
*/
|
||||
public int getTime()
|
||||
{
|
||||
return _time;
|
||||
}
|
||||
}
|
||||
|
||||
private class WalkInfo
|
||||
{
|
||||
private final Location _charPos;
|
||||
private final String _nextEvent;
|
||||
private final int _time;
|
||||
|
||||
public WalkInfo(Location charPos, String nextEvent, int time)
|
||||
{
|
||||
_charPos = charPos;
|
||||
_nextEvent = nextEvent;
|
||||
_time = time;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the _charPos
|
||||
*/
|
||||
public Location getCharPos()
|
||||
{
|
||||
return _charPos;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the _nextEvent
|
||||
*/
|
||||
public String getNextEvent()
|
||||
{
|
||||
return _nextEvent;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the _time
|
||||
*/
|
||||
public int getTime()
|
||||
{
|
||||
return _time;
|
||||
}
|
||||
}
|
||||
|
||||
private static Map<String, ShoutInfo> talks = new FastMap<>();
|
||||
private static Map<String, WalkInfo> walks = new FastMap<>();
|
||||
|
||||
private MC_Show()
|
||||
{
|
||||
super(MC_Show.class.getSimpleName(), "ai/fantasy_isle");
|
||||
addSpawnId(32433, 32431, 32432, 32442, 32443, 32444, 32445, 32446, 32424, 32425, 32426, 32427, 32428);
|
||||
load();
|
||||
scheduleTimer();
|
||||
}
|
||||
|
||||
private void load()
|
||||
{
|
||||
// TODO put this stuff in Routes.xml
|
||||
talks.put("1", new ShoutInfo(MESSAGES[1], "2", 1000));
|
||||
talks.put("2", new ShoutInfo(MESSAGES[2], "3", 6000));
|
||||
talks.put("3", new ShoutInfo(MESSAGES[3], "4", 4000));
|
||||
talks.put("4", new ShoutInfo(MESSAGES[4], "5", 5000));
|
||||
talks.put("5", new ShoutInfo(MESSAGES[5], "6", 3000));
|
||||
talks.put("8", new ShoutInfo(MESSAGES[9], "9", 5000));
|
||||
talks.put("9", new ShoutInfo(MESSAGES[10], "10", 5000));
|
||||
talks.put("12", new ShoutInfo(MESSAGES[12], "13", 5000));
|
||||
talks.put("13", new ShoutInfo(MESSAGES[13], "14", 5000));
|
||||
talks.put("15", new ShoutInfo(MESSAGES[14], "16", 5000));
|
||||
talks.put("16", new ShoutInfo(MESSAGES[15], "17", 5000));
|
||||
talks.put("18", new ShoutInfo(MESSAGES[17], "19", 5000));
|
||||
talks.put("19", new ShoutInfo(MESSAGES[18], "20", 5000));
|
||||
talks.put("21", new ShoutInfo(MESSAGES[19], "22", 5000));
|
||||
talks.put("22", new ShoutInfo(MESSAGES[20], "23", 400));
|
||||
talks.put("25", new ShoutInfo(MESSAGES[21], "26", 5000));
|
||||
talks.put("26", new ShoutInfo(MESSAGES[22], "27", 5400));
|
||||
|
||||
walks.put("npc1_1", new WalkInfo(new Location(-56546, -56384, -2008, 0), "npc1_2", 1200));
|
||||
walks.put("npc1_2", new WalkInfo(new Location(-56597, -56384, -2008, 0), "npc1_3", 1200));
|
||||
walks.put("npc1_3", new WalkInfo(new Location(-56596, -56428, -2008, 0), "npc1_4", 1200));
|
||||
walks.put("npc1_4", new WalkInfo(new Location(-56593, -56474, -2008, 0), "npc1_5", 1000));
|
||||
walks.put("npc1_5", new WalkInfo(new Location(-56542, -56474, -2008, 0), "npc1_6", 1000));
|
||||
walks.put("npc1_6", new WalkInfo(new Location(-56493, -56473, -2008, 0), "npc1_7", 2000));
|
||||
walks.put("npc1_7", new WalkInfo(new Location(-56495, -56425, -2008, 0), "npc1_1", 4000));
|
||||
walks.put("npc2_1", new WalkInfo(new Location(-56550, -56291, -2008, 0), "npc2_2", 1200));
|
||||
walks.put("npc2_2", new WalkInfo(new Location(-56601, -56293, -2008, 0), "npc2_3", 1200));
|
||||
walks.put("npc2_3", new WalkInfo(new Location(-56603, -56247, -2008, 0), "npc2_4", 1200));
|
||||
walks.put("npc2_4", new WalkInfo(new Location(-56605, -56203, -2008, 0), "npc2_5", 1000));
|
||||
walks.put("npc2_5", new WalkInfo(new Location(-56553, -56202, -2008, 0), "npc2_6", 1100));
|
||||
walks.put("npc2_6", new WalkInfo(new Location(-56504, -56200, -2008, 0), "npc2_7", 2000));
|
||||
walks.put("npc2_7", new WalkInfo(new Location(-56503, -56243, -2008, 0), "npc2_1", 4000));
|
||||
walks.put("npc3_1", new WalkInfo(new Location(-56500, -56290, -2008, 0), "npc3_2", 1200));
|
||||
walks.put("npc3_2", new WalkInfo(new Location(-56551, -56313, -2008, 0), "npc3_3", 1200));
|
||||
walks.put("npc3_3", new WalkInfo(new Location(-56601, -56293, -2008, 0), "npc3_4", 1200));
|
||||
walks.put("npc3_4", new WalkInfo(new Location(-56651, -56294, -2008, 0), "npc3_5", 1200));
|
||||
walks.put("npc3_5", new WalkInfo(new Location(-56653, -56250, -2008, 0), "npc3_6", 1200));
|
||||
walks.put("npc3_6", new WalkInfo(new Location(-56654, -56204, -2008, 0), "npc3_7", 1200));
|
||||
walks.put("npc3_7", new WalkInfo(new Location(-56605, -56203, -2008, 0), "npc3_8", 1200));
|
||||
walks.put("npc3_8", new WalkInfo(new Location(-56554, -56202, -2008, 0), "npc3_9", 1200));
|
||||
walks.put("npc3_9", new WalkInfo(new Location(-56503, -56200, -2008, 0), "npc3_10", 1200));
|
||||
walks.put("npc3_10", new WalkInfo(new Location(-56502, -56244, -2008, 0), "npc3_1", 900));
|
||||
walks.put("npc4_1", new WalkInfo(new Location(-56495, -56381, -2008, 0), "npc4_2", 1200));
|
||||
walks.put("npc4_2", new WalkInfo(new Location(-56548, -56383, -2008, 0), "npc4_3", 1200));
|
||||
walks.put("npc4_3", new WalkInfo(new Location(-56597, -56383, -2008, 0), "npc4_4", 1200));
|
||||
walks.put("npc4_4", new WalkInfo(new Location(-56643, -56385, -2008, 0), "npc4_5", 1200));
|
||||
walks.put("npc4_5", new WalkInfo(new Location(-56639, -56436, -2008, 0), "npc4_6", 1200));
|
||||
walks.put("npc4_6", new WalkInfo(new Location(-56639, -56473, -2008, 0), "npc4_7", 1200));
|
||||
walks.put("npc4_7", new WalkInfo(new Location(-56589, -56473, -2008, 0), "npc4_8", 1200));
|
||||
walks.put("npc4_8", new WalkInfo(new Location(-56541, -56473, -2008, 0), "npc4_9", 1200));
|
||||
walks.put("npc4_9", new WalkInfo(new Location(-56496, -56473, -2008, 0), "npc4_10", 1200));
|
||||
walks.put("npc4_10", new WalkInfo(new Location(-56496, -56429, -2008, 0), "npc4_1", 900));
|
||||
walks.put("npc5_1", new WalkInfo(new Location(-56549, -56335, -2008, 0), "npc5_2", 1000));
|
||||
walks.put("npc5_2", new WalkInfo(new Location(-56599, -56337, -2008, 0), "npc5_3", 2000));
|
||||
walks.put("npc5_3", new WalkInfo(new Location(-56649, -56341, -2008, 0), "npc5_4", 26000));
|
||||
walks.put("npc5_4", new WalkInfo(new Location(-56600, -56341, -2008, 0), "npc5_5", 1000));
|
||||
walks.put("npc5_5", new WalkInfo(new Location(-56553, -56341, -2008, 0), "npc5_6", 1000));
|
||||
walks.put("npc5_6", new WalkInfo(new Location(-56508, -56331, -2008, 0), "npc5_2", 8000));
|
||||
walks.put("npc6_1", new WalkInfo(new Location(-56595, -56428, -2008, 0), "npc6_2", 1000));
|
||||
walks.put("npc6_2", new WalkInfo(new Location(-56596, -56383, -2008, 0), "npc6_3", 1000));
|
||||
walks.put("npc6_3", new WalkInfo(new Location(-56648, -56384, -2008, 0), "npc6_4", 1000));
|
||||
walks.put("npc6_4", new WalkInfo(new Location(-56645, -56429, -2008, 0), "npc6_5", 1000));
|
||||
walks.put("npc6_5", new WalkInfo(new Location(-56644, -56475, -2008, 0), "npc6_6", 1000));
|
||||
walks.put("npc6_6", new WalkInfo(new Location(-56595, -56473, -2008, 0), "npc6_7", 1000));
|
||||
walks.put("npc6_7", new WalkInfo(new Location(-56542, -56473, -2008, 0), "npc6_8", 1000));
|
||||
walks.put("npc6_8", new WalkInfo(new Location(-56492, -56472, -2008, 0), "npc6_9", 1200));
|
||||
walks.put("npc6_9", new WalkInfo(new Location(-56495, -56426, -2008, 0), "npc6_10", 2000));
|
||||
walks.put("npc6_10", new WalkInfo(new Location(-56540, -56426, -2008, 0), "npc6_1", 3000));
|
||||
walks.put("npc7_1", new WalkInfo(new Location(-56603, -56249, -2008, 0), "npc7_2", 1000));
|
||||
walks.put("npc7_2", new WalkInfo(new Location(-56601, -56294, -2008, 0), "npc7_3", 1000));
|
||||
walks.put("npc7_3", new WalkInfo(new Location(-56651, -56295, -2008, 0), "npc7_4", 1000));
|
||||
walks.put("npc7_4", new WalkInfo(new Location(-56653, -56248, -2008, 0), "npc7_5", 1000));
|
||||
walks.put("npc7_5", new WalkInfo(new Location(-56605, -56203, -2008, 0), "npc7_6", 1000));
|
||||
walks.put("npc7_6", new WalkInfo(new Location(-56554, -56202, -2008, 0), "npc7_7", 1000));
|
||||
walks.put("npc7_7", new WalkInfo(new Location(-56504, -56201, -2008, 0), "npc7_8", 1000));
|
||||
walks.put("npc7_8", new WalkInfo(new Location(-56502, -56247, -2008, 0), "npc7_9", 1200));
|
||||
walks.put("npc7_9", new WalkInfo(new Location(-56549, -56248, -2008, 0), "npc7_10", 2000));
|
||||
walks.put("npc7_10", new WalkInfo(new Location(-56549, -56248, -2008, 0), "npc7_1", 3000));
|
||||
walks.put("npc8_1", new WalkInfo(new Location(-56493, -56426, -2008, 0), "npc8_2", 1000));
|
||||
walks.put("npc8_2", new WalkInfo(new Location(-56497, -56381, -2008, 0), "npc8_3", 1200));
|
||||
walks.put("npc8_3", new WalkInfo(new Location(-56544, -56381, -2008, 0), "npc8_4", 1200));
|
||||
walks.put("npc8_4", new WalkInfo(new Location(-56596, -56383, -2008, 0), "npc8_5", 1200));
|
||||
walks.put("npc8_5", new WalkInfo(new Location(-56594, -56428, -2008, 0), "npc8_6", 900));
|
||||
walks.put("npc8_6", new WalkInfo(new Location(-56645, -56429, -2008, 0), "npc8_7", 1200));
|
||||
walks.put("npc8_7", new WalkInfo(new Location(-56647, -56384, -2008, 0), "npc8_8", 1200));
|
||||
walks.put("npc8_8", new WalkInfo(new Location(-56649, -56362, -2008, 0), "npc8_9", 9200));
|
||||
walks.put("npc8_9", new WalkInfo(new Location(-56654, -56429, -2008, 0), "npc8_10", 1200));
|
||||
walks.put("npc8_10", new WalkInfo(new Location(-56644, -56474, -2008, 0), "npc8_11", 900));
|
||||
walks.put("npc8_11", new WalkInfo(new Location(-56593, -56473, -2008, 0), "npc8_12", 1100));
|
||||
walks.put("npc8_12", new WalkInfo(new Location(-56543, -56472, -2008, 0), "npc8_13", 1200));
|
||||
walks.put("npc8_13", new WalkInfo(new Location(-56491, -56471, -2008, 0), "npc8_1", 1200));
|
||||
walks.put("npc9_1", new WalkInfo(new Location(-56505, -56246, -2008, 0), "npc9_2", 1000));
|
||||
walks.put("npc9_2", new WalkInfo(new Location(-56504, -56291, -2008, 0), "npc9_3", 1200));
|
||||
walks.put("npc9_3", new WalkInfo(new Location(-56550, -56291, -2008, 0), "npc9_4", 1200));
|
||||
walks.put("npc9_4", new WalkInfo(new Location(-56600, -56292, -2008, 0), "npc9_5", 1200));
|
||||
walks.put("npc9_5", new WalkInfo(new Location(-56603, -56248, -2008, 0), "npc9_6", 900));
|
||||
walks.put("npc9_6", new WalkInfo(new Location(-56653, -56249, -2008, 0), "npc9_7", 1200));
|
||||
walks.put("npc9_7", new WalkInfo(new Location(-56651, -56294, -2008, 0), "npc9_8", 1200));
|
||||
walks.put("npc9_8", new WalkInfo(new Location(-56650, -56316, -2008, 0), "npc9_9", 9200));
|
||||
walks.put("npc9_9", new WalkInfo(new Location(-56660, -56250, -2008, 0), "npc9_10", 1200));
|
||||
walks.put("npc9_10", new WalkInfo(new Location(-56656, -56205, -2008, 0), "npc9_11", 900));
|
||||
walks.put("npc9_11", new WalkInfo(new Location(-56606, -56204, -2008, 0), "npc9_12", 1100));
|
||||
walks.put("npc9_12", new WalkInfo(new Location(-56554, -56203, -2008, 0), "npc9_13", 1200));
|
||||
walks.put("npc9_13", new WalkInfo(new Location(-56506, -56203, -2008, 0), "npc9_1", 1200));
|
||||
walks.put("24", new WalkInfo(new Location(-56730, -56340, -2008, 0), "25", 1800));
|
||||
walks.put("27", new WalkInfo(new Location(-56702, -56340, -2008, 0), "29", 1800));
|
||||
}
|
||||
|
||||
private void scheduleTimer()
|
||||
{
|
||||
int gameTime = GameTimeController.getInstance().getGameTime();
|
||||
int hours = (gameTime / 60) % 24;
|
||||
int minutes = gameTime % 60;
|
||||
int hourDiff, minDiff;
|
||||
hourDiff = (20 - hours);
|
||||
if (hourDiff < 0)
|
||||
{
|
||||
hourDiff = 24 - (hourDiff *= -1);
|
||||
}
|
||||
minDiff = (30 - minutes);
|
||||
if (minDiff < 0)
|
||||
{
|
||||
minDiff = 60 - (minDiff *= -1);
|
||||
}
|
||||
long diff;
|
||||
hourDiff *= 3600000;
|
||||
minDiff *= 60000;
|
||||
diff = hourDiff + minDiff;
|
||||
if (Config.DEBUG)
|
||||
{
|
||||
SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
|
||||
_log.info("Fantasy Isle: MC show script starting at " + format.format(System.currentTimeMillis() + diff) + " and is scheduled each next 4 hours.");
|
||||
}
|
||||
// TODO startRepeatingQuestTimer("Start", diff, 14400000, null, null);
|
||||
// missing option to provide different initial delay
|
||||
ThreadPoolManager.getInstance().scheduleGeneralAtFixedRate(new StartMCShow(), diff, 14400000L);
|
||||
}
|
||||
|
||||
private void autoChat(L2Npc npc, NpcStringId npcString, int type)
|
||||
{
|
||||
npc.broadcastPacket(new NpcSay(npc.getObjectId(), type, npc.getId(), npcString));
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (IS_STARTED)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case 32433:
|
||||
autoChat(npc, MESSAGES[0], Say2.NPC_SHOUT);
|
||||
startQuestTimer("1", 30000, npc, null);
|
||||
break;
|
||||
case 32431:
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(-56657, -56338, -2008, 33102));
|
||||
startQuestTimer("social1", 6000, npc, null, true);
|
||||
startQuestTimer("7", 215000, npc, null);
|
||||
break;
|
||||
case 32432:
|
||||
startQuestTimer("social1", 6000, npc, null, true);
|
||||
startQuestTimer("7", 215000, npc, null);
|
||||
break;
|
||||
case 32442:
|
||||
case 32443:
|
||||
case 32444:
|
||||
case 32445:
|
||||
case 32446:
|
||||
startQuestTimer("11", 100000, npc, null);
|
||||
break;
|
||||
case 32424:
|
||||
case 32425:
|
||||
case 32426:
|
||||
case 32427:
|
||||
case 32428:
|
||||
startQuestTimer("social1", 5500, npc, null);
|
||||
startQuestTimer("social1", 12500, npc, null);
|
||||
startQuestTimer("28", 19700, npc, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if ((event == null) || event.isEmpty())
|
||||
{
|
||||
_log.warning("MC_Show: Null/Empty event for npc " + npc + " and player " + player + "!");
|
||||
return null;
|
||||
}
|
||||
|
||||
if (event.equalsIgnoreCase("Start"))
|
||||
{
|
||||
IS_STARTED = true;
|
||||
addSpawn(MC, -56698, -56430, -2008, 32768, false, 0);
|
||||
}
|
||||
else if ((npc != null) && IS_STARTED)
|
||||
{
|
||||
// TODO switch on event
|
||||
if (event.equalsIgnoreCase("6"))
|
||||
{
|
||||
autoChat(npc, MESSAGES[6], Say2.NPC_SHOUT);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(-56511, -56647, -2008, 36863));
|
||||
npc.broadcastPacket(new PlaySound(1, "NS22_F", 0, 0, 0, 0, 0));
|
||||
addSpawn(SINGERS[0], -56344, -56328, -2008, 32768, false, 224000);
|
||||
addSpawn(SINGERS[1], -56552, -56245, -2008, 36863, false, 224000);
|
||||
addSpawn(SINGERS[1], -56546, -56426, -2008, 28672, false, 224000);
|
||||
addSpawn(SINGERS[1], -56570, -56473, -2008, 28672, false, 224000);
|
||||
addSpawn(SINGERS[1], -56594, -56516, -2008, 28672, false, 224000);
|
||||
addSpawn(SINGERS[1], -56580, -56203, -2008, 36863, false, 224000);
|
||||
addSpawn(SINGERS[1], -56606, -56157, -2008, 36863, false, 224000);
|
||||
startQuestTimer("7", 215000, npc, null);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("7"))
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case 32433:
|
||||
autoChat(npc, MESSAGES[7], Say2.NPC_SHOUT);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(-56698, -56430, -2008, 32768));
|
||||
startQuestTimer("8", 12000, npc, null);
|
||||
break;
|
||||
default:
|
||||
cancelQuestTimer("social1", npc, null);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(-56594, -56064, -2008, 32768));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (event.equalsIgnoreCase("10"))
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(-56483, -56665, -2034, 32768));
|
||||
npc.broadcastPacket(new PlaySound(1, "TP05_F", 0, 0, 0, 0, 0));
|
||||
startQuestTimer("npc1_1", 3000, addSpawn(CIRCUS[0], -56495, -56375, -2008, 32768, false, 101000), null);
|
||||
startQuestTimer("npc2_1", 3000, addSpawn(CIRCUS[0], -56491, -56289, -2008, 32768, false, 101000), null);
|
||||
startQuestTimer("npc3_1", 3000, addSpawn(CIRCUS[1], -56502, -56246, -2008, 32768, false, 101000), null);
|
||||
startQuestTimer("npc4_1", 3000, addSpawn(CIRCUS[1], -56496, -56429, -2008, 32768, false, 101000), null);
|
||||
startQuestTimer("npc5_1", 3500, addSpawn(CIRCUS[2], -56505, -56334, -2008, 32768, false, 101000), null);
|
||||
startQuestTimer("npc6_1", 4000, addSpawn(CIRCUS[3], -56545, -56427, -2008, 32768, false, 101000), null);
|
||||
startQuestTimer("npc7_1", 4000, addSpawn(CIRCUS[3], -56552, -56248, -2008, 32768, false, 101000), null);
|
||||
startQuestTimer("npc8_1", 3000, addSpawn(CIRCUS[4], -56493, -56473, -2008, 32768, false, 101000), null);
|
||||
startQuestTimer("npc9_1", 3000, addSpawn(CIRCUS[4], -56504, -56201, -2008, 32768, false, 101000), null);
|
||||
startQuestTimer("11", 100000, npc, null);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("11"))
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case 32433:
|
||||
autoChat(npc, MESSAGES[11], Say2.NPC_SHOUT);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(-56698, -56430, -2008, 32768));
|
||||
startQuestTimer("12", 5000, npc, null);
|
||||
break;
|
||||
default:
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(-56343, -56330, -2008, 32768));
|
||||
break;
|
||||
}
|
||||
}
|
||||
else if (event.equalsIgnoreCase("14"))
|
||||
{
|
||||
startQuestTimer("social1", 2000, addSpawn(INDIVIDUALS[0], -56700, -56385, -2008, 32768, false, 49000), null);
|
||||
startQuestTimer("15", 7000, npc, null);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("17"))
|
||||
{
|
||||
autoChat(npc, MESSAGES[16], Say2.NPC_SHOUT);
|
||||
startQuestTimer("social1", 2000, addSpawn(INDIVIDUALS[1], -56700, -56340, -2008, 32768, false, 32000), null);
|
||||
startQuestTimer("18", 9000, npc, null);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("20"))
|
||||
{
|
||||
startQuestTimer("social1", 2000, addSpawn(INDIVIDUALS[2], -56703, -56296, -2008, 32768, false, 13000), null);
|
||||
startQuestTimer("21", 8000, npc, null);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("23"))
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(-56702, -56340, -2008, 32768));
|
||||
startQuestTimer("24", 2800, npc, null);
|
||||
addSpawn(SHOWSTUFF[0], -56672, -56406, -2000, 32768, false, 20900);
|
||||
addSpawn(SHOWSTUFF[1], -56648, -56368, -2000, 32768, false, 20900);
|
||||
addSpawn(SHOWSTUFF[2], -56608, -56338, -2000, 32768, false, 20900);
|
||||
addSpawn(SHOWSTUFF[3], -56652, -56307, -2000, 32768, false, 20900);
|
||||
addSpawn(SHOWSTUFF[4], -56672, -56272, -2000, 32768, false, 20900);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("28"))
|
||||
{
|
||||
autoChat(npc, MESSAGES[23], Say2.NPC_ALL);
|
||||
startQuestTimer("social1", 1, npc, null);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("29"))
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(-56730, -56340, -2008, 32768));
|
||||
startQuestTimer("clean_npc", 4100, npc, null);
|
||||
startQuestTimer("timer_check", 60000, null, null, true);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("social1"))
|
||||
{
|
||||
npc.broadcastSocialAction(1);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("clean_npc"))
|
||||
{
|
||||
IS_STARTED = false;
|
||||
npc.deleteMe();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (talks.containsKey(event))
|
||||
{
|
||||
final ShoutInfo si = talks.get(event);
|
||||
if (si != null)
|
||||
{
|
||||
autoChat(npc, si.getNpcStringId(), Say2.NPC_SHOUT);
|
||||
startQuestTimer(si.getNextEvent(), si.getTime(), npc, null);
|
||||
}
|
||||
}
|
||||
else if (walks.containsKey(event))
|
||||
{
|
||||
final WalkInfo wi = walks.get(event);
|
||||
if (wi != null)
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, wi.getCharPos());
|
||||
startQuestTimer(wi.getNextEvent(), wi.getTime(), npc, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new MC_Show();
|
||||
}
|
||||
}
|
||||
33
trunk/dist/game/data/scripts/ai/fantasy_isle/StartMCShow.java
vendored
Normal file
33
trunk/dist/game/data/scripts/ai/fantasy_isle/StartMCShow.java
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.fantasy_isle;
|
||||
|
||||
import com.l2jserver.gameserver.instancemanager.QuestManager;
|
||||
|
||||
/**
|
||||
* Start MC Show.
|
||||
*/
|
||||
public class StartMCShow implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
QuestManager.getInstance().getQuest("MC_Show").notifyEvent("Start", null, null);
|
||||
}
|
||||
}
|
||||
87
trunk/dist/game/data/scripts/ai/group_template/AdenReconstructorManager.java
vendored
Normal file
87
trunk/dist/game/data/scripts/ai/group_template/AdenReconstructorManager.java
vendored
Normal file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Aden Reconstructor Manager AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class AdenReconstructorManager extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int[] NPCS =
|
||||
{
|
||||
33584, // Moe
|
||||
33581, // Eeny
|
||||
};
|
||||
|
||||
private AdenReconstructorManager()
|
||||
{
|
||||
super(AdenReconstructorManager.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(NPCS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "SPAM_TEXT":
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.THE_LAND_OF_ADEN_IS_IN_NEED_OF_MATERIALS_TO_REBUILD_FROM_SHILEN_S_DESTRUCTION);
|
||||
startQuestTimer("SPAM_TEXT2", 1000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "SPAM_TEXT2":
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.PLEASE_DONATE_ANY_UNUSED_MATERIALS_YOU_HAVE_TO_HELP_REBUILD_ADEN);
|
||||
startQuestTimer("SPAM_TEXT3", 1000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "SPAM_TEXT3":
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.YOU_LL_RECEIVE_A_GIFT_FOR_ANY_APPLICABLE_DONATION);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
startQuestTimer("SPAM_TEXT", (5 * 60 * 1000), npc, null, true);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new AdenReconstructorManager();
|
||||
}
|
||||
}
|
||||
487
trunk/dist/game/data/scripts/ai/group_template/BeastFarm.java
vendored
Normal file
487
trunk/dist/game/data/scripts/ai/group_template/BeastFarm.java
vendored
Normal file
@@ -0,0 +1,487 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
import quests.Q00020_BringUpWithLove.Q00020_BringUpWithLove;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.NpcData;
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.idfactory.IdFactory;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2TamedBeastInstance;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcInfo;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Growth-capable mobs: Polymorphing upon successful feeding.<br>
|
||||
* Updated to Freya.
|
||||
* @author Fulminus, Gigiikun
|
||||
*/
|
||||
public final class BeastFarm extends AbstractNpcAI
|
||||
{
|
||||
private static final int GOLDEN_SPICE = 15474;
|
||||
private static final int CRYSTAL_SPICE = 15475;
|
||||
private static final int SKILL_GOLDEN_SPICE = 9049;
|
||||
private static final int SKILL_CRYSTAL_SPICE = 9050;
|
||||
private static final int SKILL_BLESSED_GOLDEN_SPICE = 9051;
|
||||
private static final int SKILL_BLESSED_CRYSTAL_SPICE = 9052;
|
||||
private static final int SKILL_SGRADE_GOLDEN_SPICE = 9053;
|
||||
private static final int SKILL_SGRADE_CRYSTAL_SPICE = 9054;
|
||||
private static final int[] TAMED_BEASTS =
|
||||
{
|
||||
18869,
|
||||
18870,
|
||||
18871,
|
||||
18872
|
||||
};
|
||||
private static final int TAME_CHANCE = 20;
|
||||
protected static final int[] SPECIAL_SPICE_CHANCES =
|
||||
{
|
||||
33,
|
||||
75
|
||||
};
|
||||
|
||||
// all mobs that can eat...
|
||||
private static final int[] FEEDABLE_BEASTS =
|
||||
{
|
||||
// Kookaburras
|
||||
18873,
|
||||
18874,
|
||||
18875,
|
||||
18876,
|
||||
18877,
|
||||
18878,
|
||||
18879,
|
||||
// Cougars
|
||||
18880,
|
||||
18881,
|
||||
18882,
|
||||
18883,
|
||||
18884,
|
||||
18885,
|
||||
18886,
|
||||
// Buffalos
|
||||
18887,
|
||||
18888,
|
||||
18889,
|
||||
18890,
|
||||
18891,
|
||||
18892,
|
||||
18893,
|
||||
// Grendels
|
||||
18894,
|
||||
18895,
|
||||
18896,
|
||||
18897,
|
||||
18898,
|
||||
18899,
|
||||
18900
|
||||
};
|
||||
|
||||
private static Map<Integer, Integer> _FeedInfo = new FastMap<>();
|
||||
private static Map<Integer, GrowthCapableMob> _GrowthCapableMobs = new FastMap<>();
|
||||
private static List<TamedBeast> TAMED_BEAST_DATA = new ArrayList<>();
|
||||
|
||||
private BeastFarm()
|
||||
{
|
||||
super(BeastFarm.class.getSimpleName(), "ai/group_template");
|
||||
addSkillSeeId(FEEDABLE_BEASTS);
|
||||
addKillId(FEEDABLE_BEASTS);
|
||||
|
||||
GrowthCapableMob temp;
|
||||
|
||||
// Kookabura
|
||||
temp = new GrowthCapableMob(100, 0, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18874);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18875);
|
||||
temp.addNpcIdForSkillId(SKILL_BLESSED_GOLDEN_SPICE, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_BLESSED_CRYSTAL_SPICE, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_SGRADE_GOLDEN_SPICE, 18878);
|
||||
temp.addNpcIdForSkillId(SKILL_SGRADE_CRYSTAL_SPICE, 18879);
|
||||
_GrowthCapableMobs.put(18873, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18876);
|
||||
_GrowthCapableMobs.put(18874, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18877);
|
||||
_GrowthCapableMobs.put(18875, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18878);
|
||||
_GrowthCapableMobs.put(18876, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18869);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18879);
|
||||
_GrowthCapableMobs.put(18877, temp);
|
||||
|
||||
// Cougar
|
||||
temp = new GrowthCapableMob(100, 0, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18881);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18882);
|
||||
temp.addNpcIdForSkillId(SKILL_BLESSED_GOLDEN_SPICE, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_BLESSED_CRYSTAL_SPICE, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_SGRADE_GOLDEN_SPICE, 18885);
|
||||
temp.addNpcIdForSkillId(SKILL_SGRADE_CRYSTAL_SPICE, 18886);
|
||||
_GrowthCapableMobs.put(18880, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18883);
|
||||
_GrowthCapableMobs.put(18881, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18884);
|
||||
_GrowthCapableMobs.put(18882, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18885);
|
||||
_GrowthCapableMobs.put(18883, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18870);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18886);
|
||||
_GrowthCapableMobs.put(18884, temp);
|
||||
|
||||
// Buffalo
|
||||
temp = new GrowthCapableMob(100, 0, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18888);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18889);
|
||||
temp.addNpcIdForSkillId(SKILL_BLESSED_GOLDEN_SPICE, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_BLESSED_CRYSTAL_SPICE, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_SGRADE_GOLDEN_SPICE, 18892);
|
||||
temp.addNpcIdForSkillId(SKILL_SGRADE_CRYSTAL_SPICE, 18893);
|
||||
_GrowthCapableMobs.put(18887, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18890);
|
||||
_GrowthCapableMobs.put(18888, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18891);
|
||||
_GrowthCapableMobs.put(18889, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18892);
|
||||
_GrowthCapableMobs.put(18890, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18871);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18893);
|
||||
_GrowthCapableMobs.put(18891, temp);
|
||||
|
||||
// Grendel
|
||||
temp = new GrowthCapableMob(100, 0, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18895);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18896);
|
||||
temp.addNpcIdForSkillId(SKILL_BLESSED_GOLDEN_SPICE, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_BLESSED_CRYSTAL_SPICE, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_SGRADE_GOLDEN_SPICE, 18899);
|
||||
temp.addNpcIdForSkillId(SKILL_SGRADE_CRYSTAL_SPICE, 18900);
|
||||
_GrowthCapableMobs.put(18894, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18897);
|
||||
_GrowthCapableMobs.put(18895, temp);
|
||||
|
||||
temp = new GrowthCapableMob(40, 1, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18898);
|
||||
_GrowthCapableMobs.put(18896, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_GOLDEN_SPICE, 18899);
|
||||
_GrowthCapableMobs.put(18897, temp);
|
||||
|
||||
temp = new GrowthCapableMob(25, 2, 18872);
|
||||
temp.addNpcIdForSkillId(SKILL_CRYSTAL_SPICE, 18900);
|
||||
_GrowthCapableMobs.put(18898, temp);
|
||||
|
||||
// Tamed beasts data
|
||||
TAMED_BEAST_DATA.add(new TamedBeast("%name% of Focus", new SkillHolder(6432, 1), new SkillHolder(6668, 1)));
|
||||
TAMED_BEAST_DATA.add(new TamedBeast("%name% of Guiding", new SkillHolder(6433, 1), new SkillHolder(6670, 1)));
|
||||
TAMED_BEAST_DATA.add(new TamedBeast("%name% of Swifth", new SkillHolder(6434, 1), new SkillHolder(6667, 1)));
|
||||
TAMED_BEAST_DATA.add(new TamedBeast("Berserker %name%", new SkillHolder(6671, 1)));
|
||||
TAMED_BEAST_DATA.add(new TamedBeast("%name% of Protect", new SkillHolder(6669, 1), new SkillHolder(6672, 1)));
|
||||
TAMED_BEAST_DATA.add(new TamedBeast("%name% of Vigor", new SkillHolder(6431, 1), new SkillHolder(6666, 1)));
|
||||
}
|
||||
|
||||
public void spawnNext(L2Npc npc, L2PcInstance player, int nextNpcId, int food)
|
||||
{
|
||||
// remove the feedinfo of the mob that got despawned, if any
|
||||
if (_FeedInfo.containsKey(npc.getObjectId()))
|
||||
{
|
||||
if (_FeedInfo.get(npc.getObjectId()) == player.getObjectId())
|
||||
{
|
||||
_FeedInfo.remove(npc.getObjectId());
|
||||
}
|
||||
}
|
||||
// despawn the old mob
|
||||
// TODO: same code? FIXED?
|
||||
/*
|
||||
* if (_GrowthCapableMobs.get(npc.getNpcId()).getGrowthLevel() == 0) { npc.deleteMe(); } else {
|
||||
*/
|
||||
npc.deleteMe();
|
||||
// }
|
||||
|
||||
// if this is finally a trained mob, then despawn any other trained mobs that the
|
||||
// player might have and initialize the Tamed Beast.
|
||||
if (Util.contains(TAMED_BEASTS, nextNpcId))
|
||||
{
|
||||
L2NpcTemplate template = NpcData.getInstance().getTemplate(nextNpcId);
|
||||
L2TamedBeastInstance nextNpc = new L2TamedBeastInstance(IdFactory.getInstance().getNextId(), template, player, food, npc.getX(), npc.getY(), npc.getZ(), true);
|
||||
|
||||
TamedBeast beast = TAMED_BEAST_DATA.get(getRandom(TAMED_BEAST_DATA.size()));
|
||||
String name = beast.getName();
|
||||
switch (nextNpcId)
|
||||
{
|
||||
case 18869:
|
||||
name = name.replace("%name%", "Alpine Kookaburra");
|
||||
break;
|
||||
case 18870:
|
||||
name = name.replace("%name%", "Alpine Cougar");
|
||||
break;
|
||||
case 18871:
|
||||
name = name.replace("%name%", "Alpine Buffalo");
|
||||
break;
|
||||
case 18872:
|
||||
name = name.replace("%name%", "Alpine Grendel");
|
||||
break;
|
||||
}
|
||||
nextNpc.setName(name);
|
||||
nextNpc.broadcastPacket(new NpcInfo(nextNpc));
|
||||
nextNpc.setRunning();
|
||||
|
||||
SkillData st = SkillData.getInstance();
|
||||
for (SkillHolder sh : beast.getSkills())
|
||||
{
|
||||
nextNpc.addBeastSkill(st.getSkill(sh.getSkillId(), sh.getSkillLvl()));
|
||||
}
|
||||
|
||||
Q00020_BringUpWithLove.checkJewelOfInnocence(player);
|
||||
}
|
||||
else
|
||||
{
|
||||
// if not trained, the newly spawned mob will automatically be agro against its feeder
|
||||
// (what happened to "never bite the hand that feeds you" anyway?!)
|
||||
L2Attackable nextNpc = (L2Attackable) addSpawn(nextNpcId, npc);
|
||||
|
||||
// register the player in the feedinfo for the mob that just spawned
|
||||
_FeedInfo.put(nextNpc.getObjectId(), player.getObjectId());
|
||||
nextNpc.setRunning();
|
||||
nextNpc.addDamageHate(player, 0, 99999);
|
||||
nextNpc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
|
||||
|
||||
player.setTarget(nextNpc);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
// this behavior is only run when the target of skill is the passed npc (chest)
|
||||
// i.e. when the player is attempting to open the chest using a skill
|
||||
if (!Util.contains(targets, npc))
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
// gather some values on local variables
|
||||
int npcId = npc.getId();
|
||||
int skillId = skill.getId();
|
||||
// check if the npc and skills used are valid for this script. Exit if invalid.
|
||||
if (!Util.contains(FEEDABLE_BEASTS, npcId) || ((skillId != SKILL_GOLDEN_SPICE) && (skillId != SKILL_CRYSTAL_SPICE) && (skillId != SKILL_BLESSED_GOLDEN_SPICE) && (skillId != SKILL_BLESSED_CRYSTAL_SPICE) && (skillId != SKILL_SGRADE_GOLDEN_SPICE) && (skillId != SKILL_SGRADE_CRYSTAL_SPICE)))
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
// first gather some values on local variables
|
||||
int objectId = npc.getObjectId();
|
||||
int growthLevel = 3; // if a mob is in FEEDABLE_BEASTS but not in _GrowthCapableMobs, then it's at max growth (3)
|
||||
if (_GrowthCapableMobs.containsKey(npcId))
|
||||
{
|
||||
growthLevel = _GrowthCapableMobs.get(npcId).getGrowthLevel();
|
||||
}
|
||||
|
||||
// prevent exploit which allows 2 players to simultaneously raise the same 0-growth beast
|
||||
// If the mob is at 0th level (when it still listens to all feeders) lock it to the first feeder!
|
||||
if ((growthLevel == 0) && _FeedInfo.containsKey(objectId))
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
_FeedInfo.put(objectId, caster.getObjectId());
|
||||
|
||||
// display the social action of the beast eating the food.
|
||||
npc.broadcastSocialAction(2);
|
||||
|
||||
int food = 0;
|
||||
if ((skillId == SKILL_GOLDEN_SPICE) || (skillId == SKILL_BLESSED_GOLDEN_SPICE))
|
||||
{
|
||||
food = GOLDEN_SPICE;
|
||||
}
|
||||
else if ((skillId == SKILL_CRYSTAL_SPICE) || (skillId == SKILL_BLESSED_CRYSTAL_SPICE))
|
||||
{
|
||||
food = CRYSTAL_SPICE;
|
||||
}
|
||||
|
||||
// if this pet can't grow, it's all done.
|
||||
if (_GrowthCapableMobs.containsKey(npcId))
|
||||
{
|
||||
// do nothing if this mob doesn't eat the specified food (food gets consumed but has no effect).
|
||||
int newNpcId = _GrowthCapableMobs.get(npcId).getLeveledNpcId(skillId);
|
||||
if (newNpcId == -1)
|
||||
{
|
||||
if (growthLevel == 0)
|
||||
{
|
||||
_FeedInfo.remove(objectId);
|
||||
npc.setRunning();
|
||||
((L2Attackable) npc).addDamageHate(caster, 0, 1);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, caster);
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
else if ((growthLevel > 0) && (_FeedInfo.get(objectId) != caster.getObjectId()))
|
||||
{
|
||||
// check if this is the same player as the one who raised it from growth 0.
|
||||
// if no, then do not allow a chance to raise the pet (food gets consumed but has no effect).
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
spawnNext(npc, caster, newNpcId, food);
|
||||
}
|
||||
else
|
||||
{
|
||||
caster.sendMessage("The beast spit out the feed instead of eating it.");
|
||||
npc.dropItem(caster, food, 1);
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
// remove the feedinfo of the mob that got killed, if any
|
||||
if (_FeedInfo.containsKey(npc.getObjectId()))
|
||||
{
|
||||
_FeedInfo.remove(npc.getObjectId());
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
// all mobs that grow by eating
|
||||
private static class GrowthCapableMob
|
||||
{
|
||||
private final int _chance;
|
||||
private final int _growthLevel;
|
||||
private final int _tameNpcId;
|
||||
private final Map<Integer, Integer> _skillSuccessNpcIdList = new FastMap<>();
|
||||
|
||||
public GrowthCapableMob(int chance, int growthLevel, int tameNpcId)
|
||||
{
|
||||
_chance = chance;
|
||||
_growthLevel = growthLevel;
|
||||
_tameNpcId = tameNpcId;
|
||||
}
|
||||
|
||||
public void addNpcIdForSkillId(int skillId, int npcId)
|
||||
{
|
||||
_skillSuccessNpcIdList.put(skillId, npcId);
|
||||
}
|
||||
|
||||
public int getGrowthLevel()
|
||||
{
|
||||
return _growthLevel;
|
||||
}
|
||||
|
||||
public int getLeveledNpcId(int skillId)
|
||||
{
|
||||
if (!_skillSuccessNpcIdList.containsKey(skillId))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
else if ((skillId == SKILL_BLESSED_GOLDEN_SPICE) || (skillId == SKILL_BLESSED_CRYSTAL_SPICE) || (skillId == SKILL_SGRADE_GOLDEN_SPICE) || (skillId == SKILL_SGRADE_CRYSTAL_SPICE))
|
||||
{
|
||||
if (getRandom(100) < SPECIAL_SPICE_CHANCES[0])
|
||||
{
|
||||
if (getRandom(100) < SPECIAL_SPICE_CHANCES[1])
|
||||
{
|
||||
return _skillSuccessNpcIdList.get(skillId);
|
||||
}
|
||||
else if ((skillId == SKILL_BLESSED_GOLDEN_SPICE) || (skillId == SKILL_SGRADE_GOLDEN_SPICE))
|
||||
{
|
||||
return _skillSuccessNpcIdList.get(SKILL_GOLDEN_SPICE);
|
||||
}
|
||||
else
|
||||
{
|
||||
return _skillSuccessNpcIdList.get(SKILL_CRYSTAL_SPICE);
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
else if ((_growthLevel == 2) && (getRandom(100) < TAME_CHANCE))
|
||||
{
|
||||
return _tameNpcId;
|
||||
}
|
||||
else if (getRandom(100) < _chance)
|
||||
{
|
||||
return _skillSuccessNpcIdList.get(skillId);
|
||||
}
|
||||
else
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class TamedBeast
|
||||
{
|
||||
private final String name;
|
||||
private final SkillHolder[] sh;
|
||||
|
||||
public TamedBeast(String beastName, SkillHolder... holders)
|
||||
{
|
||||
name = beastName;
|
||||
sh = holders;
|
||||
}
|
||||
|
||||
public String getName()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
|
||||
public SkillHolder[] getSkills()
|
||||
{
|
||||
return sh;
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new BeastFarm();
|
||||
}
|
||||
}
|
||||
238
trunk/dist/game/data/scripts/ai/group_template/DenOfEvil.java
vendored
Normal file
238
trunk/dist/game/data/scripts/ai/group_template/DenOfEvil.java
vendored
Normal file
@@ -0,0 +1,238 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.zone.type.L2EffectZone;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SystemMessage;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Dummy AI for spawns/respawns only for testing.
|
||||
* @author Gnacik
|
||||
*/
|
||||
public final class DenOfEvil extends AbstractNpcAI
|
||||
{
|
||||
// private static final int _buffer_id = 32656;
|
||||
protected static final int[] EYE_IDS =
|
||||
{
|
||||
18812,
|
||||
18813,
|
||||
18814
|
||||
};
|
||||
private static final int SKILL_ID = 6150; // others +2
|
||||
|
||||
private static final Location[] EYE_SPAWNS =
|
||||
{
|
||||
new Location(71544, -129400, -3360, 16472),
|
||||
new Location(70954, -128854, -3360, 16),
|
||||
new Location(72145, -128847, -3368, 32832),
|
||||
new Location(76147, -128372, -3144, 16152),
|
||||
new Location(71573, -128309, -3360, 49152),
|
||||
new Location(75211, -127441, -3152, 0),
|
||||
new Location(77005, -127406, -3144, 32784),
|
||||
new Location(75965, -126486, -3144, 49120),
|
||||
new Location(70972, -126429, -3016, 19208),
|
||||
new Location(69916, -125838, -3024, 2840),
|
||||
new Location(71658, -125459, -3016, 35136),
|
||||
new Location(70605, -124646, -3040, 52104),
|
||||
new Location(67283, -123237, -2912, 12376),
|
||||
new Location(68383, -122754, -2912, 27904),
|
||||
new Location(74137, -122733, -3024, 13272),
|
||||
new Location(66736, -122007, -2896, 60576),
|
||||
new Location(73289, -121769, -3024, 1024),
|
||||
new Location(67894, -121491, -2912, 43872),
|
||||
new Location(75530, -121477, -3008, 34424),
|
||||
new Location(74117, -120459, -3024, 52344),
|
||||
new Location(69608, -119855, -2534, 17251),
|
||||
new Location(71014, -119027, -2520, 31904),
|
||||
new Location(68944, -118964, -2527, 59874),
|
||||
new Location(62261, -118263, -3072, 12888),
|
||||
new Location(70300, -117942, -2528, 46208),
|
||||
new Location(74312, -117583, -2272, 15280),
|
||||
new Location(63276, -117409, -3064, 24760),
|
||||
new Location(68104, -117192, -2168, 15888),
|
||||
new Location(73758, -116945, -2216, 0),
|
||||
new Location(74944, -116858, -2220, 30892),
|
||||
new Location(61715, -116623, -3064, 59888),
|
||||
new Location(69140, -116464, -2168, 28952),
|
||||
new Location(67311, -116374, -2152, 1280),
|
||||
new Location(62459, -116370, -3064, 48624),
|
||||
new Location(74475, -116260, -2216, 47456),
|
||||
new Location(68333, -115015, -2168, 45136),
|
||||
new Location(68280, -108129, -1160, 17992),
|
||||
new Location(62983, -107259, -2384, 12552),
|
||||
new Location(67062, -107125, -1144, 64008),
|
||||
new Location(68893, -106954, -1160, 36704),
|
||||
new Location(63848, -106771, -2384, 32784),
|
||||
new Location(62372, -106514, -2384, 0),
|
||||
new Location(67838, -106143, -1160, 51232),
|
||||
new Location(62905, -106109, -2384, 51288)
|
||||
};
|
||||
|
||||
private DenOfEvil()
|
||||
{
|
||||
super(DenOfEvil.class.getSimpleName(), "ai/group_template");
|
||||
addKillId(EYE_IDS);
|
||||
addSpawnId(EYE_IDS);
|
||||
for (Location loc : EYE_SPAWNS)
|
||||
{
|
||||
addSpawn(EYE_IDS[getRandom(EYE_IDS.length)], loc, false, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private int getSkillIdByNpcId(int npcId)
|
||||
{
|
||||
int diff = npcId - EYE_IDS[0];
|
||||
diff *= 2;
|
||||
return SKILL_ID + diff;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.disableCoreAI(true);
|
||||
npc.setIsImmobilized(true);
|
||||
L2EffectZone zone = ZoneManager.getInstance().getZone(npc, L2EffectZone.class);
|
||||
if (zone == null)
|
||||
{
|
||||
_log.warning("NPC " + npc + " spawned outside of L2EffectZone, check your zone coords! X:" + npc.getX() + " Y:" + npc.getY() + " Z:" + npc.getZ());
|
||||
return null;
|
||||
}
|
||||
int skillId = getSkillIdByNpcId(npc.getId());
|
||||
int skillLevel = zone.getSkillLevel(skillId);
|
||||
zone.addSkill(skillId, skillLevel + 1);
|
||||
if (skillLevel == 3) // 3+1=4
|
||||
{
|
||||
ThreadPoolManager.getInstance().scheduleAi(new KashaDestruction(zone), 2 * 60 * 1000l);
|
||||
zone.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.DEFEAT_KASHA_S_EYES_TO_LIFT_THE_GREAT_CURSE));
|
||||
}
|
||||
else if (skillLevel == 2)
|
||||
{
|
||||
zone.broadcastPacket(SystemMessage.getSystemMessage(SystemMessageId.A_GREAT_CURSE_CAN_BE_FELT_FROM_KASHA_S_EYES));
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
ThreadPoolManager.getInstance().scheduleAi(new RespawnNewEye(npc.getLocation()), 15000);
|
||||
L2EffectZone zone = ZoneManager.getInstance().getZone(npc, L2EffectZone.class);
|
||||
if (zone == null)
|
||||
{
|
||||
_log.warning("NPC " + npc + " killed outside of L2EffectZone, check your zone coords! X:" + npc.getX() + " Y:" + npc.getY() + " Z:" + npc.getZ());
|
||||
return null;
|
||||
}
|
||||
int skillId = getSkillIdByNpcId(npc.getId());
|
||||
int skillLevel = zone.getSkillLevel(skillId);
|
||||
zone.addSkill(skillId, skillLevel - 1);
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
private class RespawnNewEye implements Runnable
|
||||
{
|
||||
private final Location _loc;
|
||||
|
||||
public RespawnNewEye(Location loc)
|
||||
{
|
||||
_loc = loc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
addSpawn(EYE_IDS[getRandom(EYE_IDS.length)], _loc, false, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private class KashaDestruction implements Runnable
|
||||
{
|
||||
L2EffectZone _zone;
|
||||
|
||||
public KashaDestruction(L2EffectZone zone)
|
||||
{
|
||||
_zone = zone;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
for (int i = SKILL_ID; i <= (SKILL_ID + 4); i = i + 2)
|
||||
{
|
||||
// test 3 skills if some is lvl 4
|
||||
if (_zone.getSkillLevel(i) > 3)
|
||||
{
|
||||
destroyZone();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void destroyZone()
|
||||
{
|
||||
for (L2Character character : _zone.getCharactersInside())
|
||||
{
|
||||
if (character == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (character.isPlayable())
|
||||
{
|
||||
Skill skill = SkillData.getInstance().getSkill(6149, 1);
|
||||
skill.applyEffects(character, character);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (character.doDie(null)) // mobs die
|
||||
{
|
||||
if (character.isNpc())
|
||||
{
|
||||
// respawn eye
|
||||
L2Npc npc = (L2Npc) character;
|
||||
if (Util.contains(EYE_IDS, npc.getId()))
|
||||
{
|
||||
ThreadPoolManager.getInstance().scheduleAi(new RespawnNewEye(npc.getLocation()), 15000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = SKILL_ID; i <= (SKILL_ID + 4); i = i + 2)
|
||||
{
|
||||
_zone.removeSkill(i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new DenOfEvil();
|
||||
}
|
||||
}
|
||||
299
trunk/dist/game/data/scripts/ai/group_template/DragonValley.java
vendored
Normal file
299
trunk/dist/game/data/scripts/ai/group_template/DragonValley.java
vendored
Normal file
@@ -0,0 +1,299 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import java.util.EnumMap;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.base.ClassId;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Dragon Valley AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class DragonValley extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int NECROMANCER_OF_THE_VALLEY = 22858;
|
||||
private static final int EXPLODING_ORC_GHOST = 22818;
|
||||
private static final int WRATHFUL_ORC_GHOST = 22819;
|
||||
private static final int DRAKOS_ASSASSIN = 22823;
|
||||
private static final int[] SUMMON_NPC =
|
||||
{
|
||||
22822, // Drakos Warrior
|
||||
22824, // Drakos Guardian
|
||||
22862, // Drakos Hunter
|
||||
};
|
||||
private static final int[] SPAWN_ANIMATION =
|
||||
{
|
||||
22826, // Scorpion Bones
|
||||
22823, // Drakos Assassin
|
||||
22828, // Parasitic Leech
|
||||
|
||||
};
|
||||
private static final int[] SPOIL_REACT_MONSTER =
|
||||
{
|
||||
22822, // Drakos Warrior
|
||||
22823, // Drakos Assassin
|
||||
22824, // Drakos Guardian
|
||||
22825, // Giant Scorpion Bones
|
||||
22826, // Scorpion Bones
|
||||
22827, // Batwing Drake
|
||||
22828, // Parasitic Leech
|
||||
22829, // Emerald Drake
|
||||
22830, // Gem Dragon
|
||||
22831, // Dragon Tracker of the Valley
|
||||
22832, // Dragon Scout of the Valley
|
||||
22833, // Sand Drake Tracker
|
||||
22834, // Dust Dragon Tracker
|
||||
22860, // Hungry Parasitic Leech
|
||||
22861, // Hard Scorpion Bones
|
||||
22862, // Drakos Hunter
|
||||
};
|
||||
// Items
|
||||
private static final int GREATER_HERB_OF_MANA = 8604;
|
||||
private static final int SUPERIOR_HERB_OF_MANA = 8605;
|
||||
// Skills
|
||||
private static final SkillHolder SELF_DESTRUCTION = new SkillHolder(6850, 1);
|
||||
private static final SkillHolder MORALE_BOOST1 = new SkillHolder(6885, 1);
|
||||
private static final SkillHolder MORALE_BOOST2 = new SkillHolder(6885, 2);
|
||||
private static final SkillHolder MORALE_BOOST3 = new SkillHolder(6885, 3);
|
||||
// Misc
|
||||
private static final int MIN_DISTANCE = 1500;
|
||||
private static final int MIN_MEMBERS = 3;
|
||||
private static final int MIN_LVL = 80;
|
||||
private static final int CLASS_LVL = 3;
|
||||
private static final EnumMap<ClassId, Double> CLASS_POINTS = new EnumMap<>(ClassId.class);
|
||||
{
|
||||
CLASS_POINTS.put(ClassId.ADVENTURER, 0.2);
|
||||
CLASS_POINTS.put(ClassId.ARCANA_LORD, 1.5);
|
||||
CLASS_POINTS.put(ClassId.ARCHMAGE, 0.3);
|
||||
CLASS_POINTS.put(ClassId.CARDINAL, -0.6);
|
||||
CLASS_POINTS.put(ClassId.DOMINATOR, 0.2);
|
||||
CLASS_POINTS.put(ClassId.DOOMBRINGER, 0.2);
|
||||
CLASS_POINTS.put(ClassId.DOOMCRYER, 0.1);
|
||||
CLASS_POINTS.put(ClassId.DREADNOUGHT, 0.7);
|
||||
CLASS_POINTS.put(ClassId.DUELIST, 0.2);
|
||||
CLASS_POINTS.put(ClassId.ELEMENTAL_MASTER, 1.4);
|
||||
CLASS_POINTS.put(ClassId.EVA_SAINT, -0.6);
|
||||
CLASS_POINTS.put(ClassId.EVA_TEMPLAR, 0.8);
|
||||
CLASS_POINTS.put(ClassId.FEMALE_SOUL_HOUND, 0.4);
|
||||
CLASS_POINTS.put(ClassId.FORTUNE_SEEKER, 0.9);
|
||||
CLASS_POINTS.put(ClassId.GHOST_HUNTER, 0.2);
|
||||
CLASS_POINTS.put(ClassId.GHOST_SENTINEL, 0.2);
|
||||
CLASS_POINTS.put(ClassId.GRAND_KHAVATARI, 0.2);
|
||||
CLASS_POINTS.put(ClassId.HELL_KNIGHT, 0.6);
|
||||
CLASS_POINTS.put(ClassId.HIEROPHANT, 0.0);
|
||||
CLASS_POINTS.put(ClassId.JUDICATOR, 0.1);
|
||||
CLASS_POINTS.put(ClassId.MOONLIGHT_SENTINEL, 0.2);
|
||||
CLASS_POINTS.put(ClassId.MAESTRO, 0.7);
|
||||
CLASS_POINTS.put(ClassId.MALE_SOUL_HOUND, 0.4);
|
||||
CLASS_POINTS.put(ClassId.MYSTIC_MUSE, 0.3);
|
||||
CLASS_POINTS.put(ClassId.PHOENIX_KNIGHT, 0.6);
|
||||
CLASS_POINTS.put(ClassId.SAGITTARIUS, 0.2);
|
||||
CLASS_POINTS.put(ClassId.SHILLIEN_SAINT, -0.6);
|
||||
CLASS_POINTS.put(ClassId.SHILLIEN_TEMPLAR, 0.8);
|
||||
CLASS_POINTS.put(ClassId.SOULTAKER, 0.3);
|
||||
CLASS_POINTS.put(ClassId.SPECTRAL_DANCER, 0.4);
|
||||
CLASS_POINTS.put(ClassId.SPECTRAL_MASTER, 1.4);
|
||||
CLASS_POINTS.put(ClassId.STORM_SCREAMER, 0.3);
|
||||
CLASS_POINTS.put(ClassId.SWORD_MUSE, 0.4);
|
||||
CLASS_POINTS.put(ClassId.TITAN, 0.3);
|
||||
CLASS_POINTS.put(ClassId.TRICKSTER, 0.5);
|
||||
CLASS_POINTS.put(ClassId.WIND_RIDER, 0.2);
|
||||
}
|
||||
|
||||
private DragonValley()
|
||||
{
|
||||
super(DragonValley.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(NECROMANCER_OF_THE_VALLEY);
|
||||
addAttackId(SUMMON_NPC);
|
||||
addKillId(NECROMANCER_OF_THE_VALLEY);
|
||||
addKillId(SPOIL_REACT_MONSTER);
|
||||
addSpawnId(EXPLODING_ORC_GHOST, NECROMANCER_OF_THE_VALLEY);
|
||||
addSpawnId(SPOIL_REACT_MONSTER);
|
||||
addSpellFinishedId(EXPLODING_ORC_GHOST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("SELF_DESTRUCTION") && (npc != null) && !npc.isDead())
|
||||
{
|
||||
final L2Playable playable = npc.getVariables().getObject("playable", L2Playable.class);
|
||||
|
||||
if ((playable != null) && (npc.calculateDistance(playable, true, false) < 250))
|
||||
{
|
||||
npc.disableCoreAI(true);
|
||||
npc.doCast(SELF_DESTRUCTION.getSkill());
|
||||
}
|
||||
else if (playable != null)
|
||||
{
|
||||
startQuestTimer("SELF_DESTRUCTION", 3000, npc, null);
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == NECROMANCER_OF_THE_VALLEY)
|
||||
{
|
||||
spawnGhost(npc, attacker, isSummon, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((npc.getCurrentHp() < (npc.getMaxHp() / 2)) && (getRandom(100) < 5) && npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
final int rnd = getRandom(3, 5);
|
||||
for (int i = 0; i < rnd; i++)
|
||||
{
|
||||
final L2Playable playable = isSummon ? attacker.getSummon() : attacker;
|
||||
final L2Npc minion = addSpawn(DRAKOS_ASSASSIN, npc.getX(), npc.getY(), npc.getZ() + 10, npc.getHeading(), true, 0, true);
|
||||
addAttackPlayerDesire(minion, playable);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == NECROMANCER_OF_THE_VALLEY)
|
||||
{
|
||||
spawnGhost(npc, killer, isSummon, 20);
|
||||
}
|
||||
else if (((L2Attackable) npc).isSweepActive())
|
||||
{
|
||||
npc.dropItem(killer, getRandom(GREATER_HERB_OF_MANA, SUPERIOR_HERB_OF_MANA), 1);
|
||||
manageMoraleBoost(killer, npc);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
((L2Attackable) npc).setOnKillDelay(0);
|
||||
if (npc.getId() == EXPLODING_ORC_GHOST)
|
||||
{
|
||||
startQuestTimer("SELF_DESTRUCTION", 3000, npc, null);
|
||||
}
|
||||
else if (Util.contains(SPAWN_ANIMATION, npc.getId()))
|
||||
{
|
||||
npc.setShowSummonAnimation(true);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
if (skill == SELF_DESTRUCTION.getSkill())
|
||||
{
|
||||
npc.doDie(player);
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
private void manageMoraleBoost(L2PcInstance player, L2Npc npc)
|
||||
{
|
||||
double points = 0;
|
||||
int moraleBoostLv = 0;
|
||||
|
||||
if (player.isInParty() && (player.getParty().getMemberCount() >= MIN_MEMBERS) && (npc != null))
|
||||
{
|
||||
for (L2PcInstance member : player.getParty().getMembers())
|
||||
{
|
||||
if ((member.getLevel() >= MIN_LVL) && (member.getClassId().level() >= CLASS_LVL) && (npc.calculateDistance(member, true, false) < MIN_DISTANCE))
|
||||
{
|
||||
points += CLASS_POINTS.get(member.getClassId());
|
||||
}
|
||||
}
|
||||
|
||||
if (points >= 3)
|
||||
{
|
||||
moraleBoostLv = 3;
|
||||
}
|
||||
else if (points >= 2)
|
||||
{
|
||||
moraleBoostLv = 2;
|
||||
}
|
||||
else if (points >= 1)
|
||||
{
|
||||
moraleBoostLv = 1;
|
||||
}
|
||||
|
||||
for (L2PcInstance member : player.getParty().getMembers())
|
||||
{
|
||||
if (npc.calculateDistance(member, true, false) < MIN_DISTANCE)
|
||||
{
|
||||
switch (moraleBoostLv)
|
||||
{
|
||||
case 1:
|
||||
MORALE_BOOST1.getSkill().applyEffects(member, member);
|
||||
break;
|
||||
case 2:
|
||||
MORALE_BOOST2.getSkill().applyEffects(member, member);
|
||||
break;
|
||||
case 3:
|
||||
MORALE_BOOST3.getSkill().applyEffects(member, member);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void spawnGhost(L2Npc npc, L2PcInstance player, boolean isSummon, int chance)
|
||||
{
|
||||
if ((npc.getScriptValue() < 2) && (getRandom(100) < chance))
|
||||
{
|
||||
int val = npc.getScriptValue();
|
||||
final L2Playable attacker = isSummon ? player.getSummon() : player;
|
||||
final L2Npc ghost1 = addSpawn(EXPLODING_ORC_GHOST, npc.getX(), npc.getY(), npc.getZ() + 10, npc.getHeading(), false, 0, true);
|
||||
ghost1.getVariables().set("playable", attacker);
|
||||
addAttackPlayerDesire(ghost1, attacker);
|
||||
val++;
|
||||
if ((val < 2) && (getRandomBoolean()))
|
||||
{
|
||||
final L2Npc ghost2 = addSpawn(WRATHFUL_ORC_GHOST, npc.getX(), npc.getY(), npc.getZ() + 20, npc.getHeading(), false, 0, false);
|
||||
addAttackPlayerDesire(ghost2, attacker);
|
||||
val++;
|
||||
}
|
||||
npc.setScriptValue(val);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new DragonValley();
|
||||
}
|
||||
}
|
||||
90
trunk/dist/game/data/scripts/ai/group_template/FairyTrees.java
vendored
Normal file
90
trunk/dist/game/data/scripts/ai/group_template/FairyTrees.java
vendored
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
|
||||
/**
|
||||
* Fairy Trees AI.
|
||||
* @author Charus
|
||||
*/
|
||||
public class FairyTrees extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int SOUL_GUARDIAN = 27189; // Soul of Tree Guardian
|
||||
|
||||
private static final int[] MOBS =
|
||||
{
|
||||
27185, // Fairy Tree of Wind
|
||||
27186, // Fairy Tree of Star
|
||||
27187, // Fairy Tree of Twilight
|
||||
27188, // Fairy Tree of Abyss
|
||||
};
|
||||
|
||||
// Skill
|
||||
private static SkillHolder VENOMOUS_POISON = new SkillHolder(4243, 1); // Venomous Poison
|
||||
|
||||
// Misc
|
||||
private static final int MIN_DISTANCE = 1500;
|
||||
|
||||
private FairyTrees()
|
||||
{
|
||||
super(FairyTrees.class.getSimpleName(), "ai/group_template");
|
||||
addKillId(MOBS);
|
||||
addSpawnId(MOBS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc.calculateDistance(killer, true, false) <= MIN_DISTANCE)
|
||||
{
|
||||
for (int i = 0; i < 20; i++)
|
||||
{
|
||||
final L2Npc guardian = addSpawn(SOUL_GUARDIAN, npc, false, 30000);
|
||||
final L2Playable attacker = isSummon ? killer.getSummon() : killer;
|
||||
addAttackPlayerDesire(guardian, attacker);
|
||||
if (getRandomBoolean())
|
||||
{
|
||||
guardian.setTarget(attacker);
|
||||
guardian.doCast(VENOMOUS_POISON.getSkill());
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.setIsNoRndWalk(true);
|
||||
npc.setIsImmobilized(true);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FairyTrees();
|
||||
}
|
||||
}
|
||||
617
trunk/dist/game/data/scripts/ai/group_template/FeedableBeasts.java
vendored
Normal file
617
trunk/dist/game/data/scripts/ai/group_template/FeedableBeasts.java
vendored
Normal file
@@ -0,0 +1,617 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
import quests.Q00020_BringUpWithLove.Q00020_BringUpWithLove;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.NpcData;
|
||||
import com.l2jserver.gameserver.idfactory.IdFactory;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2TamedBeastInstance;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Growth-capable mobs: Polymorphing upon successful feeding.
|
||||
* @author Fulminus
|
||||
*/
|
||||
public final class FeedableBeasts extends AbstractNpcAI
|
||||
{
|
||||
private static final int GOLDEN_SPICE = 6643;
|
||||
private static final int CRYSTAL_SPICE = 6644;
|
||||
private static final int SKILL_GOLDEN_SPICE = 2188;
|
||||
private static final int SKILL_CRYSTAL_SPICE = 2189;
|
||||
private static final int FOODSKILLDIFF = GOLDEN_SPICE - SKILL_GOLDEN_SPICE;
|
||||
// @formatter:off
|
||||
private static final int[] TAMED_BEASTS =
|
||||
{
|
||||
16013, 16014, 16015, 16016, 16017, 16018
|
||||
};
|
||||
// all mobs that can eat...
|
||||
private static final int[] FEEDABLE_BEASTS =
|
||||
{
|
||||
21451, 21452, 21453, 21454, 21455, 21456, 21457, 21458, 21459, 21460,
|
||||
21461, 21462, 21463, 21464, 21465, 21466, 21467, 21468, 21469, 21470,
|
||||
21471, 21472, 21473, 21474, 21475, 21476, 21477, 21478, 21479, 21480,
|
||||
21481, 21482, 21483, 21484, 21485, 21486, 21487, 21488, 21489, 21490,
|
||||
21491, 21492, 21493, 21494, 21495, 21496, 21497, 21498, 21499, 21500,
|
||||
21501, 21502, 21503, 21504, 21505, 21506, 21507, 21824, 21825, 21826,
|
||||
21827, 21828, 21829, 16013, 16014, 16015, 16016, 16017, 16018
|
||||
};
|
||||
// @formatter:on
|
||||
|
||||
private static final Map<Integer, Integer> MAD_COW_POLYMORPH = new FastMap<>();
|
||||
static
|
||||
{
|
||||
MAD_COW_POLYMORPH.put(21824, 21468);
|
||||
MAD_COW_POLYMORPH.put(21825, 21469);
|
||||
MAD_COW_POLYMORPH.put(21826, 21487);
|
||||
MAD_COW_POLYMORPH.put(21827, 21488);
|
||||
MAD_COW_POLYMORPH.put(21828, 21506);
|
||||
MAD_COW_POLYMORPH.put(21829, 21507);
|
||||
}
|
||||
|
||||
private static final NpcStringId[][] TEXT =
|
||||
{
|
||||
{
|
||||
NpcStringId.WHAT_DID_YOU_JUST_DO_TO_ME,
|
||||
NpcStringId.ARE_YOU_TRYING_TO_TAME_ME_DON_T_DO_THAT,
|
||||
NpcStringId.DON_T_GIVE_SUCH_A_THING_YOU_CAN_ENDANGER_YOURSELF,
|
||||
NpcStringId.YUCK_WHAT_IS_THIS_IT_TASTES_TERRIBLE,
|
||||
NpcStringId.I_M_HUNGRY_GIVE_ME_A_LITTLE_MORE_PLEASE,
|
||||
NpcStringId.WHAT_IS_THIS_IS_THIS_EDIBLE,
|
||||
NpcStringId.DON_T_WORRY_ABOUT_ME,
|
||||
NpcStringId.THANK_YOU_THAT_WAS_DELICIOUS,
|
||||
NpcStringId.I_THINK_I_AM_STARTING_TO_LIKE_YOU,
|
||||
NpcStringId.EEEEEK_EEEEEK
|
||||
},
|
||||
{
|
||||
NpcStringId.DON_T_KEEP_TRYING_TO_TAME_ME_I_DON_T_WANT_TO_BE_TAMED,
|
||||
NpcStringId.IT_IS_JUST_FOOD_TO_ME_ALTHOUGH_IT_MAY_ALSO_BE_YOUR_HAND,
|
||||
NpcStringId.IF_I_KEEP_EATING_LIKE_THIS_WON_T_I_BECOME_FAT_CHOMP_CHOMP,
|
||||
NpcStringId.WHY_DO_YOU_KEEP_FEEDING_ME,
|
||||
NpcStringId.DON_T_TRUST_ME_I_M_AFRAID_I_MAY_BETRAY_YOU_LATER
|
||||
},
|
||||
{
|
||||
NpcStringId.GRRRRR,
|
||||
NpcStringId.YOU_BROUGHT_THIS_UPON_YOURSELF,
|
||||
NpcStringId.I_FEEL_STRANGE_I_KEEP_HAVING_THESE_EVIL_THOUGHTS,
|
||||
NpcStringId.ALAS_SO_THIS_IS_HOW_IT_ALL_ENDS,
|
||||
NpcStringId.I_DON_T_FEEL_SO_GOOD_OH_MY_MIND_IS_VERY_TROUBLED
|
||||
}
|
||||
};
|
||||
|
||||
private static final NpcStringId[] TAMED_TEXT =
|
||||
{
|
||||
NpcStringId.S1_SO_WHAT_DO_YOU_THINK_IT_IS_LIKE_TO_BE_TAMED,
|
||||
NpcStringId.S1_WHENEVER_I_SEE_SPICE_I_THINK_I_WILL_MISS_YOUR_HAND_THAT_USED_TO_FEED_IT_TO_ME,
|
||||
NpcStringId.S1_DON_T_GO_TO_THE_VILLAGE_I_DON_T_HAVE_THE_STRENGTH_TO_FOLLOW_YOU,
|
||||
NpcStringId.THANK_YOU_FOR_TRUSTING_ME_S1_I_HOPE_I_WILL_BE_HELPFUL_TO_YOU,
|
||||
NpcStringId.S1_WILL_I_BE_ABLE_TO_HELP_YOU,
|
||||
NpcStringId.I_GUESS_IT_S_JUST_MY_ANIMAL_MAGNETISM,
|
||||
NpcStringId.TOO_MUCH_SPICY_FOOD_MAKES_ME_SWEAT_LIKE_A_BEAST,
|
||||
NpcStringId.ANIMALS_NEED_LOVE_TOO
|
||||
};
|
||||
|
||||
private static Map<Integer, Integer> _FeedInfo = new FastMap<>();
|
||||
private static Map<Integer, GrowthCapableMob> _GrowthCapableMobs = new FastMap<>();
|
||||
|
||||
// all mobs that grow by eating
|
||||
private static class GrowthCapableMob
|
||||
{
|
||||
private final int _growthLevel;
|
||||
private final int _chance;
|
||||
|
||||
private final Map<Integer, int[][]> _spiceToMob = new FastMap<>();
|
||||
|
||||
public GrowthCapableMob(int growthLevel, int chance)
|
||||
{
|
||||
_growthLevel = growthLevel;
|
||||
_chance = chance;
|
||||
}
|
||||
|
||||
public void addMobs(int spice, int[][] Mobs)
|
||||
{
|
||||
_spiceToMob.put(spice, Mobs);
|
||||
}
|
||||
|
||||
public Integer getMob(int spice, int mobType, int classType)
|
||||
{
|
||||
if (_spiceToMob.containsKey(spice))
|
||||
{
|
||||
return _spiceToMob.get(spice)[mobType][classType];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public Integer getRandomMob(int spice)
|
||||
{
|
||||
int[][] temp;
|
||||
temp = _spiceToMob.get(spice);
|
||||
int rand = getRandom(temp[0].length);
|
||||
return temp[0][rand];
|
||||
}
|
||||
|
||||
public Integer getChance()
|
||||
{
|
||||
return _chance;
|
||||
}
|
||||
|
||||
public Integer getGrowthLevel()
|
||||
{
|
||||
return _growthLevel;
|
||||
}
|
||||
}
|
||||
|
||||
private FeedableBeasts()
|
||||
{
|
||||
super(FeedableBeasts.class.getSimpleName(), "ai/group_template");
|
||||
addKillId(FEEDABLE_BEASTS);
|
||||
addSkillSeeId(FEEDABLE_BEASTS);
|
||||
|
||||
// TODO: no grendels?
|
||||
GrowthCapableMob temp;
|
||||
|
||||
//@formatter:off
|
||||
final int[][] Kookabura_0_Gold = {{ 21452, 21453, 21454, 21455 }};
|
||||
final int[][] Kookabura_0_Crystal = {{ 21456, 21457, 21458, 21459 }};
|
||||
final int[][] Kookabura_1_Gold_1= {{ 21460, 21462 }};
|
||||
final int[][] Kookabura_1_Gold_2 = {{ 21461, 21463 }};
|
||||
final int[][] Kookabura_1_Crystal_1 = {{ 21464, 21466 }};
|
||||
final int[][] Kookabura_1_Crystal_2 = {{ 21465, 21467 }};
|
||||
final int[][] Kookabura_2_1 = {{ 21468, 21824}, { 16017, 16018 }};
|
||||
final int[][] Kookabura_2_2 = {{ 21469, 21825}, { 16017, 16018 }};
|
||||
|
||||
final int[][] Buffalo_0_Gold = {{ 21471, 21472, 21473, 21474 }};
|
||||
final int[][] Buffalo_0_Crystal = {{ 21475, 21476, 21477, 21478 }};
|
||||
final int[][] Buffalo_1_Gold_1 = {{ 21479, 21481 }};
|
||||
final int[][] Buffalo_1_Gold_2 = {{ 21481, 21482 }};
|
||||
final int[][] Buffalo_1_Crystal_1 = {{ 21483, 21485 }};
|
||||
final int[][] Buffalo_1_Crystal_2 = {{ 21484, 21486 }};
|
||||
final int[][] Buffalo_2_1 = {{ 21487,21826}, {16013, 16014 }};
|
||||
final int[][] Buffalo_2_2 = {{ 21488,21827}, {16013, 16014 }};
|
||||
|
||||
final int[][] Cougar_0_Gold = {{ 21490, 21491, 21492, 21493 }};
|
||||
final int[][] Cougar_0_Crystal = {{ 21494,21495, 21496, 21497 }};
|
||||
final int[][] Cougar_1_Gold_1 = {{ 21498, 21500 }};
|
||||
final int[][] Cougar_1_Gold_2 = {{ 21499, 21501 }};
|
||||
final int[][] Cougar_1_Crystal_1 = {{ 21502,21504 }};
|
||||
final int[][] Cougar_1_Crystal_2 = {{ 21503,21505 }};
|
||||
final int[][] Cougar_2_1 = {{ 21506, 21828 }, { 16015,16016 }};
|
||||
final int[][] Cougar_2_2 = {{ 21507, 21829 }, { 16015,16016 }};
|
||||
//@formatter:on
|
||||
|
||||
// Alpen Kookabura
|
||||
temp = new GrowthCapableMob(0, 100);
|
||||
temp.addMobs(GOLDEN_SPICE, Kookabura_0_Gold);
|
||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_0_Crystal);
|
||||
_GrowthCapableMobs.put(21451, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Kookabura_1_Gold_1);
|
||||
_GrowthCapableMobs.put(21452, temp);
|
||||
_GrowthCapableMobs.put(21454, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Kookabura_1_Gold_2);
|
||||
_GrowthCapableMobs.put(21453, temp);
|
||||
_GrowthCapableMobs.put(21455, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_1_Crystal_1);
|
||||
_GrowthCapableMobs.put(21456, temp);
|
||||
_GrowthCapableMobs.put(21458, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_1_Crystal_2);
|
||||
_GrowthCapableMobs.put(21457, temp);
|
||||
_GrowthCapableMobs.put(21459, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Kookabura_2_1);
|
||||
_GrowthCapableMobs.put(21460, temp);
|
||||
_GrowthCapableMobs.put(21462, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Kookabura_2_2);
|
||||
_GrowthCapableMobs.put(21461, temp);
|
||||
_GrowthCapableMobs.put(21463, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_2_1);
|
||||
_GrowthCapableMobs.put(21464, temp);
|
||||
_GrowthCapableMobs.put(21466, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Kookabura_2_2);
|
||||
_GrowthCapableMobs.put(21465, temp);
|
||||
_GrowthCapableMobs.put(21467, temp);
|
||||
|
||||
// Alpen Buffalo
|
||||
temp = new GrowthCapableMob(0, 100);
|
||||
temp.addMobs(GOLDEN_SPICE, Buffalo_0_Gold);
|
||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_0_Crystal);
|
||||
_GrowthCapableMobs.put(21470, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Buffalo_1_Gold_1);
|
||||
_GrowthCapableMobs.put(21471, temp);
|
||||
_GrowthCapableMobs.put(21473, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Buffalo_1_Gold_2);
|
||||
_GrowthCapableMobs.put(21472, temp);
|
||||
_GrowthCapableMobs.put(21474, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_1_Crystal_1);
|
||||
_GrowthCapableMobs.put(21475, temp);
|
||||
_GrowthCapableMobs.put(21477, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_1_Crystal_2);
|
||||
_GrowthCapableMobs.put(21476, temp);
|
||||
_GrowthCapableMobs.put(21478, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Buffalo_2_1);
|
||||
_GrowthCapableMobs.put(21479, temp);
|
||||
_GrowthCapableMobs.put(21481, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Buffalo_2_2);
|
||||
_GrowthCapableMobs.put(21480, temp);
|
||||
_GrowthCapableMobs.put(21482, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_2_1);
|
||||
_GrowthCapableMobs.put(21483, temp);
|
||||
_GrowthCapableMobs.put(21485, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Buffalo_2_2);
|
||||
_GrowthCapableMobs.put(21484, temp);
|
||||
_GrowthCapableMobs.put(21486, temp);
|
||||
|
||||
// Alpen Cougar
|
||||
temp = new GrowthCapableMob(0, 100);
|
||||
temp.addMobs(GOLDEN_SPICE, Cougar_0_Gold);
|
||||
temp.addMobs(CRYSTAL_SPICE, Cougar_0_Crystal);
|
||||
_GrowthCapableMobs.put(21489, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Cougar_1_Gold_1);
|
||||
_GrowthCapableMobs.put(21490, temp);
|
||||
_GrowthCapableMobs.put(21492, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(GOLDEN_SPICE, Cougar_1_Gold_2);
|
||||
_GrowthCapableMobs.put(21491, temp);
|
||||
_GrowthCapableMobs.put(21493, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Cougar_1_Crystal_1);
|
||||
_GrowthCapableMobs.put(21494, temp);
|
||||
_GrowthCapableMobs.put(21496, temp);
|
||||
|
||||
temp = new GrowthCapableMob(1, 40);
|
||||
temp.addMobs(CRYSTAL_SPICE, Cougar_1_Crystal_2);
|
||||
_GrowthCapableMobs.put(21495, temp);
|
||||
_GrowthCapableMobs.put(21497, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Cougar_2_1);
|
||||
_GrowthCapableMobs.put(21498, temp);
|
||||
_GrowthCapableMobs.put(21500, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(GOLDEN_SPICE, Cougar_2_2);
|
||||
_GrowthCapableMobs.put(21499, temp);
|
||||
_GrowthCapableMobs.put(21501, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Cougar_2_1);
|
||||
_GrowthCapableMobs.put(21502, temp);
|
||||
_GrowthCapableMobs.put(21504, temp);
|
||||
|
||||
temp = new GrowthCapableMob(2, 25);
|
||||
temp.addMobs(CRYSTAL_SPICE, Cougar_2_2);
|
||||
_GrowthCapableMobs.put(21503, temp);
|
||||
_GrowthCapableMobs.put(21505, temp);
|
||||
}
|
||||
|
||||
private void spawnNext(L2Npc npc, int growthLevel, L2PcInstance player, int food)
|
||||
{
|
||||
int npcId = npc.getId();
|
||||
int nextNpcId = 0;
|
||||
|
||||
// find the next mob to spawn, based on the current npcId, growthlevel, and food.
|
||||
if (growthLevel == 2)
|
||||
{
|
||||
// if tamed, the mob that will spawn depends on the class type (fighter/mage) of the player!
|
||||
if (getRandom(2) == 0)
|
||||
{
|
||||
if (player.getClassId().isMage())
|
||||
{
|
||||
nextNpcId = _GrowthCapableMobs.get(npcId).getMob(food, 1, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextNpcId = _GrowthCapableMobs.get(npcId).getMob(food, 1, 0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// if not tamed, there is a small chance that have "mad cow" disease.
|
||||
// that is a stronger-than-normal animal that attacks its feeder
|
||||
if (getRandom(5) == 0)
|
||||
{
|
||||
nextNpcId = _GrowthCapableMobs.get(npcId).getMob(food, 0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
nextNpcId = _GrowthCapableMobs.get(npcId).getMob(food, 0, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// all other levels of growth are straight-forward
|
||||
nextNpcId = _GrowthCapableMobs.get(npcId).getRandomMob(food);
|
||||
}
|
||||
|
||||
// remove the feedinfo of the mob that got despawned, if any
|
||||
if (_FeedInfo.containsKey(npc.getObjectId()))
|
||||
{
|
||||
if (_FeedInfo.get(npc.getObjectId()) == player.getObjectId())
|
||||
{
|
||||
_FeedInfo.remove(npc.getObjectId());
|
||||
}
|
||||
}
|
||||
// despawn the old mob
|
||||
// TODO: same code? FIXED?
|
||||
// @formatter:off
|
||||
/*
|
||||
* if (_GrowthCapableMobs.get(npcId).getGrowthLevel() == 0)
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
else
|
||||
{
|
||||
*/
|
||||
npc.deleteMe();
|
||||
// }
|
||||
// @formatter:on
|
||||
|
||||
// if this is finally a trained mob, then despawn any other trained mobs that the
|
||||
// player might have and initialize the Tamed Beast.
|
||||
if (Util.contains(TAMED_BEASTS, nextNpcId))
|
||||
{
|
||||
if ((player.getTrainedBeasts() != null) && !player.getTrainedBeasts().isEmpty())
|
||||
{
|
||||
for (L2TamedBeastInstance oldTrained : player.getTrainedBeasts())
|
||||
{
|
||||
oldTrained.deleteMe();
|
||||
}
|
||||
}
|
||||
|
||||
L2NpcTemplate template = NpcData.getInstance().getTemplate(nextNpcId);
|
||||
L2TamedBeastInstance nextNpc = new L2TamedBeastInstance(IdFactory.getInstance().getNextId(), template, player, food - FOODSKILLDIFF, npc.getX(), npc.getY(), npc.getZ());
|
||||
nextNpc.setRunning();
|
||||
Q00020_BringUpWithLove.checkJewelOfInnocence(player);
|
||||
|
||||
// also, perform a rare random chat
|
||||
if (getRandom(20) == 0)
|
||||
{
|
||||
NpcStringId message = NpcStringId.getNpcStringId(getRandom(2024, 2029));
|
||||
NpcSay packet = new NpcSay(nextNpc, 0, message);
|
||||
if (message.getParamCount() > 0) // player name, $s1
|
||||
{
|
||||
packet.addStringParameter(player.getName());
|
||||
}
|
||||
npc.broadcastPacket(packet);
|
||||
}
|
||||
// @formatter:off
|
||||
/*
|
||||
TODO: The tamed beast consumes one golden/crystal spice
|
||||
every 60 seconds with an initial delay of 60 seconds
|
||||
if (tamed beast exists and is alive)
|
||||
{
|
||||
if (player has 1+ golden/crystal spice)
|
||||
{
|
||||
take one golden/crystal spice;
|
||||
say random NpcString(getRandom(2029, 2038));
|
||||
}
|
||||
}
|
||||
*/
|
||||
// @formatter:on
|
||||
}
|
||||
else
|
||||
{
|
||||
// if not trained, the newly spawned mob will automatically be aggro against its feeder
|
||||
// (what happened to "never bite the hand that feeds you" anyway?!)
|
||||
L2Attackable nextNpc = (L2Attackable) addSpawn(nextNpcId, npc);
|
||||
|
||||
if (MAD_COW_POLYMORPH.containsKey(nextNpcId))
|
||||
{
|
||||
this.startQuestTimer("polymorph Mad Cow", 10000, nextNpc, player);
|
||||
}
|
||||
|
||||
// register the player in the feedinfo for the mob that just spawned
|
||||
_FeedInfo.put(nextNpc.getObjectId(), player.getObjectId());
|
||||
nextNpc.setRunning();
|
||||
nextNpc.addDamageHate(player, 0, 99999);
|
||||
nextNpc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equalsIgnoreCase("polymorph Mad Cow") && (npc != null) && (player != null))
|
||||
{
|
||||
if (MAD_COW_POLYMORPH.containsKey(npc.getId()))
|
||||
{
|
||||
// remove the feed info from the previous mob
|
||||
if (_FeedInfo.get(npc.getObjectId()) == player.getObjectId())
|
||||
{
|
||||
_FeedInfo.remove(npc.getObjectId());
|
||||
}
|
||||
// despawn the mad cow
|
||||
npc.deleteMe();
|
||||
// spawn the new mob
|
||||
L2Attackable nextNpc = (L2Attackable) addSpawn(MAD_COW_POLYMORPH.get(npc.getId()), npc);
|
||||
|
||||
// register the player in the feedinfo for the mob that just spawned
|
||||
_FeedInfo.put(nextNpc.getObjectId(), player.getObjectId());
|
||||
nextNpc.setRunning();
|
||||
nextNpc.addDamageHate(player, 0, 99999);
|
||||
nextNpc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, player);
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
// this behavior is only run when the target of skill is the passed npc (chest)
|
||||
// i.e. when the player is attempting to open the chest using a skill
|
||||
if (!Util.contains(targets, npc))
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
// gather some values on local variables
|
||||
int npcId = npc.getId();
|
||||
int skillId = skill.getId();
|
||||
// check if the npc and skills used are valid for this script. Exit if invalid.
|
||||
if ((skillId != SKILL_GOLDEN_SPICE) && (skillId != SKILL_CRYSTAL_SPICE))
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
// first gather some values on local variables
|
||||
int objectId = npc.getObjectId();
|
||||
int growthLevel = 3; // if a mob is in FEEDABLE_BEASTS but not in _GrowthCapableMobs, then it's at max growth (3)
|
||||
if (_GrowthCapableMobs.containsKey(npcId))
|
||||
{
|
||||
growthLevel = _GrowthCapableMobs.get(npcId).getGrowthLevel();
|
||||
}
|
||||
|
||||
// prevent exploit which allows 2 players to simultaneously raise the same 0-growth beast
|
||||
// If the mob is at 0th level (when it still listens to all feeders) lock it to the first feeder!
|
||||
if ((growthLevel == 0) && _FeedInfo.containsKey(objectId))
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
_FeedInfo.put(objectId, caster.getObjectId());
|
||||
|
||||
int food = 0;
|
||||
if (skillId == SKILL_GOLDEN_SPICE)
|
||||
{
|
||||
food = GOLDEN_SPICE;
|
||||
}
|
||||
else if (skillId == SKILL_CRYSTAL_SPICE)
|
||||
{
|
||||
food = CRYSTAL_SPICE;
|
||||
}
|
||||
|
||||
// display the social action of the beast eating the food.
|
||||
npc.broadcastSocialAction(2);
|
||||
|
||||
// if this pet can't grow, it's all done.
|
||||
if (_GrowthCapableMobs.containsKey(npcId))
|
||||
{
|
||||
// do nothing if this mob doesn't eat the specified food (food gets consumed but has no effect).
|
||||
if (_GrowthCapableMobs.get(npcId).getMob(food, 0, 0) == null)
|
||||
{
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
// rare random talk...
|
||||
if (getRandom(20) == 0)
|
||||
{
|
||||
NpcStringId message = TEXT[growthLevel][getRandom(TEXT[growthLevel].length)];
|
||||
NpcSay packet = new NpcSay(npc, 0, message);
|
||||
if (message.getParamCount() > 0) // player name, $s1
|
||||
{
|
||||
packet.addStringParameter(caster.getName());
|
||||
}
|
||||
npc.broadcastPacket(packet);
|
||||
}
|
||||
|
||||
if ((growthLevel > 0) && (_FeedInfo.get(objectId) != caster.getObjectId()))
|
||||
{
|
||||
// check if this is the same player as the one who raised it from growth 0.
|
||||
// if no, then do not allow a chance to raise the pet (food gets consumed but has no effect).
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
// Polymorph the mob, with a certain chance, given its current growth level
|
||||
if (getRandom(100) < _GrowthCapableMobs.get(npcId).getChance())
|
||||
{
|
||||
spawnNext(npc, growthLevel, caster, food);
|
||||
}
|
||||
}
|
||||
else if (Util.contains(TAMED_BEASTS, npcId) && (npc instanceof L2TamedBeastInstance))
|
||||
{
|
||||
L2TamedBeastInstance beast = ((L2TamedBeastInstance) npc);
|
||||
if (skillId == beast.getFoodType())
|
||||
{
|
||||
beast.onReceiveFood();
|
||||
NpcStringId message = TAMED_TEXT[getRandom(TAMED_TEXT.length)];
|
||||
NpcSay packet = new NpcSay(npc, 0, message);
|
||||
if (message.getParamCount() > 0)
|
||||
{
|
||||
packet.addStringParameter(caster.getName());
|
||||
}
|
||||
beast.broadcastPacket(packet);
|
||||
}
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
// remove the feedinfo of the mob that got killed, if any
|
||||
if (_FeedInfo.containsKey(npc.getObjectId()))
|
||||
{
|
||||
_FeedInfo.remove(npc.getObjectId());
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FeedableBeasts();
|
||||
}
|
||||
}
|
||||
94
trunk/dist/game/data/scripts/ai/group_template/FleeMonsters.java
vendored
Normal file
94
trunk/dist/game/data/scripts/ai/group_template/FleeMonsters.java
vendored
Normal file
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.GeoData;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.interfaces.ILocational;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Flee Monsters AI.
|
||||
* @author Pandragon, NosBit
|
||||
*/
|
||||
public final class FleeMonsters extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int[] MOBS =
|
||||
{
|
||||
18150, // Victim
|
||||
18151, // Victim
|
||||
18152, // Victim
|
||||
18153, // Victim
|
||||
18154, // Victim
|
||||
18155, // Victim
|
||||
18156, // Victim
|
||||
18157, // Victim
|
||||
20002, // Rabbit
|
||||
20432, // Elpy
|
||||
22228, // Grey Elpy
|
||||
25604, // Mutated Elpy
|
||||
};
|
||||
// Misc
|
||||
private static final int FLEE_DISTANCE = 500;
|
||||
|
||||
private FleeMonsters()
|
||||
{
|
||||
super(FleeMonsters.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(MOBS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
npc.disableCoreAI(true);
|
||||
npc.setRunning();
|
||||
|
||||
final L2Summon summon = isSummon ? attacker.getSummon() : null;
|
||||
final ILocational attackerLoc = summon == null ? attacker : summon;
|
||||
final double radians = Math.toRadians(Util.calculateAngleFrom(attackerLoc, npc));
|
||||
final int posX = (int) (npc.getX() + (FLEE_DISTANCE * Math.cos(radians)));
|
||||
final int posY = (int) (npc.getY() + (FLEE_DISTANCE * Math.sin(radians)));
|
||||
final int posZ = npc.getZ();
|
||||
|
||||
final Location destination;
|
||||
if (Config.GEODATA > 0)
|
||||
{
|
||||
destination = GeoData.getInstance().moveCheck(npc.getX(), npc.getY(), npc.getZ(), posX, posY, posZ, attacker.getInstanceId());
|
||||
}
|
||||
else
|
||||
{
|
||||
destination = new Location(posX, posY, posZ);
|
||||
}
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, destination);
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FleeMonsters();
|
||||
}
|
||||
}
|
||||
71
trunk/dist/game/data/scripts/ai/group_template/FrozenLabyrinth.java
vendored
Normal file
71
trunk/dist/game/data/scripts/ai/group_template/FrozenLabyrinth.java
vendored
Normal file
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* Frozen Labyrinth AI.
|
||||
* @author malyelfik
|
||||
*/
|
||||
public final class FrozenLabyrinth extends AbstractNpcAI
|
||||
{
|
||||
// Monsters
|
||||
private static final int PRONGHORN_SPIRIT = 22087;
|
||||
private static final int PRONGHORN = 22088;
|
||||
private static final int LOST_BUFFALO = 22093;
|
||||
private static final int FROST_BUFFALO = 22094;
|
||||
|
||||
private FrozenLabyrinth()
|
||||
{
|
||||
super(FrozenLabyrinth.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(PRONGHORN, FROST_BUFFALO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill)
|
||||
{
|
||||
if (npc.isScriptValue(0) && (skill != null) && !skill.isMagic())
|
||||
{
|
||||
final int spawnId = (npc.getId() == PRONGHORN) ? PRONGHORN_SPIRIT : LOST_BUFFALO;
|
||||
int diff = 0;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
final int x = diff < 60 ? npc.getX() + diff : npc.getX();
|
||||
final int y = diff >= 60 ? npc.getY() + (diff - 40) : npc.getY();
|
||||
|
||||
final L2Npc monster = addSpawn(spawnId, x, y, npc.getZ(), npc.getHeading(), false, 0);
|
||||
addAttackPlayerDesire(monster, attacker);
|
||||
diff += 20;
|
||||
}
|
||||
npc.setScriptValue(1);
|
||||
npc.deleteMe();
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon, skill);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FrozenLabyrinth();
|
||||
}
|
||||
}
|
||||
114
trunk/dist/game/data/scripts/ai/group_template/GiantsCave.java
vendored
Normal file
114
trunk/dist/game/data/scripts/ai/group_template/GiantsCave.java
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Giant's Cave AI.
|
||||
* @author Gnacik, St3eT
|
||||
*/
|
||||
public final class GiantsCave extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int[] SCOUTS =
|
||||
{
|
||||
22668, // Gamlin (Scout)
|
||||
22669, // Leogul (Scout)
|
||||
};
|
||||
|
||||
private GiantsCave()
|
||||
{
|
||||
super(GiantsCave.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(SCOUTS);
|
||||
addAggroRangeEnterId(SCOUTS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("ATTACK") && (player != null) && (npc != null) && !npc.isDead())
|
||||
{
|
||||
if (npc.getId() == SCOUTS[0]) // Gamlin
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_SHOUT, NpcStringId.INTRUDER_DETECTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_SHOUT, NpcStringId.OH_GIANTS_AN_INTRUDER_HAS_BEEN_DISCOVERED);
|
||||
}
|
||||
|
||||
for (L2Character characters : npc.getKnownList().getKnownCharactersInRadius(450))
|
||||
{
|
||||
if ((characters != null) && (characters.isAttackable()) && (getRandomBoolean()))
|
||||
{
|
||||
addAttackPlayerDesire((L2Npc) characters, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.equals("CLEAR") && (npc != null) && !npc.isDead())
|
||||
{
|
||||
npc.setScriptValue(0);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
startQuestTimer("ATTACK", 6000, npc, attacker);
|
||||
startQuestTimer("CLEAR", 120000, npc, null);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
if (npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
if (getRandomBoolean())
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.YOU_GUYS_ARE_DETECTED);
|
||||
}
|
||||
else
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.WHAT_KIND_OF_CREATURES_ARE_YOU);
|
||||
}
|
||||
startQuestTimer("ATTACK", 6000, npc, player);
|
||||
startQuestTimer("CLEAR", 120000, npc, null);
|
||||
}
|
||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new GiantsCave();
|
||||
}
|
||||
}
|
||||
109
trunk/dist/game/data/scripts/ai/group_template/HotSprings.java
vendored
Normal file
109
trunk/dist/game/data/scripts/ai/group_template/HotSprings.java
vendored
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.skills.BuffInfo;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* Hot Springs AI.
|
||||
* @author Pandragon
|
||||
*/
|
||||
public final class HotSprings extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int BANDERSNATCHLING = 21314;
|
||||
private static final int FLAVA = 21316;
|
||||
private static final int ATROXSPAWN = 21317;
|
||||
private static final int NEPENTHES = 21319;
|
||||
private static final int ATROX = 21321;
|
||||
private static final int BANDERSNATCH = 21322;
|
||||
// Skills
|
||||
private static final int RHEUMATISM = 4551;
|
||||
private static final int CHOLERA = 4552;
|
||||
private static final int FLU = 4553;
|
||||
private static final int MALARIA = 4554;
|
||||
// Misc
|
||||
private static final int DISEASE_CHANCE = 10;
|
||||
|
||||
private HotSprings()
|
||||
{
|
||||
super(HotSprings.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(BANDERSNATCHLING, FLAVA, ATROXSPAWN, NEPENTHES, ATROX, BANDERSNATCH);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (getRandom(100) < DISEASE_CHANCE)
|
||||
{
|
||||
tryToInfect(npc, attacker, MALARIA);
|
||||
}
|
||||
|
||||
if (getRandom(100) < DISEASE_CHANCE)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case BANDERSNATCHLING:
|
||||
case ATROX:
|
||||
{
|
||||
tryToInfect(npc, attacker, RHEUMATISM);
|
||||
break;
|
||||
}
|
||||
case FLAVA:
|
||||
case NEPENTHES:
|
||||
{
|
||||
tryToInfect(npc, attacker, CHOLERA);
|
||||
break;
|
||||
}
|
||||
case ATROXSPAWN:
|
||||
case BANDERSNATCH:
|
||||
{
|
||||
tryToInfect(npc, attacker, FLU);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
private void tryToInfect(L2Npc npc, L2Character player, int diseaseId)
|
||||
{
|
||||
final BuffInfo info = player.getEffectList().getBuffInfoBySkillId(diseaseId);
|
||||
final int skillLevel = (info == null) ? 1 : (info.getSkill().getLevel() < 10) ? info.getSkill().getLevel() + 1 : 10;
|
||||
final Skill skill = SkillData.getInstance().getSkill(diseaseId, skillLevel);
|
||||
|
||||
if ((skill != null) && !npc.isCastingNow() && npc.checkDoCastConditions(skill))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(skill);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new HotSprings();
|
||||
}
|
||||
}
|
||||
83
trunk/dist/game/data/scripts/ai/group_template/IsleOfPrayer.java
vendored
Normal file
83
trunk/dist/game/data/scripts/ai/group_template/IsleOfPrayer.java
vendored
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.ItemChanceHolder;
|
||||
|
||||
/**
|
||||
* Isle of Prayer AI.
|
||||
* @author Zoey76
|
||||
*/
|
||||
public final class IsleOfPrayer extends AbstractNpcAI
|
||||
{
|
||||
// Items
|
||||
private static final int YELLOW_SEED_OF_EVIL_SHARD = 9593;
|
||||
private static final int GREEN_SEED_OF_EVIL_SHARD = 9594;
|
||||
private static final int BLUE_SEED_OF_EVIL_SHARD = 9595;
|
||||
private static final int RED_SEED_OF_EVIL_SHARD = 9596;
|
||||
// Monsters
|
||||
private static final Map<Integer, ItemChanceHolder> MONSTERS = new HashMap<>();
|
||||
static
|
||||
{
|
||||
MONSTERS.put(22257, new ItemChanceHolder(YELLOW_SEED_OF_EVIL_SHARD, 2087)); // Island Guardian
|
||||
MONSTERS.put(22258, new ItemChanceHolder(YELLOW_SEED_OF_EVIL_SHARD, 2147)); // White Sand Mirage
|
||||
MONSTERS.put(22259, new ItemChanceHolder(YELLOW_SEED_OF_EVIL_SHARD, 2642)); // Muddy Coral
|
||||
MONSTERS.put(22260, new ItemChanceHolder(YELLOW_SEED_OF_EVIL_SHARD, 2292)); // Kleopora
|
||||
MONSTERS.put(22261, new ItemChanceHolder(GREEN_SEED_OF_EVIL_SHARD, 1171)); // Seychelles
|
||||
MONSTERS.put(22262, new ItemChanceHolder(GREEN_SEED_OF_EVIL_SHARD, 1173)); // Naiad
|
||||
MONSTERS.put(22263, new ItemChanceHolder(GREEN_SEED_OF_EVIL_SHARD, 1403)); // Sonneratia
|
||||
MONSTERS.put(22264, new ItemChanceHolder(GREEN_SEED_OF_EVIL_SHARD, 1207)); // Castalia
|
||||
MONSTERS.put(22265, new ItemChanceHolder(RED_SEED_OF_EVIL_SHARD, 575)); // Chrysocolla
|
||||
MONSTERS.put(22266, new ItemChanceHolder(RED_SEED_OF_EVIL_SHARD, 493)); // Pythia
|
||||
MONSTERS.put(22267, new ItemChanceHolder(RED_SEED_OF_EVIL_SHARD, 770)); // Dark Water Dragon
|
||||
MONSTERS.put(22268, new ItemChanceHolder(BLUE_SEED_OF_EVIL_SHARD, 987)); // Shade
|
||||
MONSTERS.put(22269, new ItemChanceHolder(BLUE_SEED_OF_EVIL_SHARD, 995)); // Shade
|
||||
MONSTERS.put(22270, new ItemChanceHolder(BLUE_SEED_OF_EVIL_SHARD, 1008)); // Water Dragon Detractor
|
||||
MONSTERS.put(22271, new ItemChanceHolder(BLUE_SEED_OF_EVIL_SHARD, 1008)); // Water Dragon Detractor
|
||||
}
|
||||
|
||||
private IsleOfPrayer()
|
||||
{
|
||||
super(IsleOfPrayer.class.getSimpleName(), "ai/group_template");
|
||||
addKillId(MONSTERS.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final ItemChanceHolder holder = MONSTERS.get(npc.getId());
|
||||
if (getRandom(10000) <= holder.getChance())
|
||||
{
|
||||
npc.dropItem(killer, holder);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new IsleOfPrayer();
|
||||
}
|
||||
}
|
||||
144
trunk/dist/game/data/scripts/ai/group_template/LairOfAntharas.java
vendored
Normal file
144
trunk/dist/game/data/scripts/ai/group_template/LairOfAntharas.java
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ValidateLocation;
|
||||
|
||||
/**
|
||||
* Lair of Antharas AI.
|
||||
* @author St3eT, UnAfraid
|
||||
*/
|
||||
public final class LairOfAntharas extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
final private static int KNORIKS = 22857;
|
||||
final private static int DRAGON_KNIGHT = 22844;
|
||||
final private static int DRAGON_KNIGHT2 = 22845;
|
||||
final private static int ELITE_DRAGON_KNIGHT = 22846;
|
||||
|
||||
final private static int DRAGON_GUARD = 22852;
|
||||
final private static int DRAGON_MAGE = 22853;
|
||||
// Misc
|
||||
final private static int KNIGHT_CHANCE = 30;
|
||||
final private static int KNORIKS_CHANCE = 60;
|
||||
final private static int KNORIKS_CHANCE2 = 50;
|
||||
|
||||
private LairOfAntharas()
|
||||
{
|
||||
super(LairOfAntharas.class.getSimpleName(), "ai/group_template");
|
||||
addKillId(DRAGON_KNIGHT, DRAGON_KNIGHT2, DRAGON_GUARD, DRAGON_MAGE);
|
||||
addSpawnId(DRAGON_KNIGHT, DRAGON_KNIGHT2, DRAGON_GUARD, DRAGON_MAGE);
|
||||
addMoveFinishedId(DRAGON_GUARD, DRAGON_MAGE);
|
||||
addAggroRangeEnterId(KNORIKS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("CHECK_HOME") && (npc != null) && !npc.isDead())
|
||||
{
|
||||
if ((npc.calculateDistance(npc.getSpawn().getLocation(), false, false) > 10) && !npc.isInCombat())
|
||||
{
|
||||
((L2Attackable) npc).returnHome();
|
||||
}
|
||||
else if ((npc.getHeading() != npc.getSpawn().getHeading()) && !npc.isInCombat())
|
||||
{
|
||||
npc.setHeading(npc.getSpawn().getHeading());
|
||||
npc.broadcastPacket(new ValidateLocation(npc));
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
if (npc.isScriptValue(0) && (getRandom(100) < KNORIKS_CHANCE))
|
||||
{
|
||||
if (getRandom(100) < KNORIKS_CHANCE2)
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
broadcastNpcSay(npc, Say2.NPC_SHOUT, NpcStringId.WHO_S_THERE_IF_YOU_DISTURB_THE_TEMPER_OF_THE_GREAT_LAND_DRAGON_ANTHARAS_I_WILL_NEVER_FORGIVE_YOU);
|
||||
}
|
||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case DRAGON_KNIGHT:
|
||||
{
|
||||
if (getRandom(100) > KNIGHT_CHANCE)
|
||||
{
|
||||
final L2Npc newKnight = addSpawn(DRAGON_KNIGHT2, npc, false, 0, true);
|
||||
npc.deleteMe();
|
||||
broadcastNpcSay(newKnight, Say2.NPC_SHOUT, NpcStringId.THOSE_WHO_SET_FOOT_IN_THIS_PLACE_SHALL_NOT_LEAVE_ALIVE);
|
||||
addAttackPlayerDesire(newKnight, killer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DRAGON_KNIGHT2:
|
||||
{
|
||||
if (getRandom(100) > KNIGHT_CHANCE)
|
||||
{
|
||||
final L2Npc eliteKnight = addSpawn(ELITE_DRAGON_KNIGHT, npc, false, 0, true);
|
||||
npc.deleteMe();
|
||||
broadcastNpcSay(eliteKnight, Say2.NPC_SHOUT, NpcStringId.IF_YOU_WISH_TO_SEE_HELL_I_WILL_GRANT_YOU_YOUR_WISH);
|
||||
addAttackPlayerDesire(eliteKnight, killer);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case DRAGON_GUARD:
|
||||
case DRAGON_MAGE:
|
||||
{
|
||||
cancelQuestTimer("CHECK_HOME", npc, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
mob.setOnKillDelay(0);
|
||||
if ((npc.getId() == DRAGON_GUARD) || (npc.getId() == DRAGON_MAGE))
|
||||
{
|
||||
mob.setIsNoRndWalk(true);
|
||||
startQuestTimer("CHECK_HOME", 10000, npc, null, true);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new LairOfAntharas();
|
||||
}
|
||||
}
|
||||
455
trunk/dist/game/data/scripts/ai/group_template/MinionSpawnManager.java
vendored
Normal file
455
trunk/dist/game/data/scripts/ai/group_template/MinionSpawnManager.java
vendored
Normal file
@@ -0,0 +1,455 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.MinionHolder;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Minion Spawn Manager.
|
||||
* @author Zealar
|
||||
*/
|
||||
public final class MinionSpawnManager extends AbstractNpcAI
|
||||
{
|
||||
private static final Set<Integer> NPC = new HashSet<>(354);
|
||||
|
||||
static
|
||||
{
|
||||
NPC.add(18344); // Ancient Egg
|
||||
NPC.add(18352); // Kamael Guard
|
||||
NPC.add(18353); // Guardian of Records
|
||||
NPC.add(18354); // Guardian of Observation
|
||||
NPC.add(18355); // Spicula's Guard
|
||||
NPC.add(18356); // Harkilgamed's Gatekeeper
|
||||
NPC.add(18357); // Rodenpicula's Gatekeeper
|
||||
NPC.add(18359); // Arviterre's Guardian
|
||||
NPC.add(18360); // Katenar's Gatekeeper
|
||||
NPC.add(18361); // Guardian of Prediction
|
||||
NPC.add(18484); // Naia Failan
|
||||
NPC.add(18491); // Lock
|
||||
NPC.add(18547); // Ancient Experiment
|
||||
NPC.add(18551); // Cruma Phantom
|
||||
NPC.add(35375); // Bloody Lord Nurka
|
||||
NPC.add(20376); // Varikan Brigand Leader
|
||||
NPC.add(20398); // Vrykolakas
|
||||
NPC.add(20520); // Pirate Captain Uthanka
|
||||
NPC.add(20522); // White Fang
|
||||
NPC.add(20738); // Kobold Looter Bepook
|
||||
NPC.add(20745); // Gigantiops
|
||||
NPC.add(20747); // Roxide
|
||||
NPC.add(20749); // Death Fire
|
||||
NPC.add(20751); // Snipe
|
||||
NPC.add(20753); // Dark Lord
|
||||
NPC.add(20755); // Talakin
|
||||
NPC.add(20758); // Dragon Bearer Chief
|
||||
NPC.add(20761); // Pytan
|
||||
NPC.add(20767); // Timak Orc Troop Leader
|
||||
NPC.add(20773); // Conjurer Bat Lord
|
||||
NPC.add(20939); // Tanor Silenos Warrior
|
||||
NPC.add(20941); // Tanor Silenos Chieftain
|
||||
NPC.add(20944); // Nightmare Lord
|
||||
NPC.add(20956); // Past Knight
|
||||
NPC.add(20959); // Dark Guard
|
||||
NPC.add(20963); // Bloody Lord
|
||||
NPC.add(20974); // Spiteful Soul Leader
|
||||
NPC.add(20977); // Elmoradan's Lady
|
||||
NPC.add(20980); // Hallate's Follower Mul
|
||||
NPC.add(20983); // Binder
|
||||
NPC.add(20986); // Sairon
|
||||
NPC.add(20991); // Swamp Tribe
|
||||
NPC.add(20994); // Garden Guard Leader
|
||||
NPC.add(21075); // Slaughter Bathin
|
||||
NPC.add(21078); // Magus Valac
|
||||
NPC.add(21081); // Power Angel Amon
|
||||
NPC.add(21090); // Bloody Guardian
|
||||
NPC.add(21312); // Eye of Ruler
|
||||
NPC.add(21343); // Ketra Commander
|
||||
NPC.add(21345); // Ketra's Head Shaman
|
||||
NPC.add(21347); // Ketra Prophet
|
||||
NPC.add(21369); // Varka's Commander
|
||||
NPC.add(21371); // Varka's Head Magus
|
||||
NPC.add(21373); // Varka's Prophet
|
||||
NPC.add(21432); // Chakram Beetle
|
||||
NPC.add(21434); // Seer of Blood
|
||||
NPC.add(21512); // Splinter Stakato Drone
|
||||
NPC.add(21517); // Needle Stakato Drone
|
||||
NPC.add(21541); // Pilgrim of Splendor
|
||||
NPC.add(21544); // Judge of Splendor
|
||||
NPC.add(21596); // Requiem Lord
|
||||
NPC.add(21599); // Requiem Priest
|
||||
NPC.add(21652); // Scarlet Stakato Noble
|
||||
NPC.add(21653); // Assassin Beetle
|
||||
NPC.add(21654); // Necromancer of Destruction
|
||||
NPC.add(21655); // Arimanes of Destruction
|
||||
NPC.add(21656); // Ashuras of Destruction
|
||||
NPC.add(21657); // Magma Drake
|
||||
NPC.add(22028); // Vagabond of the Ruins
|
||||
NPC.add(22080); // Massive Lost Bandersnatch
|
||||
NPC.add(22084); // Panthera
|
||||
NPC.add(22092); // Frost Iron Golem
|
||||
NPC.add(22096); // Ursus
|
||||
NPC.add(22100); // Freya's Gardener
|
||||
NPC.add(22102); // Freya's Servant
|
||||
NPC.add(22104); // Freya's Dog
|
||||
NPC.add(22155); // Triol's High Priest
|
||||
NPC.add(22159); // Triol's High Priest
|
||||
NPC.add(22163); // Triol's High Priest
|
||||
NPC.add(22167); // Triol's High Priest
|
||||
NPC.add(22171); // Triol's High Priest
|
||||
NPC.add(22188); // Andreas' Captain of the Royal Guard
|
||||
NPC.add(22196); // Velociraptor
|
||||
NPC.add(22198); // Velociraptor
|
||||
NPC.add(22202); // Ornithomimus
|
||||
NPC.add(22205); // Deinonychus
|
||||
NPC.add(22210); // Pachycephalosaurus
|
||||
NPC.add(22213); // Wild Strider
|
||||
NPC.add(22223); // Velociraptor
|
||||
NPC.add(22224); // Ornithomimus
|
||||
NPC.add(22225); // Deinonychus
|
||||
NPC.add(22275); // Gatekeeper Lohan
|
||||
NPC.add(22277); // Gatekeeper Provo
|
||||
NPC.add(22305); // Kechi's Captain
|
||||
NPC.add(22306); // Kechi's Captain
|
||||
NPC.add(22307); // Kechi's Captain
|
||||
NPC.add(22320); // Junior Watchman
|
||||
NPC.add(22321); // Junior Summoner
|
||||
NPC.add(22346); // Quarry Foreman
|
||||
NPC.add(22363); // Body Destroyer
|
||||
NPC.add(22370); // Passageway Captain
|
||||
NPC.add(22377); // Master Zelos
|
||||
NPC.add(22390); // Foundry Foreman
|
||||
NPC.add(22416); // Kechi's Captain
|
||||
NPC.add(22423); // Original Sin Warden
|
||||
NPC.add(22431); // Original Sin Warden
|
||||
NPC.add(22448); // Leodas
|
||||
NPC.add(22449); // Amaskari
|
||||
NPC.add(22621); // Male Spiked Stakato
|
||||
NPC.add(22625); // Cannibalistic Stakato Leader
|
||||
NPC.add(22630); // Spiked Stakato Nurse
|
||||
NPC.add(22666); // Barif
|
||||
NPC.add(22670); // Cursed Lord
|
||||
NPC.add(22742); // Ornithomimus
|
||||
NPC.add(22743); // Deinonychus
|
||||
NPC.add(25001); // Greyclaw Kutus
|
||||
NPC.add(25004); // Turek Mercenary Captain
|
||||
NPC.add(25007); // Retreat Spider Cletu
|
||||
NPC.add(25010); // Furious Thieles
|
||||
NPC.add(25013); // Ghost of Peasant Leader
|
||||
NPC.add(25016); // The 3rd Underwater Guardian
|
||||
NPC.add(25020); // Breka Warlock Pastu
|
||||
NPC.add(25023); // Stakato Queen Zyrnna
|
||||
NPC.add(25026); // Ketra Commander Atis
|
||||
NPC.add(25029); // Atraiban
|
||||
NPC.add(25032); // Eva's Guardian Millenu
|
||||
NPC.add(25035); // Shilen's Messenger Cabrio
|
||||
NPC.add(25038); // Tirak
|
||||
NPC.add(25041); // Remmel
|
||||
NPC.add(25044); // Barion
|
||||
NPC.add(25047); // Karte
|
||||
NPC.add(25051); // Rahha
|
||||
NPC.add(25054); // Kernon
|
||||
NPC.add(25057); // Beacon of Blue Sky
|
||||
NPC.add(25060); // Unrequited Kael
|
||||
NPC.add(25064); // Wizard of Storm Teruk
|
||||
NPC.add(25067); // Captain of Red Flag Shaka
|
||||
NPC.add(25070); // Enchanted Forest Watcher Ruell
|
||||
NPC.add(25073); // Bloody Priest Rudelto
|
||||
NPC.add(25076); // Princess Molrang
|
||||
NPC.add(25079); // Cat's Eye Bandit
|
||||
NPC.add(25082); // Leader of Cat Gang
|
||||
NPC.add(25085); // Timak Orc Chief Ranger
|
||||
NPC.add(25089); // Soulless Wild Boar
|
||||
NPC.add(25092); // Korim
|
||||
NPC.add(25095); // Elf Renoa
|
||||
NPC.add(25099); // Rotting Tree Repiro
|
||||
NPC.add(25103); // Sorcerer Isirr
|
||||
NPC.add(25106); // Ghost of the Well Lidia
|
||||
NPC.add(25109); // Antharas Priest Cloe
|
||||
NPC.add(25112); // Beleth's Agent, Meana
|
||||
NPC.add(25115); // Icarus Sample 1
|
||||
NPC.add(25119); // Messenger of Fairy Queen Berun
|
||||
NPC.add(25122); // Refugee Applicant Leo
|
||||
NPC.add(25128); // Vuku Grand Seer Gharmash
|
||||
NPC.add(25131); // Carnage Lord Gato
|
||||
NPC.add(25134); // Leto Chief Talkin
|
||||
NPC.add(25137); // Beleth's Seer, Sephia
|
||||
NPC.add(25140); // Hekaton Prime
|
||||
NPC.add(25143); // Fire of Wrath Shuriel
|
||||
NPC.add(25146); // Serpent Demon Bifrons
|
||||
NPC.add(25149); // Zombie Lord Crowl
|
||||
NPC.add(25152); // Flame Lord Shadar
|
||||
NPC.add(25155); // Shaman King Selu
|
||||
NPC.add(25159); // Paniel the Unicorn
|
||||
NPC.add(25166); // Ikuntai
|
||||
NPC.add(25170); // Lizardmen Leader Hellion
|
||||
NPC.add(25173); // Tiger King Karuta
|
||||
NPC.add(25176); // Black Lily
|
||||
NPC.add(25179); // Guardian of the Statue of Giant Karum
|
||||
NPC.add(25182); // Demon Kuri
|
||||
NPC.add(25185); // Tasaba Patriarch Hellena
|
||||
NPC.add(25189); // Cronos's Servitor Mumu
|
||||
NPC.add(25192); // Earth Protector Panathen
|
||||
NPC.add(25199); // Water Dragon Seer Sheshark
|
||||
NPC.add(25202); // Krokian Padisha Sobekk
|
||||
NPC.add(25205); // Ocean Flame Ashakiel
|
||||
NPC.add(25208); // Water Couatle Ateka
|
||||
NPC.add(25211); // Sebek
|
||||
NPC.add(25214); // Fafurion's Page Sika
|
||||
NPC.add(25217); // Cursed Clara
|
||||
NPC.add(25220); // Death Lord Hallate
|
||||
NPC.add(25223); // Soul Collector Acheron
|
||||
NPC.add(25226); // Roaring Lord Kastor
|
||||
NPC.add(25230); // Timak Seer Ragoth
|
||||
NPC.add(25235); // Vanor Chief Kandra
|
||||
NPC.add(25238); // Abyss Brukunt
|
||||
NPC.add(25241); // Harit Hero Tamash
|
||||
NPC.add(25245); // Last Lesser Giant Glaki
|
||||
NPC.add(25249); // Menacing Palatanos
|
||||
NPC.add(25252); // Palibati Queen Themis
|
||||
NPC.add(25256); // Taik High Prefect Arak
|
||||
NPC.add(25260); // Iron Giant Totem
|
||||
NPC.add(25263); // Kernon's Faithful Servant Kelone
|
||||
NPC.add(25266); // Bloody Empress Decarbia
|
||||
NPC.add(25269); // Beast Lord Behemoth
|
||||
NPC.add(25273); // Carnamakos
|
||||
NPC.add(25277); // Lilith's Witch Marilion
|
||||
NPC.add(25283); // Lilith
|
||||
NPC.add(25286); // Anakim
|
||||
NPC.add(25290); // Daimon the White-Eyed
|
||||
NPC.add(25293); // Hesti Guardian Deity of the Hot Springs
|
||||
NPC.add(25296); // Icicle Emperor Bumbalump
|
||||
NPC.add(25299); // Ketra's Hero Hekaton
|
||||
NPC.add(25302); // Ketra's Commander Tayr
|
||||
NPC.add(25306); // Soul of Fire Nastron
|
||||
NPC.add(25309); // Varka's Hero Shadith
|
||||
NPC.add(25312); // Varka's Commander Mos
|
||||
NPC.add(25316); // Soul of Water Ashutar
|
||||
NPC.add(25319); // Ember
|
||||
NPC.add(25322); // Demon's Agent Falston
|
||||
NPC.add(25325); // Flame of Splendor Barakiel
|
||||
NPC.add(25328); // Eilhalder von Hellmann
|
||||
NPC.add(25352); // Giant Wasteland Basilisk
|
||||
NPC.add(25354); // Gargoyle Lord Sirocco
|
||||
NPC.add(25357); // Sukar Wererat Chief
|
||||
NPC.add(25360); // Tiger Hornet
|
||||
NPC.add(25362); // Tracker Leader Sharuk
|
||||
NPC.add(25366); // Kuroboros' Priest
|
||||
NPC.add(25369); // Soul Scavenger
|
||||
NPC.add(25373); // Malex Herald of Dagoniel
|
||||
NPC.add(25375); // Zombie Lord Ferkel
|
||||
NPC.add(25378); // Madness Beast
|
||||
NPC.add(25380); // Kaysha Herald of Icarus
|
||||
NPC.add(25383); // Revenant of Sir Calibus
|
||||
NPC.add(25385); // Evil Spirit Tempest
|
||||
NPC.add(25388); // Red Eye Captain Trakia
|
||||
NPC.add(25392); // Captain of Queen's Royal Guards
|
||||
NPC.add(25395); // Archon Suscepter
|
||||
NPC.add(25398); // Beleth's Eye
|
||||
NPC.add(25401); // Skyla
|
||||
NPC.add(25404); // Corsair Captain Kylon
|
||||
NPC.add(25407); // Lord Ishka
|
||||
NPC.add(25410); // Road Scavenger Leader
|
||||
NPC.add(25412); // Necrosentinel Royal Guard
|
||||
NPC.add(25415); // Nakondas
|
||||
NPC.add(25418); // Dread Avenger Kraven
|
||||
NPC.add(25420); // Orfen's Handmaiden
|
||||
NPC.add(25423); // Fairy Queen Timiniel
|
||||
NPC.add(25426); // Betrayer of Urutu Freki
|
||||
NPC.add(25429); // Mammon Collector Talos
|
||||
NPC.add(25431); // Flamestone Golem
|
||||
NPC.add(25434); // Bandit Leader Barda
|
||||
NPC.add(25438); // Thief Kelbar
|
||||
NPC.add(25441); // Evil Spirit Cyrion
|
||||
NPC.add(25444); // Enmity Ghost Ramdal
|
||||
NPC.add(25447); // Immortal Savior Mardil
|
||||
NPC.add(25450); // Cherub Galaxia
|
||||
NPC.add(25453); // Meanas Anor
|
||||
NPC.add(25456); // Mirror of Oblivion
|
||||
NPC.add(25460); // Deadman Ereve
|
||||
NPC.add(25463); // Harit Guardian Garangky
|
||||
NPC.add(25467); // Gorgolos
|
||||
NPC.add(25470); // Last Titan Utenus
|
||||
NPC.add(25473); // Grave Robber Kim
|
||||
NPC.add(25475); // Ghost Knight Kabed
|
||||
NPC.add(25478); // Shilen's Priest Hisilrome
|
||||
NPC.add(25481); // Magus Kenishee
|
||||
NPC.add(25484); // Zaken's Chief Mate Tillion
|
||||
NPC.add(25487); // Water Spirit Lian
|
||||
NPC.add(25490); // Gwindorr
|
||||
NPC.add(25493); // Eva's Spirit Niniel
|
||||
NPC.add(25496); // Fafurion's Envoy Pingolpin
|
||||
NPC.add(25498); // Fafurion's Henchman Istary
|
||||
NPC.add(25501); // Boss Akata
|
||||
NPC.add(25504); // Nellis' Vengeful Spirit
|
||||
NPC.add(25506); // Rayito the Looter
|
||||
NPC.add(25509); // Dark Shaman Varangka
|
||||
NPC.add(25514); // Queen Shyeed
|
||||
NPC.add(25524); // Flamestone Giant
|
||||
NPC.add(25528); // Tiberias
|
||||
NPC.add(25536); // Hannibal
|
||||
NPC.add(25546); // Rhianna the Traitor
|
||||
NPC.add(25549); // Tesla the Deceiver
|
||||
NPC.add(25554); // Brutus the Obstinate
|
||||
NPC.add(25557); // Ranger Karankawa
|
||||
NPC.add(25560); // Sargon the Mad
|
||||
NPC.add(25563); // Beautiful Atrielle
|
||||
NPC.add(25566); // Nagen the Tomboy
|
||||
NPC.add(25569); // Jax the Destroyer
|
||||
NPC.add(25572); // Hager the Outlaw
|
||||
NPC.add(25575); // All-Seeing Rango
|
||||
NPC.add(25579); // Helsing
|
||||
NPC.add(25582); // Gillien
|
||||
NPC.add(25585); // Medici
|
||||
NPC.add(25589); // Brand the Exile
|
||||
NPC.add(25593); // Gerg the Hunter
|
||||
NPC.add(25600); // Temenir
|
||||
NPC.add(25601); // Draksius
|
||||
NPC.add(25602); // Kiretcenah
|
||||
NPC.add(25671); // Queen Shyeed
|
||||
NPC.add(25674); // Gwindorr
|
||||
NPC.add(25677); // Water Spirit Lian
|
||||
NPC.add(25681); // Gorgolos
|
||||
NPC.add(25684); // Last Titan Utenus
|
||||
NPC.add(25687); // Hekaton Prime
|
||||
NPC.add(25703); // Gigantic Golem
|
||||
NPC.add(25710); // Lost Captain
|
||||
NPC.add(25735); // Greyclaw Kutus
|
||||
NPC.add(25738); // Lead Tracker Sharuk
|
||||
NPC.add(25741); // Sukar Wererat Chief
|
||||
NPC.add(25744); // Ikuntai
|
||||
NPC.add(25747); // Zombie Lord Crowl
|
||||
NPC.add(25750); // Zombie Lord Ferkel
|
||||
NPC.add(25754); // Fire Lord Shadar
|
||||
NPC.add(25757); // Soul Collector Acheron
|
||||
NPC.add(25760); // Lord Ishka
|
||||
NPC.add(25763); // Demon Kuri
|
||||
NPC.add(25767); // Carnage Lord Gato
|
||||
NPC.add(25770); // Ketra Commander Atis
|
||||
NPC.add(25773); // Beacon of Blue Sky
|
||||
NPC.add(25776); // Earth Protector Panathen
|
||||
NPC.add(25779); // Betrayer of Urutu Freki
|
||||
NPC.add(25782); // Nellis' Vengeful Spirit
|
||||
NPC.add(25784); // Rayito the Looter
|
||||
NPC.add(25787); // Ketra's Hero Hekaton
|
||||
NPC.add(25790); // Varka's Hero Shadith
|
||||
NPC.add(25794); // Kernon
|
||||
NPC.add(25797); // Meanas Anor
|
||||
NPC.add(25800); // Mammon Collector Talos
|
||||
NPC.add(27036); // Calpico
|
||||
NPC.add(27041); // Varangka's Messenger
|
||||
NPC.add(27062); // Tanukia
|
||||
NPC.add(27065); // Roko
|
||||
NPC.add(27068); // Murtika
|
||||
NPC.add(27093); // Delu Chief Kalkis
|
||||
NPC.add(27108); // Stenoa Gorgon Queen
|
||||
NPC.add(27110); // Shyslassys
|
||||
NPC.add(27112); // Gorr
|
||||
NPC.add(27113); // Baraham
|
||||
NPC.add(27114); // Succubus Queen
|
||||
NPC.add(27185); // Fairy Tree of Wind
|
||||
NPC.add(27186); // Fairy Tree of Star
|
||||
NPC.add(27187); // Fairy Tree of Twilight
|
||||
NPC.add(27188); // Fairy Tree of Abyss
|
||||
NPC.add(27259); // Archangel Iconoclasis
|
||||
NPC.add(27260); // Archangel Iconoclasis
|
||||
NPC.add(27266); // Fallen Angel Haures
|
||||
NPC.add(27267); // Fallen Angel Haures
|
||||
NPC.add(27290); // White Wing Commander
|
||||
NPC.add(29030); // Fenril Hound Kerinne
|
||||
NPC.add(29033); // Fenril Hound Freki
|
||||
NPC.add(29037); // Fenril Hound Kinaz
|
||||
NPC.add(29040); // Wings of Flame, Ixion
|
||||
NPC.add(29056); // Ice Fairy Sirra
|
||||
NPC.add(29062); // Andreas Van Halter
|
||||
NPC.add(29096); // Anais
|
||||
NPC.add(29129); // Lost Captain
|
||||
NPC.add(29132); // Lost Captain
|
||||
NPC.add(29135); // Lost Captain
|
||||
NPC.add(29138); // Lost Captain
|
||||
NPC.add(29141); // Lost Captain
|
||||
NPC.add(29144); // Lost Captain
|
||||
NPC.add(29147); // Lost Captain
|
||||
}
|
||||
|
||||
private static final NpcStringId[] ON_ATTACK_MSG =
|
||||
{
|
||||
NpcStringId.COME_OUT_YOU_CHILDREN_OF_DARKNESS,
|
||||
NpcStringId.SHOW_YOURSELVES,
|
||||
NpcStringId.DESTROY_THE_ENEMY_MY_BROTHERS,
|
||||
NpcStringId.FORCES_OF_DARKNESS_FOLLOW_ME
|
||||
};
|
||||
|
||||
private static final int[] ON_ATTACK_NPC =
|
||||
{
|
||||
20767, // Timak Orc Troop Leader
|
||||
};
|
||||
|
||||
private MinionSpawnManager()
|
||||
{
|
||||
super(MinionSpawnManager.class.getSimpleName(), "ai/group_template");
|
||||
|
||||
addSpawnId(NPC);
|
||||
addAttackId(ON_ATTACK_NPC);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (npc.getTemplate().getParameters().getSet().get("SummonPrivateRate") == null)
|
||||
{
|
||||
((L2MonsterInstance) npc).getMinionList().spawnMinions(npc.getTemplate().getParameters().getMinionList("Privates"));
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.isMonster())
|
||||
{
|
||||
final L2MonsterInstance monster = (L2MonsterInstance) npc;
|
||||
if (!monster.isTeleporting())
|
||||
{
|
||||
if (getRandom(1, 100) <= npc.getTemplate().getParameters().getInt("SummonPrivateRate", 0))
|
||||
{
|
||||
for (MinionHolder is : npc.getTemplate().getParameters().getMinionList("Privates"))
|
||||
{
|
||||
addMinion((L2MonsterInstance) npc, is.getId());
|
||||
}
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, ON_ATTACK_MSG[getRandom(ON_ATTACK_MSG.length)]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new MinionSpawnManager();
|
||||
}
|
||||
}
|
||||
296
trunk/dist/game/data/scripts/ai/group_template/MonasteryOfSilence.java
vendored
Normal file
296
trunk/dist/game/data/scripts/ai/group_template/MonasteryOfSilence.java
vendored
Normal file
@@ -0,0 +1,296 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.effects.L2EffectType;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Monastery of Silence AI.
|
||||
* @author Kerberos, nonom
|
||||
*/
|
||||
public final class MonasteryOfSilence extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int CAPTAIN = 18910; // Solina Knight Captain
|
||||
private static final int KNIGHT = 18909; // Solina Knights
|
||||
private static final int SCARECROW = 18912; // Scarecrow
|
||||
private static final int GUIDE = 22789; // Guide Solina
|
||||
private static final int SEEKER = 22790; // Seeker Solina
|
||||
private static final int SAVIOR = 22791; // Savior Solina
|
||||
private static final int ASCETIC = 22793; // Ascetic Solina
|
||||
private static final int[] DIVINITY_CLAN =
|
||||
{
|
||||
22794, // Divinity Judge
|
||||
22795, // Divinity Manager
|
||||
};
|
||||
// Skills
|
||||
private static final SkillHolder ORDEAL_STRIKE = new SkillHolder(6303, 1); // Trial of the Coup
|
||||
private static final SkillHolder LEADER_STRIKE = new SkillHolder(6304, 1); // Shock
|
||||
private static final SkillHolder SAVER_STRIKE = new SkillHolder(6305, 1); // Sacred Gnosis
|
||||
private static final SkillHolder SAVER_BLEED = new SkillHolder(6306, 1); // Solina Strike
|
||||
private static final SkillHolder LEARNING_MAGIC = new SkillHolder(6308, 1); // Opus of the Wave
|
||||
private static final SkillHolder STUDENT_CANCEL = new SkillHolder(6310, 1); // Loss of Quest
|
||||
private static final SkillHolder WARRIOR_THRUSTING = new SkillHolder(6311, 1); // Solina Thrust
|
||||
private static final SkillHolder KNIGHT_BLESS = new SkillHolder(6313, 1); // Solina Bless
|
||||
// Misc
|
||||
private static final NpcStringId[] DIVINITY_MSG =
|
||||
{
|
||||
NpcStringId.S1_WHY_WOULD_YOU_CHOOSE_THE_PATH_OF_DARKNESS,
|
||||
NpcStringId.S1_HOW_DARE_YOU_DEFY_THE_WILL_OF_EINHASAD
|
||||
};
|
||||
private static final NpcStringId[] SOLINA_KNIGHTS_MSG =
|
||||
{
|
||||
NpcStringId.PUNISH_ALL_THOSE_WHO_TREAD_FOOTSTEPS_IN_THIS_PLACE,
|
||||
NpcStringId.WE_ARE_THE_SWORD_OF_TRUTH_THE_SWORD_OF_SOLINA,
|
||||
NpcStringId.WE_RAISE_OUR_BLADES_FOR_THE_GLORY_OF_SOLINA
|
||||
};
|
||||
|
||||
private MonasteryOfSilence()
|
||||
{
|
||||
super(MonasteryOfSilence.class.getSimpleName(), "ai/group_template");
|
||||
addSkillSeeId(DIVINITY_CLAN);
|
||||
addAttackId(KNIGHT, CAPTAIN, GUIDE, SEEKER, ASCETIC);
|
||||
addNpcHateId(GUIDE, SEEKER, SAVIOR, ASCETIC);
|
||||
addAggroRangeEnterId(GUIDE, SEEKER, SAVIOR, ASCETIC);
|
||||
addSpawnId(SCARECROW);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "TRAINING":
|
||||
{
|
||||
for (L2Character character : npc.getKnownList().getKnownCharactersInRadius(400))
|
||||
{
|
||||
if ((getRandom(100) < 30) && character.isNpc() && !character.isDead() && !character.isInCombat())
|
||||
{
|
||||
if ((character.getId() == CAPTAIN) && (getRandom(100) < 10) && npc.isScriptValue(0))
|
||||
{
|
||||
final L2Npc captain = (L2Npc) character;
|
||||
broadcastNpcSay(captain, Say2.NPC_ALL, SOLINA_KNIGHTS_MSG[getRandom(SOLINA_KNIGHTS_MSG.length)]);
|
||||
captain.setScriptValue(1);
|
||||
startQuestTimer("TIMER", 10000, captain, null);
|
||||
}
|
||||
else if (character.getId() == KNIGHT)
|
||||
{
|
||||
character.setRunning();
|
||||
((L2Attackable) character).addDamageHate(npc, 0, 100);
|
||||
character.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, npc, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "DO_CAST":
|
||||
{
|
||||
if ((npc != null) && (player != null) && (getRandom(100) < 3))
|
||||
{
|
||||
if (npc.checkDoCastConditions(STUDENT_CANCEL.getSkill()))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(STUDENT_CANCEL.getSkill());
|
||||
}
|
||||
npc.setScriptValue(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "TIMER":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
npc.setScriptValue(0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isSummon)
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
|
||||
switch (npc.getId())
|
||||
{
|
||||
case KNIGHT:
|
||||
{
|
||||
if ((getRandom(100) < 10) && (mob.getMostHated() == player) && mob.checkDoCastConditions(WARRIOR_THRUSTING.getSkill()))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(WARRIOR_THRUSTING.getSkill());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case CAPTAIN:
|
||||
{
|
||||
if ((getRandom(100) < 20) && (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) && npc.isScriptValue(0))
|
||||
{
|
||||
if (npc.checkDoCastConditions(KNIGHT_BLESS.getSkill()))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(KNIGHT_BLESS.getSkill());
|
||||
}
|
||||
npc.setScriptValue(1);
|
||||
broadcastNpcSay(npc, Say2.ALL, NpcStringId.FOR_THE_GLORY_OF_SOLINA);
|
||||
addAttackPlayerDesire(addSpawn(KNIGHT, npc), player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GUIDE:
|
||||
{
|
||||
if ((getRandom(100) < 3) && (mob.getMostHated() == player) && npc.checkDoCastConditions(ORDEAL_STRIKE.getSkill()))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(ORDEAL_STRIKE.getSkill());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SEEKER:
|
||||
{
|
||||
if ((getRandom(100) < 33) && (mob.getMostHated() == player) && npc.checkDoCastConditions(SAVER_STRIKE.getSkill()))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(SAVER_STRIKE.getSkill());
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ASCETIC:
|
||||
{
|
||||
if ((mob.getMostHated() == player) && npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
startQuestTimer("DO_CAST", 20000, npc, player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, player, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onNpcHate(L2Attackable mob, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
return player.getActiveWeaponInstance() != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
if (player.getActiveWeaponInstance() != null)
|
||||
{
|
||||
SkillHolder skill = null;
|
||||
switch (npc.getId())
|
||||
{
|
||||
case GUIDE:
|
||||
{
|
||||
if (getRandom(100) < 3)
|
||||
{
|
||||
skill = LEADER_STRIKE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SEEKER:
|
||||
{
|
||||
skill = SAVER_BLEED;
|
||||
break;
|
||||
}
|
||||
case SAVIOR:
|
||||
{
|
||||
skill = LEARNING_MAGIC;
|
||||
break;
|
||||
}
|
||||
case ASCETIC:
|
||||
{
|
||||
if (getRandom(100) < 3)
|
||||
{
|
||||
skill = STUDENT_CANCEL;
|
||||
}
|
||||
|
||||
if (npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
startQuestTimer("DO_CAST", 20000, npc, player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ((skill != null) && npc.checkDoCastConditions(skill.getSkill()))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(skill.getSkill());
|
||||
}
|
||||
|
||||
if (!npc.isInCombat())
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.YOU_CANNOT_CARRY_A_WEAPON_WITHOUT_AUTHORIZATION);
|
||||
}
|
||||
|
||||
addAttackPlayerDesire(npc, player);
|
||||
}
|
||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if (skill.hasEffectType(L2EffectType.AGGRESSION) && (targets.length != 0))
|
||||
{
|
||||
for (L2Object obj : targets)
|
||||
{
|
||||
if (obj.equals(npc))
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, DIVINITY_MSG[getRandom(DIVINITY_MSG.length)], caster.getName());
|
||||
addAttackPlayerDesire(npc, caster);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.setIsInvul(true);
|
||||
npc.disableCoreAI(true);
|
||||
startQuestTimer("TRAINING", 30000, npc, null, true);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new MonasteryOfSilence();
|
||||
}
|
||||
}
|
||||
52
trunk/dist/game/data/scripts/ai/group_template/NonLethalableNpcs.java
vendored
Normal file
52
trunk/dist/game/data/scripts/ai/group_template/NonLethalableNpcs.java
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
|
||||
/**
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public final class NonLethalableNpcs extends AbstractNpcAI
|
||||
{
|
||||
private static final int[] NPCS =
|
||||
{
|
||||
35062, // Headquarters
|
||||
};
|
||||
|
||||
public NonLethalableNpcs()
|
||||
{
|
||||
super(NonLethalableNpcs.class.getSimpleName(), "ai/group_template");
|
||||
addSpawnId(NPCS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.setLethalable(false);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new NonLethalableNpcs();
|
||||
}
|
||||
}
|
||||
62
trunk/dist/game/data/scripts/ai/group_template/PavelArchaic.java
vendored
Normal file
62
trunk/dist/game/data/scripts/ai/group_template/PavelArchaic.java
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* Pavel Archaic AI.
|
||||
* @author Gnacik, St3eT
|
||||
*/
|
||||
public final class PavelArchaic extends AbstractNpcAI
|
||||
{
|
||||
private static final int SAFETY_DEVICE = 18917; // Pavel Safety Device
|
||||
private static final int PINCER_GOLEM = 22801; // Cruel Pincer Golem
|
||||
private static final int PINCER_GOLEM2 = 22802; // Cruel Pincer Golem
|
||||
private static final int PINCER_GOLEM3 = 22803; // Cruel Pincer Golem
|
||||
private static final int JACKHAMMER_GOLEM = 22804; // Horrifying Jackhammer Golem
|
||||
|
||||
private PavelArchaic()
|
||||
{
|
||||
super(PavelArchaic.class.getSimpleName(), "ai/group_template");
|
||||
addKillId(SAFETY_DEVICE, PINCER_GOLEM, JACKHAMMER_GOLEM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (getRandom(100) < 70)
|
||||
{
|
||||
final L2Npc golem1 = addSpawn(PINCER_GOLEM2, npc.getX(), npc.getY(), npc.getZ() + 10, npc.getHeading(), false, 0, false);
|
||||
addAttackPlayerDesire(golem1, killer);
|
||||
|
||||
final L2Npc golem2 = addSpawn(PINCER_GOLEM3, npc.getX(), npc.getY(), npc.getZ() + 10, npc.getHeading(), false, 0, false);
|
||||
addAttackPlayerDesire(golem2, killer);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PavelArchaic();
|
||||
}
|
||||
}
|
||||
99
trunk/dist/game/data/scripts/ai/group_template/PlainsOfDion.java
vendored
Normal file
99
trunk/dist/game/data/scripts/ai/group_template/PlainsOfDion.java
vendored
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.GeoData;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* AI for mobs in Plains of Dion (near Floran Village).
|
||||
* @author Gladicek
|
||||
*/
|
||||
public final class PlainsOfDion extends AbstractNpcAI
|
||||
{
|
||||
private static final int DELU_LIZARDMEN[] =
|
||||
{
|
||||
21104, // Delu Lizardman Supplier
|
||||
21105, // Delu Lizardman Special Agent
|
||||
21107, // Delu Lizardman Commander
|
||||
};
|
||||
|
||||
private static final NpcStringId[] MONSTERS_MSG =
|
||||
{
|
||||
NpcStringId.S1_HOW_DARE_YOU_INTERRUPT_OUR_FIGHT_HEY_GUYS_HELP,
|
||||
NpcStringId.S1_HEY_WE_RE_HAVING_A_DUEL_HERE,
|
||||
NpcStringId.THE_DUEL_IS_OVER_ATTACK,
|
||||
NpcStringId.FOUL_KILL_THE_COWARD,
|
||||
NpcStringId.HOW_DARE_YOU_INTERRUPT_A_SACRED_DUEL_YOU_MUST_BE_TAUGHT_A_LESSON
|
||||
};
|
||||
|
||||
private static final NpcStringId[] MONSTERS_ASSIST_MSG =
|
||||
{
|
||||
NpcStringId.DIE_YOU_COWARD,
|
||||
NpcStringId.KILL_THE_COWARD,
|
||||
NpcStringId.WHAT_ARE_YOU_LOOKING_AT
|
||||
};
|
||||
|
||||
private PlainsOfDion()
|
||||
{
|
||||
super(PlainsOfDion.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(DELU_LIZARDMEN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.isScriptValue(0))
|
||||
{
|
||||
final int i = getRandom(5);
|
||||
if (i < 2)
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, MONSTERS_MSG[i], player.getName());
|
||||
}
|
||||
else
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, MONSTERS_MSG[i]);
|
||||
}
|
||||
|
||||
for (L2Character obj : npc.getKnownList().getKnownCharactersInRadius(npc.getTemplate().getClanHelpRange()))
|
||||
{
|
||||
if (obj.isMonster() && Util.contains(DELU_LIZARDMEN, obj.getId()) && !obj.isAttackingNow() && !obj.isDead() && GeoData.getInstance().canSeeTarget(npc, obj))
|
||||
{
|
||||
final L2Npc monster = (L2Npc) obj;
|
||||
addAttackPlayerDesire(monster, player);
|
||||
broadcastNpcSay(monster, Say2.NPC_ALL, MONSTERS_ASSIST_MSG[getRandom(3)]);
|
||||
}
|
||||
}
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
return super.onAttack(npc, player, damage, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PlainsOfDion();
|
||||
}
|
||||
}
|
||||
244
trunk/dist/game/data/scripts/ai/group_template/PlainsOfLizardman.java
vendored
Normal file
244
trunk/dist/game/data/scripts/ai/group_template/PlainsOfLizardman.java
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
|
||||
/**
|
||||
* Plains of Lizardmen AI.
|
||||
* @author Gnacik, malyelfik
|
||||
*/
|
||||
public final class PlainsOfLizardman extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int INVISIBLE_NPC = 18919;
|
||||
private static final int TANTA_GUARD = 18862;
|
||||
private static final int FANTASY_MUSHROOM = 18864;
|
||||
private static final int STICKY_MUSHROOM = 18865;
|
||||
private static final int RAINBOW_FROG = 18866;
|
||||
private static final int ENERGY_PLANT = 18868;
|
||||
private static final int TANTA_SCOUT = 22768;
|
||||
private static final int TANTA_MAGICIAN = 22773;
|
||||
private static final int TANTA_SUMMONER = 22774;
|
||||
private static final int[] TANTA_LIZARDMEN =
|
||||
{
|
||||
22768, // Tanta Lizardman Scout
|
||||
22769, // Tanta Lizardman Warrior
|
||||
22770, // Tanta Lizardman Soldier
|
||||
22771, // Tanta Lizardman Berserker
|
||||
22772, // Tanta Lizardman Archer
|
||||
22773, // Tanta Lizardman Magician
|
||||
22774, // Tanta Lizardman Summoner
|
||||
};
|
||||
// Skills
|
||||
private static final SkillHolder STUN_EFFECT = new SkillHolder(6622, 1);
|
||||
private static final SkillHolder DEMOTIVATION_HEX = new SkillHolder(6425, 1);
|
||||
private static final SkillHolder FANTASY_MUSHROOM_SKILL = new SkillHolder(6427, 1);
|
||||
private static final SkillHolder RAINBOW_FROG_SKILL = new SkillHolder(6429, 1);
|
||||
private static final SkillHolder STICKY_MUSHROOM_SKILL = new SkillHolder(6428, 1);
|
||||
private static final SkillHolder ENERGY_PLANT_SKILL = new SkillHolder(6430, 1);
|
||||
// Buffs
|
||||
private static final SkillHolder[] BUFFS =
|
||||
{
|
||||
new SkillHolder(6625, 1), // Energy of Life
|
||||
new SkillHolder(6626, 2), // Energy of Life's Power
|
||||
new SkillHolder(6627, 3), // Energy of Life's Highest Power
|
||||
new SkillHolder(6628, 1), // Energy of Mana
|
||||
new SkillHolder(6629, 2), // Energy of Mana's Power
|
||||
new SkillHolder(6630, 3), // Energy of Mana's Highest Power
|
||||
new SkillHolder(6631, 1), // Energy of Power
|
||||
new SkillHolder(6633, 1), // Energy of Attack Speed
|
||||
new SkillHolder(6635, 1), // Energy of Crt Rate
|
||||
new SkillHolder(6636, 1), // Energy of Moving Speed
|
||||
new SkillHolder(6638, 1), // Aura of Mystery
|
||||
new SkillHolder(6639, 1), // Bane of Auras - Damage
|
||||
new SkillHolder(6640, 1), // Energizing Aura
|
||||
new SkillHolder(6674, 1), // Energy of Range Increment
|
||||
};
|
||||
// Misc
|
||||
// @formatter:off
|
||||
private static final int[] BUFF_LIST =
|
||||
{
|
||||
6, 7, 8, 11, 13
|
||||
};
|
||||
// @formatter:on
|
||||
|
||||
private PlainsOfLizardman()
|
||||
{
|
||||
super(PlainsOfLizardman.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(FANTASY_MUSHROOM, RAINBOW_FROG, STICKY_MUSHROOM, ENERGY_PLANT, TANTA_SUMMONER);
|
||||
addKillId(TANTA_LIZARDMEN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("fantasy_mushroom") && (npc != null) && (player != null))
|
||||
{
|
||||
npc.doCast(FANTASY_MUSHROOM_SKILL.getSkill());
|
||||
for (L2Character target : npc.getKnownList().getKnownCharactersInRadius(200))
|
||||
{
|
||||
if ((target != null) && target.isAttackable())
|
||||
{
|
||||
final L2Npc monster = (L2Npc) target;
|
||||
npc.setTarget(monster);
|
||||
npc.doCast(STUN_EFFECT.getSkill());
|
||||
addAttackPlayerDesire(monster, player);
|
||||
}
|
||||
}
|
||||
npc.doDie(player);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case TANTA_SUMMONER:
|
||||
if (!npc.isAffectedBySkill(DEMOTIVATION_HEX.getSkillId()))
|
||||
{
|
||||
npc.doCast(DEMOTIVATION_HEX.getSkill());
|
||||
}
|
||||
break;
|
||||
case RAINBOW_FROG:
|
||||
castSkill(npc, attacker, RAINBOW_FROG_SKILL);
|
||||
break;
|
||||
case ENERGY_PLANT:
|
||||
castSkill(npc, attacker, ENERGY_PLANT_SKILL);
|
||||
break;
|
||||
case STICKY_MUSHROOM:
|
||||
castSkill(npc, attacker, STICKY_MUSHROOM_SKILL);
|
||||
break;
|
||||
case FANTASY_MUSHROOM:
|
||||
if (npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
npc.setIsInvul(true);
|
||||
for (L2Character target : npc.getKnownList().getKnownCharactersInRadius(1000))
|
||||
{
|
||||
if ((target != null) && target.isAttackable())
|
||||
{
|
||||
final L2Attackable monster = (L2Attackable) target;
|
||||
if ((monster.getId() == TANTA_MAGICIAN) || (monster.getId() == TANTA_SCOUT))
|
||||
{
|
||||
target.setIsRunning(true);
|
||||
target.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(npc.getX(), npc.getY(), npc.getZ(), 0));
|
||||
}
|
||||
}
|
||||
}
|
||||
startQuestTimer("fantasy_mushroom", 4000, npc, attacker);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
// Tanta Guard
|
||||
if (getRandom(1000) == 0)
|
||||
{
|
||||
addAttackPlayerDesire(addSpawn(TANTA_GUARD, npc), killer);
|
||||
}
|
||||
|
||||
// Invisible buff npc
|
||||
final int random = getRandom(100);
|
||||
final L2Npc buffer = addSpawn(INVISIBLE_NPC, npc.getLocation(), false, 6000);
|
||||
buffer.setTarget(killer);
|
||||
|
||||
if (random <= 42)
|
||||
{
|
||||
castRandomBuff(buffer, 7, 45, BUFFS[0], BUFFS[1], BUFFS[2]);
|
||||
}
|
||||
if (random <= 11)
|
||||
{
|
||||
castRandomBuff(buffer, 8, 60, BUFFS[3], BUFFS[4], BUFFS[5]);
|
||||
castRandomBuff(buffer, 3, 6, BUFFS[9], BUFFS[10], BUFFS[12]);
|
||||
}
|
||||
if (random <= 25)
|
||||
{
|
||||
buffer.doCast(BUFFS[BUFF_LIST[getRandom(BUFF_LIST.length)]].getSkill());
|
||||
}
|
||||
if (random <= 10)
|
||||
{
|
||||
buffer.doCast(BUFFS[13].getSkill());
|
||||
}
|
||||
if (random <= 1)
|
||||
{
|
||||
final int i = getRandom(100);
|
||||
if (i <= 34)
|
||||
{
|
||||
buffer.doCast(BUFFS[6].getSkill());
|
||||
buffer.doCast(BUFFS[7].getSkill());
|
||||
buffer.doCast(BUFFS[8].getSkill());
|
||||
}
|
||||
else if (i < 67)
|
||||
{
|
||||
buffer.doCast(BUFFS[13].getSkill());
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer.doCast(BUFFS[2].getSkill());
|
||||
buffer.doCast(BUFFS[5].getSkill());
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
private void castRandomBuff(L2Npc npc, int chance1, int chance2, SkillHolder... buffs)
|
||||
{
|
||||
final int rand = getRandom(100);
|
||||
if (rand <= chance1)
|
||||
{
|
||||
npc.doCast(buffs[2].getSkill());
|
||||
}
|
||||
else if (rand <= chance2)
|
||||
{
|
||||
npc.doCast(buffs[1].getSkill());
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.doCast(buffs[0].getSkill());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void castSkill(L2Npc npc, L2Playable target, SkillHolder skill)
|
||||
{
|
||||
npc.doDie(target);
|
||||
super.castSkill(addSpawn(INVISIBLE_NPC, npc, false, 6000), target, skill);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PlainsOfLizardman();
|
||||
}
|
||||
}
|
||||
63
trunk/dist/game/data/scripts/ai/group_template/PolymorphingAngel.java
vendored
Normal file
63
trunk/dist/game/data/scripts/ai/group_template/PolymorphingAngel.java
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* Angel spawns...when one of the angels in the keys dies, the other angel will spawn.
|
||||
*/
|
||||
public final class PolymorphingAngel extends AbstractNpcAI
|
||||
{
|
||||
private static final Map<Integer, Integer> ANGELSPAWNS = new FastMap<>();
|
||||
static
|
||||
{
|
||||
ANGELSPAWNS.put(20830, 20859);
|
||||
ANGELSPAWNS.put(21067, 21068);
|
||||
ANGELSPAWNS.put(21062, 21063);
|
||||
ANGELSPAWNS.put(20831, 20860);
|
||||
ANGELSPAWNS.put(21070, 21071);
|
||||
}
|
||||
|
||||
private PolymorphingAngel()
|
||||
{
|
||||
super(PolymorphingAngel.class.getSimpleName(), "ai/group_template");
|
||||
addKillId(ANGELSPAWNS.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final L2Attackable newNpc = (L2Attackable) addSpawn(ANGELSPAWNS.get(npc.getId()), npc);
|
||||
newNpc.setRunning();
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PolymorphingAngel();
|
||||
}
|
||||
}
|
||||
120
trunk/dist/game/data/scripts/ai/group_template/PolymorphingOnAttack.java
vendored
Normal file
120
trunk/dist/game/data/scripts/ai/group_template/PolymorphingOnAttack.java
vendored
Normal file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
|
||||
|
||||
/**
|
||||
* Polymorphing on attack monsters AI.
|
||||
* @author Slyce
|
||||
*/
|
||||
public final class PolymorphingOnAttack extends AbstractNpcAI
|
||||
{
|
||||
private static final Map<Integer, List<Integer>> MOBSPAWNS = new HashMap<>();
|
||||
static
|
||||
{
|
||||
MOBSPAWNS.put(21258, Arrays.asList(21259, 100, 100, -1)); // Fallen Orc Shaman -> Sharp Talon Tiger (always polymorphs)
|
||||
MOBSPAWNS.put(21261, Arrays.asList(21262, 100, 20, 0)); // Ol Mahum Transcender 1st stage
|
||||
MOBSPAWNS.put(21262, Arrays.asList(21263, 100, 10, 1)); // Ol Mahum Transcender 2nd stage
|
||||
MOBSPAWNS.put(21263, Arrays.asList(21264, 100, 5, 2)); // Ol Mahum Transcender 3rd stage
|
||||
MOBSPAWNS.put(21265, Arrays.asList(21271, 100, 33, 0)); // Cave Ant Larva -> Cave Ant
|
||||
MOBSPAWNS.put(21266, Arrays.asList(21269, 100, 100, -1)); // Cave Ant Larva -> Cave Ant (always polymorphs)
|
||||
MOBSPAWNS.put(21267, Arrays.asList(21270, 100, 100, -1)); // Cave Ant Larva -> Cave Ant Soldier (always polymorphs)
|
||||
MOBSPAWNS.put(21271, Arrays.asList(21272, 66, 10, 1)); // Cave Ant -> Cave Ant Soldier
|
||||
MOBSPAWNS.put(21272, Arrays.asList(21273, 33, 5, 2)); // Cave Ant Soldier -> Cave Noble Ant
|
||||
MOBSPAWNS.put(21521, Arrays.asList(21522, 100, 30, -1)); // Claws of Splendor
|
||||
MOBSPAWNS.put(21527, Arrays.asList(21528, 100, 30, -1)); // Anger of Splendor
|
||||
MOBSPAWNS.put(21533, Arrays.asList(21534, 100, 30, -1)); // Alliance of Splendor
|
||||
MOBSPAWNS.put(21537, Arrays.asList(21538, 100, 30, -1)); // Fang of Splendor
|
||||
}
|
||||
protected static final NpcStringId[][] MOBTEXTS =
|
||||
{
|
||||
new NpcStringId[]
|
||||
{
|
||||
NpcStringId.ENOUGH_FOOLING_AROUND_GET_READY_TO_DIE,
|
||||
NpcStringId.YOU_IDIOT_I_VE_JUST_BEEN_TOYING_WITH_YOU,
|
||||
NpcStringId.NOW_THE_FUN_STARTS
|
||||
},
|
||||
new NpcStringId[]
|
||||
{
|
||||
NpcStringId.I_MUST_ADMIT_NO_ONE_MAKES_MY_BLOOD_BOIL_QUITE_LIKE_YOU_DO,
|
||||
NpcStringId.NOW_THE_BATTLE_BEGINS,
|
||||
NpcStringId.WITNESS_MY_TRUE_POWER
|
||||
},
|
||||
new NpcStringId[]
|
||||
{
|
||||
NpcStringId.PREPARE_TO_DIE,
|
||||
NpcStringId.I_LL_DOUBLE_MY_STRENGTH,
|
||||
NpcStringId.YOU_HAVE_MORE_SKILL_THAN_I_THOUGHT
|
||||
}
|
||||
};
|
||||
|
||||
private PolymorphingOnAttack()
|
||||
{
|
||||
super(PolymorphingOnAttack.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(MOBSPAWNS.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.isVisible() && !npc.isDead())
|
||||
{
|
||||
final List<Integer> tmp = MOBSPAWNS.get(npc.getId());
|
||||
if (tmp != null)
|
||||
{
|
||||
if ((npc.getCurrentHp() <= ((npc.getMaxHp() * tmp.get(1)) / 100.0)) && (getRandom(100) < tmp.get(2)))
|
||||
{
|
||||
if (tmp.get(3) >= 0)
|
||||
{
|
||||
NpcStringId npcString = MOBTEXTS[tmp.get(3)][getRandom(MOBTEXTS[tmp.get(3)].length)];
|
||||
npc.broadcastPacket(new CreatureSay(npc.getObjectId(), Say2.NPC_ALL, npc.getName(), npcString));
|
||||
|
||||
}
|
||||
npc.deleteMe();
|
||||
final L2Attackable newNpc = (L2Attackable) addSpawn(tmp.get(0), npc.getX(), npc.getY(), npc.getZ() + 10, npc.getHeading(), false, 0, true);
|
||||
final L2Character originalAttacker = isSummon ? attacker.getSummon() : attacker;
|
||||
newNpc.setRunning();
|
||||
newNpc.addDamageHate(originalAttacker, 0, 500);
|
||||
newNpc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, originalAttacker);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PolymorphingOnAttack();
|
||||
}
|
||||
}
|
||||
515
trunk/dist/game/data/scripts/ai/group_template/PrimevalIsle.java
vendored
Normal file
515
trunk/dist/game/data/scripts/ai/group_template/PrimevalIsle.java
vendored
Normal file
@@ -0,0 +1,515 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.GeoData;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.handler.IItemHandler;
|
||||
import com.l2jserver.gameserver.handler.ItemHandler;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.items.instance.L2ItemInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Primeval Isle AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class PrimevalIsle extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int EGG = 18344; // Ancient Egg
|
||||
private static final int SAILREN = 29065; // Sailren
|
||||
private static final int ORNIT = 22742; // Ornithomimus
|
||||
private static final int DEINO = 22743; // Deinonychus
|
||||
private static final int[] SPRIGNANT =
|
||||
{
|
||||
18345, // Sprigant (Anesthesia)
|
||||
18346, // Sprigant (Deadly Poison)
|
||||
};
|
||||
private static final int[] MONSTERS =
|
||||
{
|
||||
22196, // Velociraptor
|
||||
22198, // Velociraptor
|
||||
22200, // Ornithomimus
|
||||
22202, // Ornithomimus
|
||||
22203, // Deinonychus
|
||||
22205, // Deinonychus
|
||||
22208, // Pachycephalosaurus
|
||||
22210, // Pachycephalosaurus
|
||||
22211, // Wild Strider
|
||||
22213, // Wild Strider
|
||||
22223, // Velociraptor
|
||||
22224, // Ornithomimus
|
||||
22225, // Deinonychus
|
||||
22226, // Pachycephalosaurus
|
||||
22227, // Wild Strider
|
||||
22742, // Ornithomimus
|
||||
22743, // Deinonychus
|
||||
};
|
||||
private static final int[] TREX =
|
||||
{
|
||||
22215, // Tyrannosaurus
|
||||
22216, // Tyrannosaurus
|
||||
22217, // Tyrannosaurus
|
||||
};
|
||||
private static final int[] VEGETABLE =
|
||||
{
|
||||
22200, // Ornithomimus
|
||||
22201, // Ornithomimus
|
||||
22202, // Ornithomimus
|
||||
22203, // Deinonychus
|
||||
22204, // Deinonychus
|
||||
22205, // Deinonychus
|
||||
22224, // Ornithomimus
|
||||
22225, // Deinonychus
|
||||
};
|
||||
// Item
|
||||
private static final int DEINONYCHUS = 14828; // Deinonychus Mesozoic Stone
|
||||
// Skill
|
||||
private static final SkillHolder ANESTHESIA = new SkillHolder(5085, 1); // Anesthesia
|
||||
private static final SkillHolder DEADLY_POISON = new SkillHolder(5086, 1); // Deadly Poison
|
||||
private static final SkillHolder SELFBUFF1 = new SkillHolder(5087, 1); // Berserk
|
||||
private static final SkillHolder SELFBUFF2 = new SkillHolder(5087, 2); // Berserk
|
||||
private static final SkillHolder LONGRANGEDMAGIC1 = new SkillHolder(5120, 1); // Stun
|
||||
private static final SkillHolder PHYSICALSPECIAL1 = new SkillHolder(5083, 4); // Stun
|
||||
private static final SkillHolder PHYSICALSPECIAL2 = new SkillHolder(5081, 4); // Silence
|
||||
private static final SkillHolder PHYSICALSPECIAL3 = new SkillHolder(5082, 4); // NPC Spinning, Slashing Trick
|
||||
private static final SkillHolder CREW_SKILL = new SkillHolder(6172, 1); // Presentation - Tyranno
|
||||
private static final SkillHolder INVIN_BUFF_ON = new SkillHolder(5225, 1); // Invincible
|
||||
|
||||
private PrimevalIsle()
|
||||
{
|
||||
super(PrimevalIsle.class.getSimpleName(), "ai/group_template");
|
||||
addSpawnId(TREX);
|
||||
addSpawnId(SPRIGNANT);
|
||||
addSpawnId(MONSTERS);
|
||||
addAggroRangeEnterId(TREX);
|
||||
addSpellFinishedId(TREX);
|
||||
addAttackId(EGG);
|
||||
addAttackId(TREX);
|
||||
addAttackId(MONSTERS);
|
||||
addKillId(EGG, SAILREN, DEINO, ORNIT);
|
||||
addSeeCreatureId(TREX);
|
||||
addSeeCreatureId(MONSTERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
if (skill.getId() == CREW_SKILL.getSkillId())
|
||||
{
|
||||
startQuestTimer("START_INVUL", 4000, npc, null);
|
||||
final L2Npc target = (L2Npc) npc.getTarget();
|
||||
if (target != null)
|
||||
{
|
||||
target.doDie(npc);
|
||||
}
|
||||
}
|
||||
if (npc.isInCombat())
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
final L2Character target = mob.getMostHated();
|
||||
if (((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 60)
|
||||
{
|
||||
if (skill.getId() == SELFBUFF1.getSkillId())
|
||||
{
|
||||
npc.setScriptValue(3);
|
||||
if ((target != null))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
mob.setIsRunning(true);
|
||||
mob.addDamageHate(target, 0, 555);
|
||||
mob.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (((npc.getCurrentHp() / npc.getMaxHp()) * 100) < 30)
|
||||
{
|
||||
if (skill.getId() == SELFBUFF1.getSkillId())
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
if ((target != null))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
mob.setIsRunning(true);
|
||||
mob.addDamageHate(target, 0, 555);
|
||||
mob.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
|
||||
}
|
||||
}
|
||||
else if (skill.getId() == SELFBUFF2.getSkillId())
|
||||
{
|
||||
npc.setScriptValue(5);
|
||||
if ((target != null))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
mob.setIsRunning(true);
|
||||
mob.addDamageHate(target, 0, 555);
|
||||
mob.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "USE_SKILL":
|
||||
{
|
||||
if ((npc != null) && !npc.isDead())
|
||||
{
|
||||
npc.doCast((npc.getId() == SPRIGNANT[0] ? ANESTHESIA.getSkill() : DEADLY_POISON.getSkill()));
|
||||
startQuestTimer("USE_SKILL", 15000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "GHOST_DESPAWN":
|
||||
{
|
||||
if ((npc != null) && !npc.isDead())
|
||||
{
|
||||
if (!npc.isInCombat())
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
else
|
||||
{
|
||||
startQuestTimer("GHOST_DESPAWN", 1800000, npc, null);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "TREX_ATTACK":
|
||||
{
|
||||
if ((npc != null) && (player != null))
|
||||
{
|
||||
npc.setScriptValue(0);
|
||||
if (player.isInsideRadius(npc, 800, true, false))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(LONGRANGEDMAGIC1.getSkill());
|
||||
addAttackPlayerDesire(npc, player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "START_INVUL":
|
||||
{
|
||||
if ((npc != null) && !npc.isDead())
|
||||
{
|
||||
npc.doCast(INVIN_BUFF_ON.getSkill());
|
||||
startQuestTimer("START_INVUL_2", 30000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "START_INVUL_2":
|
||||
{
|
||||
if ((npc != null) && !npc.isDead())
|
||||
{
|
||||
INVIN_BUFF_ON.getSkill().applyEffects(npc, npc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
|
||||
{
|
||||
if (Util.contains(MONSTERS, npc.getId()))
|
||||
{
|
||||
if (creature.isPlayer())
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
final int ag_type = npc.getTemplate().getParameters().getInt("ag_type", 0);
|
||||
final int probPhysicalSpecial1 = npc.getTemplate().getParameters().getInt("ProbPhysicalSpecial1", 0);
|
||||
final int probPhysicalSpecial2 = npc.getTemplate().getParameters().getInt("ProbPhysicalSpecial2", 0);
|
||||
final SkillHolder physicalSpecial1 = npc.getTemplate().getParameters().getObject("PhysicalSpecial1", SkillHolder.class);
|
||||
final SkillHolder physicalSpecial2 = npc.getTemplate().getParameters().getObject("PhysicalSpecial2", SkillHolder.class);
|
||||
|
||||
if (((getRandom(100) < 30) && (npc.getId() == DEINO)) || ((npc.getId() == ORNIT) && npc.isScriptValue(0)))
|
||||
{
|
||||
mob.clearAggroList();
|
||||
npc.setScriptValue(1);
|
||||
npc.setRunning();
|
||||
|
||||
final int distance = 3000;
|
||||
final int heading = Util.calculateHeadingFrom(creature, npc);
|
||||
final double angle = Util.convertHeadingToDegree(heading);
|
||||
final double radian = Math.toRadians(angle);
|
||||
final double sin = Math.sin(radian);
|
||||
final double cos = Math.cos(radian);
|
||||
final int newX = (int) (npc.getX() + (cos * distance));
|
||||
final int newY = (int) (npc.getY() + (sin * distance));
|
||||
final Location loc = GeoData.getInstance().moveCheck(npc.getX(), npc.getY(), npc.getZ(), newX, newY, npc.getZ(), npc.getInstanceId());
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, loc, 0);
|
||||
}
|
||||
else if (ag_type == 1)
|
||||
{
|
||||
if (getRandom(100) <= (probPhysicalSpecial1 * npc.getVariables().getInt("SKILL_MULTIPLER")))
|
||||
{
|
||||
if (!npc.isSkillDisabled(physicalSpecial1.getSkillId()))
|
||||
{
|
||||
npc.setTarget(creature);
|
||||
npc.doCast(physicalSpecial1.getSkill());
|
||||
}
|
||||
}
|
||||
else if (getRandom(100) <= (probPhysicalSpecial2 * npc.getVariables().getInt("SKILL_MULTIPLER")))
|
||||
{
|
||||
if (!npc.isSkillDisabled(physicalSpecial2.getSkill()))
|
||||
{
|
||||
npc.setTarget(creature);
|
||||
npc.doCast(physicalSpecial2.getSkill());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Util.contains(VEGETABLE, creature.getId()))
|
||||
{
|
||||
npc.setTarget(creature);
|
||||
npc.doCast(CREW_SKILL.getSkill());
|
||||
npc.setIsRunning(true);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, creature);
|
||||
}
|
||||
return super.onSeeCreature(npc, creature, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
if (npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, "?");
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
startQuestTimer("TREX_ATTACK", 6000, npc, player);
|
||||
}
|
||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == EGG)
|
||||
{
|
||||
if ((getRandom(100) <= 80) && npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
final L2Playable playable = isSummon ? attacker.getSummon() : attacker;
|
||||
for (L2Character characters : npc.getKnownList().getKnownCharactersInRadius(500))
|
||||
{
|
||||
if ((characters != null) && (characters.isAttackable()) && (getRandomBoolean()))
|
||||
{
|
||||
L2Attackable monster = (L2Attackable) characters;
|
||||
addAttackPlayerDesire(monster, playable);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (Util.contains(TREX, npc.getId()))
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
final L2Character target = mob.getMostHated();
|
||||
|
||||
if (((npc.getCurrentHp() / npc.getMaxHp()) * 100) <= 30)
|
||||
{
|
||||
if (npc.isScriptValue(3))
|
||||
{
|
||||
if (!npc.isSkillDisabled(SELFBUFF1.getSkill()))
|
||||
{
|
||||
npc.doCast(SELFBUFF1.getSkill());
|
||||
}
|
||||
}
|
||||
else if (npc.isScriptValue(1))
|
||||
{
|
||||
if (!npc.isSkillDisabled(SELFBUFF2.getSkill()))
|
||||
{
|
||||
npc.doCast(SELFBUFF2.getSkill());
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((((npc.getCurrentHp() / npc.getMaxHp()) * 100) <= 60) && (npc.isScriptValue(3)))
|
||||
{
|
||||
if (!npc.isSkillDisabled(SELFBUFF1.getSkill()))
|
||||
{
|
||||
npc.doCast(SELFBUFF1.getSkill());
|
||||
}
|
||||
}
|
||||
|
||||
if (Util.calculateDistance(npc, attacker, true, false) > 100)
|
||||
{
|
||||
if (!npc.isSkillDisabled(LONGRANGEDMAGIC1.getSkill()) && (getRandom(100) <= (10 * npc.getScriptValue())))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(LONGRANGEDMAGIC1.getSkill());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!npc.isSkillDisabled(LONGRANGEDMAGIC1.getSkill()) && (getRandom(100) <= (10 * npc.getScriptValue())))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
npc.doCast(LONGRANGEDMAGIC1.getSkill());
|
||||
}
|
||||
if (!npc.isSkillDisabled(PHYSICALSPECIAL1.getSkill()) && (getRandom(100) <= (5 * npc.getScriptValue())))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
npc.doCast(PHYSICALSPECIAL1.getSkill());
|
||||
}
|
||||
if (!npc.isSkillDisabled(PHYSICALSPECIAL2.getSkill()) && (getRandom(100) <= (3 * npc.getScriptValue())))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
npc.doCast(PHYSICALSPECIAL2.getSkill());
|
||||
}
|
||||
if (!npc.isSkillDisabled(PHYSICALSPECIAL3.getSkill()) && (getRandom(100) <= (5 * npc.getScriptValue())))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
npc.doCast(PHYSICALSPECIAL3.getSkill());
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
L2Character target = null;
|
||||
final int probPhysicalSpecial1 = npc.getTemplate().getParameters().getInt("ProbPhysicalSpecial1", 0);
|
||||
final int probPhysicalSpecial2 = npc.getTemplate().getParameters().getInt("ProbPhysicalSpecial2", 0);
|
||||
final SkillHolder selfRangeBuff1 = npc.getTemplate().getParameters().getObject("SelfRangeBuff1", SkillHolder.class);
|
||||
final SkillHolder physicalSpecial1 = npc.getTemplate().getParameters().getObject("PhysicalSpecial1", SkillHolder.class);
|
||||
final SkillHolder physicalSpecial2 = npc.getTemplate().getParameters().getObject("PhysicalSpecial2", SkillHolder.class);
|
||||
|
||||
if (((npc.getCurrentHp() / npc.getMaxHp()) * 100) <= 50)
|
||||
{
|
||||
npc.getVariables().set("SKILL_MULTIPLER", 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.getVariables().set("SKILL_MULTIPLER", 1);
|
||||
}
|
||||
|
||||
if ((((npc.getCurrentHp() / npc.getMaxHp()) * 100) <= 30) && (npc.getVariables().getInt("SELFBUFF_USED") == 0))
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
target = mob.getMostHated();
|
||||
mob.clearAggroList();
|
||||
if (!npc.isSkillDisabled(selfRangeBuff1.getSkillId()))
|
||||
{
|
||||
npc.getVariables().set("SELFBUFF_USED", 1);
|
||||
npc.doCast(selfRangeBuff1.getSkill());
|
||||
npc.setIsRunning(true);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, target);
|
||||
}
|
||||
}
|
||||
|
||||
if (target != null)
|
||||
{
|
||||
if (getRandom(100) <= (probPhysicalSpecial1 * npc.getVariables().getInt("SKILL_MULTIPLER")))
|
||||
{
|
||||
if (!npc.isSkillDisabled(physicalSpecial1.getSkill()))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
npc.doCast(physicalSpecial1.getSkill());
|
||||
}
|
||||
}
|
||||
if (getRandom(100) <= (probPhysicalSpecial2 * npc.getVariables().getInt("SKILL_MULTIPLER")))
|
||||
{
|
||||
if (!npc.isSkillDisabled(physicalSpecial2.getSkill()))
|
||||
{
|
||||
npc.setTarget(target);
|
||||
npc.doCast(physicalSpecial2.getSkill());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if ((npc.getId() == DEINO) || ((npc.getId() == ORNIT) && !npc.isScriptValue(1)))
|
||||
{
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
if ((npc.getId() == SAILREN) || (getRandom(100) < 3))
|
||||
{
|
||||
final L2PcInstance player = npc.getId() == SAILREN ? getRandomPartyMember(killer) : killer;
|
||||
if (player.getInventory().getSize(false) <= (player.getInventoryLimit() * 0.8))
|
||||
{
|
||||
giveItems(player, DEINONYCHUS, 1);
|
||||
final L2ItemInstance summonItem = player.getInventory().getItemByItemId(DEINONYCHUS);
|
||||
final IItemHandler handler = ItemHandler.getInstance().getHandler(summonItem.getEtcItem());
|
||||
if ((handler != null) && !player.hasPet())
|
||||
{
|
||||
handler.useItem(player, summonItem, true);
|
||||
}
|
||||
showOnScreenMsg(player, NpcStringId.LIFE_STONE_FROM_THE_BEGINNING_ACQUIRED, 2, 6000);
|
||||
}
|
||||
else
|
||||
{
|
||||
showOnScreenMsg(player, NpcStringId.WHEN_INVENTORY_WEIGHT_NUMBER_ARE_MORE_THAN_80_THE_LIFE_STONE_FROM_THE_BEGINNING_CANNOT_BE_ACQUIRED, 2, 6000);
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (Util.contains(SPRIGNANT, npc.getId()))
|
||||
{
|
||||
startQuestTimer("USE_SKILL", 15000, npc, null);
|
||||
}
|
||||
else if (Util.contains(TREX, npc.getId()))
|
||||
{
|
||||
final int collectGhost = npc.getTemplate().getParameters().getInt("CollectGhost", 0);
|
||||
final int collectDespawn = npc.getTemplate().getParameters().getInt("CollectGhostDespawnTime", 30);
|
||||
|
||||
if (collectGhost == 1)
|
||||
{
|
||||
startQuestTimer("GHOST_DESPAWN", collectDespawn * 60000, npc, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.getVariables().set("SELFBUFF_USED", 0);
|
||||
npc.getVariables().set("SKILL_MULTIPLER", 1);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PrimevalIsle();
|
||||
}
|
||||
}
|
||||
161
trunk/dist/game/data/scripts/ai/group_template/PrisonGuards.java
vendored
Normal file
161
trunk/dist/game/data/scripts/ai/group_template/PrisonGuards.java
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Prison Guards AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class PrisonGuards extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int GUARD_HEAD = 18367; // Prison Guard
|
||||
private static final int GUARD = 18368; // Prison Guard
|
||||
// Item
|
||||
private static final int STAMP = 10013; // Race Stamp
|
||||
// Skills
|
||||
private static final int TIMER = 5239; // Event Timer
|
||||
private static final SkillHolder STONE = new SkillHolder(4578, 1); // Petrification
|
||||
private static final SkillHolder SILENCE = new SkillHolder(4098, 9); // Silence
|
||||
|
||||
private PrisonGuards()
|
||||
{
|
||||
super(PrisonGuards.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(GUARD_HEAD, GUARD);
|
||||
addSpawnId(GUARD_HEAD, GUARD);
|
||||
addNpcHateId(GUARD);
|
||||
addSkillSeeId(GUARD);
|
||||
addSpellFinishedId(GUARD_HEAD, GUARD);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("CLEAR_STATUS"))
|
||||
{
|
||||
npc.setScriptValue(0);
|
||||
}
|
||||
else if (event.equals("CHECK_HOME"))
|
||||
{
|
||||
if ((npc.calculateDistance(npc.getSpawn().getLocation(), false, false) > 10) && !npc.isInCombat() && !npc.isDead())
|
||||
{
|
||||
npc.teleToLocation(npc.getSpawn().getLocation());
|
||||
}
|
||||
startQuestTimer("CHECK_HOME", 30000, npc, null);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == GUARD_HEAD)
|
||||
{
|
||||
if (player.isAffectedBySkill(TIMER))
|
||||
{
|
||||
if ((getRandom(100) < 10) && (npc.calculateDistance(player, true, false) < 100))
|
||||
{
|
||||
if ((getQuestItemsCount(player, STAMP) <= 3) && npc.isScriptValue(0))
|
||||
{
|
||||
giveItems(player, STAMP, 1);
|
||||
npc.setScriptValue(1);
|
||||
startQuestTimer("CLEAR_STATUS", 600000, npc, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(STONE.getSkill());
|
||||
broadcastNpcSay(npc, Say2.ALL, NpcStringId.IT_S_NOT_EASY_TO_OBTAIN);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!player.isAffectedBySkill(TIMER) && (npc.calculateDistance(npc.getSpawn().getLocation(), false, false) < 2000))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(STONE.getSkill());
|
||||
broadcastNpcSay(npc, Say2.ALL, NpcStringId.YOU_RE_OUT_OF_YOUR_MIND_COMING_HERE);
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, player, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if (!caster.isAffectedBySkill(TIMER))
|
||||
{
|
||||
npc.setTarget(caster);
|
||||
npc.doCast(SILENCE.getSkill());
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
if ((skill == SILENCE.getSkill()) || (skill == STONE.getSkill()))
|
||||
{
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
npc.setTarget(npc);
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onNpcHate(L2Attackable mob, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
return player.isAffectedBySkill(TIMER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (npc.getId() == GUARD_HEAD)
|
||||
{
|
||||
npc.setIsImmobilized(true);
|
||||
npc.setIsInvul(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.setIsNoRndWalk(true);
|
||||
cancelQuestTimer("CHECK_HOME", npc, null);
|
||||
startQuestTimer("CHECK_HOME", 30000, npc, null);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new PrisonGuards();
|
||||
}
|
||||
}
|
||||
123
trunk/dist/game/data/scripts/ai/group_template/RandomSpawn.java
vendored
Normal file
123
trunk/dist/game/data/scripts/ai/group_template/RandomSpawn.java
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
|
||||
/**
|
||||
* Manages spawn of NPCs having several random spawn points.
|
||||
* @author GKR
|
||||
*/
|
||||
public final class RandomSpawn extends AbstractNpcAI
|
||||
{
|
||||
private static Map<Integer, Location[]> SPAWN_POINTS = new FastMap<>();
|
||||
static
|
||||
{
|
||||
// Keltas
|
||||
SPAWN_POINTS.put(22341, new Location[]
|
||||
{
|
||||
new Location(-27136, 250938, -3523),
|
||||
new Location(-29658, 252897, -3523),
|
||||
new Location(-27237, 251943, -3527),
|
||||
new Location(-28868, 250113, -3479)
|
||||
});
|
||||
// Keymaster
|
||||
SPAWN_POINTS.put(22361, new Location[]
|
||||
{
|
||||
new Location(14091, 250533, -1940),
|
||||
new Location(15762, 252440, -2015),
|
||||
new Location(19836, 256212, -2090),
|
||||
new Location(21940, 254107, -2010),
|
||||
new Location(17299, 252943, -2015),
|
||||
});
|
||||
// Typhoon
|
||||
SPAWN_POINTS.put(25539, new Location[]
|
||||
{
|
||||
new Location(-20641, 255370, -3235),
|
||||
new Location(-16157, 250993, -3058),
|
||||
new Location(-18269, 250721, -3151),
|
||||
new Location(-16532, 254864, -3223),
|
||||
new Location(-19055, 253489, -3440),
|
||||
new Location(-9684, 254256, -3148),
|
||||
new Location(-6209, 251924, -3189),
|
||||
new Location(-10547, 251359, -2929),
|
||||
new Location(-7254, 254997, -3261),
|
||||
new Location(-4883, 253171, -3322)
|
||||
});
|
||||
// Mutated Elpy
|
||||
SPAWN_POINTS.put(25604, new Location[]
|
||||
{
|
||||
new Location(-46080, 246368, -14183),
|
||||
new Location(-44816, 246368, -14183),
|
||||
new Location(-44224, 247440, -14184),
|
||||
new Location(-44896, 248464, -14183),
|
||||
new Location(-46064, 248544, -14183),
|
||||
new Location(-46720, 247424, -14183)
|
||||
});
|
||||
}
|
||||
|
||||
public RandomSpawn()
|
||||
{
|
||||
super(RandomSpawn.class.getSimpleName(), "ai/group_template");
|
||||
addSpawnId(SPAWN_POINTS.keySet());
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onSpawn(L2Npc npc)
|
||||
{
|
||||
final Location[] spawnlist = SPAWN_POINTS.get(npc.getId());
|
||||
final Location loc = spawnlist[getRandom(spawnlist.length)];
|
||||
if (!npc.isInsideRadius(loc, 200, false, false))
|
||||
{
|
||||
npc.getSpawn().setLocation(loc);
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Teleport(npc, loc), 100);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
private static class Teleport implements Runnable
|
||||
{
|
||||
private final L2Npc _npc;
|
||||
private final Location _loc;
|
||||
|
||||
public Teleport(L2Npc npc, Location loc)
|
||||
{
|
||||
_npc = npc;
|
||||
_loc = loc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
_npc.teleToLocation(_loc, false);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new RandomSpawn();
|
||||
}
|
||||
}
|
||||
118
trunk/dist/game/data/scripts/ai/group_template/RangeGuard.java
vendored
Normal file
118
trunk/dist/game/data/scripts/ai/group_template/RangeGuard.java
vendored
Normal file
@@ -0,0 +1,118 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.datatables.NpcData;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Range Guard AI.
|
||||
* @author St3eT.
|
||||
*/
|
||||
public final class RangeGuard extends AbstractNpcAI
|
||||
{
|
||||
// Skill
|
||||
private static SkillHolder ULTIMATE_DEFENSE = new SkillHolder(5044, 3); // NPC Ultimate Defense
|
||||
//@formatter:off
|
||||
private static final int[] NOT_ALLOWED_SKILLS =
|
||||
{
|
||||
15, 28, // Charm / Aggression
|
||||
51, 65, // Lure / Horror
|
||||
106, 115, // Veil / Power Break
|
||||
122, 127, // Hex / Hamstring
|
||||
254, 352, // Spoil / Shield Bash
|
||||
353, 358, // Shield Slam / Bluff
|
||||
402, 403, // Arrest / Shackle
|
||||
412, 485, // Sand Bomb / Disarm
|
||||
501, 511, // Violent Temper / Temptation
|
||||
522, 531, // Real Target / Critical Wound
|
||||
680, 695, // Divine Knight Hate / Divine Wizard Divine Cloud
|
||||
696, 716, // Divine Wizard Surrender to Divine / Zaken Hold
|
||||
775, 792, // Weapon Blockade / Betrayal Mark
|
||||
1042, 1049, // Hold Undead / Requiem
|
||||
1069, 1071, // Sleep / Surrender To Water
|
||||
1072, 1074, // Sleeping Cloud / Surrender To Wind
|
||||
1083, 1097, // Surrender To Fire / Dreaming Spirit
|
||||
1092, 1064, // Fear / Silence
|
||||
1160, 1164, // Slow / Curse Weakness
|
||||
1169, 1170, // Curse Fear / Anchor
|
||||
1201, 1206, // Dryad Root / Wind Shackle
|
||||
1222, 1223, // Curse Chaos / Surrender To Earth
|
||||
1224, 1263, // Surrender To Poison / Curse Gloom
|
||||
1269, 1336, // Curse Disease / Curse of Doom
|
||||
1337, 1338, // Curse of Abyss / Arcane Chaos
|
||||
1358, 1359, // Block Shield / Block Wind Walk
|
||||
1386, 1394, // Arcane Disruption / Trance
|
||||
1396, 1445, // Magical BackFire / Surrender to Dark
|
||||
1446, 1447, // Shadow Bind / Voice Bind
|
||||
1481, 1482, // Oblivion / Weak Constitution
|
||||
1483, 1484, // Thin Skin / Enervation
|
||||
1485, 1486, // Spite / Mental Impoverish
|
||||
1511, 1524, // Curse of Life Flow / Surrender to the Divine
|
||||
1529, // Soul Web
|
||||
};
|
||||
//@formatter:on
|
||||
// Misc
|
||||
private static final int MIN_DISTANCE = 150;
|
||||
|
||||
private RangeGuard()
|
||||
{
|
||||
super(RangeGuard.class.getSimpleName(), "ai/group_template");
|
||||
|
||||
for (L2NpcTemplate template : NpcData.getInstance().getAllNpcOfClassType("L2Monster"))
|
||||
{
|
||||
if (template.getParameters().getInt("LongRangeGuardRate", -1) > 0)
|
||||
{
|
||||
addAttackId(template.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill)
|
||||
{
|
||||
final L2Playable playable = (isSummon) ? attacker.getSummon() : attacker;
|
||||
final int longRangeGuardRate = npc.getTemplate().getParameters().getInt("LongRangeGuardRate");
|
||||
final double distance = Util.calculateDistance(npc, playable, true, false);
|
||||
|
||||
if (npc.isAffectedBySkill(ULTIMATE_DEFENSE.getSkillId()) && (distance <= MIN_DISTANCE))
|
||||
{
|
||||
npc.stopSkillEffects(true, ULTIMATE_DEFENSE.getSkillId());
|
||||
}
|
||||
else if ((distance > MIN_DISTANCE) && !npc.isSkillDisabled(ULTIMATE_DEFENSE.getSkillId()) && !((skill != null) && Util.contains(NOT_ALLOWED_SKILLS, skill.getId())) && (getRandom(100) < longRangeGuardRate))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(ULTIMATE_DEFENSE.getSkill());
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon, skill);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new RangeGuard();
|
||||
}
|
||||
}
|
||||
93
trunk/dist/game/data/scripts/ai/group_template/Remnants.java
vendored
Normal file
93
trunk/dist/game/data/scripts/ai/group_template/Remnants.java
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* Remnants AI.
|
||||
* @author DS
|
||||
*/
|
||||
public final class Remnants extends AbstractNpcAI
|
||||
{
|
||||
private static final int[] NPCS =
|
||||
{
|
||||
18463,
|
||||
18464,
|
||||
18465
|
||||
};
|
||||
private static final int SKILL_HOLY_WATER = 2358;
|
||||
|
||||
// TODO: Find retail strings.
|
||||
// private static final String MSG = "The holy water affects Remnants Ghost. You have freed his soul.";
|
||||
// private static final String MSG_DEREK = "The holy water affects Derek. You have freed his soul.";
|
||||
private Remnants()
|
||||
{
|
||||
super(Remnants.class.getSimpleName(), "ai/group_template");
|
||||
addSpawnId(NPCS);
|
||||
addSkillSeeId(NPCS);
|
||||
// Do not override onKill for Derek here. Let's make global Hellbound manipulations in Engine where it is possible.
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.setIsMortal(false);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if (skill.getId() == SKILL_HOLY_WATER)
|
||||
{
|
||||
if (!npc.isDead())
|
||||
{
|
||||
if ((targets.length > 0) && (targets[0] == npc))
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.02)) // Lower, than 2%
|
||||
{
|
||||
npc.doDie(caster);
|
||||
//@formatter:off
|
||||
/*if (npc.getNpcId() == DEREK)
|
||||
{
|
||||
caster.sendMessage(MSG_DEREK);
|
||||
}
|
||||
else
|
||||
{
|
||||
caster.sendMessage(MSG);
|
||||
}*/
|
||||
//@formatter:on
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Remnants();
|
||||
}
|
||||
}
|
||||
56
trunk/dist/game/data/scripts/ai/group_template/Sandstorms.java
vendored
Normal file
56
trunk/dist/game/data/scripts/ai/group_template/Sandstorms.java
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
|
||||
/**
|
||||
* Sandstorms AI.
|
||||
* @author Ectis
|
||||
*/
|
||||
public class Sandstorms extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int SANDSTORM = 32350;
|
||||
// Skills
|
||||
private static final SkillHolder GUST = new SkillHolder(5435, 1); // Gust
|
||||
|
||||
public Sandstorms()
|
||||
{
|
||||
super(Sandstorms.class.getSimpleName(), "ai/group_template");
|
||||
addAggroRangeEnterId(SANDSTORM); // Sandstorm
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(GUST.getSkill());
|
||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Sandstorms();
|
||||
}
|
||||
}
|
||||
63
trunk/dist/game/data/scripts/ai/group_template/SeeThroughSilentMove.java
vendored
Normal file
63
trunk/dist/game/data/scripts/ai/group_template/SeeThroughSilentMove.java
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
|
||||
/**
|
||||
* See Through Silent Move AI.
|
||||
* @author Gigiikun
|
||||
*/
|
||||
public class SeeThroughSilentMove extends AbstractNpcAI
|
||||
{
|
||||
//@formatter:off
|
||||
private static final int[] MONSTERS =
|
||||
{
|
||||
18001, 18002, 22199, 22215, 22216, 22217, 22327, 22746, 22747, 22748,
|
||||
22749, 22750, 22751, 22752, 22753, 22754, 22755, 22756, 22757, 22758,
|
||||
22759, 22760, 22761, 22762, 22763, 22764, 22765, 22794, 22795, 22796,
|
||||
22797, 22798, 22799, 22800, 22843, 22857, 25725, 25726, 25727, 29009,
|
||||
29010, 29011, 29012, 29013
|
||||
};
|
||||
//@formatter:on
|
||||
|
||||
private SeeThroughSilentMove()
|
||||
{
|
||||
super(SeeThroughSilentMove.class.getSimpleName(), "ai/group_template");
|
||||
addSpawnId(MONSTERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (npc.isAttackable())
|
||||
{
|
||||
((L2Attackable) npc).setSeeThroughSilentMove(true);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SeeThroughSilentMove();
|
||||
}
|
||||
}
|
||||
321
trunk/dist/game/data/scripts/ai/group_template/SelMahumDrill.java
vendored
Normal file
321
trunk/dist/game/data/scripts/ai/group_template/SelMahumDrill.java
vendored
Normal file
@@ -0,0 +1,321 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.SpawnTable;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.L2Spawn;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Sel Mahum Training Ground AI for drill groups.
|
||||
* @author GKR
|
||||
*/
|
||||
public final class SelMahumDrill extends AbstractNpcAI
|
||||
{
|
||||
private static final int[] MAHUM_CHIEFS =
|
||||
{
|
||||
22775, // Sel Mahum Drill Sergeant
|
||||
22776, // Sel Mahum Training Officer
|
||||
22778, // Sel Mahum Drill Sergeant
|
||||
};
|
||||
|
||||
private static final int[] MAHUM_SOLDIERS =
|
||||
{
|
||||
22780, // Sel Mahum Recruit
|
||||
22782, // Sel Mahum Recruit
|
||||
22783, // Sel Mahum Soldier
|
||||
22784, // Sel Mahum Recruit
|
||||
22785, // Sel Mahum Soldier
|
||||
};
|
||||
|
||||
private static final int[] CHIEF_SOCIAL_ACTIONS =
|
||||
{
|
||||
1,
|
||||
4,
|
||||
5,
|
||||
7
|
||||
};
|
||||
|
||||
private static final Actions[] SOLDIER_SOCIAL_ACTIONS =
|
||||
{
|
||||
Actions.SCE_TRAINING_ACTION_A,
|
||||
Actions.SCE_TRAINING_ACTION_B,
|
||||
Actions.SCE_TRAINING_ACTION_C,
|
||||
Actions.SCE_TRAINING_ACTION_D
|
||||
};
|
||||
|
||||
private static final NpcStringId[] CHIEF_FSTRINGS =
|
||||
{
|
||||
NpcStringId.HOW_DARE_YOU_ATTACK_MY_RECRUITS,
|
||||
NpcStringId.WHO_IS_DISRUPTING_THE_ORDER
|
||||
};
|
||||
|
||||
private static final NpcStringId[] SOLDIER_FSTRINGS =
|
||||
{
|
||||
NpcStringId.THE_DRILLMASTER_IS_DEAD,
|
||||
NpcStringId.LINE_UP_THE_RANKS
|
||||
};
|
||||
|
||||
// Chiefs event broadcast range
|
||||
private static final int TRAINING_RANGE = 1000;
|
||||
|
||||
private static enum Actions
|
||||
{
|
||||
SCE_TRAINING_ACTION_A(4, -1, 2, 2333),
|
||||
SCE_TRAINING_ACTION_B(1, -1, 2, 4333),
|
||||
SCE_TRAINING_ACTION_C(6, 5, 4, 1000),
|
||||
SCE_TRAINING_ACTION_D(7, -1, 2, 1000);
|
||||
|
||||
private final int _socialActionId;
|
||||
private final int _altSocialActionId;
|
||||
private final int _repeatCount;
|
||||
private final int _repeatInterval;
|
||||
|
||||
private Actions(int socialActionId, int altSocialActionId, int repeatCount, int repeatInterval)
|
||||
{
|
||||
_socialActionId = socialActionId;
|
||||
_altSocialActionId = altSocialActionId;
|
||||
_repeatCount = repeatCount;
|
||||
_repeatInterval = repeatInterval;
|
||||
}
|
||||
|
||||
protected int getSocialActionId()
|
||||
{
|
||||
return _socialActionId;
|
||||
}
|
||||
|
||||
protected int getAltSocialActionId()
|
||||
{
|
||||
return _altSocialActionId;
|
||||
}
|
||||
|
||||
protected int getRepeatCount()
|
||||
{
|
||||
return _repeatCount;
|
||||
}
|
||||
|
||||
protected int getRepeatInterval()
|
||||
{
|
||||
return _repeatInterval;
|
||||
}
|
||||
}
|
||||
|
||||
private SelMahumDrill()
|
||||
{
|
||||
super(SelMahumDrill.class.getSimpleName(), "ai/group_template");
|
||||
|
||||
addAttackId(MAHUM_SOLDIERS);
|
||||
addKillId(MAHUM_CHIEFS);
|
||||
addEventReceivedId(MAHUM_CHIEFS);
|
||||
addEventReceivedId(MAHUM_SOLDIERS);
|
||||
addSpawnId(MAHUM_CHIEFS);
|
||||
addSpawnId(MAHUM_SOLDIERS);
|
||||
// Start global return home timer
|
||||
startQuestTimer("return_home", 120000, null, null, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "do_social_action":
|
||||
{
|
||||
if ((npc != null) && !npc.isDead())
|
||||
{
|
||||
if (Util.contains(MAHUM_CHIEFS, npc.getId()))
|
||||
{
|
||||
if ((npc.getVariables().getInt("BUSY_STATE") == 0) && (npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_ACTIVE) && npc.staysInSpawnLoc())
|
||||
{
|
||||
final int idx = getRandom(6);
|
||||
if (idx <= (CHIEF_SOCIAL_ACTIONS.length - 1))
|
||||
{
|
||||
npc.broadcastSocialAction(CHIEF_SOCIAL_ACTIONS[idx]);
|
||||
npc.getVariables().set("SOCIAL_ACTION_NEXT_INDEX", idx); // Pass social action index to soldiers via script value
|
||||
npc.broadcastEvent("do_social_action", TRAINING_RANGE, null);
|
||||
}
|
||||
}
|
||||
|
||||
startQuestTimer("do_social_action", 15000, npc, null);
|
||||
}
|
||||
else if (Util.contains(MAHUM_SOLDIERS, npc.getId()))
|
||||
{
|
||||
handleSocialAction(npc, SOLDIER_SOCIAL_ACTIONS[npc.getVariables().getInt("SOCIAL_ACTION_NEXT_INDEX")], false);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "reset_busy_state":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
npc.getVariables().remove("BUSY_STATE");
|
||||
npc.disableCoreAI(false);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "return_home":
|
||||
{
|
||||
for (int npcId : MAHUM_SOLDIERS)
|
||||
{
|
||||
for (L2Spawn npcSpawn : SpawnTable.getInstance().getSpawns(npcId))
|
||||
{
|
||||
final L2Npc soldier = npcSpawn.getLastSpawn();
|
||||
if ((soldier != null) && !soldier.isDead() && (npcSpawn.getName() != null) && npcSpawn.getName().startsWith("smtg_drill_group") && !soldier.staysInSpawnLoc() && ((soldier.getAI().getIntention() == CtrlIntention.AI_INTENTION_ACTIVE) || (soldier.getAI().getIntention() == CtrlIntention.AI_INTENTION_IDLE)))
|
||||
{
|
||||
soldier.setHeading(npcSpawn.getHeading());
|
||||
soldier.teleToLocation(npcSpawn.getLocation(), false);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (getRandom(10) < 1)
|
||||
{
|
||||
npc.broadcastEvent("ATTACKED", 1000, null);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEventReceived(String eventName, L2Npc sender, L2Npc receiver, L2Object reference)
|
||||
{
|
||||
if ((receiver != null) && !receiver.isDead() && receiver.isInMySpawnGroup(sender))
|
||||
{
|
||||
switch (eventName)
|
||||
{
|
||||
case "do_social_action":
|
||||
{
|
||||
if (Util.contains(MAHUM_SOLDIERS, receiver.getId()))
|
||||
{
|
||||
final int actionIndex = sender.getVariables().getInt("SOCIAL_ACTION_NEXT_INDEX");
|
||||
receiver.getVariables().set("SOCIAL_ACTION_NEXT_INDEX", actionIndex);
|
||||
handleSocialAction(receiver, SOLDIER_SOCIAL_ACTIONS[actionIndex], true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "CHIEF_DIED":
|
||||
{
|
||||
if (Util.contains(MAHUM_SOLDIERS, receiver.getId()))
|
||||
{
|
||||
if (getRandom(4) < 1)
|
||||
{
|
||||
broadcastNpcSay(receiver, Say2.NPC_ALL, SOLDIER_FSTRINGS[getRandom(2)]);
|
||||
}
|
||||
if (receiver.canBeAttacked())
|
||||
{
|
||||
((L2Attackable) receiver).clearAggroList();
|
||||
}
|
||||
receiver.disableCoreAI(true);
|
||||
receiver.getVariables().set("BUSY_STATE", 1);
|
||||
receiver.setIsRunning(true);
|
||||
receiver.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location((receiver.getX() + getRandom(-800, 800)), (receiver.getY() + getRandom(-800, 800)), receiver.getZ(), receiver.getHeading()));
|
||||
startQuestTimer("reset_busy_state", 5000, receiver, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "ATTACKED":
|
||||
{
|
||||
if (Util.contains(MAHUM_CHIEFS, receiver.getId()))
|
||||
{
|
||||
broadcastNpcSay(receiver, Say2.NPC_ALL, CHIEF_FSTRINGS[getRandom(2)]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onEventReceived(eventName, sender, receiver, reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
npc.broadcastEvent("CHIEF_DIED", TRAINING_RANGE, null);
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (Util.contains(MAHUM_CHIEFS, npc.getId()))
|
||||
{
|
||||
startQuestTimer("do_social_action", 15000, npc, null);
|
||||
}
|
||||
|
||||
else if ((getRandom(18) < 1) && Util.contains(MAHUM_SOLDIERS, npc.getId()))
|
||||
{
|
||||
npc.getVariables().set("SOCIAL_ACTION_ALT_BEHAVIOR", 1);
|
||||
}
|
||||
|
||||
// Restore AI handling by core
|
||||
npc.disableCoreAI(false);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
private void handleSocialAction(L2Npc npc, Actions action, boolean firstCall)
|
||||
{
|
||||
if ((npc.getVariables().getInt("BUSY_STATE") != 0) || (npc.getAI().getIntention() != CtrlIntention.AI_INTENTION_ACTIVE) || !npc.staysInSpawnLoc())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int socialActionId = (npc.getVariables().getInt("SOCIAL_ACTION_ALT_BEHAVIOR") == 0) ? action.getSocialActionId() : action.getAltSocialActionId();
|
||||
|
||||
if (socialActionId < 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (firstCall)
|
||||
{
|
||||
npc.getVariables().set("SOCIAL_ACTION_REMAINED_COUNT", action.getRepeatCount());
|
||||
}
|
||||
|
||||
npc.broadcastSocialAction(socialActionId);
|
||||
|
||||
final int remainedCount = npc.getVariables().getInt("SOCIAL_ACTION_REMAINED_COUNT");
|
||||
if (remainedCount > 0)
|
||||
{
|
||||
npc.getVariables().set("SOCIAL_ACTION_REMAINED_COUNT", (remainedCount - 1));
|
||||
startQuestTimer("do_social_action", action.getRepeatInterval(), npc, null);
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SelMahumDrill();
|
||||
}
|
||||
}
|
||||
405
trunk/dist/game/data/scripts/ai/group_template/SelMahumSquad.java
vendored
Normal file
405
trunk/dist/game/data/scripts/ai/group_template/SelMahumSquad.java
vendored
Normal file
@@ -0,0 +1,405 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.GameTimeController;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Sel Mahum Training Ground AI for squads and chefs.
|
||||
* @author GKR
|
||||
*/
|
||||
public final class SelMahumSquad extends AbstractNpcAI
|
||||
{
|
||||
// NPC's
|
||||
private static final int CHEF = 18908;
|
||||
private static final int FIRE = 18927;
|
||||
private static final int STOVE = 18933;
|
||||
|
||||
private static final int OHS_Weapon = 15280;
|
||||
private static final int THS_Weapon = 15281;
|
||||
|
||||
// Sel Mahum Squad Leaders
|
||||
private static final int[] SQUAD_LEADERS =
|
||||
{
|
||||
22786,
|
||||
22787,
|
||||
22788
|
||||
};
|
||||
|
||||
private static final NpcStringId[] CHEF_FSTRINGS =
|
||||
{
|
||||
NpcStringId.I_BROUGHT_THE_FOOD,
|
||||
NpcStringId.COME_AND_EAT
|
||||
};
|
||||
|
||||
private static final int FIRE_EFFECT_BURN = 1;
|
||||
private static final int FIRE_EFFECT_NONE = 2;
|
||||
|
||||
private static final int MAHUM_EFFECT_EAT = 1;
|
||||
private static final int MAHUM_EFFECT_SLEEP = 2;
|
||||
private static final int MAHUM_EFFECT_NONE = 3;
|
||||
|
||||
private SelMahumSquad()
|
||||
{
|
||||
super(SelMahumSquad.class.getSimpleName(), "ai/group_template");
|
||||
|
||||
addAttackId(CHEF);
|
||||
addAttackId(SQUAD_LEADERS);
|
||||
addEventReceivedId(CHEF, FIRE, STOVE);
|
||||
addEventReceivedId(SQUAD_LEADERS);
|
||||
addFactionCallId(SQUAD_LEADERS);
|
||||
addKillId(CHEF);
|
||||
addMoveFinishedId(SQUAD_LEADERS);
|
||||
addNodeArrivedId(CHEF);
|
||||
addSkillSeeId(STOVE);
|
||||
addSpawnId(CHEF, FIRE);
|
||||
addSpawnId(SQUAD_LEADERS);
|
||||
addSpellFinishedId(CHEF);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "chef_disable_reward":
|
||||
{
|
||||
npc.getVariables().set("REWARD_TIME_GONE", 1);
|
||||
break;
|
||||
}
|
||||
case "chef_heal_player":
|
||||
{
|
||||
healPlayer(npc, player);
|
||||
break;
|
||||
}
|
||||
case "chef_remove_invul":
|
||||
{
|
||||
if (npc.isMonster())
|
||||
{
|
||||
npc.setIsInvul(false);
|
||||
npc.getVariables().remove("INVUL_REMOVE_TIMER_STARTED");
|
||||
if ((player != null) && !player.isDead() && npc.getKnownList().knowsThePlayer(player))
|
||||
{
|
||||
addAttackPlayerDesire(npc, player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "chef_set_invul":
|
||||
{
|
||||
if (!npc.isDead())
|
||||
{
|
||||
npc.setIsInvul(true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "fire":
|
||||
{
|
||||
startQuestTimer("fire", 30000 + getRandom(5000), npc, null);
|
||||
npc.setDisplayEffect(FIRE_EFFECT_NONE);
|
||||
|
||||
if (getRandom(GameTimeController.getInstance().isNight() ? 2 : 4) < 1)
|
||||
{
|
||||
npc.setDisplayEffect(FIRE_EFFECT_BURN); // fire burns
|
||||
npc.broadcastEvent("SCE_CAMPFIRE_START", 600, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.setDisplayEffect(FIRE_EFFECT_NONE); // fire goes out
|
||||
npc.broadcastEvent("SCE_CAMPFIRE_END", 600, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "fire_arrived":
|
||||
{
|
||||
// myself.i_quest0 = 1;
|
||||
npc.setIsRunning(false);
|
||||
npc.setTarget(npc);
|
||||
|
||||
if (npc.isNoRndWalk())
|
||||
{
|
||||
npc.doCast(SkillData.getInstance().getSkill(6331, 1));
|
||||
npc.setDisplayEffect(MAHUM_EFFECT_SLEEP);
|
||||
}
|
||||
if (npc.getVariables().getInt("BUSY_STATE") == 1) // Eating
|
||||
{
|
||||
npc.doCast(SkillData.getInstance().getSkill(6332, 1));
|
||||
npc.setDisplayEffect(MAHUM_EFFECT_EAT);
|
||||
}
|
||||
|
||||
startQuestTimer("remove_effects", 300000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "notify_dinner":
|
||||
{
|
||||
npc.broadcastEvent("SCE_DINNER_EAT", 600, null);
|
||||
break;
|
||||
}
|
||||
case "remove_effects":
|
||||
{
|
||||
// myself.i_quest0 = 0;
|
||||
npc.setIsRunning(true);
|
||||
npc.setDisplayEffect(MAHUM_EFFECT_NONE);
|
||||
break;
|
||||
}
|
||||
case "reset_full_bottle_prize":
|
||||
{
|
||||
npc.getVariables().remove("FULL_BARREL_REWARDING_PLAYER");
|
||||
break;
|
||||
}
|
||||
case "return_from_fire":
|
||||
{
|
||||
if (npc.isMonster() && !npc.isDead())
|
||||
{
|
||||
((L2MonsterInstance) npc).returnHome();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill)
|
||||
{
|
||||
if ((npc.getId() == CHEF) && (npc.getVariables().getInt("BUSY_STATE") == 0))
|
||||
{
|
||||
if (npc.getVariables().getInt("INVUL_REMOVE_TIMER_STARTED") == 0)
|
||||
{
|
||||
startQuestTimer("chef_remove_invul", 180000, npc, attacker);
|
||||
startQuestTimer("chef_disable_reward", 60000, npc, null);
|
||||
npc.getVariables().set("INVUL_REMOVE_TIMER_STARTED", 1);
|
||||
}
|
||||
startQuestTimer("chef_heal_player", 1000, npc, attacker);
|
||||
startQuestTimer("chef_set_invul", 60000, npc, null);
|
||||
npc.getVariables().set("BUSY_STATE", 1);
|
||||
}
|
||||
else if (Util.contains(SQUAD_LEADERS, npc.getId()))
|
||||
{
|
||||
handlePreAttackMotion(npc);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFactionCall(L2Npc npc, L2Npc caller, L2PcInstance attacker, boolean isSummon)
|
||||
{
|
||||
handlePreAttackMotion(npc);
|
||||
return super.onFactionCall(npc, caller, attacker, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEventReceived(String eventName, L2Npc sender, L2Npc receiver, L2Object reference)
|
||||
{
|
||||
switch (eventName)
|
||||
{
|
||||
case "SCE_DINNER_CHECK":
|
||||
{
|
||||
if (receiver.getId() == FIRE)
|
||||
{
|
||||
receiver.setDisplayEffect(FIRE_EFFECT_BURN);
|
||||
final L2Npc stove = addSpawn(STOVE, receiver.getX(), receiver.getY(), receiver.getZ() + 100, 0, false, 0);
|
||||
stove.setSummoner(receiver);
|
||||
startQuestTimer("notify_dinner", 2000, receiver, null); // @SCE_DINNER_EAT
|
||||
broadcastNpcSay(sender, Say2.NPC_ALL, CHEF_FSTRINGS[getRandom(2)], 1250);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SCE_CAMPFIRE_START":
|
||||
{
|
||||
if (!receiver.isNoRndWalk() && !receiver.isDead() && (receiver.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) && Util.contains(SQUAD_LEADERS, receiver.getId()))
|
||||
{
|
||||
receiver.setIsNoRndWalk(true); // Moving to fire - i_ai0 = 1
|
||||
receiver.setIsRunning(true);
|
||||
final Location loc = sender.getPointInRange(100, 200);
|
||||
loc.setHeading(receiver.getHeading());
|
||||
receiver.stopMove(null);
|
||||
receiver.getVariables().set("DESTINATION_X", loc.getX());
|
||||
receiver.getVariables().set("DESTINATION_Y", loc.getY());
|
||||
receiver.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, loc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SCE_CAMPFIRE_END":
|
||||
{
|
||||
if ((receiver.getId() == STOVE) && (receiver.getSummoner() == sender))
|
||||
{
|
||||
receiver.deleteMe();
|
||||
}
|
||||
else if ((receiver.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) && Util.contains(SQUAD_LEADERS, receiver.getId()))
|
||||
{
|
||||
receiver.setIsNoRndWalk(false);
|
||||
receiver.getVariables().remove("BUSY_STATE");
|
||||
receiver.setRHandId(THS_Weapon);
|
||||
startQuestTimer("return_from_fire", 3000, receiver, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SCE_DINNER_EAT":
|
||||
{
|
||||
if (!receiver.isDead() && (receiver.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) && (receiver.getVariables().getInt("BUSY_STATE", 0) == 0) && Util.contains(SQUAD_LEADERS, receiver.getId()))
|
||||
{
|
||||
if (receiver.isNoRndWalk()) // i_ai0 == 1
|
||||
{
|
||||
receiver.setRHandId(THS_Weapon);
|
||||
}
|
||||
receiver.setIsNoRndWalk(true); // Moving to fire - i_ai0 = 1
|
||||
receiver.getVariables().set("BUSY_STATE", 1); // Eating - i_ai3 = 1
|
||||
receiver.setIsRunning(true);
|
||||
broadcastNpcSay(receiver, Say2.NPC_ALL, (getRandom(3) < 1) ? NpcStringId.LOOKS_DELICIOUS : NpcStringId.LET_S_GO_EAT);
|
||||
final Location loc = sender.getPointInRange(100, 200);
|
||||
loc.setHeading(receiver.getHeading());
|
||||
receiver.stopMove(null);
|
||||
receiver.getVariables().set("DESTINATION_X", loc.getX());
|
||||
receiver.getVariables().set("DESTINATION_Y", loc.getY());
|
||||
receiver.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, loc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SCE_SOUP_FAILURE":
|
||||
{
|
||||
if (Util.contains(SQUAD_LEADERS, receiver.getId()))
|
||||
{
|
||||
receiver.getVariables().set("FULL_BARREL_REWARDING_PLAYER", reference.getObjectId()); // TODO: Use it in 289 quest
|
||||
startQuestTimer("reset_full_bottle_prize", 180000, receiver, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onEventReceived(eventName, sender, receiver, reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc.isMonster() && (npc.getVariables().getInt("REWARD_TIME_GONE") == 0))
|
||||
{
|
||||
((L2MonsterInstance) npc).dropItem(killer, 15492, 1);
|
||||
}
|
||||
cancelQuestTimer("chef_remove_invul", npc, null);
|
||||
cancelQuestTimer("chef_disable_reward", npc, null);
|
||||
cancelQuestTimer("chef_heal_player", npc, null);
|
||||
cancelQuestTimer("chef_set_invul", npc, null);
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveFinished(L2Npc npc)
|
||||
{
|
||||
// Npc moves to fire
|
||||
if (npc.isNoRndWalk() && (npc.getX() == npc.getVariables().getInt("DESTINATION_X")) && (npc.getY() == npc.getVariables().getInt("DESTINATION_Y")))
|
||||
{
|
||||
npc.setRHandId(OHS_Weapon);
|
||||
startQuestTimer("fire_arrived", 3000, npc, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNodeArrived(L2Npc npc)
|
||||
{
|
||||
npc.broadcastEvent("SCE_DINNER_CHECK", 300, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if ((npc.getId() == STOVE) && (skill.getId() == 9075) && Util.contains(targets, npc))
|
||||
{
|
||||
npc.doCast(SkillData.getInstance().getSkill(6688, 1));
|
||||
npc.broadcastEvent("SCE_SOUP_FAILURE", 600, caster);
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (npc.getId() == CHEF)
|
||||
{
|
||||
npc.setIsInvul(false);
|
||||
}
|
||||
else if (npc.getId() == FIRE)
|
||||
{
|
||||
startQuestTimer("fire", 1000, npc, null);
|
||||
}
|
||||
else if (Util.contains(SQUAD_LEADERS, npc.getId()))
|
||||
{
|
||||
npc.setDisplayEffect(3);
|
||||
npc.setIsNoRndWalk(false);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
if ((skill != null) && (skill.getId() == 6330))
|
||||
{
|
||||
healPlayer(npc, player);
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
private void healPlayer(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if ((player != null) && !player.isDead() && (npc.getVariables().getInt("INVUL_REMOVE_TIMER_STARTED") != 1) && ((npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_ATTACK) || (npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_CAST)))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(SkillData.getInstance().getSkill(6330, 1));
|
||||
}
|
||||
else
|
||||
{
|
||||
cancelQuestTimer("chef_set_invul", npc, null);
|
||||
npc.getVariables().remove("BUSY_STATE");
|
||||
npc.getVariables().remove("INVUL_REMOVE_TIMER_STARTED");
|
||||
npc.setIsRunning(false);
|
||||
}
|
||||
}
|
||||
|
||||
private void handlePreAttackMotion(L2Npc attacked)
|
||||
{
|
||||
cancelQuestTimer("remove_effects", attacked, null);
|
||||
attacked.getVariables().remove("BUSY_STATE");
|
||||
attacked.setIsNoRndWalk(false);
|
||||
attacked.setDisplayEffect(MAHUM_EFFECT_NONE);
|
||||
if (attacked.getRightHandItem() == OHS_Weapon)
|
||||
{
|
||||
attacked.setRHandId(THS_Weapon);
|
||||
}
|
||||
// TODO: Check about i_quest0
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SelMahumSquad();
|
||||
}
|
||||
}
|
||||
210
trunk/dist/game/data/scripts/ai/group_template/SilentValley.java
vendored
Normal file
210
trunk/dist/game/data/scripts/ai/group_template/SilentValley.java
vendored
Normal file
@@ -0,0 +1,210 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Silent Valley AI
|
||||
* @author malyelfik
|
||||
*/
|
||||
public final class SilentValley extends AbstractNpcAI
|
||||
{
|
||||
// Skills
|
||||
private static final SkillHolder BETRAYAL = new SkillHolder(6033, 1); // Treasure Seeker's Betrayal
|
||||
private static final SkillHolder BLAZE = new SkillHolder(4157, 10); // NPC Blaze - Magic
|
||||
// Item
|
||||
private static final int SACK = 13799; // Treasure Sack of the Ancient Giants
|
||||
// Chance
|
||||
private static final int SPAWN_CHANCE = 2;
|
||||
private static final int CHEST_DIE_CHANCE = 5;
|
||||
// Monsters
|
||||
private static final int CHEST = 18693; // Treasure Chest of the Ancient Giants
|
||||
private static final int GUARD1 = 18694; // Treasure Chest Guard
|
||||
private static final int GUARD2 = 18695; // Treasure Chest Guard
|
||||
private static final int[] MOBS =
|
||||
{
|
||||
20965, // Chimera Piece
|
||||
20966, // Changed Creation
|
||||
20967, // Past Creature
|
||||
20968, // Nonexistent Man
|
||||
20969, // Giant's Shadow
|
||||
20970, // Soldier of Ancient Times
|
||||
20971, // Warrior of Ancient Times
|
||||
20972, // Shaman of Ancient Times
|
||||
20973, // Forgotten Ancient People
|
||||
};
|
||||
|
||||
private SilentValley()
|
||||
{
|
||||
super(SilentValley.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(MOBS);
|
||||
addAttackId(CHEST, GUARD1, GUARD2);
|
||||
addEventReceivedId(GUARD1, GUARD2);
|
||||
addKillId(MOBS);
|
||||
addSeeCreatureId(MOBS);
|
||||
addSeeCreatureId(GUARD1, GUARD2);
|
||||
addSpawnId(CHEST, GUARD2);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if ((npc != null) && !npc.isDead())
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "CLEAR":
|
||||
npc.doDie(null);
|
||||
break;
|
||||
case "CLEAR_EVENT":
|
||||
npc.broadcastEvent("CLEAR_ALL_INSTANT", 2000, null);
|
||||
npc.doDie(null);
|
||||
break;
|
||||
case "SPAWN_CHEST":
|
||||
addSpawn(CHEST, npc.getX() - 100, npc.getY(), npc.getZ() - 100, 0, false, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance player, int damage, boolean isSummon)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case CHEST:
|
||||
{
|
||||
if (!isSummon && npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.YOU_WILL_BE_CURSED_FOR_SEEKING_THE_TREASURE);
|
||||
npc.setTarget(player);
|
||||
npc.doCast(BETRAYAL.getSkill());
|
||||
}
|
||||
else if (isSummon || (getRandom(100) < CHEST_DIE_CHANCE))
|
||||
{
|
||||
npc.dropItem(player, SACK, 1);
|
||||
npc.broadcastEvent("CLEAR_ALL", 2000, null);
|
||||
npc.doDie(null);
|
||||
cancelQuestTimer("CLEAR_EVENT", npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case GUARD1:
|
||||
case GUARD2:
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(BLAZE.getSkill());
|
||||
addAttackPlayerDesire(npc, player);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
{
|
||||
if (isSummon)
|
||||
{
|
||||
addAttackPlayerDesire(npc, player);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, player, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (getRandom(1000) < SPAWN_CHANCE)
|
||||
{
|
||||
final int newZ = npc.getZ() + 100;
|
||||
addSpawn(GUARD2, npc.getX() + 100, npc.getY(), newZ, 0, false, 0);
|
||||
addSpawn(GUARD1, npc.getX() - 100, npc.getY(), newZ, 0, false, 0);
|
||||
addSpawn(GUARD1, npc.getX(), npc.getY() + 100, newZ, 0, false, 0);
|
||||
addSpawn(GUARD1, npc.getX(), npc.getY() - 100, newZ, 0, false, 0);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
|
||||
{
|
||||
if (creature.isPlayable())
|
||||
{
|
||||
final L2PcInstance player = (isSummon) ? ((L2Summon) creature).getOwner() : creature.getActingPlayer();
|
||||
if ((npc.getId() == GUARD1) || (npc.getId() == GUARD2))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(BLAZE.getSkill());
|
||||
addAttackPlayerDesire(npc, player);
|
||||
}
|
||||
else if (creature.isAffectedBySkill(BETRAYAL.getSkillId()))
|
||||
{
|
||||
addAttackPlayerDesire(npc, player);
|
||||
}
|
||||
}
|
||||
return super.onSeeCreature(npc, creature, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (npc.getId() == CHEST)
|
||||
{
|
||||
npc.setIsInvul(true);
|
||||
startQuestTimer("CLEAR_EVENT", 300000, npc, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
startQuestTimer("SPAWN_CHEST", 10000, npc, null);
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEventReceived(String eventName, L2Npc sender, L2Npc receiver, L2Object reference)
|
||||
{
|
||||
if ((receiver != null) && !receiver.isDead())
|
||||
{
|
||||
switch (eventName)
|
||||
{
|
||||
case "CLEAR_ALL":
|
||||
startQuestTimer("CLEAR", 60000, receiver, null);
|
||||
break;
|
||||
case "CLEAR_ALL_INSTANT":
|
||||
receiver.doDie(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onEventReceived(eventName, sender, receiver, reference);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SilentValley();
|
||||
}
|
||||
}
|
||||
244
trunk/dist/game/data/scripts/ai/group_template/StakatoNest.java
vendored
Normal file
244
trunk/dist/game/data/scripts/ai/group_template/StakatoNest.java
vendored
Normal file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
|
||||
import com.l2jserver.gameserver.util.Broadcast;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Stakato Nest AI.
|
||||
* @author Gnacik
|
||||
*/
|
||||
public final class StakatoNest extends AbstractNpcAI
|
||||
{
|
||||
// @formatter:off
|
||||
// List of all mobs just for register
|
||||
private static final int[] STAKATO_MOBS =
|
||||
{
|
||||
18793, 18794, 18795, 18796, 18797, 18798, 22617, 22618, 22619, 22620,
|
||||
22621, 22622, 22623, 22624, 22625, 22626, 22627, 22628, 22629, 22630,
|
||||
22631, 22632, 22633, 25667
|
||||
};
|
||||
// Coocons
|
||||
private static final int[] COCOONS =
|
||||
{
|
||||
18793, 18794, 18795, 18796, 18797, 18798
|
||||
};
|
||||
// @formatter:on
|
||||
// Cannibalistic Stakato Leader
|
||||
private static final int STAKATO_LEADER = 22625;
|
||||
|
||||
// Spike Stakato Nurse
|
||||
private static final int STAKATO_NURSE = 22630;
|
||||
// Spike Stakato Nurse (Changed)
|
||||
private static final int STAKATO_NURSE_2 = 22631;
|
||||
// Spiked Stakato Baby
|
||||
private static final int STAKATO_BABY = 22632;
|
||||
// Spiked Stakato Captain
|
||||
private static final int STAKATO_CAPTAIN = 22629;
|
||||
|
||||
// Female Spiked Stakato
|
||||
private static final int STAKATO_FEMALE = 22620;
|
||||
// Male Spiked Stakato
|
||||
private static final int STAKATO_MALE = 22621;
|
||||
// Male Spiked Stakato (Changed)
|
||||
private static final int STAKATO_MALE_2 = 22622;
|
||||
// Spiked Stakato Guard
|
||||
private static final int STAKATO_GUARD = 22619;
|
||||
|
||||
// Cannibalistic Stakato Chief
|
||||
private static final int STAKATO_CHIEF = 25667;
|
||||
// Growth Accelerator
|
||||
private static final int GROWTH_ACCELERATOR = 2905;
|
||||
// Small Stakato Cocoon
|
||||
private static final int SMALL_COCOON = 14833;
|
||||
// Large Stakato Cocoon
|
||||
private static final int LARGE_COCOON = 14834;
|
||||
|
||||
private StakatoNest()
|
||||
{
|
||||
super(StakatoNest.class.getSimpleName(), "ai/group_template");
|
||||
registerMobs(STAKATO_MOBS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
final L2MonsterInstance mob = (L2MonsterInstance) npc;
|
||||
|
||||
if ((mob.getId() == STAKATO_LEADER) && (getRandom(1000) < 100) && (mob.getCurrentHp() < (mob.getMaxHp() * 0.3)))
|
||||
{
|
||||
final L2MonsterInstance _follower = checkMinion(npc);
|
||||
|
||||
if (_follower != null)
|
||||
{
|
||||
double _hp = _follower.getCurrentHp();
|
||||
|
||||
if (_hp > (_follower.getMaxHp() * 0.3))
|
||||
{
|
||||
mob.abortAttack();
|
||||
mob.abortCast();
|
||||
mob.setHeading(Util.calculateHeadingFrom(mob, _follower));
|
||||
mob.doCast(SkillData.getInstance().getSkill(4484, 1));
|
||||
mob.setCurrentHp(mob.getCurrentHp() + _hp);
|
||||
_follower.doDie(_follower);
|
||||
_follower.deleteMe();
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final L2MonsterInstance monster;
|
||||
switch (npc.getId())
|
||||
{
|
||||
case STAKATO_NURSE:
|
||||
monster = checkMinion(npc);
|
||||
if (monster != null)
|
||||
{
|
||||
Broadcast.toSelfAndKnownPlayers(npc, new MagicSkillUse(npc, 2046, 1, 1000, 0));
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
L2Npc spawned = addSpawn(STAKATO_CAPTAIN, monster, true);
|
||||
addAttackPlayerDesire(spawned, killer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STAKATO_BABY:
|
||||
monster = ((L2MonsterInstance) npc).getLeader();
|
||||
if ((monster != null) && !monster.isDead())
|
||||
{
|
||||
startQuestTimer("nurse_change", 5000, monster, killer);
|
||||
}
|
||||
break;
|
||||
case STAKATO_MALE:
|
||||
monster = checkMinion(npc);
|
||||
if (monster != null)
|
||||
{
|
||||
Broadcast.toSelfAndKnownPlayers(npc, new MagicSkillUse(npc, 2046, 1, 1000, 0));
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
L2Npc spawned = addSpawn(STAKATO_GUARD, monster, true);
|
||||
addAttackPlayerDesire(spawned, killer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case STAKATO_FEMALE:
|
||||
monster = ((L2MonsterInstance) npc).getLeader();
|
||||
if ((monster != null) && !monster.isDead())
|
||||
{
|
||||
startQuestTimer("male_change", 5000, monster, killer);
|
||||
}
|
||||
break;
|
||||
case STAKATO_CHIEF:
|
||||
if (killer.isInParty())
|
||||
{
|
||||
List<L2PcInstance> party = killer.getParty().getMembers();
|
||||
for (L2PcInstance member : party)
|
||||
{
|
||||
giveCocoon(member, npc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
giveCocoon(killer, npc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if (Util.contains(COCOONS, npc.getId()) && Util.contains(targets, npc) && (skill.getId() == GROWTH_ACCELERATOR))
|
||||
{
|
||||
npc.doDie(caster);
|
||||
final L2Npc spawned = addSpawn(STAKATO_CHIEF, npc.getX(), npc.getY(), npc.getZ(), Util.calculateHeadingFrom(npc, caster), false, 0, true);
|
||||
addAttackPlayerDesire(spawned, caster);
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if ((npc == null) || (player == null) || npc.isDead())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int npcId = 0;
|
||||
switch (event)
|
||||
{
|
||||
case "nurse_change":
|
||||
npcId = STAKATO_NURSE_2;
|
||||
break;
|
||||
case "male_change":
|
||||
npcId = STAKATO_MALE_2;
|
||||
break;
|
||||
}
|
||||
if (npcId > 0)
|
||||
{
|
||||
npc.getSpawn().decreaseCount(npc);
|
||||
npc.deleteMe();
|
||||
final L2Npc spawned = addSpawn(npcId, npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), false, 0, true);
|
||||
addAttackPlayerDesire(spawned, player);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
private static L2MonsterInstance checkMinion(L2Npc npc)
|
||||
{
|
||||
final L2MonsterInstance mob = (L2MonsterInstance) npc;
|
||||
if (mob.hasMinions())
|
||||
{
|
||||
final List<L2MonsterInstance> minion = mob.getMinionList().getSpawnedMinions();
|
||||
if ((minion != null) && !minion.isEmpty() && (minion.get(0) != null) && !minion.get(0).isDead())
|
||||
{
|
||||
return minion.get(0);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void giveCocoon(L2PcInstance player, L2Npc npc)
|
||||
{
|
||||
player.addItem("StakatoCocoon", ((getRandom(100) > 80) ? LARGE_COCOON : SMALL_COCOON), 1, npc, true);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new StakatoNest();
|
||||
}
|
||||
}
|
||||
106
trunk/dist/game/data/scripts/ai/group_template/SummonPc.java
vendored
Normal file
106
trunk/dist/game/data/scripts/ai/group_template/SummonPc.java
vendored
Normal file
@@ -0,0 +1,106 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
|
||||
/**
|
||||
* Summon Pc AI.<br>
|
||||
* Summon the player to the NPC on attack.
|
||||
* @author Zoey76
|
||||
*/
|
||||
public final class SummonPc extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int PORTA = 20213;
|
||||
private static final int PERUM = 20221;
|
||||
// Skill
|
||||
private static final SkillHolder SUMMON_PC = new SkillHolder(4161, 1);
|
||||
|
||||
private SummonPc()
|
||||
{
|
||||
super(SummonPc.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(PORTA, PERUM);
|
||||
addSpellFinishedId(PORTA, PERUM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
final int chance = getRandom(100);
|
||||
final boolean attacked = npc.getVariables().getBoolean("attacked", false);
|
||||
if ((npc.calculateDistance(attacker, true, false) > 300) && !attacked)
|
||||
{
|
||||
if (chance < 50)
|
||||
{
|
||||
if ((SUMMON_PC.getSkill().getMpConsume() < npc.getCurrentMp()) && (SUMMON_PC.getSkill().getHpConsume() < npc.getCurrentHp()) && !npc.isSkillDisabled(SUMMON_PC.getSkill()))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(SUMMON_PC.getSkill());
|
||||
}
|
||||
|
||||
if ((SUMMON_PC.getSkill().getMpConsume() < npc.getCurrentMp()) && (SUMMON_PC.getSkill().getHpConsume() < npc.getCurrentHp()) && !npc.isSkillDisabled(SUMMON_PC.getSkill()))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(SUMMON_PC.getSkill());
|
||||
npc.getVariables().set("attacked", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if ((npc.calculateDistance(attacker, true, false) > 100) && !attacked)
|
||||
{
|
||||
final L2Attackable monster = (L2Attackable) npc;
|
||||
if (monster.getMostHated() != null)
|
||||
{
|
||||
if (((monster.getMostHated() == attacker) && (chance < 50)) || (chance < 10))
|
||||
{
|
||||
if ((SUMMON_PC.getSkill().getMpConsume() < npc.getCurrentMp()) && (SUMMON_PC.getSkill().getHpConsume() < npc.getCurrentHp()) && !npc.isSkillDisabled(SUMMON_PC.getSkill()))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(SUMMON_PC.getSkill());
|
||||
npc.getVariables().set("attacked", true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
if ((skill.getId() == SUMMON_PC.getSkillId()) && !npc.isDead() && npc.getVariables().getBoolean("attacked", false))
|
||||
{
|
||||
player.teleToLocation(npc);
|
||||
npc.getVariables().set("attacked", false);
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SummonPc();
|
||||
}
|
||||
}
|
||||
138
trunk/dist/game/data/scripts/ai/group_template/TurekOrcs.java
vendored
Normal file
138
trunk/dist/game/data/scripts/ai/group_template/TurekOrcs.java
vendored
Normal file
@@ -0,0 +1,138 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.L2World;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
|
||||
/**
|
||||
* Turek Orcs AI - flee and return with assistance
|
||||
* @author GKR
|
||||
*/
|
||||
|
||||
public final class TurekOrcs extends AbstractNpcAI
|
||||
{
|
||||
// NPC's
|
||||
private static final int[] MOBS =
|
||||
{
|
||||
20494, // Turek War Hound
|
||||
20495, // Turek Orc Warlord
|
||||
20497, // Turek Orc Skirmisher
|
||||
20498, // Turek Orc Supplier
|
||||
20499, // Turek Orc Footman
|
||||
20500, // Turek Orc Sentinel
|
||||
};
|
||||
|
||||
private TurekOrcs()
|
||||
{
|
||||
super(TurekOrcs.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(MOBS);
|
||||
addEventReceivedId(MOBS);
|
||||
addMoveFinishedId(MOBS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equalsIgnoreCase("checkState") && !npc.isDead() && (npc.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK))
|
||||
{
|
||||
if ((npc.getCurrentHp() > (npc.getMaxHp() * 0.7)) && (npc.getVariables().getInt("state") == 2))
|
||||
{
|
||||
npc.getVariables().set("state", 3);
|
||||
((L2Attackable) npc).returnHome();
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.getVariables().remove("state");
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (!npc.getVariables().hasVariable("isHit"))
|
||||
{
|
||||
npc.getVariables().set("isHit", 1);
|
||||
}
|
||||
else if ((npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) && (npc.getCurrentHp() > (npc.getMaxHp() * 0.3)) && (attacker.getCurrentHp() > (attacker.getMaxHp() * 0.25)) && npc.hasAIValue("fleeX") && npc.hasAIValue("fleeY") && npc.hasAIValue("fleeZ") && (npc.getVariables().getInt("state") == 0) && (getRandom(100) < 10))
|
||||
{
|
||||
// Say and flee
|
||||
broadcastNpcSay(npc, 0, NpcStringId.getNpcStringId(getRandom(1000007, 1000027)));
|
||||
npc.disableCoreAI(true); // to avoid attacking behaviour, while flee
|
||||
npc.setIsRunning(true);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(npc.getAIValue("fleeX"), npc.getAIValue("fleeY"), npc.getAIValue("fleeZ")));
|
||||
npc.getVariables().set("state", 1);
|
||||
npc.getVariables().set("attacker", attacker.getObjectId());
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEventReceived(String eventName, L2Npc sender, L2Npc receiver, L2Object reference)
|
||||
{
|
||||
if (eventName.equals("WARNING") && !receiver.isDead() && (receiver.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK) && (reference != null) && (reference.getActingPlayer() != null) && !reference.getActingPlayer().isDead())
|
||||
{
|
||||
receiver.getVariables().set("state", 3);
|
||||
receiver.setIsRunning(true);
|
||||
((L2Attackable) receiver).addDamageHate(reference.getActingPlayer(), 0, 99999);
|
||||
receiver.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, reference.getActingPlayer());
|
||||
}
|
||||
return super.onEventReceived(eventName, sender, receiver, reference);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onMoveFinished(L2Npc npc)
|
||||
{
|
||||
// NPC reaches flee point
|
||||
if (npc.getVariables().getInt("state") == 1)
|
||||
{
|
||||
if ((npc.getX() == npc.getAIValue("fleeX")) && (npc.getY() == npc.getAIValue("fleeY")))
|
||||
{
|
||||
npc.disableCoreAI(false);
|
||||
startQuestTimer("checkState", 15000, npc, null);
|
||||
npc.getVariables().set("state", 2);
|
||||
npc.broadcastEvent("WARNING", 400, L2World.getInstance().getPlayer(npc.getVariables().getInt("attacker")));
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(npc.getAIValue("fleeX"), npc.getAIValue("fleeY"), npc.getAIValue("fleeZ")));
|
||||
}
|
||||
}
|
||||
else if ((npc.getVariables().getInt("state") == 3) && npc.staysInSpawnLoc())
|
||||
{
|
||||
npc.disableCoreAI(false);
|
||||
npc.getVariables().remove("state");
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new TurekOrcs();
|
||||
}
|
||||
}
|
||||
218
trunk/dist/game/data/scripts/ai/group_template/VarkaKetra.java
vendored
Normal file
218
trunk/dist/game/data/scripts/ai/group_template/VarkaKetra.java
vendored
Normal file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import quests.Q00605_AllianceWithKetraOrcs.Q00605_AllianceWithKetraOrcs;
|
||||
import quests.Q00606_BattleAgainstVarkaSilenos.Q00606_BattleAgainstVarkaSilenos;
|
||||
import quests.Q00607_ProveYourCourageKetra.Q00607_ProveYourCourageKetra;
|
||||
import quests.Q00608_SlayTheEnemyCommanderKetra.Q00608_SlayTheEnemyCommanderKetra;
|
||||
import quests.Q00609_MagicalPowerOfWaterPart1.Q00609_MagicalPowerOfWaterPart1;
|
||||
import quests.Q00610_MagicalPowerOfWaterPart2.Q00610_MagicalPowerOfWaterPart2;
|
||||
import quests.Q00611_AllianceWithVarkaSilenos.Q00611_AllianceWithVarkaSilenos;
|
||||
import quests.Q00612_BattleAgainstKetraOrcs.Q00612_BattleAgainstKetraOrcs;
|
||||
import quests.Q00613_ProveYourCourageVarka.Q00613_ProveYourCourageVarka;
|
||||
import quests.Q00614_SlayTheEnemyCommanderVarka.Q00614_SlayTheEnemyCommanderVarka;
|
||||
import quests.Q00615_MagicalPowerOfFirePart1.Q00615_MagicalPowerOfFirePart1;
|
||||
import quests.Q00616_MagicalPowerOfFirePart2.Q00616_MagicalPowerOfFirePart2;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.quest.QuestState;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Varka Silenos Barracks and Ketra Orc Outpost AI
|
||||
* @author malyelfik
|
||||
*/
|
||||
public class VarkaKetra extends AbstractNpcAI
|
||||
{
|
||||
// Monsters
|
||||
private static final int[] KETRA =
|
||||
{
|
||||
21324, // Ketra Orc Footman
|
||||
21325, // Ketra's War Hound
|
||||
21327, // Ketra Orc Raider
|
||||
21328, // Ketra Orc Scout
|
||||
21329, // Ketra Orc Shaman
|
||||
21331, // Ketra Orc Warrior
|
||||
21332, // Ketra Orc Lieutenant
|
||||
21334, // Ketra Orc Medium
|
||||
21336, // Ketra Orc White Captain
|
||||
21338, // Ketra Orc Seer
|
||||
21339, // Ketra Orc General
|
||||
21340, // Ketra Orc Battalion Commander
|
||||
21342, // Ketra Orc Grand Seer
|
||||
21343, // Ketra Commander
|
||||
21344, // Ketra Elite Guard
|
||||
21345, // Ketra's Head Shaman
|
||||
21346, // Ketra's Head Guard
|
||||
21347, // Ketra Prophet
|
||||
21348, // Prophet's Guard
|
||||
21349, // Prophet's Aide
|
||||
25299, // Ketra's Hero Hekaton (Raid Boss)
|
||||
25302, // Ketra's Commander Tayr (Raid Boss)
|
||||
25305, // Ketra's Chief Brakki (Raid Boss)
|
||||
25306, // Soul of Fire Nastron (Raid Boss)
|
||||
};
|
||||
private static final int[] VARKA =
|
||||
{
|
||||
21350, // Varka Silenos Recruit
|
||||
21351, // Varka Silenos Footman
|
||||
21353, // Varka Silenos Scout
|
||||
21354, // Varka Silenos Hunter
|
||||
21355, // Varka Silenos Shaman
|
||||
21357, // Varka Silenos Priest
|
||||
21358, // Varka Silenos Warrior
|
||||
21360, // Varka Silenos Medium
|
||||
21361, // Varka Silenos Magus
|
||||
21362, // Varka Silenos Officer
|
||||
21364, // Varka Silenos Seer
|
||||
21365, // Varka Silenos Great Magus
|
||||
21366, // Varka Silenos General
|
||||
21368, // Varka Silenos Great Seer
|
||||
21369, // Varka's Commander
|
||||
21370, // Varka's Elite Guard
|
||||
21371, // Varka's Head Magus
|
||||
21372, // Varka's Head Guard
|
||||
21373, // Varka's Prophet
|
||||
21374, // Prophet's Guard
|
||||
21375, // Disciple of Prophet
|
||||
25309, // Varka's Hero Shadith (Raid Boss)
|
||||
25312, // Varka's Commander Mos (Raid Boss)
|
||||
25315, // Varka's Chief Horus (Raid Boss)
|
||||
25316, // Soul of Water Ashutar (Raid Boss)
|
||||
};
|
||||
// Items
|
||||
private static final int[] KETRA_MARKS =
|
||||
{
|
||||
7211, // Mark of Ketra's Alliance - Level 1
|
||||
7212, // Mark of Ketra's Alliance - Level 2
|
||||
7213, // Mark of Ketra's Alliance - Level 3
|
||||
7214, // Mark of Ketra's Alliance - Level 4
|
||||
7215, // Mark of Ketra's Alliance - Level 5
|
||||
};
|
||||
private static final int[] VARKA_MARKS =
|
||||
{
|
||||
7221, // Mark of Varka's Alliance - Level 1
|
||||
7222, // Mark of Varka's Alliance - Level 2
|
||||
7223, // Mark of Varka's Alliance - Level 3
|
||||
7224, // Mark of Varka's Alliance - Level 4
|
||||
7225, // Mark of Varka's Alliance - Level 5
|
||||
};
|
||||
// Quests
|
||||
private static final String[] KETRA_QUESTS =
|
||||
{
|
||||
Q00605_AllianceWithKetraOrcs.class.getSimpleName(),
|
||||
Q00606_BattleAgainstVarkaSilenos.class.getSimpleName(),
|
||||
Q00607_ProveYourCourageKetra.class.getSimpleName(),
|
||||
Q00608_SlayTheEnemyCommanderKetra.class.getSimpleName(),
|
||||
Q00609_MagicalPowerOfWaterPart1.class.getSimpleName(),
|
||||
Q00610_MagicalPowerOfWaterPart2.class.getSimpleName()
|
||||
};
|
||||
private static final String[] VARKA_QUESTS =
|
||||
{
|
||||
Q00611_AllianceWithVarkaSilenos.class.getSimpleName(),
|
||||
Q00612_BattleAgainstKetraOrcs.class.getSimpleName(),
|
||||
Q00613_ProveYourCourageVarka.class.getSimpleName(),
|
||||
Q00614_SlayTheEnemyCommanderVarka.class.getSimpleName(),
|
||||
Q00615_MagicalPowerOfFirePart1.class.getSimpleName(),
|
||||
Q00616_MagicalPowerOfFirePart2.class.getSimpleName()
|
||||
};
|
||||
|
||||
private VarkaKetra()
|
||||
{
|
||||
super(VarkaKetra.class.getSimpleName(), "ai/group_template");
|
||||
addKillId(KETRA);
|
||||
addKillId(VARKA);
|
||||
addNpcHateId(KETRA);
|
||||
addNpcHateId(VARKA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void actionForEachPlayer(L2PcInstance player, L2Npc npc, boolean isSummon)
|
||||
{
|
||||
if (Util.checkIfInRange(1500, player, npc, false))
|
||||
{
|
||||
if (Util.contains(KETRA, npc.getId()) && hasAtLeastOneQuestItem(player, KETRA_MARKS))
|
||||
{
|
||||
decreaseAlliance(player, KETRA_MARKS);
|
||||
exitQuests(player, KETRA_QUESTS);
|
||||
}
|
||||
else if (Util.contains(VARKA, npc.getId()) && hasAtLeastOneQuestItem(player, VARKA_MARKS))
|
||||
{
|
||||
decreaseAlliance(player, VARKA_MARKS);
|
||||
exitQuests(player, VARKA_QUESTS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final void decreaseAlliance(L2PcInstance player, int[] marks)
|
||||
{
|
||||
for (int i = 0; i < marks.length; i++)
|
||||
{
|
||||
if (hasQuestItems(player, marks[i]))
|
||||
{
|
||||
takeItems(player, marks[i], -1);
|
||||
if (i > 0)
|
||||
{
|
||||
giveItems(player, marks[i - 1], 1);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private final void exitQuests(L2PcInstance player, String[] quests)
|
||||
{
|
||||
for (String quest : quests)
|
||||
{
|
||||
final QuestState qs = player.getQuestState(quest);
|
||||
if ((qs != null) && qs.isStarted())
|
||||
{
|
||||
qs.exitQuest(true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
executeForEachPlayer(killer, npc, isSummon, true, false);
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onNpcHate(L2Attackable mob, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
return stopAttack(player, mob) ? false : super.onNpcHate(mob, player, isSummon);
|
||||
}
|
||||
|
||||
private final boolean stopAttack(L2PcInstance player, L2Character monster)
|
||||
{
|
||||
return (Util.contains(KETRA, monster.getId()) && hasAtLeastOneQuestItem(player, KETRA_MARKS)) || (Util.contains(VARKA, monster.getId()) && hasAtLeastOneQuestItem(player, VARKA_MARKS));
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new VarkaKetra();
|
||||
}
|
||||
}
|
||||
142
trunk/dist/game/data/scripts/ai/group_template/WarriorFishingBlock.java
vendored
Normal file
142
trunk/dist/game/data/scripts/ai/group_template/WarriorFishingBlock.java
vendored
Normal file
@@ -0,0 +1,142 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.group_template;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlEvent;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Warrior Fishing Block AI.
|
||||
* @author Zoey76
|
||||
*/
|
||||
public final class WarriorFishingBlock extends AbstractNpcAI
|
||||
{
|
||||
// Monsters
|
||||
private static final int[] MONSTERS =
|
||||
{
|
||||
18319, // Caught Frog
|
||||
18320, // Caught Undine
|
||||
18321, // Caught Rakul
|
||||
18322, // Caught Sea Giant
|
||||
18323, // Caught Sea Horse Soldier
|
||||
18324, // Caught Homunculus
|
||||
18325, // Caught Flava
|
||||
18326, // Caught Gigantic Eye
|
||||
};
|
||||
// NPC Strings
|
||||
private static final NpcStringId[] NPC_STRINGS_ON_SPAWN =
|
||||
{
|
||||
NpcStringId.CROAK_CROAK_FOOD_LIKE_S1_IN_THIS_PLACE,
|
||||
NpcStringId.S1_HOW_LUCKY_I_AM,
|
||||
NpcStringId.PRAY_THAT_YOU_CAUGHT_A_WRONG_FISH_S1
|
||||
};
|
||||
private static final NpcStringId[] NPC_STRINGS_ON_ATTACK =
|
||||
{
|
||||
NpcStringId.DO_YOU_KNOW_WHAT_A_FROG_TASTES_LIKE,
|
||||
NpcStringId.I_WILL_SHOW_YOU_THE_POWER_OF_A_FROG,
|
||||
NpcStringId.I_WILL_SWALLOW_AT_A_MOUTHFUL
|
||||
};
|
||||
private static final NpcStringId[] NPC_STRINGS_ON_KILL =
|
||||
{
|
||||
NpcStringId.UGH_NO_CHANCE_HOW_COULD_THIS_ELDER_PASS_AWAY_LIKE_THIS,
|
||||
NpcStringId.CROAK_CROAK_A_FROG_IS_DYING,
|
||||
NpcStringId.A_FROG_TASTES_BAD_YUCK
|
||||
};
|
||||
// Misc
|
||||
private static final int CHANCE_TO_SHOUT_ON_ATTACK = 33;
|
||||
private static final int DESPAWN_TIME = 50; // 50 seconds to despawn
|
||||
|
||||
public WarriorFishingBlock()
|
||||
{
|
||||
super(WarriorFishingBlock.class.getSimpleName(), "ai/group_template");
|
||||
addAttackId(MONSTERS);
|
||||
addKillId(MONSTERS);
|
||||
addSpawnId(MONSTERS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "SPAWN":
|
||||
{
|
||||
final L2Object obj = npc.getTarget();
|
||||
if ((obj == null) || !obj.isPlayer())
|
||||
{
|
||||
npc.decayMe();
|
||||
}
|
||||
else
|
||||
{
|
||||
final L2PcInstance target = obj.getActingPlayer();
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NPC_STRINGS_ON_SPAWN[getRandom(NPC_STRINGS_ON_SPAWN.length)], target.getName());
|
||||
((L2Attackable) npc).addDamageHate(target, 0, 2000);
|
||||
npc.getAI().notifyEvent(CtrlEvent.EVT_ATTACKED, target);
|
||||
npc.addAttackerToAttackByList(target);
|
||||
|
||||
startQuestTimer("DESPAWN", DESPAWN_TIME * 1000, npc, target);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "DESPAWN":
|
||||
{
|
||||
npc.decayMe();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (getRandom(100) < CHANCE_TO_SHOUT_ON_ATTACK)
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NPC_STRINGS_ON_ATTACK[getRandom(NPC_STRINGS_ON_ATTACK.length)]);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NPC_STRINGS_ON_KILL[getRandom(NPC_STRINGS_ON_KILL.length)]);
|
||||
cancelQuestTimer("DESPAWN", npc, killer);
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
startQuestTimer("SPAWN", 2000, npc, null);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new WarriorFishingBlock();
|
||||
}
|
||||
}
|
||||
12
trunk/dist/game/data/scripts/ai/group_template/documentation.txt
vendored
Normal file
12
trunk/dist/game/data/scripts/ai/group_template/documentation.txt
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
Group Template AI:
|
||||
This folder contains AI scripts for group templates. That is, if many different mobs share the same behaviour,
|
||||
a group AI script can be created for all of them. Such group templates ought to be here.
|
||||
|
||||
Group templates can be subclassed. In other words, a group may inherit from another group. For example,
|
||||
one group template might define mobs that cast spells. Another template may then define the AI for mobs
|
||||
that cast spells AND use shots. In that case, instead of rewriting all the attack and spell-use AI, we can
|
||||
inherit from the first group template, then add the new behaviours, and split up the NPC registrations appropriately.
|
||||
|
||||
"NPC registrations" refers to the addition of NPCs in the various events of the scripts, such as onAttack, onKill, etc
|
||||
Those are done by using keywords such as "addKillId" etc. For more details on registrations, see
|
||||
"scripts/quests/documentation.txt"
|
||||
37
trunk/dist/game/data/scripts/ai/group_template/package-info.java
vendored
Normal file
37
trunk/dist/game/data/scripts/ai/group_template/package-info.java
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Group Template AI:<br>
|
||||
* This folder contains AI scripts for group templates.<br>
|
||||
* That is, if many different mobs share the same behavior, a group AI script can be created for all of them.<br>
|
||||
* Such group templates ought to be here.<br>
|
||||
* <br>
|
||||
* Group templates can be sub-classed.<br>
|
||||
* In other words, a group may inherit from another group.<br>
|
||||
* For example, one group template might define mobs that cast spells.<br>
|
||||
* Another template may then define the AI for mobs that cast spells AND use shots.<br>
|
||||
* In that case, instead of rewriting all the attack and spell-use AI, we can inherit from the first group template, then add the new behaviors, and split up the NPC registrations appropriately.<br>
|
||||
* <br>
|
||||
* "NPC registrations" refers to the addition of NPCs in the various events of the scripts, such as onAttack, onKill, etc.<br>
|
||||
* Those are done by using methods such as addKillId(..) etc.<br>
|
||||
* @see quests
|
||||
* @author Fulminus, Zoey76
|
||||
*/
|
||||
package ai.group_template;
|
||||
200
trunk/dist/game/data/scripts/ai/individual/Anais.java
vendored
Normal file
200
trunk/dist/game/data/scripts/ai/individual/Anais.java
vendored
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Map;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.quest.QuestTimer;
|
||||
|
||||
/**
|
||||
* Anais AI.
|
||||
* @author nonom
|
||||
*/
|
||||
public final class Anais extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int ANAIS = 25701;
|
||||
private static final int DIVINE_BURNER = 18915;
|
||||
private static final int GRAIL_WARD = 18929;
|
||||
// Skill
|
||||
private static SkillHolder DIVINE_NOVA = new SkillHolder(6326, 1);
|
||||
// Instances
|
||||
ArrayList<L2Npc> _divineBurners = new ArrayList<>(4);
|
||||
private L2PcInstance _nextTarget = null;
|
||||
private L2Npc _current = null;
|
||||
private int _pot = 0;
|
||||
|
||||
private Anais()
|
||||
{
|
||||
super(Anais.class.getSimpleName(), "ai/individual");
|
||||
addAttackId(ANAIS);
|
||||
addSpawnId(DIVINE_BURNER);
|
||||
addKillId(GRAIL_WARD);
|
||||
}
|
||||
|
||||
private void burnerOnAttack(int pot, L2Npc anais)
|
||||
{
|
||||
L2Npc npc = _divineBurners.get(pot);
|
||||
npc.setDisplayEffect(1);
|
||||
npc.setIsRunning(false);
|
||||
if (pot < 4)
|
||||
{
|
||||
_current = npc;
|
||||
QuestTimer checkAround = getQuestTimer("CHECK", anais, null);
|
||||
if (checkAround == null) // || !checkAround.getIsActive()
|
||||
{
|
||||
startQuestTimer("CHECK", 3000, anais, null);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cancelQuestTimer("CHECK", anais, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "CHECK":
|
||||
{
|
||||
if (!npc.isAttackingNow())
|
||||
{
|
||||
cancelQuestTimer("CHECK", npc, null);
|
||||
}
|
||||
if ((_current != null) || (_pot < 4))
|
||||
{
|
||||
final Map<Integer, L2PcInstance> players = npc.getKnownList().getKnownPlayers();
|
||||
final L2PcInstance target = players.get(getRandom(players.size() - 1));
|
||||
_nextTarget = target;
|
||||
if (_nextTarget == null)
|
||||
{
|
||||
_nextTarget = (L2PcInstance) npc.getTarget();
|
||||
}
|
||||
final L2Npc b = _divineBurners.get(_pot);
|
||||
_pot = _pot + 1;
|
||||
b.setDisplayEffect(1);
|
||||
b.setIsRunning(false);
|
||||
L2Npc ward = addSpawn(GRAIL_WARD, new Location(b.getX(), b.getY(), b.getZ()), true, 0);
|
||||
((L2Attackable) ward).addDamageHate(_nextTarget, 0, 999);
|
||||
ward.setIsRunning(true);
|
||||
ward.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, _nextTarget, null);
|
||||
startQuestTimer("GUARD_ATTACK", 1000, ward, _nextTarget, true);
|
||||
startQuestTimer("SUICIDE", 20000, ward, null);
|
||||
ward.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, _nextTarget);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "GUARD_ATTACK":
|
||||
{
|
||||
if (_nextTarget != null)
|
||||
{
|
||||
final double distance = npc.calculateDistance(_nextTarget, false, false);
|
||||
if (distance < 100)
|
||||
{
|
||||
npc.doCast(DIVINE_NOVA.getSkill());
|
||||
}
|
||||
else if (distance > 2000)
|
||||
{
|
||||
npc.doDie(null);
|
||||
cancelQuestTimer("GUARD_ATTACK", npc, player);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SUICIDE":
|
||||
{
|
||||
npc.doCast(DIVINE_NOVA.getSkill());
|
||||
cancelQuestTimer("GUARD_ATTACK", npc, _nextTarget);
|
||||
if (_current != null)
|
||||
{
|
||||
_current.setDisplayEffect(2);
|
||||
_current.setIsRunning(false);
|
||||
_current = null;
|
||||
}
|
||||
npc.doDie(null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (_pot == 0)
|
||||
{
|
||||
burnerOnAttack(0, npc);
|
||||
}
|
||||
else if ((npc.getCurrentHp() <= (npc.getMaxRecoverableHp() * 0.75)) && (_pot == 1))
|
||||
{
|
||||
burnerOnAttack(1, npc);
|
||||
}
|
||||
else if ((npc.getCurrentHp() <= (npc.getMaxRecoverableHp() * 0.5)) && (_pot == 2))
|
||||
{
|
||||
burnerOnAttack(2, npc);
|
||||
}
|
||||
else if ((npc.getCurrentHp() <= (npc.getMaxRecoverableHp() * 0.25)) && (_pot == 3))
|
||||
{
|
||||
burnerOnAttack(3, npc);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
/*
|
||||
* (non-Javadoc)
|
||||
* @see com.l2jserver.gameserver.model.quest.Quest#onSpawn(com.l2jserver.gameserver.model.actor.L2Npc)
|
||||
*/
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
_divineBurners.add(npc);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
npc.doCast(DIVINE_NOVA.getSkill());
|
||||
cancelQuestTimer("GUARD_ATTACK", npc, _nextTarget);
|
||||
cancelQuestTimer("CHECK", npc, null);
|
||||
if (_current != null)
|
||||
{
|
||||
_current.setDisplayEffect(2);
|
||||
_current.setIsRunning(false);
|
||||
_current = null;
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Anais();
|
||||
}
|
||||
}
|
||||
8
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-01.html
vendored
Normal file
8
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-01.html
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<html><body>Heart of Warding:<br>
|
||||
You are overcome by a voice, a voice so powerful you are helpless as it speaks.<br>
|
||||
<font color="LEVEL">Do not expect Shilen's authority will diminish<br>
|
||||
while false gods freely roam.<br>
|
||||
Leave, and<br>
|
||||
prepare to face the return of Antharas.</font><br>
|
||||
(Challenging Antharas is not currently available.)
|
||||
</body></html>
|
||||
6
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-02.html
vendored
Normal file
6
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-02.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<html><body>Heart of Warding:<br>
|
||||
You are overcome by a voice, a voice so powerful you are helpless as it speaks:<br>
|
||||
<font color="LEVEL">Do not expect that you might challenge Antharas at your own convenience.<br>
|
||||
When the time is right, Shilen's authority will judge you.</font><br>
|
||||
(Currently, other members are challenging Antharas.)
|
||||
</body></html>
|
||||
6
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-03.html
vendored
Normal file
6
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-03.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<html><body>Heart of Warding:<br>
|
||||
A voice that can shatter your entire body is resonating in your head:<br>
|
||||
<font color="LEVEL">Do not dare to face Shilen's authority<br>
|
||||
without the most determined preparation.</font><br>
|
||||
(Only those who have the Portal Stone can challenge Antharas.)
|
||||
</body></html>
|
||||
6
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-04.html
vendored
Normal file
6
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-04.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<html><body>Heart of Warding:<br>
|
||||
You are overcome by a voice, a voice so powerful you are helpless as it speaks:<br>
|
||||
<font color="LEVEL">No matter how many gather to follow false gods,<br>
|
||||
Shilen's authority is too great.</font><br>
|
||||
(The number of participants are above the allowed number in challenging Antharas.)
|
||||
</body></html>
|
||||
6
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-05.html
vendored
Normal file
6
trunk/dist/game/data/scripts/ai/individual/Antharas/13001-05.html
vendored
Normal file
@@ -0,0 +1,6 @@
|
||||
<html><body>Heart of Warding:<br>
|
||||
You are overcome by a voice, a voice so powerful you are helpless as it speaks:<br>
|
||||
<font color="LEVEL">You seek death and defeat by coming here without your leader! You appear before Shilen's authority<br>
|
||||
and you tempt Shilen's wrath!</font><br>
|
||||
(The players who belong to an association can only enter through the Association Leader.)
|
||||
</body></html>
|
||||
12
trunk/dist/game/data/scripts/ai/individual/Antharas/13001.html
vendored
Normal file
12
trunk/dist/game/data/scripts/ai/individual/Antharas/13001.html
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
<html><body>Heart of Warding:<br>
|
||||
You are overcome by a voice, a voice so powerful you are helpless as it speaks:<br>
|
||||
<font color="LEVEL">A terrible creature <br>
|
||||
fell to the earth from above <br>
|
||||
in order to vent a mother's spite,<br>
|
||||
cursed and forsaken by her own children.<br>
|
||||
Dark Pilgrim of the Holy Land,<br>
|
||||
Do you dare face the Land Dragon Antharas?</font><br>
|
||||
(A maximum of 200 people can challenge Antharas.)<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Antharas enter">Move to Antharas' Nest</a><br>
|
||||
<a action="bypass -h npc_%objectId%_Quest">Quest</a>
|
||||
</body></html>
|
||||
1052
trunk/dist/game/data/scripts/ai/individual/Antharas/Antharas.java
vendored
Normal file
1052
trunk/dist/game/data/scripts/ai/individual/Antharas/Antharas.java
vendored
Normal file
File diff suppressed because it is too large
Load Diff
3
trunk/dist/game/data/scripts/ai/individual/Baium/31862-01.html
vendored
Normal file
3
trunk/dist/game/data/scripts/ai/individual/Baium/31862-01.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><head><body>Angelic Vortex:<br>
|
||||
The Angelic Vortex emits a faint light which twinkles out. The vortex becomes inactive. It seems like, in order to go to the place where the Angelic Vortex is leading, you will need some special object.
|
||||
</body></html>
|
||||
5
trunk/dist/game/data/scripts/ai/individual/Baium/31862-02.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/individual/Baium/31862-02.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Angelic Vortex:<br>
|
||||
The Angelic Vortex emits a faint light, in the midst of which an image appears. A giant that normally appears as a stone statue has come alive and is fighting with many people. Even angels have joined the fray. It seems that the angels are angry at the humans who have broken the seal of the stone statue.<br>
|
||||
It appears impossible to cross over to that place right now. You have no choice but to wait until the fight is over.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Baium 31862-04.html">Ask about the stone statue that has come alive.</a>
|
||||
</body></html>
|
||||
5
trunk/dist/game/data/scripts/ai/individual/Baium/31862-03.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/individual/Baium/31862-03.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Angelic Vortex:<br>
|
||||
The Angelic Vortex emits a faint light, in the midst of which an image appears. A large, open space... but the gigantic, human-like stone statue is no longer there.<br>
|
||||
It seems that while the statue is not visible, one could cross over to that place.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Baium 31862-04.html">Ask about the stone statue.</a>
|
||||
</body></html>
|
||||
7
trunk/dist/game/data/scripts/ai/individual/Baium/31862-04.html
vendored
Normal file
7
trunk/dist/game/data/scripts/ai/individual/Baium/31862-04.html
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<html><body>Angelic Vortex:<br>
|
||||
In ancient times a mighty emperor named Baium became so enamored of his own power that he began to fancy himself a god. He conscripted all of his people to build an awesome tower that reached almost to heaven.<br>
|
||||
The gods were not amused. They struck him down, cursed him with immortality and imprisoned him in his own tower for eternity! A statue of the foolish emperor stands there to this day.<br>
|
||||
Occasionally, the old emperor himself is woken up by those who seek his power. Unfortunately, when Baium is disturbed, so are the angels who guard him.<br>
|
||||
Although the angels are certainly no friend of Baium, they regard Humans with equal disdain.<font color="LEVEL"> Ultimate success against Baium depends upon the defeat of the guardian angels.</font><br>
|
||||
This is all I can tell you. Good luck!
|
||||
</body></html>
|
||||
4
trunk/dist/game/data/scripts/ai/individual/Baium/31862.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/individual/Baium/31862.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Angelic Vortex:<br>
|
||||
The Angelic Vortex emits a faint light, and in the midst of the light an image appears. In the deepest part of a spacious area, a gigantic stone statue is visible. The statue has a human-like appearance and is in a seated position, as though it was being held by some invisible force against its will.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Baium enter">Go where the Angelic Vortex leads.</a>
|
||||
</body></html>
|
||||
792
trunk/dist/game/data/scripts/ai/individual/Baium/Baium.java
vendored
Normal file
792
trunk/dist/game/data/scripts/ai/individual/Baium/Baium.java
vendored
Normal file
@@ -0,0 +1,792 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual.Baium;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.enums.CategoryType;
|
||||
import com.l2jserver.gameserver.enums.MountType;
|
||||
import com.l2jserver.gameserver.instancemanager.GrandBossManager;
|
||||
import com.l2jserver.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.variables.NpcVariables;
|
||||
import com.l2jserver.gameserver.model.zone.type.L2NoRestartZone;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.Earthquake;
|
||||
import com.l2jserver.gameserver.network.serverpackets.ExShowScreenMessage;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Baium AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class Baium extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int BAIUM = 29020; // Baium
|
||||
private static final int BAIUM_STONE = 29025; // Baium
|
||||
private static final int ANG_VORTEX = 31862; // Angelic Vortex
|
||||
private static final int ARCHANGEL = 29021; // Archangel
|
||||
private static final int TELE_CUBE = 31842; // Teleportation Cubic
|
||||
// Skills
|
||||
private static final SkillHolder BAIUM_ATTACK = new SkillHolder(4127, 1); // Baium: General Attack
|
||||
private static final SkillHolder ENERGY_WAVE = new SkillHolder(4128, 1); // Wind Of Force
|
||||
private static final SkillHolder EARTH_QUAKE = new SkillHolder(4129, 1); // Earthquake
|
||||
private static final SkillHolder THUNDERBOLT = new SkillHolder(4130, 1); // Striking of Thunderbolt
|
||||
private static final SkillHolder GROUP_HOLD = new SkillHolder(4131, 1); // Stun
|
||||
private static final SkillHolder SPEAR_ATTACK = new SkillHolder(4132, 1); // Spear: Pound the Ground
|
||||
private static final SkillHolder ANGEL_HEAL = new SkillHolder(4133, 1); // Angel Heal
|
||||
private static final SkillHolder HEAL_OF_BAIUM = new SkillHolder(4135, 1); // Baium Heal
|
||||
private static final SkillHolder BAIUM_PRESENT = new SkillHolder(4136, 1); // Baium's Gift
|
||||
private static final SkillHolder ANTI_STRIDER = new SkillHolder(4258, 1); // Hinder Strider
|
||||
// Items
|
||||
private static final int FABRIC = 4295; // Blooded Fabric
|
||||
// Zone
|
||||
private static final L2NoRestartZone zone = ZoneManager.getInstance().getZoneById(70051, L2NoRestartZone.class); // Baium zone
|
||||
// Status
|
||||
private static final int ALIVE = 0;
|
||||
private static final int WAITING = 1;
|
||||
private static final int IN_FIGHT = 2;
|
||||
private static final int DEAD = 3;
|
||||
// Locations
|
||||
private static final Location BAIUM_GIFT_LOC = new Location(115910, 17337, 10105);
|
||||
private static final Location BAIUM_LOC = new Location(116033, 17447, 10107, -25348);
|
||||
private static final Location TELEPORT_CUBIC_LOC = new Location(115017, 15549, 10090);
|
||||
private static final Location TELEPORT_IN_LOC = new Location(114077, 15882, 10078);
|
||||
private static final Location[] TELEPORT_OUT_LOC =
|
||||
{
|
||||
new Location(108784, 16000, -4928),
|
||||
new Location(113824, 10448, -5164),
|
||||
new Location(115488, 22096, -5168),
|
||||
};
|
||||
private static final Location[] ARCHANGEL_LOC =
|
||||
{
|
||||
new Location(115792, 16608, 10136, 0),
|
||||
new Location(115168, 17200, 10136, 0),
|
||||
new Location(115780, 15564, 10136, 13620),
|
||||
new Location(114880, 16236, 10136, 5400),
|
||||
new Location(114239, 17168, 10136, -1992)
|
||||
};
|
||||
// Misc
|
||||
private L2GrandBossInstance _baium = null;
|
||||
private static long _lastAttack = 0;
|
||||
private static L2PcInstance _standbyPlayer = null;
|
||||
|
||||
private Baium()
|
||||
{
|
||||
super(Baium.class.getSimpleName(), "ai/individual");
|
||||
addFirstTalkId(ANG_VORTEX);
|
||||
addTalkId(ANG_VORTEX, TELE_CUBE, BAIUM_STONE);
|
||||
addStartNpc(ANG_VORTEX, TELE_CUBE, BAIUM_STONE);
|
||||
addAttackId(BAIUM, ARCHANGEL);
|
||||
addKillId(BAIUM);
|
||||
addSeeCreatureId(BAIUM);
|
||||
addSpellFinishedId(BAIUM);
|
||||
|
||||
final StatsSet info = GrandBossManager.getInstance().getStatsSet(BAIUM);
|
||||
final int curr_hp = info.getInt("currentHP");
|
||||
final int curr_mp = info.getInt("currentMP");
|
||||
final int loc_x = info.getInt("loc_x");
|
||||
final int loc_y = info.getInt("loc_y");
|
||||
final int loc_z = info.getInt("loc_z");
|
||||
final int heading = info.getInt("heading");
|
||||
final long respawnTime = info.getLong("respawn_time");
|
||||
|
||||
switch (getStatus())
|
||||
{
|
||||
case WAITING:
|
||||
{
|
||||
setStatus(ALIVE);
|
||||
}
|
||||
case ALIVE:
|
||||
{
|
||||
addSpawn(BAIUM_STONE, BAIUM_LOC, false, 0);
|
||||
break;
|
||||
}
|
||||
case IN_FIGHT:
|
||||
{
|
||||
_baium = (L2GrandBossInstance) addSpawn(BAIUM, loc_x, loc_y, loc_z, heading, false, 0);
|
||||
_baium.setCurrentHpMp(curr_hp, curr_mp);
|
||||
_lastAttack = System.currentTimeMillis();
|
||||
addBoss(_baium);
|
||||
|
||||
for (Location loc : ARCHANGEL_LOC)
|
||||
{
|
||||
final L2Npc archangel = addSpawn(ARCHANGEL, loc, false, 0, true);
|
||||
startQuestTimer("SELECT_TARGET", 5000, archangel, null);
|
||||
}
|
||||
startQuestTimer("CHECK_ATTACK", 60000, _baium, null);
|
||||
break;
|
||||
}
|
||||
case DEAD:
|
||||
{
|
||||
final long remain = respawnTime - System.currentTimeMillis();
|
||||
if (remain > 0)
|
||||
{
|
||||
startQuestTimer("CLEAR_STATUS", remain, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
notifyEvent("CLEAR_STATUS", null, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "31862-04.html":
|
||||
{
|
||||
return event;
|
||||
}
|
||||
case "enter":
|
||||
{
|
||||
String htmltext = null;
|
||||
if (getStatus() == DEAD)
|
||||
{
|
||||
htmltext = "31862-03.html";
|
||||
}
|
||||
else if (getStatus() == IN_FIGHT)
|
||||
{
|
||||
htmltext = "31862-02.html";
|
||||
}
|
||||
else if (!hasQuestItems(player, FABRIC))
|
||||
{
|
||||
htmltext = "31862-01.html";
|
||||
}
|
||||
else
|
||||
{
|
||||
takeItems(player, FABRIC, 1);
|
||||
player.teleToLocation(TELEPORT_IN_LOC);
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
case "teleportOut":
|
||||
{
|
||||
final Location destination = TELEPORT_OUT_LOC[getRandom(TELEPORT_OUT_LOC.length)];
|
||||
player.teleToLocation(destination.getX() + getRandom(100), destination.getY() + getRandom(100), destination.getZ());
|
||||
break;
|
||||
}
|
||||
case "wakeUp":
|
||||
{
|
||||
if (getStatus() == ALIVE)
|
||||
{
|
||||
npc.deleteMe();
|
||||
setStatus(IN_FIGHT);
|
||||
_baium = (L2GrandBossInstance) addSpawn(BAIUM, BAIUM_LOC, false, 0);
|
||||
_baium.disableCoreAI(true);
|
||||
addBoss(_baium);
|
||||
_lastAttack = System.currentTimeMillis();
|
||||
startQuestTimer("WAKEUP_ACTION", 50, _baium, null);
|
||||
startQuestTimer("MANAGE_EARTHQUAKE", 2000, _baium, null);
|
||||
startQuestTimer("CHECK_ATTACK", 60000, _baium, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "WAKEUP_ACTION":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
zone.broadcastPacket(new SocialAction(_baium.getObjectId(), 2));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "MANAGE_EARTHQUAKE":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
zone.broadcastPacket(new Earthquake(npc.getX(), npc.getY(), npc.getZ(), 40, 10));
|
||||
zone.broadcastPacket(new PlaySound("BS02_A"));
|
||||
startQuestTimer("SOCIAL_ACTION", 8000, npc, player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SOCIAL_ACTION":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
zone.broadcastPacket(new SocialAction(npc.getObjectId(), 3));
|
||||
startQuestTimer("PLAYER_PORT", 6000, npc, player);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "PLAYER_PORT":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
if ((player != null) && player.isInsideRadius(npc, 16000, true, false))
|
||||
{
|
||||
player.teleToLocation(BAIUM_GIFT_LOC);
|
||||
startQuestTimer("PLAYER_KILL", 3000, npc, player);
|
||||
}
|
||||
else if ((_standbyPlayer != null) && _standbyPlayer.isInsideRadius(npc, 16000, true, false))
|
||||
{
|
||||
_standbyPlayer.teleToLocation(BAIUM_GIFT_LOC);
|
||||
startQuestTimer("PLAYER_KILL", 3000, npc, _standbyPlayer);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "PLAYER_KILL":
|
||||
{
|
||||
if ((player != null) && player.isInsideRadius(npc, 16000, true, false))
|
||||
{
|
||||
zone.broadcastPacket(new SocialAction(npc.getObjectId(), 1));
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, player.getName() + ", How dare you wake me! Now you shall die!"); // TODO: replace with NpcStringId when are done core support
|
||||
npc.setTarget(player);
|
||||
npc.doCast(BAIUM_PRESENT.getSkill());
|
||||
}
|
||||
|
||||
for (L2PcInstance players : zone.getPlayersInside())
|
||||
{
|
||||
if (players.isHero())
|
||||
{
|
||||
zone.broadcastPacket(new ExShowScreenMessage(NpcStringId.NOT_EVEN_THE_GODS_THEMSELVES_COULD_TOUCH_ME_BUT_YOU_S1_YOU_DARE_CHALLENGE_ME_IGNORANT_MORTAL, 2, 4000, players.getName()));
|
||||
break;
|
||||
}
|
||||
}
|
||||
startQuestTimer("SPAWN_ARCHANGEL", 8000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "SPAWN_ARCHANGEL":
|
||||
{
|
||||
_baium.disableCoreAI(false);
|
||||
|
||||
for (Location loc : ARCHANGEL_LOC)
|
||||
{
|
||||
final L2Npc archangel = addSpawn(ARCHANGEL, loc, false, 0, true);
|
||||
startQuestTimer("SELECT_TARGET", 5000, archangel, null);
|
||||
}
|
||||
|
||||
if ((player != null) && !player.isDead())
|
||||
{
|
||||
addAttackPlayerDesire(npc, player);
|
||||
}
|
||||
else if ((_standbyPlayer != null) && !_standbyPlayer.isDead())
|
||||
{
|
||||
addAttackPlayerDesire(npc, _standbyPlayer);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (L2Character creature : npc.getKnownList().getKnownCharactersInRadius(2000))
|
||||
{
|
||||
if ((creature != null) && creature.isPlayer() && zone.isInsideZone(creature) && !creature.isDead())
|
||||
{
|
||||
addAttackPlayerDesire(npc, (L2Playable) creature);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SELECT_TARGET":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
final L2Character mostHated = mob.getMostHated();
|
||||
|
||||
if ((_baium == null) || _baium.isDead())
|
||||
{
|
||||
mob.deleteMe();
|
||||
break;
|
||||
}
|
||||
|
||||
if ((mostHated != null) && mostHated.isPlayer() && zone.isInsideZone(mostHated))
|
||||
{
|
||||
if (mob.getTarget() != mostHated)
|
||||
{
|
||||
mob.clearAggroList();
|
||||
}
|
||||
addAttackPlayerDesire(mob, (L2Playable) mostHated);
|
||||
}
|
||||
else
|
||||
{
|
||||
boolean found = false;
|
||||
for (L2Character creature : mob.getKnownList().getKnownCharactersInRadius(1000))
|
||||
{
|
||||
if ((creature != null) && creature.isPlayable() && zone.isInsideZone(creature) && !creature.isDead())
|
||||
{
|
||||
if (mob.getTarget() != creature)
|
||||
{
|
||||
mob.clearAggroList();
|
||||
}
|
||||
addAttackPlayerDesire(mob, (L2Playable) creature);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
if (mob.isInsideRadius(_baium, 40, true, false))
|
||||
{
|
||||
if (mob.getTarget() != _baium)
|
||||
{
|
||||
mob.clearAggroList();
|
||||
}
|
||||
mob.setIsRunning(true);
|
||||
mob.addDamageHate(_baium, 0, 999);
|
||||
mob.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, _baium);
|
||||
}
|
||||
else
|
||||
{
|
||||
mob.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _baium);
|
||||
}
|
||||
}
|
||||
}
|
||||
startQuestTimer("SELECT_TARGET", 5000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "CHECK_ATTACK":
|
||||
{
|
||||
if ((npc != null) && ((_lastAttack + 1800000) < System.currentTimeMillis()))
|
||||
{
|
||||
notifyEvent("CLEAR_ZONE", null, null);
|
||||
addSpawn(BAIUM_STONE, BAIUM_LOC, false, 0);
|
||||
setStatus(ALIVE);
|
||||
}
|
||||
else if (npc != null)
|
||||
{
|
||||
if (((_lastAttack + 300000) < System.currentTimeMillis()) && (npc.getCurrentHp() < (npc.getMaxHp() * 0.75)))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(HEAL_OF_BAIUM.getSkill());
|
||||
}
|
||||
startQuestTimer("CHECK_ATTACK", 60000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "CLEAR_STATUS":
|
||||
{
|
||||
setStatus(ALIVE);
|
||||
addSpawn(BAIUM_STONE, BAIUM_LOC, false, 0);
|
||||
break;
|
||||
}
|
||||
case "CLEAR_ZONE":
|
||||
{
|
||||
for (L2Character charInside : zone.getCharactersInside())
|
||||
{
|
||||
if (charInside != null)
|
||||
{
|
||||
if (charInside.isNpc())
|
||||
{
|
||||
charInside.deleteMe();
|
||||
}
|
||||
else if (charInside.isPlayer())
|
||||
{
|
||||
notifyEvent("teleportOut", null, (L2PcInstance) charInside);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "RESPAWN_BAIUM":
|
||||
{
|
||||
if (getStatus() == DEAD)
|
||||
{
|
||||
setRespawn(0);
|
||||
cancelQuestTimer("CLEAR_STATUS", null, null);
|
||||
notifyEvent("CLEAR_STATUS", null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendMessage(getClass().getSimpleName() + ": You cant respawn Baium while Baium is alive!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "ABORT_FIGHT":
|
||||
{
|
||||
if (getStatus() == IN_FIGHT)
|
||||
{
|
||||
_baium = null;
|
||||
notifyEvent("CLEAR_ZONE", null, null);
|
||||
notifyEvent("CLEAR_STATUS", null, null);
|
||||
player.sendMessage(getClass().getSimpleName() + ": Aborting fight!");
|
||||
}
|
||||
else
|
||||
{
|
||||
player.sendMessage(getClass().getSimpleName() + ": You cant abort attack right now!");
|
||||
}
|
||||
cancelQuestTimers("CHECK_ATTACK");
|
||||
cancelQuestTimers("SELECT_TARGET");
|
||||
break;
|
||||
}
|
||||
case "DESPAWN_MINIONS":
|
||||
{
|
||||
if (getStatus() == IN_FIGHT)
|
||||
{
|
||||
for (L2Character charInside : zone.getCharactersInside())
|
||||
{
|
||||
if ((charInside != null) && charInside.isNpc() && (charInside.getId() == ARCHANGEL))
|
||||
{
|
||||
charInside.deleteMe();
|
||||
}
|
||||
}
|
||||
if (player != null)
|
||||
{
|
||||
player.sendMessage(getClass().getSimpleName() + ": All archangels has been deleted!");
|
||||
}
|
||||
}
|
||||
else if (player != null)
|
||||
{
|
||||
player.sendMessage(getClass().getSimpleName() + ": You cant despawn archangels right now!");
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "MANAGE_SKILLS":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
manageSkills(npc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon, Skill skill)
|
||||
{
|
||||
_lastAttack = System.currentTimeMillis();
|
||||
|
||||
if (npc.getId() == BAIUM)
|
||||
{
|
||||
if ((attacker.getMountType() == MountType.STRIDER) && !attacker.isAffectedBySkill(ANTI_STRIDER.getSkillId()))
|
||||
{
|
||||
if (!npc.isSkillDisabled(ANTI_STRIDER.getSkill()))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(ANTI_STRIDER.getSkill());
|
||||
}
|
||||
}
|
||||
|
||||
if (skill == null)
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 1000));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25))
|
||||
{
|
||||
refreshAiParams(attacker, npc, ((damage / 3) * 100));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5))
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 20));
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75))
|
||||
{
|
||||
refreshAiParams(attacker, npc, (damage * 10));
|
||||
}
|
||||
else
|
||||
{
|
||||
refreshAiParams(attacker, npc, ((damage / 3) * 20));
|
||||
}
|
||||
manageSkills(npc);
|
||||
}
|
||||
else
|
||||
{
|
||||
final L2Attackable mob = (L2Attackable) npc;
|
||||
final L2Character mostHated = mob.getMostHated();
|
||||
|
||||
if ((getRandom(100) < 10) && mob.checkDoCastConditions(SPEAR_ATTACK.getSkill()))
|
||||
{
|
||||
if ((mostHated != null) && (npc.calculateDistance(mostHated, true, false) < 1000) && zone.isCharacterInZone(mostHated))
|
||||
{
|
||||
mob.setTarget(mostHated);
|
||||
mob.doCast(SPEAR_ATTACK.getSkill());
|
||||
}
|
||||
else if (zone.isCharacterInZone(attacker))
|
||||
{
|
||||
mob.setTarget(attacker);
|
||||
mob.doCast(SPEAR_ATTACK.getSkill());
|
||||
}
|
||||
}
|
||||
|
||||
if ((getRandom(100) < 5) && (npc.getCurrentHp() < (npc.getMaxHp() * 0.5)) && mob.checkDoCastConditions(ANGEL_HEAL.getSkill()))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(ANGEL_HEAL.getSkill());
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (zone.isCharacterInZone(killer))
|
||||
{
|
||||
setStatus(DEAD);
|
||||
addSpawn(TELE_CUBE, TELEPORT_CUBIC_LOC, false, 900000);
|
||||
zone.broadcastPacket(new PlaySound("BS01_D"));
|
||||
long respawnTime = (Config.BAIUM_SPAWN_INTERVAL + getRandom(-Config.BAIUM_SPAWN_RANDOM, Config.BAIUM_SPAWN_RANDOM)) * 3600000;
|
||||
setRespawn(respawnTime);
|
||||
startQuestTimer("CLEAR_STATUS", respawnTime, null, null);
|
||||
startQuestTimer("CLEAR_ZONE", 900000, null, null);
|
||||
cancelQuestTimer("CHECK_ATTACK", npc, null);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
|
||||
{
|
||||
if (!zone.isInsideZone(creature) || (creature.isNpc() && (creature.getId() == BAIUM_STONE)))
|
||||
{
|
||||
return super.onSeeCreature(npc, creature, isSummon);
|
||||
}
|
||||
|
||||
if (creature.isPlayer() && !creature.isDead() && (_standbyPlayer == null))
|
||||
{
|
||||
_standbyPlayer = (L2PcInstance) creature;
|
||||
}
|
||||
|
||||
if (creature.isInCategory(CategoryType.CLERIC_GROUP))
|
||||
{
|
||||
if (npc.getCurrentHp() < (npc.getMaxHp() * 0.25))
|
||||
{
|
||||
refreshAiParams(creature, npc, 10000);
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.5))
|
||||
{
|
||||
refreshAiParams(creature, npc, 10000, 6000);
|
||||
}
|
||||
else if (npc.getCurrentHp() < (npc.getMaxHp() * 0.75))
|
||||
{
|
||||
refreshAiParams(creature, npc, 10000, 3000);
|
||||
}
|
||||
else
|
||||
{
|
||||
refreshAiParams(creature, npc, 10000, 2000);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
refreshAiParams(creature, npc, 10000, 1000);
|
||||
}
|
||||
manageSkills(npc);
|
||||
return super.onSeeCreature(npc, creature, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
startQuestTimer("MANAGE_SKILLS", 1000, npc, null);
|
||||
|
||||
if (!zone.isCharacterInZone(npc) && (_baium != null))
|
||||
{
|
||||
_baium.teleToLocation(BAIUM_LOC);
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unload(boolean removeFromList)
|
||||
{
|
||||
if (_baium != null)
|
||||
{
|
||||
_baium.deleteMe();
|
||||
}
|
||||
return super.unload(removeFromList);
|
||||
}
|
||||
|
||||
private final void refreshAiParams(L2Character attacker, L2Npc npc, int damage)
|
||||
{
|
||||
refreshAiParams(attacker, npc, damage, damage);
|
||||
}
|
||||
|
||||
private final void refreshAiParams(L2Character attacker, L2Npc npc, int damage, int aggro)
|
||||
{
|
||||
final int newAggroVal = damage + getRandom(3000);
|
||||
final int aggroVal = aggro + 1000;
|
||||
final NpcVariables vars = npc.getVariables();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
if (attacker == vars.getObject("c_quest" + i, L2Character.class))
|
||||
{
|
||||
if (vars.getInt("i_quest" + i) < aggroVal)
|
||||
{
|
||||
vars.set("i_quest" + i, newAggroVal);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
final int index = Util.getIndexOfMinValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2"));
|
||||
vars.set("i_quest" + index, newAggroVal);
|
||||
vars.set("c_quest" + index, attacker);
|
||||
}
|
||||
|
||||
private int getStatus()
|
||||
{
|
||||
return GrandBossManager.getInstance().getBossStatus(BAIUM);
|
||||
}
|
||||
|
||||
private void addBoss(L2GrandBossInstance grandboss)
|
||||
{
|
||||
GrandBossManager.getInstance().addBoss(grandboss);
|
||||
}
|
||||
|
||||
private void setStatus(int status)
|
||||
{
|
||||
GrandBossManager.getInstance().setBossStatus(BAIUM, status);
|
||||
}
|
||||
|
||||
private void setRespawn(long respawnTime)
|
||||
{
|
||||
GrandBossManager.getInstance().getStatsSet(BAIUM).set("respawn_time", (System.currentTimeMillis() + respawnTime));
|
||||
}
|
||||
|
||||
private void manageSkills(L2Npc npc)
|
||||
{
|
||||
if (npc.isCastingNow() || npc.isCoreAIDisabled() || !npc.isInCombat())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final NpcVariables vars = npc.getVariables();
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
final L2Character attacker = vars.getObject("c_quest" + i, L2Character.class);
|
||||
if ((attacker == null) || ((npc.calculateDistance(attacker, true, false) > 9000) || attacker.isDead()))
|
||||
{
|
||||
vars.set("i_quest" + i, 0);
|
||||
}
|
||||
}
|
||||
final int index = Util.getIndexOfMaxValue(vars.getInt("i_quest0"), vars.getInt("i_quest1"), vars.getInt("i_quest2"));
|
||||
final L2Character player = vars.getObject("c_quest" + index, L2Character.class);
|
||||
final int i2 = vars.getInt("i_quest" + index);
|
||||
if ((i2 > 0) && (getRandom(100) < 70))
|
||||
{
|
||||
vars.set("i_quest" + index, 500);
|
||||
}
|
||||
|
||||
SkillHolder skillToCast = null;
|
||||
if ((player != null) && !player.isDead())
|
||||
{
|
||||
if (npc.getCurrentHp() > (npc.getMaxHp() * 0.75))
|
||||
{
|
||||
if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = ENERGY_WAVE;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = EARTH_QUAKE;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillToCast = BAIUM_ATTACK;
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() > (npc.getMaxHp() * 0.5))
|
||||
{
|
||||
if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = GROUP_HOLD;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = ENERGY_WAVE;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = EARTH_QUAKE;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillToCast = BAIUM_ATTACK;
|
||||
}
|
||||
}
|
||||
else if (npc.getCurrentHp() > (npc.getMaxHp() * 0.25))
|
||||
{
|
||||
if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = THUNDERBOLT;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = GROUP_HOLD;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = ENERGY_WAVE;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = EARTH_QUAKE;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillToCast = BAIUM_ATTACK;
|
||||
}
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = THUNDERBOLT;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = GROUP_HOLD;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = ENERGY_WAVE;
|
||||
}
|
||||
else if (getRandom(100) < 10)
|
||||
{
|
||||
skillToCast = EARTH_QUAKE;
|
||||
}
|
||||
else
|
||||
{
|
||||
skillToCast = BAIUM_ATTACK;
|
||||
}
|
||||
}
|
||||
|
||||
if ((skillToCast != null) && npc.checkDoCastConditions(skillToCast.getSkill()))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(skillToCast.getSkill());
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Baium();
|
||||
}
|
||||
}
|
||||
104
trunk/dist/game/data/scripts/ai/individual/Ballista.java
vendored
Normal file
104
trunk/dist/game/data/scripts/ai/individual/Ballista.java
vendored
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.network.SystemMessageId;
|
||||
|
||||
/**
|
||||
* Ballista AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class Ballista extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int[] BALLISTA =
|
||||
{
|
||||
35685, // Shanty Fortress
|
||||
35723, // Southern Fortress
|
||||
35754, // Hive Fortress
|
||||
35792, // Valley Fortress
|
||||
35823, // Ivory Fortress
|
||||
35854, // Narsell Fortress
|
||||
35892, // Bayou Fortress
|
||||
35923, // White Sands Fortress
|
||||
35961, // Borderland Fortress
|
||||
35999, // Swamp Fortress
|
||||
36030, // Archaic Fortress
|
||||
36068, // Floran Fortress
|
||||
36106, // Cloud Mountain)
|
||||
36137, // Tanor Fortress
|
||||
36168, // Dragonspine Fortress
|
||||
36206, // Antharas's Fortress
|
||||
36244, // Western Fortress
|
||||
36282, // Hunter's Fortress
|
||||
36313, // Aaru Fortress
|
||||
36351, // Demon Fortress
|
||||
36389, // Monastic Fortress
|
||||
};
|
||||
// Skill
|
||||
private static final SkillHolder BOMB = new SkillHolder(2342, 1); // Ballista Bomb
|
||||
// Misc
|
||||
private static final int MIN_CLAN_LV = 5;
|
||||
|
||||
private Ballista()
|
||||
{
|
||||
super(Ballista.class.getSimpleName(), "ai/individual");
|
||||
addSkillSeeId(BALLISTA);
|
||||
addSpawnId(BALLISTA);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if ((skill != null) && (caster.getTarget() == npc) && (getRandom(100) < 40) && (skill == BOMB.getSkill()))
|
||||
{
|
||||
if (npc.getFort().getSiege().isInProgress())
|
||||
{
|
||||
if ((caster.getClan() != null) && (caster.getClan().getLevel() >= MIN_CLAN_LV))
|
||||
{
|
||||
caster.getClan().addReputationScore(Config.BALLISTA_POINTS, true);
|
||||
caster.sendPacket(SystemMessageId.THE_BALLISTA_HAS_BEEN_SUCCESSFULLY_DESTROYED_THE_CLAN_REPUTATION_WILL_BE_INCREASED);
|
||||
}
|
||||
}
|
||||
npc.doDie(caster);
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.disableCoreAI(true);
|
||||
npc.setIsMortal(false);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Ballista();
|
||||
}
|
||||
}
|
||||
782
trunk/dist/game/data/scripts/ai/individual/Beleth.java
vendored
Normal file
782
trunk/dist/game/data/scripts/ai/individual/Beleth.java
vendored
Normal file
@@ -0,0 +1,782 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.concurrent.ScheduledFuture;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.ThreadPoolManager;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.cache.HtmCache;
|
||||
import com.l2jserver.gameserver.datatables.DoorTable;
|
||||
import com.l2jserver.gameserver.datatables.NpcData;
|
||||
import com.l2jserver.gameserver.instancemanager.GrandBossManager;
|
||||
import com.l2jserver.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.L2Spawn;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2DoorInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
|
||||
import com.l2jserver.gameserver.model.effects.L2EffectType;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.zone.L2ZoneType;
|
||||
import com.l2jserver.gameserver.network.serverpackets.CreatureSay;
|
||||
import com.l2jserver.gameserver.network.serverpackets.DoorStatusUpdate;
|
||||
import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SpecialCamera;
|
||||
import com.l2jserver.gameserver.network.serverpackets.StaticObject;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Beleth's AI.
|
||||
* @author Treat
|
||||
*/
|
||||
public final class Beleth extends AbstractNpcAI
|
||||
{
|
||||
protected static L2Npc CAMERA;
|
||||
protected static L2Npc CAMERA2;
|
||||
protected static L2Npc CAMERA3;
|
||||
protected static L2Npc CAMERA4;
|
||||
protected static L2Npc BELETH;
|
||||
protected static L2Npc PRIEST;
|
||||
protected static L2ZoneType ZONE = null;
|
||||
private static L2PcInstance BELETH_KILLER;
|
||||
private static boolean DEBUG = false;
|
||||
protected static boolean MOVIE = false;
|
||||
private static boolean ATTACKED = false;
|
||||
private static int ALLOW_OBJECT_ID = 0;
|
||||
private static int KILLED = 0;
|
||||
protected static ScheduledFuture<?> SPAWN_TIMER = null;
|
||||
protected static ArrayList<L2Npc> MINIONS = new ArrayList<>();
|
||||
private static SkillHolder BLEED = new SkillHolder(5495, 1);
|
||||
private static SkillHolder FIREBALL = new SkillHolder(5496, 1);
|
||||
private static SkillHolder HORN_OF_RISING = new SkillHolder(5497, 1);
|
||||
private static SkillHolder LIGHTENING = new SkillHolder(5499, 1);
|
||||
|
||||
protected static final Location BELETH_SPAWN = new Location(16323, 213059, -9357, 49152);
|
||||
|
||||
private Beleth()
|
||||
{
|
||||
super(Beleth.class.getSimpleName(), "ai/individual");
|
||||
ZONE = ZoneManager.getInstance().getZoneById(12018);
|
||||
addEnterZoneId(12018);
|
||||
registerMobs(29118, 29119);
|
||||
addStartNpc(32470);
|
||||
addTalkId(32470);
|
||||
addFirstTalkId(29128);
|
||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(29118);
|
||||
int status = GrandBossManager.getInstance().getBossStatus(29118);
|
||||
if (status == 3)
|
||||
{
|
||||
long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
|
||||
if (temp > 0)
|
||||
{
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new unlock(), temp);
|
||||
}
|
||||
else
|
||||
{
|
||||
GrandBossManager.getInstance().setBossStatus(29118, 0);
|
||||
}
|
||||
}
|
||||
else if (status != 0)
|
||||
{
|
||||
GrandBossManager.getInstance().setBossStatus(29118, 0);
|
||||
}
|
||||
DoorTable.getInstance().getDoor(20240001).openMe();
|
||||
}
|
||||
|
||||
protected static L2Npc spawn(int npcId, Location loc)
|
||||
{
|
||||
try
|
||||
{
|
||||
L2NpcTemplate template = NpcData.getInstance().getTemplate(npcId);
|
||||
if (template != null)
|
||||
{
|
||||
L2Spawn spawn = new L2Spawn(template);
|
||||
spawn.setInstanceId(loc.getInstanceId());
|
||||
spawn.setLocation(loc);
|
||||
spawn.setAmount(spawn.getAmount() + 1);
|
||||
return spawn.doSpawn();
|
||||
}
|
||||
}
|
||||
catch (Exception ignored)
|
||||
{
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void startSpawnTask()
|
||||
{
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(1), DEBUG ? 10000 : 300000);
|
||||
}
|
||||
|
||||
protected static class unlock implements Runnable
|
||||
{
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
GrandBossManager.getInstance().setBossStatus(29118, 0);
|
||||
DoorTable.getInstance().getDoor(20240001).openMe();
|
||||
}
|
||||
}
|
||||
|
||||
private static class Cast implements Runnable
|
||||
{
|
||||
SkillHolder _skill;
|
||||
L2Npc _npc;
|
||||
|
||||
public Cast(SkillHolder skill, L2Npc npc)
|
||||
{
|
||||
_skill = skill;
|
||||
_npc = npc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
if ((_npc != null) && !_npc.isDead() && !_npc.isCastingNow())
|
||||
{
|
||||
_npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ACTIVE);
|
||||
_npc.doCast(_skill.getSkill());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static class Spawn implements Runnable
|
||||
{
|
||||
private int _taskId = 0;
|
||||
|
||||
public Spawn(int taskId)
|
||||
{
|
||||
_taskId = taskId;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try
|
||||
{
|
||||
int instanceId = 0;
|
||||
switch (_taskId)
|
||||
{
|
||||
case 1:
|
||||
MOVIE = true;
|
||||
for (L2Character npc : ZONE.getCharactersInside())
|
||||
{
|
||||
if (npc.isNpc())
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
}
|
||||
CAMERA = spawn(29120, new Location(16323, 213142, -9357, 0, instanceId));
|
||||
CAMERA2 = spawn(29121, new Location(16323, 210741, -9357, 0, instanceId));
|
||||
CAMERA3 = spawn(29122, new Location(16323, 213170, -9357, 0, instanceId));
|
||||
CAMERA4 = spawn(29123, new Location(16323, 214917, -9356, 0, instanceId));
|
||||
ZONE.broadcastPacket(new PlaySound(1, "BS07_A", 1, CAMERA.getObjectId(), CAMERA.getX(), CAMERA.getY(), CAMERA.getZ()));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 75, -25, 0, 2500, 0, 0, 1, 0, 0));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 75, -25, 0, 2500, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(2), 300);
|
||||
break;
|
||||
case 2:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 1800, -45, -45, 5000, 5000, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(3), 4900);
|
||||
break;
|
||||
case 3:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 2500, -120, -45, 5000, 5000, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(4), 4900);
|
||||
break;
|
||||
case 4:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA2, 2200, 130, 0, 0, 1500, -20, 15, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(5), 1400);
|
||||
break;
|
||||
case 5:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA2, 2300, 100, 0, 2000, 4500, 0, 10, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(6), 2500);
|
||||
break;
|
||||
case 6:
|
||||
L2DoorInstance door = DoorTable.getInstance().getDoor(20240001);
|
||||
door.closeMe();
|
||||
ZONE.broadcastPacket(new StaticObject(door, false));
|
||||
ZONE.broadcastPacket(new DoorStatusUpdate(door));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(7), 1700);
|
||||
break;
|
||||
case 7:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA4, 1500, 210, 0, 0, 1500, 0, 0, 1, 0, 0));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA4, 900, 255, 0, 5000, 6500, 0, 10, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(8), 6000);
|
||||
break;
|
||||
case 8:
|
||||
spawn(29125, new Location(16323, 214917, -9356, 0, instanceId));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA4, 900, 255, 0, 0, 1500, 0, 10, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(9), 1000);
|
||||
break;
|
||||
case 9:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA4, 1000, 255, 0, 7000, 17000, 0, 25, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(10), 3000);
|
||||
break;
|
||||
case 10:
|
||||
BELETH = spawn(29118, new Location(16321, 214211, -9352, 49369, instanceId));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(11), 200);
|
||||
break;
|
||||
case 11:
|
||||
ZONE.broadcastPacket(new SocialAction(BELETH.getObjectId(), 1));
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
int x = (int) ((150 * Math.cos(i * 1.046666667)) + 16323);
|
||||
int y = (int) ((150 * Math.sin(i * 1.046666667)) + 213059);
|
||||
L2Npc minion = spawn(29119, new Location(x, y, -9357, 49152, BELETH.getInstanceId()));
|
||||
minion.setShowSummonAnimation(true);
|
||||
minion.decayMe();
|
||||
MINIONS.add(minion);
|
||||
}
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(12), 6800);
|
||||
break;
|
||||
case 12:
|
||||
ZONE.broadcastPacket(new SpecialCamera(BELETH, 0, 270, -5, 0, 4000, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(13), 3500);
|
||||
break;
|
||||
case 13:
|
||||
ZONE.broadcastPacket(new SpecialCamera(BELETH, 800, 270, 10, 3000, 6000, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(14), 5000);
|
||||
break;
|
||||
case 14:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 100, 270, 15, 0, 5000, 0, 0, 1, 0, 0));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 100, 270, 15, 0, 5000, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(15), 100);
|
||||
break;
|
||||
case 15:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 100, 270, 15, 3000, 6000, 0, 5, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(16), 1400);
|
||||
break;
|
||||
case 16:
|
||||
BELETH.teleToLocation(BELETH_SPAWN);
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(17), 200);
|
||||
break;
|
||||
case 17:
|
||||
ZONE.broadcastPacket(new MagicSkillUse(BELETH, BELETH, 5532, 1, 2000, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(18), 2000);
|
||||
break;
|
||||
case 18:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 700, 270, 20, 1500, 8000, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(19), 6900);
|
||||
break;
|
||||
case 19:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 40, 260, 0, 0, 4000, 0, 0, 1, 0, 0));
|
||||
for (L2Npc blth : MINIONS)
|
||||
{
|
||||
blth.spawnMe();
|
||||
}
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(20), 3000);
|
||||
break;
|
||||
case 20:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 40, 280, 0, 0, 4000, 5, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(21), 3000);
|
||||
break;
|
||||
case 21:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA3, 5, 250, 5, 0, 13000, 20, 15, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(22), 1000);
|
||||
break;
|
||||
case 22:
|
||||
ZONE.broadcastPacket(new SocialAction(BELETH.getObjectId(), 3));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(23), 4000);
|
||||
break;
|
||||
case 23:
|
||||
ZONE.broadcastPacket(new MagicSkillUse(BELETH, BELETH, 5533, 1, 2000, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(24), 6800);
|
||||
break;
|
||||
case 24:
|
||||
BELETH.deleteMe();
|
||||
for (L2Npc bel : MINIONS)
|
||||
{
|
||||
bel.deleteMe();
|
||||
}
|
||||
MINIONS.clear();
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(25), 1000);
|
||||
break;
|
||||
case 25:
|
||||
CAMERA.deleteMe();
|
||||
CAMERA2.deleteMe();
|
||||
CAMERA3.deleteMe();
|
||||
CAMERA4.deleteMe();
|
||||
MOVIE = false;
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(26), 60000);
|
||||
break;
|
||||
case 26:
|
||||
if (SPAWN_TIMER != null)
|
||||
{
|
||||
SPAWN_TIMER.cancel(false);
|
||||
setSpawnTimer(0);
|
||||
}
|
||||
SpawnBeleths();
|
||||
break;
|
||||
case 27:
|
||||
BELETH.doDie(null);
|
||||
CAMERA = spawn(29122, new Location(16323, 213170, -9357, 0, instanceId));
|
||||
CAMERA.broadcastPacket(new PlaySound(1, "BS07_D", 1, CAMERA.getObjectId(), CAMERA.getX(), CAMERA.getY(), CAMERA.getZ()));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 290, 25, 0, 10000, 0, 0, 1, 0, 0));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 290, 25, 0, 10000, 0, 0, 1, 0, 0));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 110, 25, 4000, 10000, 0, 0, 1, 0, 0));
|
||||
ZONE.broadcastPacket(new SocialAction(BELETH.getObjectId(), 5));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(28), 4000);
|
||||
break;
|
||||
case 28:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 295, 25, 4000, 5000, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(29), 4500);
|
||||
break;
|
||||
case 29:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 400, 295, 10, 4000, 11000, 0, 25, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(30), 9000);
|
||||
break;
|
||||
case 30:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 250, 90, 25, 0, 1000, 0, 0, 1, 0, 0));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA, 250, 90, 25, 0, 10000, 0, 0, 1, 0, 0));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(31), 2000);
|
||||
break;
|
||||
case 31:
|
||||
PRIEST.spawnMe();
|
||||
BELETH.deleteMe();
|
||||
CAMERA2 = spawn(29121, new Location(14056, 213170, -9357, 0, instanceId));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(32), 3500);
|
||||
break;
|
||||
case 32:
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA2, 800, 180, 0, 0, 4000, 0, 10, 1, 0, 0));
|
||||
ZONE.broadcastPacket(new SpecialCamera(CAMERA2, 800, 180, 0, 0, 4000, 0, 10, 1, 0, 0));
|
||||
L2DoorInstance door2 = DoorTable.getInstance().getDoor(20240002);
|
||||
door2.openMe();
|
||||
ZONE.broadcastPacket(new StaticObject(door2, false));
|
||||
ZONE.broadcastPacket(new DoorStatusUpdate(door2));
|
||||
DoorTable.getInstance().getDoor(20240003).openMe();
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(33), 4000);
|
||||
break;
|
||||
case 33:
|
||||
CAMERA.deleteMe();
|
||||
CAMERA2.deleteMe();
|
||||
MOVIE = false;
|
||||
break;
|
||||
case 333:
|
||||
BELETH = spawn(29118, new Location(16323, 213170, -9357, 49152));
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onEnterZone(L2Character character, L2ZoneType zone)
|
||||
{
|
||||
if (((character.isPlayer()) && (GrandBossManager.getInstance().getBossStatus(29118) == 1)) || (DEBUG && (GrandBossManager.getInstance().getBossStatus(29118) != 2) && (character.isPlayer())))
|
||||
{
|
||||
startSpawnTask();
|
||||
GrandBossManager.getInstance().setBossStatus(29118, 2);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc == null)
|
||||
{
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
if ((npc.getId() == 29118) && (killer != null))
|
||||
{
|
||||
setBelethKiller(1, killer);
|
||||
GrandBossManager.getInstance().setBossStatus(29118, 3);
|
||||
// Calculate Min and Max respawn times randomly.
|
||||
long respawnTime = Config.BELETH_SPAWN_INTERVAL + getRandom(-Config.BELETH_SPAWN_RANDOM, Config.BELETH_SPAWN_RANDOM);
|
||||
respawnTime *= 3600000;
|
||||
|
||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(29118);
|
||||
info.set("respawn_time", System.currentTimeMillis() + respawnTime);
|
||||
GrandBossManager.getInstance().setStatsSet(29118, info);
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new unlock(), respawnTime);
|
||||
deleteAll();
|
||||
npc.deleteMe();
|
||||
MOVIE = true;
|
||||
BELETH = spawn(29118, new Location(16323, 213170, -9357, 49152));
|
||||
BELETH.setIsInvul(true);
|
||||
BELETH.setIsImmobilized(true);
|
||||
BELETH.disableAllSkills();
|
||||
PRIEST = spawn(29128, new Location(BELETH));
|
||||
PRIEST.setShowSummonAnimation(true);
|
||||
PRIEST.decayMe();
|
||||
spawn(32470, new Location(12470, 215607, -9381, 49152));
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(27), 1000);
|
||||
}
|
||||
else if (npc.getId() == 29119)
|
||||
{
|
||||
if (npc.getObjectId() == ALLOW_OBJECT_ID)
|
||||
{
|
||||
MINIONS.remove(npc);
|
||||
KILLED++;
|
||||
if (KILLED >= 5)
|
||||
{
|
||||
deleteAll();
|
||||
setSpawnTimer(1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ALLOW_OBJECT_ID = MINIONS.get(getRandom(MINIONS.size())).getObjectId();
|
||||
ATTACKED = false;
|
||||
}
|
||||
}
|
||||
else if (SPAWN_TIMER == null)
|
||||
{
|
||||
deleteAll();
|
||||
setSpawnTimer(2);
|
||||
KILLED = 0;
|
||||
}
|
||||
npc.abortCast();
|
||||
npc.setTarget(null);
|
||||
npc.deleteMe();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance player, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if ((npc != null) && !npc.isDead() && ((npc.getId() == 29118) || (npc.getId() == 29119)) && !npc.isCastingNow() && skill.hasEffectType(L2EffectType.HEAL) && (getRandom(100) < 80))
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(HORN_OF_RISING.getSkill());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc == null)
|
||||
{
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
if ((npc.getId() == 29118) || (npc.getId() == 29119))
|
||||
{
|
||||
if ((npc.getObjectId() == ALLOW_OBJECT_ID) && !ATTACKED)
|
||||
{
|
||||
ATTACKED = true;
|
||||
L2Npc fakeBeleth = MINIONS.get(getRandom(MINIONS.size()));
|
||||
while (fakeBeleth.getObjectId() == ALLOW_OBJECT_ID)
|
||||
{
|
||||
fakeBeleth = MINIONS.get(getRandom(MINIONS.size()));
|
||||
}
|
||||
ZONE.broadcastPacket(new CreatureSay(fakeBeleth.getObjectId(), 0, fakeBeleth.getName(), "Miss text."));
|
||||
}
|
||||
if (getRandom(100) < 40)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
final double distance = npc.calculateDistance(attacker, false, false);
|
||||
if ((distance > 500) || (getRandom(100) < 80))
|
||||
{
|
||||
for (L2Npc beleth : MINIONS)
|
||||
{
|
||||
if ((beleth != null) && !beleth.isDead() && Util.checkIfInRange(900, beleth, attacker, false) && !beleth.isCastingNow())
|
||||
{
|
||||
beleth.setTarget(attacker);
|
||||
beleth.doCast(FIREBALL.getSkill());
|
||||
}
|
||||
}
|
||||
if ((BELETH != null) && !BELETH.isDead() && Util.checkIfInRange(900, BELETH, attacker, false) && !BELETH.isCastingNow())
|
||||
{
|
||||
BELETH.setTarget(attacker);
|
||||
BELETH.doCast(FIREBALL.getSkill());
|
||||
}
|
||||
}
|
||||
else if (!npc.isDead() && !npc.isCastingNow())
|
||||
{
|
||||
if (!npc.getKnownList().getKnownPlayersInRadius(200).isEmpty())
|
||||
{
|
||||
npc.doCast(LIGHTENING.getSkill());
|
||||
return null;
|
||||
}
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
if ((npc != null) && !npc.isDead() && ((npc.getId() == 29118) || (npc.getId() == 29119)) && !npc.isCastingNow())
|
||||
{
|
||||
if ((player != null) && !player.isDead())
|
||||
{
|
||||
final double distance2 = npc.calculateDistance(player, false, false);
|
||||
if ((distance2 > 890) && !npc.isMovementDisabled())
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, player);
|
||||
double speed = npc.isRunning() ? npc.getRunSpeed() : npc.getWalkSpeed();
|
||||
int time = (int) (((distance2 - 890) / speed) * 1000);
|
||||
ThreadPoolManager.getInstance().scheduleGeneral(new Cast(FIREBALL, npc), time);
|
||||
|
||||
}
|
||||
else if (distance2 < 890)
|
||||
{
|
||||
npc.setTarget(player);
|
||||
npc.doCast(FIREBALL.getSkill());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (getRandom(100) < 40)
|
||||
{
|
||||
if (!npc.getKnownList().getKnownPlayersInRadius(200).isEmpty())
|
||||
{
|
||||
npc.doCast(LIGHTENING.getSkill());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
for (L2PcInstance plr : npc.getKnownList().getKnownPlayersInRadius(950))
|
||||
{
|
||||
npc.setTarget(plr);
|
||||
npc.doCast(FIREBALL.getSkill());
|
||||
return null;
|
||||
}
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
if ((npc != null) && !npc.isDead() && ((npc.getId() == 29118) || (npc.getId() == 29119)) && !npc.isCastingNow() && !MOVIE)
|
||||
{
|
||||
if (getRandom(100) < 40)
|
||||
{
|
||||
if (!npc.getKnownList().getKnownPlayersInRadius(200).isEmpty())
|
||||
{
|
||||
npc.doCast(BLEED.getSkill());
|
||||
return null;
|
||||
}
|
||||
}
|
||||
npc.setTarget(player);
|
||||
npc.doCast(FIREBALL.getSkill());
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if ((npc.getId() == 29118) || (npc.getId() == 29119))
|
||||
{
|
||||
npc.setRunning();
|
||||
if (!MOVIE && !npc.getKnownList().getKnownPlayersInRadius(300).isEmpty() && (getRandom(100) < 60))
|
||||
{
|
||||
npc.doCast(BLEED.getSkill());
|
||||
}
|
||||
if (npc.getId() == 29118)
|
||||
{
|
||||
npc.getSpawn().setRespawnDelay(0);// setOnKillDelay
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
final String html;
|
||||
if ((BELETH_KILLER != null) && (player.getObjectId() == BELETH_KILLER.getObjectId()))
|
||||
{
|
||||
player.addItem("Kill Beleth", 10314, 1, null, true);// giveItems(10314, 1, 0)
|
||||
setBelethKiller(0, player);
|
||||
html = "32470a.htm";
|
||||
}
|
||||
else
|
||||
{
|
||||
html = "32470b.htm";
|
||||
}
|
||||
return HtmCache.getInstance().getHtm(player.getHtmlPrefix(), "data/html/default/" + html);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void setBelethKiller(int event, L2PcInstance killer)
|
||||
{
|
||||
if (event == 0)
|
||||
{
|
||||
BELETH_KILLER = null;
|
||||
}
|
||||
else if (event == 1)
|
||||
{
|
||||
if (killer.getParty() != null)
|
||||
{
|
||||
if (killer.getParty().getCommandChannel() != null)
|
||||
{
|
||||
BELETH_KILLER = killer.getParty().getCommandChannel().getLeader();
|
||||
}
|
||||
else
|
||||
{
|
||||
BELETH_KILLER = killer.getParty().getLeader();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
BELETH_KILLER = killer;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protected static void setSpawnTimer(int event)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case 0:
|
||||
SPAWN_TIMER = null;
|
||||
break;
|
||||
case 1:
|
||||
SPAWN_TIMER = ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(333), 60000);
|
||||
break;
|
||||
case 2:
|
||||
SPAWN_TIMER = ThreadPoolManager.getInstance().scheduleGeneral(new Spawn(26), 60000);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
private static void deleteAll()
|
||||
{
|
||||
if ((MINIONS != null) && !MINIONS.isEmpty())
|
||||
{
|
||||
for (L2Npc npc : MINIONS)
|
||||
{
|
||||
if ((npc == null) || npc.isDead())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
npc.abortCast();
|
||||
npc.setTarget(null);
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
||||
npc.deleteMe();
|
||||
}
|
||||
MINIONS.clear();
|
||||
}
|
||||
ALLOW_OBJECT_ID = 0;
|
||||
ATTACKED = false;
|
||||
}
|
||||
|
||||
protected static void SpawnBeleths()
|
||||
{
|
||||
int a = 0;
|
||||
L2Npc npc;
|
||||
for (int i = 0; i < 16; i++)
|
||||
{
|
||||
a++;
|
||||
int x = (int) ((650 * Math.cos(i * 0.39)) + 16323);
|
||||
int y = (int) ((650 * Math.sin(i * 0.39)) + 213170);
|
||||
npc = spawn(29119, new Location(x, y, -9357, 49152));
|
||||
MINIONS.add(npc);
|
||||
if (a >= 2)
|
||||
{
|
||||
npc.setIsOverloaded(true);
|
||||
a = 0;
|
||||
}
|
||||
}
|
||||
int[] xm = new int[16];
|
||||
int[] ym = new int[16];
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
xm[i] = (int) ((1700 * Math.cos((i * 1.57) + 0.78)) + 16323);
|
||||
ym[i] = (int) ((1700 * Math.sin((i * 1.57) + 0.78)) + 213170);
|
||||
npc = spawn(29119, new Location(xm[i], ym[i], -9357, 49152));
|
||||
npc.setIsOverloaded(true);
|
||||
MINIONS.add(npc);
|
||||
}
|
||||
xm[4] = (xm[0] + xm[1]) / 2;
|
||||
ym[4] = (ym[0] + ym[1]) / 2;
|
||||
npc = spawn(29119, new Location(xm[4], ym[4], -9357, 49152));
|
||||
npc.setIsOverloaded(true);
|
||||
MINIONS.add(npc);
|
||||
xm[5] = (xm[1] + xm[2]) / 2;
|
||||
ym[5] = (ym[1] + ym[2]) / 2;
|
||||
npc = spawn(29119, new Location(xm[5], ym[5], -9357, 49152));
|
||||
npc.setIsOverloaded(true);
|
||||
MINIONS.add(npc);
|
||||
xm[6] = (xm[2] + xm[3]) / 2;
|
||||
ym[6] = (ym[2] + ym[3]) / 2;
|
||||
npc = spawn(29119, new Location(xm[6], ym[6], -9357, 49152));
|
||||
npc.setIsOverloaded(true);
|
||||
MINIONS.add(npc);
|
||||
xm[7] = (xm[3] + xm[0]) / 2;
|
||||
ym[7] = (ym[3] + ym[0]) / 2;
|
||||
npc = spawn(29119, new Location(xm[7], ym[7], -9357, 49152));
|
||||
npc.setIsOverloaded(true);
|
||||
MINIONS.add(npc);
|
||||
xm[8] = (xm[0] + xm[4]) / 2;
|
||||
ym[8] = (ym[0] + ym[4]) / 2;
|
||||
MINIONS.add(spawn(29119, new Location(xm[8], ym[8], -9357, 49152)));
|
||||
xm[9] = (xm[4] + xm[1]) / 2;
|
||||
ym[9] = (ym[4] + ym[1]) / 2;
|
||||
MINIONS.add(spawn(29119, new Location(xm[9], ym[9], -9357, 49152)));
|
||||
xm[10] = (xm[1] + xm[5]) / 2;
|
||||
ym[10] = (ym[1] + ym[5]) / 2;
|
||||
MINIONS.add(spawn(29119, new Location(xm[10], ym[10], -9357, 49152)));
|
||||
xm[11] = (xm[5] + xm[2]) / 2;
|
||||
ym[11] = (ym[5] + ym[2]) / 2;
|
||||
MINIONS.add(spawn(29119, new Location(xm[11], ym[11], -9357, 49152)));
|
||||
xm[12] = (xm[2] + xm[6]) / 2;
|
||||
ym[12] = (ym[2] + ym[6]) / 2;
|
||||
MINIONS.add(spawn(29119, new Location(xm[12], ym[12], -9357, 49152)));
|
||||
xm[13] = (xm[6] + xm[3]) / 2;
|
||||
ym[13] = (ym[6] + ym[3]) / 2;
|
||||
MINIONS.add(spawn(29119, new Location(xm[13], ym[13], -9357, 49152)));
|
||||
xm[14] = (xm[3] + xm[7]) / 2;
|
||||
ym[14] = (ym[3] + ym[7]) / 2;
|
||||
MINIONS.add(spawn(29119, new Location(xm[14], ym[14], -9357, 49152)));
|
||||
xm[15] = (xm[7] + xm[0]) / 2;
|
||||
ym[15] = (ym[7] + ym[0]) / 2;
|
||||
MINIONS.add(spawn(29119, new Location(xm[15], ym[15], -9357, 49152)));
|
||||
ALLOW_OBJECT_ID = MINIONS.get(getRandom(MINIONS.size())).getObjectId();
|
||||
ATTACKED = false;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Beleth();
|
||||
}
|
||||
}
|
||||
76
trunk/dist/game/data/scripts/ai/individual/CatsEyeBandit.java
vendored
Normal file
76
trunk/dist/game/data/scripts/ai/individual/CatsEyeBandit.java
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
|
||||
import com.l2jserver.gameserver.model.quest.QuestState;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Cat's Eye Bandit (Quest Monster) AI.
|
||||
* @author Gladicek
|
||||
*/
|
||||
public final class CatsEyeBandit extends AbstractNpcAI
|
||||
{
|
||||
// NPC ID
|
||||
private static final int MOB_ID = 27038;
|
||||
// Weapons
|
||||
private static final int BOW = 1181;
|
||||
private static final int DAGGER = 1182;
|
||||
|
||||
private CatsEyeBandit()
|
||||
{
|
||||
super(CatsEyeBandit.class.getSimpleName(), "ai/individual");
|
||||
addAttackId(MOB_ID);
|
||||
addKillId(MOB_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
final QuestState qs = attacker.getQuestState("403_PathToRogue"); // TODO: Replace with class name.
|
||||
if (npc.isScriptValue(0) && (qs != null) && ((qs.getItemEquipped(Inventory.PAPERDOLL_RHAND) == BOW) || (qs.getItemEquipped(Inventory.PAPERDOLL_RHAND) == DAGGER)))
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.YOU_CHILDISH_FOOL_DO_YOU_THINK_YOU_CAN_CATCH_ME);
|
||||
npc.setScriptValue(1);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final QuestState qs = killer.getQuestState("403_PathToRogue"); // TODO: Replace with class name.
|
||||
if (qs != null)
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.I_MUST_DO_SOMETHING_ABOUT_THIS_SHAMEFUL_INCIDENT);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new CatsEyeBandit();
|
||||
}
|
||||
}
|
||||
230
trunk/dist/game/data/scripts/ai/individual/Core.java
vendored
Normal file
230
trunk/dist/game/data/scripts/ai/individual/Core.java
vendored
Normal file
@@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javolution.util.FastList;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.instancemanager.GrandBossManager;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
||||
|
||||
/**
|
||||
* Core AI
|
||||
* @author DrLecter Revised By Emperorc
|
||||
*/
|
||||
public final class Core extends AbstractNpcAI
|
||||
{
|
||||
private static final int CORE = 29006;
|
||||
private static final int DEATH_KNIGHT = 29007;
|
||||
private static final int DOOM_WRAITH = 29008;
|
||||
// private static final int DICOR = 29009;
|
||||
// private static final int VALIDUS = 29010;
|
||||
private static final int SUSCEPTOR = 29011;
|
||||
// private static final int PERUM = 29012;
|
||||
// private static final int PREMO = 29013;
|
||||
|
||||
// CORE Status Tracking :
|
||||
private static final byte ALIVE = 0; // Core is spawned.
|
||||
private static final byte DEAD = 1; // Core has been killed.
|
||||
|
||||
private static boolean _FirstAttacked;
|
||||
|
||||
private final List<L2Attackable> Minions = new FastList<>();
|
||||
|
||||
private Core()
|
||||
{
|
||||
super(Core.class.getSimpleName(), "ai/individual");
|
||||
registerMobs(CORE, DEATH_KNIGHT, DOOM_WRAITH, SUSCEPTOR);
|
||||
|
||||
_FirstAttacked = false;
|
||||
final StatsSet info = GrandBossManager.getInstance().getStatsSet(CORE);
|
||||
final int status = GrandBossManager.getInstance().getBossStatus(CORE);
|
||||
if (status == DEAD)
|
||||
{
|
||||
// load the unlock date and time for Core from DB
|
||||
long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
|
||||
// if Core is locked until a certain time, mark it so and start the unlock timer
|
||||
// the unlock time has not yet expired.
|
||||
if (temp > 0)
|
||||
{
|
||||
startQuestTimer("core_unlock", temp, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
// the time has already expired while the server was offline. Immediately spawn Core.
|
||||
L2GrandBossInstance core = (L2GrandBossInstance) addSpawn(CORE, 17726, 108915, -6480, 0, false, 0);
|
||||
GrandBossManager.getInstance().setBossStatus(CORE, ALIVE);
|
||||
spawnBoss(core);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
final String test = loadGlobalQuestVar("Core_Attacked");
|
||||
if (test.equalsIgnoreCase("true"))
|
||||
{
|
||||
_FirstAttacked = true;
|
||||
}
|
||||
final int loc_x = info.getInt("loc_x");
|
||||
final int loc_y = info.getInt("loc_y");
|
||||
final int loc_z = info.getInt("loc_z");
|
||||
final int heading = info.getInt("heading");
|
||||
final int hp = info.getInt("currentHP");
|
||||
final int mp = info.getInt("currentMP");
|
||||
final L2GrandBossInstance core = (L2GrandBossInstance) addSpawn(CORE, loc_x, loc_y, loc_z, heading, false, 0);
|
||||
core.setCurrentHpMp(hp, mp);
|
||||
spawnBoss(core);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveGlobalData()
|
||||
{
|
||||
saveGlobalQuestVar("Core_Attacked", Boolean.toString(_FirstAttacked));
|
||||
}
|
||||
|
||||
public void spawnBoss(L2GrandBossInstance npc)
|
||||
{
|
||||
GrandBossManager.getInstance().addBoss(npc);
|
||||
npc.broadcastPacket(new PlaySound(1, "BS01_A", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
|
||||
// Spawn minions
|
||||
L2Attackable mob;
|
||||
for (int i = 0; i < 5; i++)
|
||||
{
|
||||
final int x = 16800 + (i * 360);
|
||||
mob = (L2Attackable) addSpawn(DEATH_KNIGHT, x, 110000, npc.getZ(), 280 + getRandom(40), false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
Minions.add(mob);
|
||||
mob = (L2Attackable) addSpawn(DEATH_KNIGHT, x, 109000, npc.getZ(), 280 + getRandom(40), false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
Minions.add(mob);
|
||||
final int x2 = 16800 + (i * 600);
|
||||
mob = (L2Attackable) addSpawn(DOOM_WRAITH, x2, 109300, npc.getZ(), 280 + getRandom(40), false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
Minions.add(mob);
|
||||
}
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
int x = 16800 + (i * 450);
|
||||
mob = (L2Attackable) addSpawn(SUSCEPTOR, x, 110300, npc.getZ(), 280 + getRandom(40), false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
Minions.add(mob);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equalsIgnoreCase("core_unlock"))
|
||||
{
|
||||
L2GrandBossInstance core = (L2GrandBossInstance) addSpawn(CORE, 17726, 108915, -6480, 0, false, 0);
|
||||
GrandBossManager.getInstance().setBossStatus(CORE, ALIVE);
|
||||
spawnBoss(core);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_minion"))
|
||||
{
|
||||
L2Attackable mob = (L2Attackable) addSpawn(npc.getId(), npc.getX(), npc.getY(), npc.getZ(), npc.getHeading(), false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
Minions.add(mob);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("despawn_minions"))
|
||||
{
|
||||
for (int i = 0; i < Minions.size(); i++)
|
||||
{
|
||||
L2Attackable mob = Minions.get(i);
|
||||
if (mob != null)
|
||||
{
|
||||
mob.decayMe();
|
||||
}
|
||||
}
|
||||
Minions.clear();
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == CORE)
|
||||
{
|
||||
if (_FirstAttacked)
|
||||
{
|
||||
if (getRandom(100) == 0)
|
||||
{
|
||||
npc.broadcastPacket(new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npc.getId(), NpcStringId.REMOVING_INTRUDERS));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
_FirstAttacked = true;
|
||||
npc.broadcastPacket(new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npc.getId(), NpcStringId.A_NON_PERMITTED_TARGET_HAS_BEEN_DISCOVERED));
|
||||
npc.broadcastPacket(new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npc.getId(), NpcStringId.INTRUDER_REMOVAL_SYSTEM_INITIATED));
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
final int npcId = npc.getId();
|
||||
if (npcId == CORE)
|
||||
{
|
||||
int objId = npc.getObjectId();
|
||||
npc.broadcastPacket(new PlaySound(1, "BS02_D", 1, objId, npc.getX(), npc.getY(), npc.getZ()));
|
||||
npc.broadcastPacket(new NpcSay(objId, Say2.NPC_ALL, npcId, NpcStringId.A_FATAL_ERROR_HAS_OCCURRED));
|
||||
npc.broadcastPacket(new NpcSay(objId, Say2.NPC_ALL, npcId, NpcStringId.SYSTEM_IS_BEING_SHUT_DOWN));
|
||||
npc.broadcastPacket(new NpcSay(objId, Say2.NPC_ALL, npcId, NpcStringId.EMPTY));
|
||||
_FirstAttacked = false;
|
||||
GrandBossManager.getInstance().setBossStatus(CORE, DEAD);
|
||||
// Calculate Min and Max respawn times randomly.
|
||||
long respawnTime = Config.CORE_SPAWN_INTERVAL + getRandom(-Config.CORE_SPAWN_RANDOM, Config.CORE_SPAWN_RANDOM);
|
||||
respawnTime *= 3600000;
|
||||
|
||||
startQuestTimer("core_unlock", respawnTime, null, null);
|
||||
// also save the respawn time so that the info is maintained past reboots
|
||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(CORE);
|
||||
info.set("respawn_time", (System.currentTimeMillis() + respawnTime));
|
||||
GrandBossManager.getInstance().setStatsSet(CORE, info);
|
||||
startQuestTimer("despawn_minions", 20000, null, null);
|
||||
cancelQuestTimers("spawn_minion");
|
||||
}
|
||||
else if ((GrandBossManager.getInstance().getBossStatus(CORE) == ALIVE) && (Minions != null) && Minions.contains(npc))
|
||||
{
|
||||
Minions.remove(npc);
|
||||
startQuestTimer("spawn_minion", 60000, npc, null);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Core();
|
||||
}
|
||||
}
|
||||
107
trunk/dist/game/data/scripts/ai/individual/CrimsonHatuOtis.java
vendored
Normal file
107
trunk/dist/game/data/scripts/ai/individual/CrimsonHatuOtis.java
vendored
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* AI for Kamaloka (33) - Crimson Hatu Otis
|
||||
* @author Gladicek
|
||||
*/
|
||||
public final class CrimsonHatuOtis extends AbstractNpcAI
|
||||
{
|
||||
// Npc
|
||||
private static final int CRIMSON_HATU_OTIS = 18558;
|
||||
// Skills
|
||||
private static SkillHolder BOSS_SPINING_SLASH = new SkillHolder(4737, 1);
|
||||
private static SkillHolder BOSS_HASTE = new SkillHolder(4175, 1);
|
||||
|
||||
private CrimsonHatuOtis()
|
||||
{
|
||||
super(CrimsonHatuOtis.class.getSimpleName(), "ai/individual");
|
||||
addAttackId(CRIMSON_HATU_OTIS);
|
||||
addKillId(CRIMSON_HATU_OTIS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "SKILL":
|
||||
{
|
||||
if (npc.isDead())
|
||||
{
|
||||
cancelQuestTimer("SKILL", npc, null);
|
||||
return null;
|
||||
}
|
||||
npc.setTarget(player);
|
||||
npc.doCast(BOSS_SPINING_SLASH.getSkill());
|
||||
startQuestTimer("SKILL", 60000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "BUFF":
|
||||
{
|
||||
if (npc.isScriptValue(2))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(BOSS_HASTE.getSkill());
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
startQuestTimer("SKILL", 5000, npc, null);
|
||||
}
|
||||
else if (npc.isScriptValue(1) && (npc.getCurrentHp() < (npc.getMaxHp() * 0.3)))
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.I_VE_HAD_IT_UP_TO_HERE_WITH_YOU_I_LL_TAKE_CARE_OF_YOU);
|
||||
npc.setScriptValue(2);
|
||||
startQuestTimer("BUFF", 1000, npc, null);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
cancelQuestTimer("SKILL", npc, null);
|
||||
cancelQuestTimer("BUFF", npc, null);
|
||||
return super.onKill(npc, player, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new CrimsonHatuOtis();
|
||||
}
|
||||
}
|
||||
248
trunk/dist/game/data/scripts/ai/individual/DarkWaterDragon.java
vendored
Normal file
248
trunk/dist/game/data/scripts/ai/individual/DarkWaterDragon.java
vendored
Normal file
@@ -0,0 +1,248 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import javolution.util.FastSet;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.NpcData;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* Dark Water Dragon's AI.
|
||||
*/
|
||||
public final class DarkWaterDragon extends AbstractNpcAI
|
||||
{
|
||||
private static final int DRAGON = 22267;
|
||||
private static final int SHADE1 = 22268;
|
||||
private static final int SHADE2 = 22269;
|
||||
private static final int FAFURION = 18482;
|
||||
private static final int DETRACTOR1 = 22270;
|
||||
private static final int DETRACTOR2 = 22271;
|
||||
private static Set<Integer> SECOND_SPAWN = new FastSet<>(); // Used to track if second Shades were already spawned
|
||||
private static Set<Integer> MY_TRACKING_SET = new FastSet<>(); // Used to track instances of npcs
|
||||
private static Map<Integer, L2PcInstance> ID_MAP = new ConcurrentHashMap<>(); // Used to track instances of npcs
|
||||
|
||||
private DarkWaterDragon()
|
||||
{
|
||||
super(DarkWaterDragon.class.getSimpleName(), "ai/individual");
|
||||
int[] mobs =
|
||||
{
|
||||
DRAGON,
|
||||
SHADE1,
|
||||
SHADE2,
|
||||
FAFURION,
|
||||
DETRACTOR1,
|
||||
DETRACTOR2
|
||||
};
|
||||
addKillId(mobs);
|
||||
addAttackId(mobs);
|
||||
addSpawnId(mobs);
|
||||
MY_TRACKING_SET.clear();
|
||||
SECOND_SPAWN.clear();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
if (event.equalsIgnoreCase("first_spawn")) // timer to start timer "1"
|
||||
{
|
||||
startQuestTimer("1", 40000, npc, null, true); // spawns detractor every 40 seconds
|
||||
}
|
||||
else if (event.equalsIgnoreCase("second_spawn")) // timer to start timer "2"
|
||||
{
|
||||
startQuestTimer("2", 40000, npc, null, true); // spawns detractor every 40 seconds
|
||||
}
|
||||
else if (event.equalsIgnoreCase("third_spawn")) // timer to start timer "3"
|
||||
{
|
||||
startQuestTimer("3", 40000, npc, null, true); // spawns detractor every 40 seconds
|
||||
}
|
||||
else if (event.equalsIgnoreCase("fourth_spawn")) // timer to start timer "4"
|
||||
{
|
||||
startQuestTimer("4", 40000, npc, null, true); // spawns detractor every 40 seconds
|
||||
}
|
||||
else if (event.equalsIgnoreCase("1")) // spawns a detractor
|
||||
{
|
||||
addSpawn(DETRACTOR1, (npc.getX() + 100), (npc.getY() + 100), npc.getZ(), 0, false, 40000);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("2")) // spawns a detractor
|
||||
{
|
||||
addSpawn(DETRACTOR2, (npc.getX() + 100), (npc.getY() - 100), npc.getZ(), 0, false, 40000);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("3")) // spawns a detractor
|
||||
{
|
||||
addSpawn(DETRACTOR1, (npc.getX() - 100), (npc.getY() + 100), npc.getZ(), 0, false, 40000);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("4")) // spawns a detractor
|
||||
{
|
||||
addSpawn(DETRACTOR2, (npc.getX() - 100), (npc.getY() - 100), npc.getZ(), 0, false, 40000);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("fafurion_despawn")) // Fafurion Kindred disappears and drops reward
|
||||
{
|
||||
cancelQuestTimer("fafurion_poison", npc, null);
|
||||
cancelQuestTimer("1", npc, null);
|
||||
cancelQuestTimer("2", npc, null);
|
||||
cancelQuestTimer("3", npc, null);
|
||||
cancelQuestTimer("4", npc, null);
|
||||
|
||||
MY_TRACKING_SET.remove(npc.getObjectId());
|
||||
player = ID_MAP.remove(npc.getObjectId());
|
||||
if (player != null)
|
||||
{
|
||||
((L2Attackable) npc).doItemDrop(NpcData.getInstance().getTemplate(18485), player);
|
||||
}
|
||||
|
||||
npc.deleteMe();
|
||||
}
|
||||
else if (event.equalsIgnoreCase("fafurion_poison")) // Reduces Fafurions hp like it is poisoned
|
||||
{
|
||||
if (npc.getCurrentHp() <= 500)
|
||||
{
|
||||
cancelQuestTimer("fafurion_despawn", npc, null);
|
||||
cancelQuestTimer("first_spawn", npc, null);
|
||||
cancelQuestTimer("second_spawn", npc, null);
|
||||
cancelQuestTimer("third_spawn", npc, null);
|
||||
cancelQuestTimer("fourth_spawn", npc, null);
|
||||
cancelQuestTimer("1", npc, null);
|
||||
cancelQuestTimer("2", npc, null);
|
||||
cancelQuestTimer("3", npc, null);
|
||||
cancelQuestTimer("4", npc, null);
|
||||
MY_TRACKING_SET.remove(npc.getObjectId());
|
||||
ID_MAP.remove(npc.getObjectId());
|
||||
}
|
||||
npc.reduceCurrentHp(500, npc, null); // poison kills Fafurion if he is not healed
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
int npcId = npc.getId();
|
||||
int npcObjId = npc.getObjectId();
|
||||
if (npcId == DRAGON)
|
||||
{
|
||||
if (!MY_TRACKING_SET.contains(npcObjId)) // this allows to handle multiple instances of npc
|
||||
{
|
||||
MY_TRACKING_SET.add(npcObjId);
|
||||
// Spawn first 5 shades on first attack on Dark Water Dragon
|
||||
L2Character originalAttacker = isSummon ? attacker.getSummon() : attacker;
|
||||
spawnShade(originalAttacker, SHADE1, npc.getX() + 100, npc.getY() + 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE2, npc.getX() + 100, npc.getY() - 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE1, npc.getX() - 100, npc.getY() + 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE2, npc.getX() - 100, npc.getY() - 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE1, npc.getX() - 150, npc.getY() + 150, npc.getZ());
|
||||
}
|
||||
else if ((npc.getCurrentHp() < (npc.getMaxHp() / 2.0)) && !(SECOND_SPAWN.contains(npcObjId)))
|
||||
{
|
||||
SECOND_SPAWN.add(npcObjId);
|
||||
// Spawn second 5 shades on half hp of on Dark Water Dragon
|
||||
L2Character originalAttacker = isSummon ? attacker.getSummon() : attacker;
|
||||
spawnShade(originalAttacker, SHADE2, npc.getX() + 100, npc.getY() + 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE1, npc.getX() + 100, npc.getY() - 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE2, npc.getX() - 100, npc.getY() + 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE1, npc.getX() - 100, npc.getY() - 100, npc.getZ());
|
||||
spawnShade(originalAttacker, SHADE2, npc.getX() - 150, npc.getY() + 150, npc.getZ());
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
int npcId = npc.getId();
|
||||
int npcObjId = npc.getObjectId();
|
||||
if (npcId == DRAGON)
|
||||
{
|
||||
MY_TRACKING_SET.remove(npcObjId);
|
||||
SECOND_SPAWN.remove(npcObjId);
|
||||
L2Attackable faf = (L2Attackable) addSpawn(FAFURION, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0); // spawns Fafurion Kindred when Dard Water Dragon is dead
|
||||
ID_MAP.put(faf.getObjectId(), killer);
|
||||
}
|
||||
else if (npcId == FAFURION)
|
||||
{
|
||||
cancelQuestTimer("fafurion_poison", npc, null);
|
||||
cancelQuestTimer("fafurion_despawn", npc, null);
|
||||
cancelQuestTimer("first_spawn", npc, null);
|
||||
cancelQuestTimer("second_spawn", npc, null);
|
||||
cancelQuestTimer("third_spawn", npc, null);
|
||||
cancelQuestTimer("fourth_spawn", npc, null);
|
||||
cancelQuestTimer("1", npc, null);
|
||||
cancelQuestTimer("2", npc, null);
|
||||
cancelQuestTimer("3", npc, null);
|
||||
cancelQuestTimer("4", npc, null);
|
||||
MY_TRACKING_SET.remove(npcObjId);
|
||||
ID_MAP.remove(npcObjId);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
int npcId = npc.getId();
|
||||
int npcObjId = npc.getObjectId();
|
||||
if (npcId == FAFURION)
|
||||
{
|
||||
if (!MY_TRACKING_SET.contains(npcObjId))
|
||||
{
|
||||
MY_TRACKING_SET.add(npcObjId);
|
||||
// Spawn 4 Detractors on spawn of Fafurion
|
||||
int x = npc.getX();
|
||||
int y = npc.getY();
|
||||
addSpawn(DETRACTOR2, x + 100, y + 100, npc.getZ(), 0, false, 40000);
|
||||
addSpawn(DETRACTOR1, x + 100, y - 100, npc.getZ(), 0, false, 40000);
|
||||
addSpawn(DETRACTOR2, x - 100, y + 100, npc.getZ(), 0, false, 40000);
|
||||
addSpawn(DETRACTOR1, x - 100, y - 100, npc.getZ(), 0, false, 40000);
|
||||
startQuestTimer("first_spawn", 2000, npc, null); // timer to delay timer "1"
|
||||
startQuestTimer("second_spawn", 4000, npc, null); // timer to delay timer "2"
|
||||
startQuestTimer("third_spawn", 8000, npc, null); // timer to delay timer "3"
|
||||
startQuestTimer("fourth_spawn", 10000, npc, null); // timer to delay timer "4"
|
||||
startQuestTimer("fafurion_poison", 3000, npc, null, true); // Every three seconds reduces Fafurions hp like it is poisoned
|
||||
startQuestTimer("fafurion_despawn", 120000, npc, null); // Fafurion Kindred disappears after two minutes
|
||||
}
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public void spawnShade(L2Character attacker, int npcId, int x, int y, int z)
|
||||
{
|
||||
final L2Npc shade = addSpawn(npcId, x, y, z, 0, false, 0);
|
||||
shade.setRunning();
|
||||
((L2Attackable) shade).addDamageHate(attacker, 0, 999);
|
||||
shade.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, attacker);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new DarkWaterDragon();
|
||||
}
|
||||
}
|
||||
69
trunk/dist/game/data/scripts/ai/individual/DivineBeast.java
vendored
Normal file
69
trunk/dist/game/data/scripts/ai/individual/DivineBeast.java
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* Simple AI that manages special conditions for Divine Beast summon.
|
||||
* @author UnAfraid
|
||||
*/
|
||||
public final class DivineBeast extends AbstractNpcAI
|
||||
{
|
||||
private static final int DIVINE_BEAST = 14870;
|
||||
private static final int TRANSFORMATION_ID = 258;
|
||||
private static final int CHECK_TIME = 2 * 1000;
|
||||
|
||||
private DivineBeast()
|
||||
{
|
||||
super(DivineBeast.class.getSimpleName(), "ai");
|
||||
addSummonSpawnId(DIVINE_BEAST);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSummonSpawn(L2Summon summon)
|
||||
{
|
||||
startQuestTimer("VALIDATE_TRANSFORMATION", CHECK_TIME, null, summon.getActingPlayer(), true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if ((player == null) || !player.hasServitor())
|
||||
{
|
||||
cancelQuestTimer(event, npc, player);
|
||||
}
|
||||
else if (player.getTransformationId() != TRANSFORMATION_ID)
|
||||
{
|
||||
cancelQuestTimer(event, npc, player);
|
||||
player.getSummon().unSummon(player);
|
||||
}
|
||||
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new DivineBeast();
|
||||
}
|
||||
}
|
||||
134
trunk/dist/game/data/scripts/ai/individual/DrChaos.java
vendored
Normal file
134
trunk/dist/game/data/scripts/ai/individual/DrChaos.java
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.SpawnTable;
|
||||
import com.l2jserver.gameserver.model.L2Spawn;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.quest.Quest;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SpecialCamera;
|
||||
|
||||
/**
|
||||
* DrChaos' AI.
|
||||
* @author Kerberos
|
||||
*/
|
||||
public final class DrChaos extends Quest
|
||||
{
|
||||
private static final int DR_CHAOS = 32033;
|
||||
private static final int STRANGE_MACHINE = 32032;
|
||||
private static final int CHAOS_GOLEM = 25703;
|
||||
private static boolean _IsGolemSpawned;
|
||||
|
||||
private static final Location PLAYER_TELEPORT = new Location(94832, -112624, -3304);
|
||||
private static final Location NPC_LOCATION = new Location(-113091, -243942, -15536);
|
||||
|
||||
private DrChaos()
|
||||
{
|
||||
// TODO extends AbstractNpcAI
|
||||
super(-1, "Doctor Chaos", "ai/individual");
|
||||
addFirstTalkId(DR_CHAOS);
|
||||
_IsGolemSpawned = false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "1":
|
||||
{
|
||||
L2Npc machine = null;
|
||||
for (L2Spawn spawn : SpawnTable.getInstance().getSpawns(STRANGE_MACHINE))
|
||||
{
|
||||
if (spawn != null)
|
||||
{
|
||||
machine = spawn.getLastSpawn();
|
||||
}
|
||||
}
|
||||
if (machine != null)
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_ATTACK, machine);
|
||||
machine.broadcastPacket(new SpecialCamera(machine, 1, -200, 15, 10000, 1000, 20000, 0, 0, 0, 0, 0));
|
||||
}
|
||||
else
|
||||
{
|
||||
startQuestTimer("2", 2000, npc, player);
|
||||
}
|
||||
startQuestTimer("3", 10000, npc, player);
|
||||
break;
|
||||
}
|
||||
case "2":
|
||||
{
|
||||
npc.broadcastSocialAction(3);
|
||||
break;
|
||||
}
|
||||
case "3":
|
||||
{
|
||||
npc.broadcastPacket(new SpecialCamera(npc, 1, -150, 10, 3000, 1000, 20000, 0, 0, 0, 0, 0));
|
||||
startQuestTimer("4", 2500, npc, player);
|
||||
break;
|
||||
}
|
||||
case "4":
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(96055, -110759, -3312, 0));
|
||||
startQuestTimer("5", 2000, npc, player);
|
||||
break;
|
||||
}
|
||||
case "5":
|
||||
{
|
||||
player.teleToLocation(PLAYER_TELEPORT);
|
||||
npc.teleToLocation(NPC_LOCATION);
|
||||
if (!_IsGolemSpawned)
|
||||
{
|
||||
L2Npc golem = addSpawn(CHAOS_GOLEM, 94640, -112496, -3336, 0, false, 0);
|
||||
_IsGolemSpawned = true;
|
||||
startQuestTimer("6", 1000, golem, player);
|
||||
player.sendPacket(new PlaySound(1, "Rm03_A", 0, 0, 0, 0, 0));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "6":
|
||||
{
|
||||
npc.broadcastPacket(new SpecialCamera(npc, 30, -200, 20, 6000, 700, 8000, 0, 0, 0, 0, 0));
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (npc.getId() == DR_CHAOS)
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(96323, -110914, -3328, 0));
|
||||
this.startQuestTimer("1", 3000, npc, player);
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new DrChaos();
|
||||
}
|
||||
}
|
||||
92
trunk/dist/game/data/scripts/ai/individual/DrillSergeant.java
vendored
Normal file
92
trunk/dist/game/data/scripts/ai/individual/DrillSergeant.java
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* Drill Sergeant AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class DrillSergeant extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int SERGANT = 33007; // Drill Sergant
|
||||
private static final int GUARD = 33018;
|
||||
// Misc
|
||||
//@formatter:off
|
||||
private final int[] SOCIAL_ACTIONS = {9, 10, 11, 1 };
|
||||
//@formatter:on
|
||||
|
||||
private DrillSergeant()
|
||||
{
|
||||
super(DrillSergeant.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(SERGANT);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("SOCIAL_SHOW"))
|
||||
{
|
||||
final int socialActionId = SOCIAL_ACTIONS[getRandom(SOCIAL_ACTIONS.length)];
|
||||
npc.broadcastSocialAction(socialActionId);
|
||||
|
||||
for (L2Character chars : npc.getKnownList().getKnownCharactersInRadius(500))
|
||||
{
|
||||
if (chars.isNpc() && (chars.getId() == GUARD))
|
||||
{
|
||||
final L2Npc guard = (L2Npc) chars;
|
||||
guard.getVariables().set("SOCIAL_ACTION_ID", socialActionId);
|
||||
startQuestTimer("SOCIAL_ACTION", getRandom(500, 1500), guard, null);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.equals("SOCIAL_ACTION"))
|
||||
{
|
||||
final int socialActionId = npc.getVariables().getInt("SOCIAL_ACTION_ID", 0);
|
||||
if (socialActionId > 0)
|
||||
{
|
||||
npc.broadcastSocialAction(socialActionId);
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
if (npc.getId() == SERGANT)
|
||||
{
|
||||
startQuestTimer("SOCIAL_SHOW", 10000, npc, null, true);
|
||||
}
|
||||
npc.setRandomAnimationEnabled(false);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new DrillSergeant();
|
||||
}
|
||||
}
|
||||
145
trunk/dist/game/data/scripts/ai/individual/Epidos.java
vendored
Normal file
145
trunk/dist/game/data/scripts/ai/individual/Epidos.java
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.util.MinionList;
|
||||
|
||||
/**
|
||||
* Manages minion's spawn, idle despawn and Teleportation Cube spawn.
|
||||
* @author GKR
|
||||
*/
|
||||
public final class Epidos extends AbstractNpcAI
|
||||
{
|
||||
private static final int[] EPIDOSES =
|
||||
{
|
||||
25609,
|
||||
25610,
|
||||
25611,
|
||||
25612
|
||||
};
|
||||
|
||||
private static final int[] MINIONS =
|
||||
{
|
||||
25605,
|
||||
25606,
|
||||
25607,
|
||||
25608
|
||||
};
|
||||
|
||||
private static final int[] MINIONS_COUNT =
|
||||
{
|
||||
3,
|
||||
6,
|
||||
11
|
||||
};
|
||||
|
||||
private final Map<Integer, Double> _lastHp = new ConcurrentHashMap<>();
|
||||
|
||||
private Epidos()
|
||||
{
|
||||
super(Epidos.class.getSimpleName(), "ai/individual");
|
||||
addKillId(EPIDOSES);
|
||||
addSpawnId(EPIDOSES);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equalsIgnoreCase("check_minions"))
|
||||
{
|
||||
if ((getRandom(1000) > 250) && _lastHp.containsKey(npc.getObjectId()))
|
||||
{
|
||||
int hpDecreasePercent = (int) (((_lastHp.get(npc.getObjectId()) - npc.getCurrentHp()) * 100) / npc.getMaxHp());
|
||||
int minionsCount = 0;
|
||||
int spawnedMinions = ((L2MonsterInstance) npc).getMinionList().countSpawnedMinions();
|
||||
|
||||
if ((hpDecreasePercent > 5) && (hpDecreasePercent <= 15) && (spawnedMinions <= 9))
|
||||
{
|
||||
minionsCount = MINIONS_COUNT[0];
|
||||
}
|
||||
else if ((((hpDecreasePercent > 1) && (hpDecreasePercent <= 5)) || ((hpDecreasePercent > 15) && (hpDecreasePercent <= 30))) && (spawnedMinions <= 6))
|
||||
{
|
||||
minionsCount = MINIONS_COUNT[1];
|
||||
}
|
||||
else if (spawnedMinions == 0)
|
||||
{
|
||||
minionsCount = MINIONS_COUNT[2];
|
||||
}
|
||||
|
||||
for (int i = 0; i < minionsCount; i++)
|
||||
{
|
||||
MinionList.spawnMinion((L2MonsterInstance) npc, MINIONS[Arrays.binarySearch(EPIDOSES, npc.getId())]);
|
||||
}
|
||||
|
||||
_lastHp.put(npc.getObjectId(), npc.getCurrentHp());
|
||||
}
|
||||
|
||||
startQuestTimer("check_minions", 10000, npc, null);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("check_idle"))
|
||||
{
|
||||
if (npc.getAI().getIntention() == CtrlIntention.AI_INTENTION_ACTIVE)
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
else
|
||||
{
|
||||
startQuestTimer("check_idle", 600000, npc, null);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc.isInsideRadius(-45474, 247450, -13994, 2000, true, false))
|
||||
{
|
||||
addSpawn(32376, -45482, 246277, -14184, 0, false, 0, false);
|
||||
}
|
||||
|
||||
_lastHp.remove(npc.getObjectId());
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onSpawn(L2Npc npc)
|
||||
{
|
||||
startQuestTimer("check_minions", 10000, npc, null);
|
||||
startQuestTimer("check_idle", 600000, npc, null);
|
||||
_lastHp.put(npc.getObjectId(), (double) npc.getMaxHp());
|
||||
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Epidos();
|
||||
}
|
||||
}
|
||||
79
trunk/dist/game/data/scripts/ai/individual/EvasGiftBox.java
vendored
Normal file
79
trunk/dist/game/data/scripts/ai/individual/EvasGiftBox.java
vendored
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.ItemHolder;
|
||||
|
||||
/**
|
||||
* Eva's Gift Box AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class EvasGiftBox extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int BOX = 32342; // Eva's Gift Box
|
||||
// Skill
|
||||
private static final int BUFF = 1073; // Kiss of Eva
|
||||
// Items
|
||||
private static final ItemHolder CORAL = new ItemHolder(9692, 1); // Red Coral
|
||||
private static final ItemHolder CRYSTAL = new ItemHolder(9693, 1); // Crystal Fragment
|
||||
|
||||
private EvasGiftBox()
|
||||
{
|
||||
super(EvasGiftBox.class.getSimpleName(), "ai/individual");
|
||||
addKillId(BOX);
|
||||
addSpawnId(BOX);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (killer.isAffectedBySkill(BUFF))
|
||||
{
|
||||
if (getRandomBoolean())
|
||||
{
|
||||
npc.dropItem(killer, CRYSTAL);
|
||||
}
|
||||
|
||||
if (getRandom(100) < 33)
|
||||
{
|
||||
npc.dropItem(killer, CORAL);
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.setIsNoRndWalk(true);
|
||||
((L2Attackable) npc).setOnKillDelay(0);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new EvasGiftBox();
|
||||
}
|
||||
}
|
||||
149
trunk/dist/game/data/scripts/ai/individual/FrightenedRagnaOrc.java
vendored
Normal file
149
trunk/dist/game/data/scripts/ai/individual/FrightenedRagnaOrc.java
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.itemcontainer.Inventory;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Frightened Ragna Orc AI.
|
||||
* @author Gladicek, malyelfik
|
||||
*/
|
||||
public final class FrightenedRagnaOrc extends AbstractNpcAI
|
||||
{
|
||||
// NPC ID
|
||||
private static final int MOB_ID = 18807;
|
||||
// Chances
|
||||
private static final int ADENA = 10000;
|
||||
private static final int CHANCE = 1000;
|
||||
private static final int ADENA2 = 1000000;
|
||||
private static final int CHANCE2 = 10;
|
||||
// Skill
|
||||
private static final SkillHolder SKILL = new SkillHolder(6234, 1);
|
||||
|
||||
private FrightenedRagnaOrc()
|
||||
{
|
||||
super(FrightenedRagnaOrc.class.getSimpleName(), "ai/individual");
|
||||
addAttackId(MOB_ID);
|
||||
addKillId(MOB_ID);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (npc.isScriptValue(0))
|
||||
{
|
||||
npc.setScriptValue(1);
|
||||
startQuestTimer("say", (getRandom(5) + 3) * 1000, npc, null, true);
|
||||
}
|
||||
else if ((npc.getCurrentHp() < (npc.getMaxHp() * 0.2)) && npc.isScriptValue(1))
|
||||
{
|
||||
startQuestTimer("reward", 10000, npc, attacker);
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.WAIT_WAIT_STOP_SAVE_ME_AND_I_LL_GIVE_YOU_10_000_000_ADENA);
|
||||
npc.setScriptValue(2);
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
final NpcStringId msg = getRandomBoolean() ? NpcStringId.UGH_A_CURSE_UPON_YOU : NpcStringId.I_REALLY_DIDN_T_WANT_TO_FIGHT;
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, msg);
|
||||
cancelQuestTimer("say", npc, null);
|
||||
cancelQuestTimer("reward", npc, player);
|
||||
return super.onKill(npc, player, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "say":
|
||||
{
|
||||
if (npc.isDead() || !npc.isScriptValue(1))
|
||||
{
|
||||
cancelQuestTimer("say", npc, null);
|
||||
return null;
|
||||
}
|
||||
final NpcStringId msg = getRandomBoolean() ? NpcStringId.I_DON_T_WANT_TO_FIGHT : NpcStringId.IS_THIS_REALLY_NECESSARY;
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, msg);
|
||||
break;
|
||||
}
|
||||
case "reward":
|
||||
{
|
||||
if (!npc.isDead() && npc.isScriptValue(2))
|
||||
{
|
||||
if (getRandom(100000) < CHANCE2)
|
||||
{
|
||||
final NpcStringId msg = getRandomBoolean() ? NpcStringId.TH_THANKS_I_COULD_HAVE_BECOME_GOOD_FRIENDS_WITH_YOU : NpcStringId.I_LL_GIVE_YOU_10_000_000_ADENA_LIKE_I_PROMISED_I_MIGHT_BE_AN_ORC_WHO_KEEPS_MY_PROMISES;
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, msg);
|
||||
npc.setScriptValue(3);
|
||||
npc.doCast(SKILL.getSkill());
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
npc.dropItem(player, Inventory.ADENA_ID, ADENA2);
|
||||
}
|
||||
}
|
||||
else if (getRandom(100000) < CHANCE)
|
||||
{
|
||||
final NpcStringId msg = getRandomBoolean() ? NpcStringId.TH_THANKS_I_COULD_HAVE_BECOME_GOOD_FRIENDS_WITH_YOU : NpcStringId.SORRY_BUT_THIS_IS_ALL_I_HAVE_GIVE_ME_A_BREAK;
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, msg);
|
||||
npc.setScriptValue(3);
|
||||
npc.doCast(SKILL.getSkill());
|
||||
for (int i = 0; i < 10; i++)
|
||||
{
|
||||
((L2Attackable) npc).dropItem(player, Inventory.ADENA_ID, ADENA);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
final NpcStringId msg = getRandomBoolean() ? NpcStringId.THANKS_BUT_THAT_THING_ABOUT_10_000_000_ADENA_WAS_A_LIE_SEE_YA : NpcStringId.YOU_RE_PRETTY_DUMB_TO_BELIEVE_ME;
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, msg);
|
||||
}
|
||||
startQuestTimer("despawn", 1000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "despawn":
|
||||
{
|
||||
npc.setRunning();
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location((npc.getX() + getRandom(-800, 800)), (npc.getY() + getRandom(-800, 800)), npc.getZ(), npc.getHeading()));
|
||||
npc.deleteMe();
|
||||
break;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new FrightenedRagnaOrc();
|
||||
}
|
||||
}
|
||||
64
trunk/dist/game/data/scripts/ai/individual/Gordon.java
vendored
Normal file
64
trunk/dist/game/data/scripts/ai/individual/Gordon.java
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
|
||||
/**
|
||||
* Gordon AI
|
||||
* @author TOFIZ, malyelfik
|
||||
*/
|
||||
public final class Gordon extends AbstractNpcAI
|
||||
{
|
||||
private static final int GORDON = 29095;
|
||||
|
||||
private Gordon()
|
||||
{
|
||||
super(Gordon.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(GORDON);
|
||||
addSeeCreatureId(GORDON);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
|
||||
{
|
||||
if (creature.isPlayer() && ((L2PcInstance) creature).isCursedWeaponEquipped())
|
||||
{
|
||||
addAttackPlayerDesire(npc, (L2PcInstance) creature);
|
||||
}
|
||||
return super.onSeeCreature(npc, creature, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
((L2Attackable) npc).setCanReturnToSpawnPoint(false);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Gordon();
|
||||
}
|
||||
}
|
||||
55
trunk/dist/game/data/scripts/ai/individual/GraveRobbers.java
vendored
Normal file
55
trunk/dist/game/data/scripts/ai/individual/GraveRobbers.java
vendored
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
|
||||
/**
|
||||
* Grove Robber's AI.<br>
|
||||
* <ul>
|
||||
* <li>Grove Robber Summoner</li>
|
||||
* <li>Grove Robber Megician</li>
|
||||
* </ul>
|
||||
* @author Zealar
|
||||
*/
|
||||
public final class GraveRobbers extends AbstractNpcAI
|
||||
{
|
||||
private static final int GRAVE_ROBBER_SUMMONER = 22678;
|
||||
private static final int GRAVE_ROBBER_MEGICIAN = 22679;
|
||||
|
||||
private GraveRobbers()
|
||||
{
|
||||
super(GraveRobbers.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(GRAVE_ROBBER_SUMMONER, GRAVE_ROBBER_MEGICIAN);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
spawnMinions(npc, "Privates" + getRandom(1, 2));
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new GraveRobbers();
|
||||
}
|
||||
}
|
||||
64
trunk/dist/game/data/scripts/ai/individual/Mahram.java
vendored
Normal file
64
trunk/dist/game/data/scripts/ai/individual/Mahram.java
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Mahram AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class Mahram extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int MAHRAM = 33271;
|
||||
|
||||
private Mahram()
|
||||
{
|
||||
super(Mahram.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(MAHRAM);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("SPAM_TEXT") && (npc != null))
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.ALCHEMY_IS_A_SCIENCE_AND_AN_ART);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
startQuestTimer("SPAM_TEXT", 10000, npc, null, true);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Mahram();
|
||||
}
|
||||
}
|
||||
357
trunk/dist/game/data/scripts/ai/individual/Orfen.java
vendored
Normal file
357
trunk/dist/game/data/scripts/ai/individual/Orfen.java
vendored
Normal file
@@ -0,0 +1,357 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javolution.util.FastList;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.instancemanager.GrandBossManager;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.L2Spawn;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.zone.type.L2BossZone;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
||||
|
||||
/**
|
||||
* Orfen's AI
|
||||
* @author Emperorc
|
||||
*/
|
||||
public final class Orfen extends AbstractNpcAI
|
||||
{
|
||||
private static final Location[] POS =
|
||||
{
|
||||
new Location(43728, 17220, -4342),
|
||||
new Location(55024, 17368, -5412),
|
||||
new Location(53504, 21248, -5486),
|
||||
new Location(53248, 24576, -5262)
|
||||
};
|
||||
|
||||
private static final NpcStringId[] TEXT =
|
||||
{
|
||||
NpcStringId.S1_STOP_KIDDING_YOURSELF_ABOUT_YOUR_OWN_POWERLESSNESS,
|
||||
NpcStringId.S1_I_LL_MAKE_YOU_FEEL_WHAT_TRUE_FEAR_IS,
|
||||
NpcStringId.YOU_RE_REALLY_STUPID_TO_HAVE_CHALLENGED_ME_S1_GET_READY,
|
||||
NpcStringId.S1_DO_YOU_THINK_THAT_S_GOING_TO_WORK
|
||||
};
|
||||
|
||||
private static final int ORFEN = 29014;
|
||||
// private static final int RAIKEL = 29015;
|
||||
private static final int RAIKEL_LEOS = 29016;
|
||||
// private static final int RIBA = 29017;
|
||||
private static final int RIBA_IREN = 29018;
|
||||
|
||||
private static boolean _IsTeleported;
|
||||
private static List<L2Attackable> _Minions = new FastList<>();
|
||||
private static L2BossZone ZONE;
|
||||
|
||||
private static final byte ALIVE = 0;
|
||||
private static final byte DEAD = 1;
|
||||
|
||||
private Orfen()
|
||||
{
|
||||
super(Orfen.class.getSimpleName(), "ai/individual");
|
||||
int[] mobs =
|
||||
{
|
||||
ORFEN,
|
||||
RAIKEL_LEOS,
|
||||
RIBA_IREN
|
||||
};
|
||||
registerMobs(mobs);
|
||||
_IsTeleported = false;
|
||||
ZONE = GrandBossManager.getInstance().getZone(POS[0]);
|
||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(ORFEN);
|
||||
int status = GrandBossManager.getInstance().getBossStatus(ORFEN);
|
||||
if (status == DEAD)
|
||||
{
|
||||
// load the unlock date and time for Orfen from DB
|
||||
long temp = info.getLong("respawn_time") - System.currentTimeMillis();
|
||||
// if Orfen is locked until a certain time, mark it so and start the unlock timer
|
||||
// the unlock time has not yet expired.
|
||||
if (temp > 0)
|
||||
{
|
||||
startQuestTimer("orfen_unlock", temp, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
// the time has already expired while the server was offline. Immediately spawn Orfen.
|
||||
int i = getRandom(10);
|
||||
Location loc;
|
||||
if (i < 4)
|
||||
{
|
||||
loc = POS[1];
|
||||
}
|
||||
else if (i < 7)
|
||||
{
|
||||
loc = POS[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
loc = POS[3];
|
||||
}
|
||||
L2GrandBossInstance orfen = (L2GrandBossInstance) addSpawn(ORFEN, loc, false, 0);
|
||||
GrandBossManager.getInstance().setBossStatus(ORFEN, ALIVE);
|
||||
spawnBoss(orfen);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int loc_x = info.getInt("loc_x");
|
||||
int loc_y = info.getInt("loc_y");
|
||||
int loc_z = info.getInt("loc_z");
|
||||
int heading = info.getInt("heading");
|
||||
int hp = info.getInt("currentHP");
|
||||
int mp = info.getInt("currentMP");
|
||||
L2GrandBossInstance orfen = (L2GrandBossInstance) addSpawn(ORFEN, loc_x, loc_y, loc_z, heading, false, 0);
|
||||
orfen.setCurrentHpMp(hp, mp);
|
||||
spawnBoss(orfen);
|
||||
}
|
||||
}
|
||||
|
||||
public void setSpawnPoint(L2Npc npc, int index)
|
||||
{
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null, null);
|
||||
L2Spawn spawn = npc.getSpawn();
|
||||
spawn.setLocation(POS[index]);
|
||||
npc.teleToLocation(POS[index], false);
|
||||
}
|
||||
|
||||
public void spawnBoss(L2GrandBossInstance npc)
|
||||
{
|
||||
GrandBossManager.getInstance().addBoss(npc);
|
||||
npc.broadcastPacket(new PlaySound(1, "BS01_A", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
|
||||
startQuestTimer("check_orfen_pos", 10000, npc, null, true);
|
||||
// Spawn minions
|
||||
int x = npc.getX();
|
||||
int y = npc.getY();
|
||||
L2Attackable mob;
|
||||
mob = (L2Attackable) addSpawn(RAIKEL_LEOS, x + 100, y + 100, npc.getZ(), 0, false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
_Minions.add(mob);
|
||||
mob = (L2Attackable) addSpawn(RAIKEL_LEOS, x + 100, y - 100, npc.getZ(), 0, false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
_Minions.add(mob);
|
||||
mob = (L2Attackable) addSpawn(RAIKEL_LEOS, x - 100, y + 100, npc.getZ(), 0, false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
_Minions.add(mob);
|
||||
mob = (L2Attackable) addSpawn(RAIKEL_LEOS, x - 100, y - 100, npc.getZ(), 0, false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
_Minions.add(mob);
|
||||
startQuestTimer("check_minion_loc", 10000, npc, null, true);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equalsIgnoreCase("orfen_unlock"))
|
||||
{
|
||||
int i = getRandom(10);
|
||||
Location loc;
|
||||
if (i < 4)
|
||||
{
|
||||
loc = POS[1];
|
||||
}
|
||||
else if (i < 7)
|
||||
{
|
||||
loc = POS[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
loc = POS[3];
|
||||
}
|
||||
L2GrandBossInstance orfen = (L2GrandBossInstance) addSpawn(ORFEN, loc, false, 0);
|
||||
GrandBossManager.getInstance().setBossStatus(ORFEN, ALIVE);
|
||||
spawnBoss(orfen);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("check_orfen_pos"))
|
||||
{
|
||||
if ((_IsTeleported && (npc.getCurrentHp() > (npc.getMaxHp() * 0.95))) || (!ZONE.isInsideZone(npc) && !_IsTeleported))
|
||||
{
|
||||
setSpawnPoint(npc, getRandom(3) + 1);
|
||||
_IsTeleported = false;
|
||||
}
|
||||
else if (_IsTeleported && !ZONE.isInsideZone(npc))
|
||||
{
|
||||
setSpawnPoint(npc, 0);
|
||||
}
|
||||
}
|
||||
else if (event.equalsIgnoreCase("check_minion_loc"))
|
||||
{
|
||||
for (int i = 0; i < _Minions.size(); i++)
|
||||
{
|
||||
L2Attackable mob = _Minions.get(i);
|
||||
if (!npc.isInsideRadius(mob, 3000, false, false))
|
||||
{
|
||||
mob.teleToLocation(npc.getLocation());
|
||||
((L2Attackable) npc).clearAggroList();
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.equalsIgnoreCase("despawn_minions"))
|
||||
{
|
||||
for (int i = 0; i < _Minions.size(); i++)
|
||||
{
|
||||
L2Attackable mob = _Minions.get(i);
|
||||
if (mob != null)
|
||||
{
|
||||
mob.decayMe();
|
||||
}
|
||||
}
|
||||
_Minions.clear();
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_minion"))
|
||||
{
|
||||
L2Attackable mob = (L2Attackable) addSpawn(RAIKEL_LEOS, npc.getX(), npc.getY(), npc.getZ(), 0, false, 0);
|
||||
mob.setIsRaidMinion(true);
|
||||
_Minions.add(mob);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSkillSee(L2Npc npc, L2PcInstance caster, Skill skill, L2Object[] targets, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == ORFEN)
|
||||
{
|
||||
L2Character originalCaster = isSummon ? caster.getSummon() : caster;
|
||||
if ((skill.getEffectPoint() > 0) && (getRandom(5) == 0) && npc.isInsideRadius(originalCaster, 1000, false, false))
|
||||
{
|
||||
NpcSay packet = new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npc.getId(), TEXT[getRandom(4)]);
|
||||
packet.addStringParameter(caster.getName().toString());
|
||||
npc.broadcastPacket(packet);
|
||||
originalCaster.teleToLocation(npc.getLocation());
|
||||
npc.setTarget(originalCaster);
|
||||
npc.doCast(SkillData.getInstance().getSkill(4064, 1));
|
||||
}
|
||||
}
|
||||
return super.onSkillSee(npc, caster, skill, targets, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFactionCall(L2Npc npc, L2Npc caller, L2PcInstance attacker, boolean isSummon)
|
||||
{
|
||||
if ((caller == null) || (npc == null) || npc.isCastingNow())
|
||||
{
|
||||
return super.onFactionCall(npc, caller, attacker, isSummon);
|
||||
}
|
||||
int npcId = npc.getId();
|
||||
int callerId = caller.getId();
|
||||
if ((npcId == RAIKEL_LEOS) && (getRandom(20) == 0))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(SkillData.getInstance().getSkill(4067, 4));
|
||||
}
|
||||
else if (npcId == RIBA_IREN)
|
||||
{
|
||||
int chance = 1;
|
||||
if (callerId == ORFEN)
|
||||
{
|
||||
chance = 9;
|
||||
}
|
||||
if ((callerId != RIBA_IREN) && (caller.getCurrentHp() < (caller.getMaxHp() / 2.0)) && (getRandom(10) < chance))
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE, null, null);
|
||||
npc.setTarget(caller);
|
||||
npc.doCast(SkillData.getInstance().getSkill(4516, 1));
|
||||
}
|
||||
}
|
||||
return super.onFactionCall(npc, caller, attacker, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
int npcId = npc.getId();
|
||||
if (npcId == ORFEN)
|
||||
{
|
||||
if (!_IsTeleported && ((npc.getCurrentHp() - damage) < (npc.getMaxHp() / 2)))
|
||||
{
|
||||
_IsTeleported = true;
|
||||
setSpawnPoint(npc, 0);
|
||||
}
|
||||
else if (npc.isInsideRadius(attacker, 1000, false, false) && !npc.isInsideRadius(attacker, 300, false, false) && (getRandom(10) == 0))
|
||||
{
|
||||
NpcSay packet = new NpcSay(npc.getObjectId(), Say2.NPC_ALL, npcId, TEXT[getRandom(3)]);
|
||||
packet.addStringParameter(attacker.getName().toString());
|
||||
npc.broadcastPacket(packet);
|
||||
attacker.teleToLocation(npc.getLocation());
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(SkillData.getInstance().getSkill(4064, 1));
|
||||
}
|
||||
}
|
||||
else if (npcId == RIBA_IREN)
|
||||
{
|
||||
if (!npc.isCastingNow() && ((npc.getCurrentHp() - damage) < (npc.getMaxHp() / 2.0)))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(SkillData.getInstance().getSkill(4516, 1));
|
||||
}
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc.getId() == ORFEN)
|
||||
{
|
||||
npc.broadcastPacket(new PlaySound(1, "BS02_D", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
|
||||
GrandBossManager.getInstance().setBossStatus(ORFEN, DEAD);
|
||||
// Calculate Min and Max respawn times randomly.
|
||||
long respawnTime = Config.ORFEN_SPAWN_INTERVAL + getRandom(-Config.ORFEN_SPAWN_RANDOM, Config.ORFEN_SPAWN_RANDOM);
|
||||
respawnTime *= 3600000;
|
||||
startQuestTimer("orfen_unlock", respawnTime, null, null);
|
||||
// also save the respawn time so that the info is maintained past reboots
|
||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(ORFEN);
|
||||
info.set("respawn_time", System.currentTimeMillis() + respawnTime);
|
||||
GrandBossManager.getInstance().setStatsSet(ORFEN, info);
|
||||
cancelQuestTimer("check_minion_loc", npc, null);
|
||||
cancelQuestTimer("check_orfen_pos", npc, null);
|
||||
startQuestTimer("despawn_minions", 20000, null, null);
|
||||
cancelQuestTimers("spawn_minion");
|
||||
}
|
||||
else if ((GrandBossManager.getInstance().getBossStatus(ORFEN) == ALIVE) && (npc.getId() == RAIKEL_LEOS))
|
||||
{
|
||||
_Minions.remove(npc);
|
||||
startQuestTimer("spawn_minion", 360000, npc, null);
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Orfen();
|
||||
}
|
||||
}
|
||||
378
trunk/dist/game/data/scripts/ai/individual/QueenAnt.java
vendored
Normal file
378
trunk/dist/game/data/scripts/ai/individual/QueenAnt.java
vendored
Normal file
@@ -0,0 +1,378 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import javolution.util.FastList;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.instancemanager.GrandBossManager;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.CommonSkill;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.zone.type.L2BossZone;
|
||||
import com.l2jserver.gameserver.network.serverpackets.MagicSkillUse;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
||||
|
||||
/**
|
||||
* Queen Ant's AI
|
||||
* @author Emperorc
|
||||
*/
|
||||
public final class QueenAnt extends AbstractNpcAI
|
||||
{
|
||||
private static final int QUEEN = 29001;
|
||||
private static final int LARVA = 29002;
|
||||
private static final int NURSE = 29003;
|
||||
private static final int GUARD = 29004;
|
||||
private static final int ROYAL = 29005;
|
||||
|
||||
private static final int[] MOBS =
|
||||
{
|
||||
QUEEN,
|
||||
LARVA,
|
||||
NURSE,
|
||||
GUARD,
|
||||
ROYAL
|
||||
};
|
||||
|
||||
private static final Location OUST_LOC_1 = new Location(-19480, 187344, -5600);
|
||||
private static final Location OUST_LOC_2 = new Location(-17928, 180912, -5520);
|
||||
private static final Location OUST_LOC_3 = new Location(-23808, 182368, -5600);
|
||||
|
||||
private static final int QUEEN_X = -21610;
|
||||
private static final int QUEEN_Y = 181594;
|
||||
private static final int QUEEN_Z = -5734;
|
||||
|
||||
// QUEEN Status Tracking :
|
||||
private static final byte ALIVE = 0; // Queen Ant is spawned.
|
||||
private static final byte DEAD = 1; // Queen Ant has been killed.
|
||||
|
||||
private static L2BossZone _zone;
|
||||
|
||||
private static SkillHolder HEAL1 = new SkillHolder(4020, 1);
|
||||
private static SkillHolder HEAL2 = new SkillHolder(4024, 1);
|
||||
|
||||
private L2MonsterInstance _queen = null;
|
||||
private L2MonsterInstance _larva = null;
|
||||
private final List<L2MonsterInstance> _nurses = new FastList<>(5);
|
||||
|
||||
private QueenAnt()
|
||||
{
|
||||
super(QueenAnt.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(MOBS);
|
||||
addKillId(MOBS);
|
||||
addAggroRangeEnterId(MOBS);
|
||||
addFactionCallId(NURSE);
|
||||
|
||||
_zone = GrandBossManager.getInstance().getZone(QUEEN_X, QUEEN_Y, QUEEN_Z);
|
||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(QUEEN);
|
||||
int status = GrandBossManager.getInstance().getBossStatus(QUEEN);
|
||||
if (status == DEAD)
|
||||
{
|
||||
// load the unlock date and time for queen ant from DB
|
||||
long temp = info.getLong("respawn_time") - System.currentTimeMillis();
|
||||
// if queen ant is locked until a certain time, mark it so and start the unlock timer
|
||||
// the unlock time has not yet expired.
|
||||
if (temp > 0)
|
||||
{
|
||||
startQuestTimer("queen_unlock", temp, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
// the time has already expired while the server was offline. Immediately spawn queen ant.
|
||||
L2GrandBossInstance queen = (L2GrandBossInstance) addSpawn(QUEEN, QUEEN_X, QUEEN_Y, QUEEN_Z, 0, false, 0);
|
||||
GrandBossManager.getInstance().setBossStatus(QUEEN, ALIVE);
|
||||
spawnBoss(queen);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
int loc_x = info.getInt("loc_x");
|
||||
int loc_y = info.getInt("loc_y");
|
||||
int loc_z = info.getInt("loc_z");
|
||||
int heading = info.getInt("heading");
|
||||
int hp = info.getInt("currentHP");
|
||||
int mp = info.getInt("currentMP");
|
||||
if (!_zone.isInsideZone(loc_x, loc_y, loc_z))
|
||||
{
|
||||
loc_x = QUEEN_X;
|
||||
loc_y = QUEEN_Y;
|
||||
loc_z = QUEEN_Z;
|
||||
}
|
||||
L2GrandBossInstance queen = (L2GrandBossInstance) addSpawn(QUEEN, loc_x, loc_y, loc_z, heading, false, 0);
|
||||
queen.setCurrentHpMp(hp, mp);
|
||||
spawnBoss(queen);
|
||||
}
|
||||
}
|
||||
|
||||
private void spawnBoss(L2GrandBossInstance npc)
|
||||
{
|
||||
GrandBossManager.getInstance().addBoss(npc);
|
||||
if (getRandom(100) < 33)
|
||||
{
|
||||
_zone.movePlayersTo(OUST_LOC_1);
|
||||
}
|
||||
else if (getRandom(100) < 50)
|
||||
{
|
||||
_zone.movePlayersTo(OUST_LOC_2);
|
||||
}
|
||||
else
|
||||
{
|
||||
_zone.movePlayersTo(OUST_LOC_3);
|
||||
}
|
||||
GrandBossManager.getInstance().addBoss(npc);
|
||||
startQuestTimer("action", 10000, npc, null, true);
|
||||
startQuestTimer("heal", 1000, null, null, true);
|
||||
npc.broadcastPacket(new PlaySound(1, "BS01_A", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
|
||||
_queen = npc;
|
||||
_larva = (L2MonsterInstance) addSpawn(LARVA, -21600, 179482, -5846, getRandom(360), false, 0);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equalsIgnoreCase("heal"))
|
||||
{
|
||||
boolean notCasting;
|
||||
final boolean larvaNeedHeal = (_larva != null) && (_larva.getCurrentHp() < _larva.getMaxHp());
|
||||
final boolean queenNeedHeal = (_queen != null) && (_queen.getCurrentHp() < _queen.getMaxHp());
|
||||
for (L2MonsterInstance nurse : _nurses)
|
||||
{
|
||||
if ((nurse == null) || nurse.isDead() || nurse.isCastingNow())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
notCasting = nurse.getAI().getIntention() != CtrlIntention.AI_INTENTION_CAST;
|
||||
if (larvaNeedHeal)
|
||||
{
|
||||
if ((nurse.getTarget() != _larva) || notCasting)
|
||||
{
|
||||
nurse.setTarget(_larva);
|
||||
nurse.useMagic(getRandomBoolean() ? HEAL1.getSkill() : HEAL2.getSkill());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (queenNeedHeal)
|
||||
{
|
||||
if (nurse.getLeader() == _larva)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if ((nurse.getTarget() != _queen) || notCasting)
|
||||
{
|
||||
nurse.setTarget(_queen);
|
||||
nurse.useMagic(HEAL1.getSkill());
|
||||
}
|
||||
continue;
|
||||
}
|
||||
// if nurse not casting - remove target
|
||||
if (notCasting && (nurse.getTarget() != null))
|
||||
{
|
||||
nurse.setTarget(null);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.equalsIgnoreCase("action") && (npc != null))
|
||||
{
|
||||
if (getRandom(3) == 0)
|
||||
{
|
||||
if (getRandom(2) == 0)
|
||||
{
|
||||
npc.broadcastSocialAction(3);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.broadcastSocialAction(4);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (event.equalsIgnoreCase("queen_unlock"))
|
||||
{
|
||||
L2GrandBossInstance queen = (L2GrandBossInstance) addSpawn(QUEEN, QUEEN_X, QUEEN_Y, QUEEN_Z, 0, false, 0);
|
||||
GrandBossManager.getInstance().setBossStatus(QUEEN, ALIVE);
|
||||
spawnBoss(queen);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
final L2MonsterInstance mob = (L2MonsterInstance) npc;
|
||||
switch (npc.getId())
|
||||
{
|
||||
case LARVA:
|
||||
mob.setIsImmobilized(true);
|
||||
mob.setIsMortal(false);
|
||||
mob.setIsRaidMinion(true);
|
||||
break;
|
||||
case NURSE:
|
||||
mob.disableCoreAI(true);
|
||||
mob.setIsRaidMinion(true);
|
||||
_nurses.add(mob);
|
||||
break;
|
||||
case ROYAL:
|
||||
case GUARD:
|
||||
mob.setIsRaidMinion(true);
|
||||
break;
|
||||
}
|
||||
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onFactionCall(L2Npc npc, L2Npc caller, L2PcInstance attacker, boolean isSummon)
|
||||
{
|
||||
if ((caller == null) || (npc == null))
|
||||
{
|
||||
return super.onFactionCall(npc, caller, attacker, isSummon);
|
||||
}
|
||||
|
||||
if (!npc.isCastingNow() && (npc.getAI().getIntention() != CtrlIntention.AI_INTENTION_CAST))
|
||||
{
|
||||
if (caller.getCurrentHp() < caller.getMaxHp())
|
||||
{
|
||||
npc.setTarget(caller);
|
||||
((L2Attackable) npc).useMagic(HEAL1.getSkill());
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
if ((npc == null) || (player.isGM() && player.isInvisible()))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final boolean isMage;
|
||||
final L2Playable character;
|
||||
if (isSummon)
|
||||
{
|
||||
isMage = false;
|
||||
character = player.getSummon();
|
||||
}
|
||||
else
|
||||
{
|
||||
isMage = player.isMageClass();
|
||||
character = player;
|
||||
}
|
||||
|
||||
if (character == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (!Config.RAID_DISABLE_CURSE && ((character.getLevel() - npc.getLevel()) > 8))
|
||||
{
|
||||
Skill curse = null;
|
||||
if (isMage)
|
||||
{
|
||||
if (!character.isMuted() && (getRandom(4) == 0))
|
||||
{
|
||||
curse = CommonSkill.RAID_CURSE.getSkill();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!character.isParalyzed() && (getRandom(4) == 0))
|
||||
{
|
||||
curse = CommonSkill.RAID_CURSE2.getSkill();
|
||||
}
|
||||
}
|
||||
|
||||
if (curse != null)
|
||||
{
|
||||
npc.broadcastPacket(new MagicSkillUse(npc, character, curse.getId(), curse.getLevel(), 300, 0));
|
||||
curse.applyEffects(npc, character);
|
||||
}
|
||||
|
||||
((L2Attackable) npc).stopHating(character); // for calling again
|
||||
return null;
|
||||
}
|
||||
|
||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
int npcId = npc.getId();
|
||||
if (npcId == QUEEN)
|
||||
{
|
||||
npc.broadcastPacket(new PlaySound(1, "BS02_D", 1, npc.getObjectId(), npc.getX(), npc.getY(), npc.getZ()));
|
||||
GrandBossManager.getInstance().setBossStatus(QUEEN, DEAD);
|
||||
// Calculate Min and Max respawn times randomly.
|
||||
long respawnTime = Config.QUEEN_ANT_SPAWN_INTERVAL + getRandom(-Config.QUEEN_ANT_SPAWN_RANDOM, Config.QUEEN_ANT_SPAWN_RANDOM);
|
||||
respawnTime *= 3600000;
|
||||
startQuestTimer("queen_unlock", respawnTime, null, null);
|
||||
cancelQuestTimer("action", npc, null);
|
||||
cancelQuestTimer("heal", null, null);
|
||||
// also save the respawn time so that the info is maintained past reboots
|
||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(QUEEN);
|
||||
info.set("respawn_time", System.currentTimeMillis() + respawnTime);
|
||||
GrandBossManager.getInstance().setStatsSet(QUEEN, info);
|
||||
_nurses.clear();
|
||||
_larva.deleteMe();
|
||||
_larva = null;
|
||||
_queen = null;
|
||||
}
|
||||
else if ((_queen != null) && !_queen.isAlikeDead())
|
||||
{
|
||||
if (npcId == ROYAL)
|
||||
{
|
||||
L2MonsterInstance mob = (L2MonsterInstance) npc;
|
||||
if (mob.getLeader() != null)
|
||||
{
|
||||
mob.getLeader().getMinionList().onMinionDie(mob, (280 + getRandom(40)) * 1000);
|
||||
}
|
||||
}
|
||||
else if (npcId == NURSE)
|
||||
{
|
||||
L2MonsterInstance mob = (L2MonsterInstance) npc;
|
||||
_nurses.remove(mob);
|
||||
if (mob.getLeader() != null)
|
||||
{
|
||||
mob.getLeader().getMinionList().onMinionDie(mob, 10000);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new QueenAnt();
|
||||
}
|
||||
}
|
||||
114
trunk/dist/game/data/scripts/ai/individual/QueenShyeed.java
vendored
Normal file
114
trunk/dist/game/data/scripts/ai/individual/QueenShyeed.java
vendored
Normal file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.zone.type.L2EffectZone;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Queen Shyeed AI
|
||||
* @author malyelfik
|
||||
*/
|
||||
public final class QueenShyeed extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int SHYEED = 25671;
|
||||
private static final Location SHYEED_LOC = new Location(79634, -55428, -6104, 0);
|
||||
|
||||
// Respawn
|
||||
private static final int RESPAWN = 86400000; // 24 h
|
||||
private static final int RANDOM_RESPAWN = 43200000; // 12 h
|
||||
|
||||
// Zones
|
||||
private static final L2EffectZone MOB_BUFF_ZONE = ZoneManager.getInstance().getZoneById(200103, L2EffectZone.class);
|
||||
private static final L2EffectZone MOB_BUFF_DISPLAY_ZONE = ZoneManager.getInstance().getZoneById(200104, L2EffectZone.class);
|
||||
private static final L2EffectZone PC_BUFF_ZONE = ZoneManager.getInstance().getZoneById(200105, L2EffectZone.class);
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "respawn":
|
||||
spawnShyeed();
|
||||
break;
|
||||
case "despawn":
|
||||
if (!npc.isDead())
|
||||
{
|
||||
npc.deleteMe();
|
||||
startRespawn();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.SHYEED_S_CRY_IS_STEADILY_DYING_DOWN);
|
||||
startRespawn();
|
||||
PC_BUFF_ZONE.setEnabled(true);
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
private QueenShyeed()
|
||||
{
|
||||
super(QueenShyeed.class.getSimpleName(), "ai/individual");
|
||||
addKillId(SHYEED);
|
||||
spawnShyeed();
|
||||
}
|
||||
|
||||
private void spawnShyeed()
|
||||
{
|
||||
final String respawn = loadGlobalQuestVar("Respawn");
|
||||
final long remain = (!respawn.isEmpty()) ? Long.parseLong(respawn) - System.currentTimeMillis() : 0;
|
||||
if (remain > 0)
|
||||
{
|
||||
startQuestTimer("respawn", remain, null, null);
|
||||
return;
|
||||
}
|
||||
final L2Npc npc = addSpawn(SHYEED, SHYEED_LOC, false, 0);
|
||||
startQuestTimer("despawn", 10800000, npc, null);
|
||||
PC_BUFF_ZONE.setEnabled(false);
|
||||
MOB_BUFF_ZONE.setEnabled(true);
|
||||
MOB_BUFF_DISPLAY_ZONE.setEnabled(true);
|
||||
}
|
||||
|
||||
private void startRespawn()
|
||||
{
|
||||
final int respawnTime = RESPAWN - getRandom(RANDOM_RESPAWN);
|
||||
saveGlobalQuestVar("Respawn", Long.toString(System.currentTimeMillis() + respawnTime));
|
||||
startQuestTimer("respawn", respawnTime, null, null);
|
||||
MOB_BUFF_ZONE.setEnabled(false);
|
||||
MOB_BUFF_DISPLAY_ZONE.setEnabled(false);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new QueenShyeed();
|
||||
}
|
||||
}
|
||||
51
trunk/dist/game/data/scripts/ai/individual/RagnaOrcCommander.java
vendored
Normal file
51
trunk/dist/game/data/scripts/ai/individual/RagnaOrcCommander.java
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
|
||||
/**
|
||||
* Ragna Orc Commander AI.
|
||||
* @author Zealar
|
||||
*/
|
||||
public final class RagnaOrcCommander extends AbstractNpcAI
|
||||
{
|
||||
private static final int RAGNA_ORC_COMMANDER = 22694;
|
||||
|
||||
private RagnaOrcCommander()
|
||||
{
|
||||
super(RagnaOrcCommander.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(RAGNA_ORC_COMMANDER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
spawnMinions(npc, "Privates1");
|
||||
spawnMinions(npc, getRandomBoolean() ? "Privates2" : "Privates3");
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new RagnaOrcCommander();
|
||||
}
|
||||
}
|
||||
50
trunk/dist/game/data/scripts/ai/individual/RagnaOrcHero.java
vendored
Normal file
50
trunk/dist/game/data/scripts/ai/individual/RagnaOrcHero.java
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
|
||||
/**
|
||||
* Ragna Orc Hero AI.
|
||||
* @author Zealar
|
||||
*/
|
||||
public final class RagnaOrcHero extends AbstractNpcAI
|
||||
{
|
||||
private static final int RAGNA_ORC_HERO = 22693;
|
||||
|
||||
private RagnaOrcHero()
|
||||
{
|
||||
super(RagnaOrcHero.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(RAGNA_ORC_HERO);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
spawnMinions(npc, getRandom(100) < 70 ? "Privates1" : "Privates2");
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new RagnaOrcHero();
|
||||
}
|
||||
}
|
||||
50
trunk/dist/game/data/scripts/ai/individual/RagnaOrcSeer.java
vendored
Normal file
50
trunk/dist/game/data/scripts/ai/individual/RagnaOrcSeer.java
vendored
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
|
||||
/**
|
||||
* Ragna Orc Seer AI.
|
||||
* @author Zealar
|
||||
*/
|
||||
public final class RagnaOrcSeer extends AbstractNpcAI
|
||||
{
|
||||
private static final int RAGNA_ORC_SEER = 22697;
|
||||
|
||||
private RagnaOrcSeer()
|
||||
{
|
||||
super(RagnaOrcSeer.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(RAGNA_ORC_SEER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
spawnMinions(npc, "Privates" + getRandom(1, 2));
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new RagnaOrcSeer();
|
||||
}
|
||||
}
|
||||
4
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-01.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-01.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Shilen's Stone Statue:<br>
|
||||
Wait.. It doesn't seem as though you are the one destined for the front lines in this battle. I was supposed to open a passage to Sailren's lair only to the leader of one party. If you wish to teleport, bring your party leader to me or return here as a party leader.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren 32109-01a.html">Prep for battle.</a>
|
||||
</body></html>
|
||||
8
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-01a.html
vendored
Normal file
8
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-01a.html
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
<html><body>Shilen's Stone Statue:<br>
|
||||
You know that in the past, Mother Shilen paid a great sacrifice to lock Sailren here.<br>
|
||||
Afterward, she created a stone likeness of herself and bestowed upon it the power to seal, making it a guardian of this place to ensure that Sailren remained imprisoned.<br>
|
||||
I am that stone statue of Shilen.<br>
|
||||
Mother Shilen also entrusted the power to seal to those who wield the sacred ax Gazkh.<br>
|
||||
I will only open the gate for those who have Gazkh and their friends. When the seal is at its weakest, however, I allow a warrior to enter in order to minimize the sacrifice.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren 32109-02a.html">Listen to the conditions to enter in detail.</a>
|
||||
</body></html>
|
||||
4
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-02.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-02.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Shilen's Stone Statue:<br>
|
||||
You have the heart to fight Sailren, of that there can be no doubt. But if you do not have Gazkh given to you by Shilen, Sailren will certainly kill you. If you want to teleport within, complete my quest and obtain Gazkh.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren 32109-01a.html">Prep for battle.</a>
|
||||
</body></html>
|
||||
5
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-02a.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-02a.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Shilen's Stone Statue:<br>
|
||||
Only a party whose leader weilds Gazkh can enter Sailren's Stronghold and battle the creature.<br>
|
||||
Be aware that any party member who is far away at the time of entry cannot enter the Stronghold. Nor can another party enter until the first party has exited.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren 32109-03a.html">Learn more about Sailren's power and how to fight it.</a>
|
||||
</body></html>
|
||||
5
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-03.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-03.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Shilen's Stone Statue:<br>
|
||||
Shilen's protection is not with you -- go away! You are not qualified to fight against Sailren...<br>
|
||||
If you want to enter Sailren's nest, then you should find a party leader who can fight against Sailren and join his party. Or you can complete my quest to become a party leader, form your own party, and then return here.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren 32109-01a.html">Listen to the entry requirements and battle method.</a>
|
||||
</body></html>
|
||||
5
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-03a.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-03a.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Shilen's Stone Statue:<br>
|
||||
There are not many of them, but Sailren is protected by its dinosaur followers. Combined with my enchantment and the power of the other statues, we are restraining Sailren and its followers from escaping. But as they begin to break free of our control, their power and magic also begins to extend beyond the Lost Nest, affecting even the Primeval Plains!<br>
|
||||
If the powers of the Stone Statues are completely broken, Sailren and its followers will escape and this island and everything on it will perish.<br>
|
||||
Alas, Shilen is not here to protect us! In order to re-seal that horrifying dinosaur, you must defeat its followers first, and then work as a team to defeat Sailren.
|
||||
</body></html>
|
||||
5
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-04.html
vendored
Normal file
5
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-04.html
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<html><body>Shilen's Stone Statue:<br>
|
||||
Currently the magic power of Sailren and its followers is very strong. I do not think you can win solely with your own power, especially given how weak the seal stones have become.<br>
|
||||
My counsel is that you first recover the power to seal and wait 'til Sailren's strength lessens a bit. Then you will have your best chance of entering the nest and defeating this ancient evil.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren 32109-01a.html">Prep for battle.</a>
|
||||
</body></html>
|
||||
4
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-05.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/individual/Sailren/32109-05.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Shilen's Stone Statue:<br>
|
||||
There is another brave party fighting against Sailren right now, so I cannot teleport you into the nest. When they return, I will teleport you.<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren 32109-01a.html">Prep for battle.</a>
|
||||
</body></html>
|
||||
7
trunk/dist/game/data/scripts/ai/individual/Sailren/32109.html
vendored
Normal file
7
trunk/dist/game/data/scripts/ai/individual/Sailren/32109.html
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<html><body>Stone Statue of Shilen:<br>
|
||||
(The statue is worn in places by wind and rain -- proof that it has stood guard here a long, long time. Despite its weatherbeaten appearance, it feels somehow dignified and majestic. Standing before it, you sense a presence.)<br>
|
||||
You, outsider... Why have you come here to this statue? For I am Mother Shilen's avatar and the last guard of Sailren!<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren 32109-01.html">Prep for battle.</a><br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Sailren enter">"I wish to participate in clearing out Sailren and its followers."</a><br>
|
||||
<a action="bypass -h npc_%objectId%_Quest">Quest.</a>
|
||||
</body></html>
|
||||
330
trunk/dist/game/data/scripts/ai/individual/Sailren/Sailren.java
vendored
Normal file
330
trunk/dist/game/data/scripts/ai/individual/Sailren/Sailren.java
vendored
Normal file
@@ -0,0 +1,330 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual.Sailren;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.instancemanager.GlobalVariablesManager;
|
||||
import com.l2jserver.gameserver.instancemanager.ZoneManager;
|
||||
import com.l2jserver.gameserver.model.TeleportWhereType;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2RaidBossInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.zone.type.L2NoRestartZone;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SpecialCamera;
|
||||
|
||||
/**
|
||||
* Sailren AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class Sailren extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int STATUE = 32109; // Shilen's Stone Statue
|
||||
private static final int MOVIE_NPC = 32110; // Invisible NPC for movie
|
||||
private static final int SAILREN = 29065; // Sailren
|
||||
private static final int VELOCIRAPTOR = 22218; // Velociraptor
|
||||
private static final int PTEROSAUR = 22199; // Pterosaur
|
||||
private static final int TREX = 22217; // Tyrannosaurus
|
||||
private static final int CUBIC = 32107; // Teleportation Cubic
|
||||
// Item
|
||||
private static final int GAZKH = 8784; // Gazkh
|
||||
// Skill
|
||||
private static final SkillHolder ANIMATION = new SkillHolder(5090, 1);
|
||||
// Zone
|
||||
private static final L2NoRestartZone zone = ZoneManager.getInstance().getZoneById(70049, L2NoRestartZone.class);
|
||||
// Misc
|
||||
private static final int RESPAWN = 1; // Respawn time (in hours)
|
||||
private static final int MAX_TIME = 3200; // Max time for Sailren fight (in minutes)
|
||||
private static Status STATUS = Status.ALIVE;
|
||||
private static int _killCount = 0;
|
||||
private static long _lastAttack = 0;
|
||||
|
||||
private static enum Status
|
||||
{
|
||||
ALIVE,
|
||||
IN_FIGHT,
|
||||
DEAD
|
||||
}
|
||||
|
||||
private Sailren()
|
||||
{
|
||||
super(Sailren.class.getSimpleName(), "ai/individual");
|
||||
addStartNpc(STATUE, CUBIC);
|
||||
addTalkId(STATUE, CUBIC);
|
||||
addFirstTalkId(STATUE);
|
||||
addKillId(VELOCIRAPTOR, PTEROSAUR, TREX, SAILREN);
|
||||
addAttackId(VELOCIRAPTOR, PTEROSAUR, TREX, SAILREN);
|
||||
|
||||
final long remain = GlobalVariablesManager.getInstance().getLong("SailrenRespawn", 0) - System.currentTimeMillis();
|
||||
if (remain > 0)
|
||||
{
|
||||
STATUS = Status.DEAD;
|
||||
startQuestTimer("CLEAR_STATUS", remain, null, null);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "32109-01.html":
|
||||
case "32109-01a.html":
|
||||
case "32109-02a.html":
|
||||
case "32109-03a.html":
|
||||
{
|
||||
return event;
|
||||
}
|
||||
case "enter":
|
||||
{
|
||||
String htmltext = null;
|
||||
if (!player.isInParty())
|
||||
{
|
||||
htmltext = "32109-01.html";
|
||||
}
|
||||
else if (STATUS == Status.DEAD)
|
||||
{
|
||||
htmltext = "32109-04.html";
|
||||
}
|
||||
else if (STATUS == Status.IN_FIGHT)
|
||||
{
|
||||
htmltext = "32109-05.html";
|
||||
}
|
||||
else if (!player.getParty().isLeader(player))
|
||||
{
|
||||
htmltext = "32109-03.html";
|
||||
}
|
||||
else if (!hasQuestItems(player, GAZKH))
|
||||
{
|
||||
htmltext = "32109-02.html";
|
||||
}
|
||||
else
|
||||
{
|
||||
takeItems(player, GAZKH, 1);
|
||||
STATUS = Status.IN_FIGHT;
|
||||
_lastAttack = System.currentTimeMillis();
|
||||
for (L2PcInstance member : player.getParty().getMembers())
|
||||
{
|
||||
if (member.isInsideRadius(npc, 1000, true, false))
|
||||
{
|
||||
member.teleToLocation(27549, -6638, -2008);
|
||||
}
|
||||
}
|
||||
startQuestTimer("SPAWN_VELOCIRAPTOR", 60000, null, null);
|
||||
startQuestTimer("TIME_OUT", MAX_TIME * 1000, null, null);
|
||||
startQuestTimer("CHECK_ATTACK", 120000, null, null);
|
||||
}
|
||||
return htmltext;
|
||||
}
|
||||
case "teleportOut":
|
||||
{
|
||||
player.teleToLocation(TeleportWhereType.TOWN);
|
||||
break;
|
||||
}
|
||||
case "SPAWN_VELOCIRAPTOR":
|
||||
{
|
||||
for (int i = 0; i < 3; i++)
|
||||
{
|
||||
addSpawn(VELOCIRAPTOR, 27313 + getRandom(150), -6766 + getRandom(150), -1975, 0, false, 0);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "SPAWN_SAILREN":
|
||||
{
|
||||
final L2RaidBossInstance sailren = (L2RaidBossInstance) addSpawn(SAILREN, 27549, -6638, -2008, 0, false, 0);
|
||||
final L2Npc movieNpc = addSpawn(MOVIE_NPC, sailren.getX(), sailren.getY(), sailren.getZ() + 30, 0, false, 26000);
|
||||
sailren.setIsInvul(true);
|
||||
sailren.setIsImmobilized(true);
|
||||
zone.broadcastPacket(new SpecialCamera(movieNpc, 60, 110, 30, 4000, 1500, 20000, 0, 65, 1, 0, 0));
|
||||
|
||||
startQuestTimer("ATTACK", 24600, sailren, null);
|
||||
startQuestTimer("ANIMATION", 2000, movieNpc, null);
|
||||
startQuestTimer("CAMERA_1", 4100, movieNpc, null);
|
||||
break;
|
||||
}
|
||||
case "ANIMATION":
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(ANIMATION.getSkill());
|
||||
startQuestTimer("ANIMATION", 2000, npc, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "CAMERA_1":
|
||||
{
|
||||
zone.broadcastPacket(new SpecialCamera(npc, 100, 180, 30, 3000, 1500, 20000, 0, 50, 1, 0, 0));
|
||||
startQuestTimer("CAMERA_2", 3000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "CAMERA_2":
|
||||
{
|
||||
zone.broadcastPacket(new SpecialCamera(npc, 150, 270, 25, 3000, 1500, 20000, 0, 30, 1, 0, 0));
|
||||
startQuestTimer("CAMERA_3", 3000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "CAMERA_3":
|
||||
{
|
||||
zone.broadcastPacket(new SpecialCamera(npc, 160, 360, 20, 3000, 1500, 20000, 10, 15, 1, 0, 0));
|
||||
startQuestTimer("CAMERA_4", 3000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "CAMERA_4":
|
||||
{
|
||||
zone.broadcastPacket(new SpecialCamera(npc, 160, 450, 10, 3000, 1500, 20000, 0, 10, 1, 0, 0));
|
||||
startQuestTimer("CAMERA_5", 3000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "CAMERA_5":
|
||||
{
|
||||
zone.broadcastPacket(new SpecialCamera(npc, 160, 560, 0, 3000, 1500, 20000, 0, 10, 1, 0, 0));
|
||||
startQuestTimer("CAMERA_6", 7000, npc, null);
|
||||
break;
|
||||
}
|
||||
case "CAMERA_6":
|
||||
{
|
||||
zone.broadcastPacket(new SpecialCamera(npc, 70, 560, 0, 500, 1500, 7000, -15, 20, 1, 0, 0));
|
||||
break;
|
||||
}
|
||||
case "ATTACK":
|
||||
{
|
||||
npc.setIsInvul(false);
|
||||
npc.setIsImmobilized(false);
|
||||
break;
|
||||
}
|
||||
case "CLEAR_STATUS":
|
||||
{
|
||||
STATUS = Status.ALIVE;
|
||||
break;
|
||||
}
|
||||
case "TIME_OUT":
|
||||
{
|
||||
if (STATUS == Status.IN_FIGHT)
|
||||
{
|
||||
STATUS = Status.ALIVE;
|
||||
}
|
||||
for (L2Character charInside : zone.getCharactersInside())
|
||||
{
|
||||
if (charInside != null)
|
||||
{
|
||||
if (charInside.isPlayer())
|
||||
{
|
||||
charInside.teleToLocation(TeleportWhereType.TOWN);
|
||||
}
|
||||
else if (charInside.isNpc())
|
||||
{
|
||||
charInside.deleteMe();
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case "CHECK_ATTACK":
|
||||
{
|
||||
if (!zone.getPlayersInside().isEmpty() && ((_lastAttack + 600000) < System.currentTimeMillis()))
|
||||
{
|
||||
cancelQuestTimer("TIME_OUT", null, null);
|
||||
notifyEvent("TIME_OUT", null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
startQuestTimer("CHECK_ATTACK", 120000, null, null);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (zone.isCharacterInZone(attacker))
|
||||
{
|
||||
_lastAttack = System.currentTimeMillis();
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (zone.isCharacterInZone(killer))
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case SAILREN:
|
||||
{
|
||||
STATUS = Status.DEAD;
|
||||
addSpawn(CUBIC, 27644, -6638, -2008, 0, false, 300000);
|
||||
final long respawnTime = RESPAWN * 3600000;
|
||||
GlobalVariablesManager.getInstance().set("SailrenRespawn", System.currentTimeMillis() + respawnTime);
|
||||
cancelQuestTimer("CHECK_ATTACK", null, null);
|
||||
cancelQuestTimer("TIME_OUT", null, null);
|
||||
startQuestTimer("CLEAR_STATUS", respawnTime, null, null);
|
||||
startQuestTimer("TIME_OUT", 300000, null, null);
|
||||
break;
|
||||
}
|
||||
case VELOCIRAPTOR:
|
||||
{
|
||||
_killCount++;
|
||||
if (_killCount == 3)
|
||||
{
|
||||
final L2Npc pterosaur = addSpawn(PTEROSAUR, 27313, -6766, -1975, 0, false, 0);
|
||||
addAttackPlayerDesire(pterosaur, killer);
|
||||
_killCount = 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case PTEROSAUR:
|
||||
{
|
||||
final L2Npc trex = addSpawn(TREX, 27313, -6766, -1975, 0, false, 0);
|
||||
addAttackPlayerDesire(trex, killer);
|
||||
break;
|
||||
}
|
||||
case TREX:
|
||||
{
|
||||
startQuestTimer("SPAWN_SAILREN", 180000, null, null);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean unload(boolean removeFromList)
|
||||
{
|
||||
if (STATUS == Status.IN_FIGHT)
|
||||
{
|
||||
_log.info(getClass().getSimpleName() + ": Script is being unloaded while Sailren is active, clearing zone.");
|
||||
notifyEvent("TIME_OUT", null, null);
|
||||
}
|
||||
return super.unload(removeFromList);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Sailren();
|
||||
}
|
||||
}
|
||||
64
trunk/dist/game/data/scripts/ai/individual/Shannon.java
vendored
Normal file
64
trunk/dist/game/data/scripts/ai/individual/Shannon.java
vendored
Normal file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Shannon AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class Shannon extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int SHANNON = 32974;
|
||||
|
||||
private Shannon()
|
||||
{
|
||||
super(Shannon.class.getSimpleName(), "ai/individual");
|
||||
addSpawnId(SHANNON);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("SPAM_TEXT") && (npc != null))
|
||||
{
|
||||
broadcastNpcSay(npc, Say2.NPC_ALL, NpcStringId.LOOK_AT_ALL_THE_NEWBIES_HA_HA_HA);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
startQuestTimer("SPAM_TEXT", 12000, npc, null, true);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Shannon();
|
||||
}
|
||||
}
|
||||
178
trunk/dist/game/data/scripts/ai/individual/SinEater.java
vendored
Normal file
178
trunk/dist/game/data/scripts/ai/individual/SinEater.java
vendored
Normal file
@@ -0,0 +1,178 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Summon;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.events.EventType;
|
||||
import com.l2jserver.gameserver.model.events.ListenerRegisterType;
|
||||
import com.l2jserver.gameserver.model.events.annotations.Id;
|
||||
import com.l2jserver.gameserver.model.events.annotations.RegisterEvent;
|
||||
import com.l2jserver.gameserver.model.events.annotations.RegisterType;
|
||||
import com.l2jserver.gameserver.model.events.impl.character.OnCreatureAttacked;
|
||||
import com.l2jserver.gameserver.model.events.impl.character.OnCreatureKill;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
||||
|
||||
/**
|
||||
* Sin Eater AI.
|
||||
* @author St3eT.
|
||||
*/
|
||||
public final class SinEater extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int SIN_EATER = 12564;
|
||||
|
||||
private SinEater()
|
||||
{
|
||||
super(SinEater.class.getSimpleName(), "ai/individual");
|
||||
addSummonSpawnId(SIN_EATER);
|
||||
addSummonTalkId(SIN_EATER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("TALK") && (player != null) && (player.getSummon() != null))
|
||||
{
|
||||
if (getRandom(100) < 30)
|
||||
{
|
||||
final int random = getRandom(100);
|
||||
final L2Summon summon = player.getSummon();
|
||||
|
||||
if (random < 20)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.YAWWWWN_IT_S_SO_BORING_HERE_WE_SHOULD_GO_AND_FIND_SOME_ACTION);
|
||||
}
|
||||
else if (random < 40)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.HEY_IF_YOU_CONTINUE_TO_WASTE_TIME_YOU_WILL_NEVER_FINISH_YOUR_PENANCE);
|
||||
}
|
||||
else if (random < 60)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.I_KNOW_YOU_DON_T_LIKE_ME_THE_FEELING_IS_MUTUAL);
|
||||
}
|
||||
else if (random < 80)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.I_NEED_A_DRINK);
|
||||
}
|
||||
else
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.OH_THIS_IS_DRAGGING_ON_TOO_LONG_AT_THIS_RATE_I_WON_T_MAKE_IT_HOME_BEFORE_THE_SEVEN_SEALS_ARE_BROKEN);
|
||||
}
|
||||
}
|
||||
startQuestTimer("TALK", 60000, null, player);
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@RegisterEvent(EventType.ON_CREATURE_KILL)
|
||||
@RegisterType(ListenerRegisterType.NPC)
|
||||
@Id(SIN_EATER)
|
||||
public void onCreatureKill(OnCreatureKill event)
|
||||
{
|
||||
final int random = getRandom(100);
|
||||
final L2Summon summon = (L2Summon) event.getTarget();
|
||||
|
||||
if (random < 30)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.OH_THIS_IS_JUST_GREAT_WHAT_ARE_YOU_GOING_TO_DO_NOW);
|
||||
}
|
||||
else if (random < 70)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.YOU_INCONSIDERATE_MORON_CAN_T_YOU_EVEN_TAKE_CARE_OF_LITTLE_OLD_ME);
|
||||
}
|
||||
else
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.OH_NO_THE_MAN_WHO_EATS_ONE_S_SINS_HAS_DIED_PENITENCE_IS_FURTHER_AWAY);
|
||||
}
|
||||
}
|
||||
|
||||
@RegisterEvent(EventType.ON_CREATURE_ATTACKED)
|
||||
@RegisterType(ListenerRegisterType.NPC)
|
||||
@Id(SIN_EATER)
|
||||
public void onCreatureAttacked(OnCreatureAttacked event)
|
||||
{
|
||||
if (getRandom(100) < 30)
|
||||
{
|
||||
final int random = getRandom(100);
|
||||
final L2Summon summon = (L2Summon) event.getTarget();
|
||||
|
||||
if (random < 35)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.OH_THAT_SMARTS);
|
||||
}
|
||||
else if (random < 70)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.HEY_MASTER_PAY_ATTENTION_I_M_DYING_OVER_HERE);
|
||||
}
|
||||
else
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.WHAT_HAVE_I_DONE_TO_DESERVE_THIS);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSummonSpawn(L2Summon summon)
|
||||
{
|
||||
broadcastSummonSay(summon, getRandomBoolean() ? NpcStringId.HEY_IT_SEEMS_LIKE_YOU_NEED_MY_HELP_DOESN_T_IT : NpcStringId.ALMOST_GOT_IT_OUCH_STOP_DAMN_THESE_BLOODY_MANACLES);
|
||||
startQuestTimer("TALK", 60000, null, summon.getOwner());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onSummonTalk(L2Summon summon)
|
||||
{
|
||||
if (getRandom(100) < 10)
|
||||
{
|
||||
final int random = getRandom(100);
|
||||
|
||||
if (random < 25)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.USING_A_SPECIAL_SKILL_HERE_COULD_TRIGGER_A_BLOODBATH);
|
||||
}
|
||||
else if (random < 50)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.HEY_WHAT_DO_YOU_EXPECT_OF_ME);
|
||||
}
|
||||
else if (random < 75)
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.UGGGGGH_PUSH_IT_S_NOT_COMING_OUT);
|
||||
}
|
||||
else
|
||||
{
|
||||
broadcastSummonSay(summon, NpcStringId.AH_I_MISSED_THE_MARK);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void broadcastSummonSay(L2Summon summon, NpcStringId npcstringId)
|
||||
{
|
||||
summon.broadcastPacket(new NpcSay(summon.getObjectId(), Say2.NPC_ALL, summon.getId(), npcstringId));
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SinEater();
|
||||
}
|
||||
}
|
||||
95
trunk/dist/game/data/scripts/ai/individual/SinWardens.java
vendored
Normal file
95
trunk/dist/game/data/scripts/ai/individual/SinWardens.java
vendored
Normal file
@@ -0,0 +1,95 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.Map;
|
||||
|
||||
import javolution.util.FastMap;
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
||||
|
||||
/**
|
||||
* Manages Sin Wardens disappearing and chat.
|
||||
* @author GKR
|
||||
*/
|
||||
public final class SinWardens extends AbstractNpcAI
|
||||
{
|
||||
private static final int[] SIN_WARDEN_MINIONS =
|
||||
{
|
||||
22424,
|
||||
22425,
|
||||
22426,
|
||||
22427,
|
||||
22428,
|
||||
22429,
|
||||
22430,
|
||||
22432,
|
||||
22433,
|
||||
22434,
|
||||
22435,
|
||||
22436,
|
||||
22437,
|
||||
22438
|
||||
};
|
||||
|
||||
private final Map<Integer, Integer> killedMinionsCount = new FastMap<>();
|
||||
|
||||
private SinWardens()
|
||||
{
|
||||
super(SinWardens.class.getSimpleName(), "ai/individual");
|
||||
addKillId(SIN_WARDEN_MINIONS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
if (npc.isMinion())
|
||||
{
|
||||
final L2MonsterInstance master = ((L2MonsterInstance) npc).getLeader();
|
||||
if ((master != null) && !master.isDead())
|
||||
{
|
||||
int killedCount = killedMinionsCount.containsKey(master.getObjectId()) ? killedMinionsCount.get(master.getObjectId()) : 0;
|
||||
killedCount++;
|
||||
|
||||
if ((killedCount) == 5)
|
||||
{
|
||||
master.broadcastPacket(new NpcSay(master.getObjectId(), Say2.NPC_ALL, master.getId(), NpcStringId.WE_MIGHT_NEED_NEW_SLAVES_I_LL_BE_BACK_SOON_SO_WAIT));
|
||||
master.doDie(killer);
|
||||
killedMinionsCount.remove(master.getObjectId());
|
||||
}
|
||||
else
|
||||
{
|
||||
killedMinionsCount.put(master.getObjectId(), killedCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new SinWardens();
|
||||
}
|
||||
}
|
||||
92
trunk/dist/game/data/scripts/ai/individual/TrainningSoldier.java
vendored
Normal file
92
trunk/dist/game/data/scripts/ai/individual/TrainningSoldier.java
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.model.L2Object;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2QuestGuardInstance;
|
||||
|
||||
/**
|
||||
* Trainning Soldier AI.
|
||||
* @author St3eT
|
||||
*/
|
||||
public final class TrainningSoldier extends AbstractNpcAI
|
||||
{
|
||||
// NPCs
|
||||
private static final int SOLDIER = 33201; // Trainning Soldier
|
||||
private static final int DUMMY = 33023; // Trainning Dummy
|
||||
|
||||
private TrainningSoldier()
|
||||
{
|
||||
super(TrainningSoldier.class.getSimpleName(), "ai/individual");
|
||||
addSeeCreatureId(SOLDIER);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (event.equals("START_ATTACK") && (npc instanceof L2QuestGuardInstance))
|
||||
{
|
||||
final L2QuestGuardInstance soldier = (L2QuestGuardInstance) npc;
|
||||
|
||||
//@formatter:off
|
||||
final L2Npc dummy = (L2Npc) soldier.getKnownList().getKnownCharactersInRadius(150)
|
||||
.stream()
|
||||
.filter(L2Object::isNpc)
|
||||
.filter(obj -> (obj.getId() == DUMMY))
|
||||
.findFirst()
|
||||
.orElse(null);
|
||||
//@formatter:on
|
||||
|
||||
if (dummy != null)
|
||||
{
|
||||
soldier.reduceCurrentHp(1, dummy, null); // TODO: Find better way for attack
|
||||
dummy.reduceCurrentHp(1, soldier, null);
|
||||
soldier.setCanStopAttackByTime(false);
|
||||
soldier.setCanReturnToSpawnPoint(false);
|
||||
soldier.setIsInvul(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
startQuestTimer("START_ATTACK", 250, npc, null);
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSeeCreature(L2Npc npc, L2Character creature, boolean isSummon)
|
||||
{
|
||||
if (creature.isPlayer() && (npc.getAI().getIntention() != CtrlIntention.AI_INTENTION_ATTACK))
|
||||
{
|
||||
startQuestTimer("START_ATTACK", 250, npc, null);
|
||||
}
|
||||
return super.onSeeCreature(npc, creature, isSummon);
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new TrainningSoldier();
|
||||
}
|
||||
}
|
||||
571
trunk/dist/game/data/scripts/ai/individual/Valakas.java
vendored
Normal file
571
trunk/dist/game/data/scripts/ai/individual/Valakas.java
vendored
Normal file
@@ -0,0 +1,571 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.Config;
|
||||
import com.l2jserver.gameserver.GeoData;
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.datatables.SkillData;
|
||||
import com.l2jserver.gameserver.enums.MountType;
|
||||
import com.l2jserver.gameserver.instancemanager.GrandBossManager;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.StatsSet;
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.L2Playable;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2GrandBossInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.BuffInfo;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.zone.type.L2BossZone;
|
||||
import com.l2jserver.gameserver.network.serverpackets.PlaySound;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SpecialCamera;
|
||||
import com.l2jserver.gameserver.util.Util;
|
||||
|
||||
/**
|
||||
* Valakas' AI.
|
||||
* @author Tryskell
|
||||
*/
|
||||
public final class Valakas extends AbstractNpcAI
|
||||
{
|
||||
// NPC
|
||||
private static final int VALAKAS = 29028;
|
||||
// Skills
|
||||
private static final SkillHolder VALAKAS_LAVA_SKIN = new SkillHolder(4680, 1);
|
||||
private static final int VALAKAS_REGENERATION = 4691;
|
||||
|
||||
private static final SkillHolder[] VALAKAS_REGULAR_SKILLS =
|
||||
{
|
||||
new SkillHolder(4681, 1), // Valakas Trample
|
||||
new SkillHolder(4682, 1), // Valakas Trample
|
||||
new SkillHolder(4683, 1), // Valakas Dragon Breath
|
||||
new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
|
||||
};
|
||||
|
||||
private static final SkillHolder[] VALAKAS_LOWHP_SKILLS =
|
||||
{
|
||||
new SkillHolder(4681, 1), // Valakas Trample
|
||||
new SkillHolder(4682, 1), // Valakas Trample
|
||||
new SkillHolder(4683, 1), // Valakas Dragon Breath
|
||||
new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
|
||||
new SkillHolder(4690, 1), // Valakas Meteor Storm
|
||||
};
|
||||
|
||||
private static final SkillHolder[] VALAKAS_AOE_SKILLS =
|
||||
{
|
||||
new SkillHolder(4683, 1), // Valakas Dragon Breath
|
||||
new SkillHolder(4684, 1), // Valakas Dragon Breath
|
||||
new SkillHolder(4685, 1), // Valakas Tail Stomp
|
||||
new SkillHolder(4686, 1), // Valakas Tail Stomp
|
||||
new SkillHolder(4688, 1), // Valakas Stun
|
||||
new SkillHolder(4689, 1), // Valakas Fear TODO: has two levels only level one is used.
|
||||
new SkillHolder(4690, 1), // Valakas Meteor Storm
|
||||
};
|
||||
|
||||
// Locations
|
||||
private static final Location TELEPORT_CUBE_LOCATIONS[] =
|
||||
{
|
||||
new Location(214880, -116144, -1644),
|
||||
new Location(213696, -116592, -1644),
|
||||
new Location(212112, -116688, -1644),
|
||||
new Location(211184, -115472, -1664),
|
||||
new Location(210336, -114592, -1644),
|
||||
new Location(211360, -113904, -1644),
|
||||
new Location(213152, -112352, -1644),
|
||||
new Location(214032, -113232, -1644),
|
||||
new Location(214752, -114592, -1644),
|
||||
new Location(209824, -115568, -1421),
|
||||
new Location(210528, -112192, -1403),
|
||||
new Location(213120, -111136, -1408),
|
||||
new Location(215184, -111504, -1392),
|
||||
new Location(215456, -117328, -1392),
|
||||
new Location(213200, -118160, -1424)
|
||||
};
|
||||
private static final Location ATTACKER_REMOVE = new Location(150037, -57255, -2976);
|
||||
private static final Location VALAKAS_LAIR = new Location(212852, -114842, -1632);
|
||||
private static final Location VALAKAS_REGENERATION_LOC = new Location(-105200, -253104, -15264);
|
||||
// Valakas status.
|
||||
private static final byte DORMANT = 0; // Valakas is spawned and no one has entered yet. Entry is unlocked.
|
||||
private static final byte WAITING = 1; // Valakas is spawned and someone has entered, triggering a 30 minute window for additional people to enter. Entry is unlocked.
|
||||
private static final byte FIGHTING = 2; // Valakas is engaged in battle, annihilating his foes. Entry is locked.
|
||||
private static final byte DEAD = 3; // Valakas has been killed. Entry is locked.
|
||||
// Misc
|
||||
private long _timeTracker = 0; // Time tracker for last attack on Valakas.
|
||||
private L2Playable _actualVictim; // Actual target of Valakas.
|
||||
private static L2BossZone ZONE;
|
||||
|
||||
private Valakas()
|
||||
{
|
||||
super(Valakas.class.getSimpleName(), "ai/individual");
|
||||
registerMobs(VALAKAS);
|
||||
|
||||
ZONE = GrandBossManager.getInstance().getZone(212852, -114842, -1632);
|
||||
final StatsSet info = GrandBossManager.getInstance().getStatsSet(VALAKAS);
|
||||
final int status = GrandBossManager.getInstance().getBossStatus(VALAKAS);
|
||||
|
||||
if (status == DEAD)
|
||||
{
|
||||
// load the unlock date and time for valakas from DB
|
||||
long temp = (info.getLong("respawn_time") - System.currentTimeMillis());
|
||||
if (temp > 0)
|
||||
{
|
||||
// The time has not yet expired. Mark Valakas as currently locked (dead).
|
||||
startQuestTimer("valakas_unlock", temp, null, null);
|
||||
}
|
||||
else
|
||||
{
|
||||
// The time has expired while the server was offline. Spawn valakas in his cave as DORMANT.
|
||||
final L2Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 0, false, 0);
|
||||
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
|
||||
GrandBossManager.getInstance().addBoss((L2GrandBossInstance) valakas);
|
||||
|
||||
valakas.setIsInvul(true);
|
||||
valakas.setRunning();
|
||||
|
||||
valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
final int loc_x = info.getInt("loc_x");
|
||||
final int loc_y = info.getInt("loc_y");
|
||||
final int loc_z = info.getInt("loc_z");
|
||||
final int heading = info.getInt("heading");
|
||||
final int hp = info.getInt("currentHP");
|
||||
final int mp = info.getInt("currentMP");
|
||||
|
||||
final L2Npc valakas = addSpawn(VALAKAS, loc_x, loc_y, loc_z, heading, false, 0);
|
||||
GrandBossManager.getInstance().addBoss((L2GrandBossInstance) valakas);
|
||||
|
||||
valakas.setCurrentHpMp(hp, mp);
|
||||
valakas.setRunning();
|
||||
|
||||
// Start timers.
|
||||
if (status == FIGHTING)
|
||||
{
|
||||
// stores current time for inactivity task.
|
||||
_timeTracker = System.currentTimeMillis();
|
||||
|
||||
startQuestTimer("regen_task", 60000, valakas, null, true);
|
||||
startQuestTimer("skill_task", 2000, valakas, null, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
valakas.setIsInvul(true);
|
||||
valakas.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
||||
|
||||
// Start timer to lock entry after 30 minutes
|
||||
if (status == WAITING)
|
||||
{
|
||||
startQuestTimer("beginning", (Config.VALAKAS_WAIT_TIME * 60000), valakas, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
if (npc != null)
|
||||
{
|
||||
if (event.equalsIgnoreCase("beginning"))
|
||||
{
|
||||
// Stores current time
|
||||
_timeTracker = System.currentTimeMillis();
|
||||
|
||||
// Teleport Valakas to his lair.
|
||||
npc.teleToLocation(VALAKAS_LAIR);
|
||||
|
||||
// Sound + socialAction.
|
||||
for (L2PcInstance plyr : ZONE.getPlayersInside())
|
||||
{
|
||||
plyr.sendPacket(new PlaySound(1, "B03_A", 0, 0, 0, 0, 0));
|
||||
plyr.sendPacket(new SocialAction(npc.getObjectId(), 3));
|
||||
}
|
||||
|
||||
// Launch the cinematic, and tasks (regen + skill).
|
||||
startQuestTimer("spawn_1", 1700, npc, null); // 1700
|
||||
startQuestTimer("spawn_2", 3200, npc, null); // 1500
|
||||
startQuestTimer("spawn_3", 6500, npc, null); // 3300
|
||||
startQuestTimer("spawn_4", 9400, npc, null); // 2900
|
||||
startQuestTimer("spawn_5", 12100, npc, null); // 2700
|
||||
startQuestTimer("spawn_6", 12430, npc, null); // 330
|
||||
startQuestTimer("spawn_7", 15430, npc, null); // 3000
|
||||
startQuestTimer("spawn_8", 16830, npc, null); // 1400
|
||||
startQuestTimer("spawn_9", 23530, npc, null); // 6700 - end of cinematic
|
||||
startQuestTimer("spawn_10", 26000, npc, null); // 2500 - AI + unlock
|
||||
}
|
||||
// Regeneration && inactivity task
|
||||
else if (event.equalsIgnoreCase("regen_task"))
|
||||
{
|
||||
// Inactivity task - 15min
|
||||
if (GrandBossManager.getInstance().getBossStatus(VALAKAS) == FIGHTING)
|
||||
{
|
||||
if ((_timeTracker + 900000) < System.currentTimeMillis())
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
||||
npc.teleToLocation(VALAKAS_REGENERATION_LOC);
|
||||
|
||||
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
|
||||
npc.setCurrentHpMp(npc.getMaxHp(), npc.getMaxMp());
|
||||
|
||||
// Drop all players from the zone.
|
||||
ZONE.oustAllPlayers();
|
||||
|
||||
// Cancel skill_task and regen_task.
|
||||
cancelQuestTimer("regen_task", npc, null);
|
||||
cancelQuestTimer("skill_task", npc, null);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
// Verify if "Valakas Regeneration" skill is active.
|
||||
final BuffInfo info = npc.getEffectList().getBuffInfoBySkillId(VALAKAS_REGENERATION);
|
||||
final int lvl = info != null ? info.getSkill().getLevel() : 0;
|
||||
|
||||
// Current HPs are inferior to 25% ; apply lvl 4 of regen skill.
|
||||
if ((npc.getCurrentHp() < (npc.getMaxHp() / 4)) && (lvl != 4))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 4));
|
||||
}
|
||||
// Current HPs are inferior to 50% ; apply lvl 3 of regen skill.
|
||||
else if ((npc.getCurrentHp() < ((npc.getMaxHp() * 2) / 4.0)) && (lvl != 3))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 3));
|
||||
}
|
||||
// Current HPs are inferior to 75% ; apply lvl 2 of regen skill.
|
||||
else if ((npc.getCurrentHp() < ((npc.getMaxHp() * 3) / 4.0)) && (lvl != 2))
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 2));
|
||||
}
|
||||
// Apply lvl 1.
|
||||
else if (lvl != 1)
|
||||
{
|
||||
npc.setTarget(npc);
|
||||
npc.doCast(SkillData.getInstance().getSkill(VALAKAS_REGENERATION, 1));
|
||||
}
|
||||
}
|
||||
// Spawn cinematic, regen_task and choose of skill.
|
||||
else if (event.equalsIgnoreCase("spawn_1"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1800, 180, -1, 1500, 15000, 10000, 0, 0, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_2"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1300, 180, -5, 3000, 15000, 10000, 0, -5, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_3"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 500, 180, -8, 600, 15000, 10000, 0, 60, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_4"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 800, 180, -8, 2700, 15000, 10000, 0, 30, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_5"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 200, 250, 70, 0, 15000, 10000, 30, 80, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_6"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1100, 250, 70, 2500, 15000, 10000, 30, 80, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_7"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 700, 150, 30, 0, 15000, 10000, -10, 60, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_8"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1200, 150, 20, 2900, 15000, 10000, -10, 30, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_9"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 750, 170, -10, 3400, 15000, 4000, 10, -15, 1, 0, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("spawn_10"))
|
||||
{
|
||||
GrandBossManager.getInstance().setBossStatus(VALAKAS, FIGHTING);
|
||||
npc.setIsInvul(false);
|
||||
|
||||
startQuestTimer("regen_task", 60000, npc, null, true);
|
||||
startQuestTimer("skill_task", 2000, npc, null, true);
|
||||
}
|
||||
// Death cinematic, spawn of Teleport Cubes.
|
||||
else if (event.equalsIgnoreCase("die_1"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 2000, 130, -1, 0, 15000, 10000, 0, 0, 1, 1, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("die_2"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1100, 210, -5, 3000, 15000, 10000, -13, 0, 1, 1, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("die_3"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1300, 200, -8, 3000, 15000, 10000, 0, 15, 1, 1, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("die_4"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1000, 190, 0, 500, 15000, 10000, 0, 10, 1, 1, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("die_5"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1700, 120, 0, 2500, 15000, 10000, 12, 40, 1, 1, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("die_6"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1700, 20, 0, 700, 15000, 10000, 10, 10, 1, 1, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("die_7"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1700, 10, 0, 1000, 15000, 10000, 20, 70, 1, 1, 0));
|
||||
}
|
||||
else if (event.equalsIgnoreCase("die_8"))
|
||||
{
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1700, 10, 0, 300, 15000, 250, 20, -20, 1, 1, 0));
|
||||
|
||||
for (Location loc : TELEPORT_CUBE_LOCATIONS)
|
||||
{
|
||||
addSpawn(31759, loc, false, 900000);
|
||||
}
|
||||
|
||||
startQuestTimer("remove_players", 900000, null, null);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("skill_task"))
|
||||
{
|
||||
callSkillAI(npc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (event.equalsIgnoreCase("valakas_unlock"))
|
||||
{
|
||||
final L2Npc valakas = addSpawn(VALAKAS, -105200, -253104, -15264, 32768, false, 0);
|
||||
GrandBossManager.getInstance().addBoss((L2GrandBossInstance) valakas);
|
||||
GrandBossManager.getInstance().setBossStatus(VALAKAS, DORMANT);
|
||||
}
|
||||
else if (event.equalsIgnoreCase("remove_players"))
|
||||
{
|
||||
ZONE.oustAllPlayers();
|
||||
}
|
||||
}
|
||||
return super.onAdvEvent(event, npc, player);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpawn(L2Npc npc)
|
||||
{
|
||||
npc.disableCoreAI(true);
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
if (!ZONE.isInsideZone(attacker))
|
||||
{
|
||||
attacker.doDie(attacker);
|
||||
return null;
|
||||
}
|
||||
|
||||
if (npc.isInvul())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (GrandBossManager.getInstance().getBossStatus(VALAKAS) != FIGHTING)
|
||||
{
|
||||
attacker.teleToLocation(ATTACKER_REMOVE);
|
||||
return null;
|
||||
}
|
||||
|
||||
// Debuff strider-mounted players.
|
||||
if (attacker.getMountType() == MountType.STRIDER)
|
||||
{
|
||||
final Skill skill = SkillData.getInstance().getSkill(4258, 1);
|
||||
if (!attacker.isAffectedBySkill(4258))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(skill);
|
||||
}
|
||||
}
|
||||
_timeTracker = System.currentTimeMillis();
|
||||
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
// Cancel skill_task and regen_task.
|
||||
cancelQuestTimer("regen_task", npc, null);
|
||||
cancelQuestTimer("skill_task", npc, null);
|
||||
|
||||
// Launch death animation.
|
||||
ZONE.broadcastPacket(new PlaySound(1, "B03_D", 0, 0, 0, 0, 0));
|
||||
ZONE.broadcastPacket(new SpecialCamera(npc, 1200, 20, -10, 0, 10000, 13000, 0, 0, 0, 0, 0));
|
||||
|
||||
startQuestTimer("die_1", 300, npc, null); // 300
|
||||
startQuestTimer("die_2", 600, npc, null); // 300
|
||||
startQuestTimer("die_3", 3800, npc, null); // 3200
|
||||
startQuestTimer("die_4", 8200, npc, null); // 4400
|
||||
startQuestTimer("die_5", 8700, npc, null); // 500
|
||||
startQuestTimer("die_6", 13300, npc, null); // 4600
|
||||
startQuestTimer("die_7", 14000, npc, null); // 700
|
||||
startQuestTimer("die_8", 16500, npc, null); // 2500
|
||||
|
||||
GrandBossManager.getInstance().setBossStatus(VALAKAS, DEAD);
|
||||
// Calculate Min and Max respawn times randomly.
|
||||
long respawnTime = Config.VALAKAS_SPAWN_INTERVAL + getRandom(-Config.VALAKAS_SPAWN_RANDOM, Config.VALAKAS_SPAWN_RANDOM);
|
||||
respawnTime *= 3600000;
|
||||
|
||||
startQuestTimer("valakas_unlock", respawnTime, null, null);
|
||||
// also save the respawn time so that the info is maintained past reboots
|
||||
StatsSet info = GrandBossManager.getInstance().getStatsSet(VALAKAS);
|
||||
info.set("respawn_time", (System.currentTimeMillis() + respawnTime));
|
||||
GrandBossManager.getInstance().setStatsSet(VALAKAS, info);
|
||||
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
private void callSkillAI(L2Npc npc)
|
||||
{
|
||||
if (npc.isInvul() || npc.isCastingNow())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Pickup a target if no or dead victim. 10% luck he decides to reconsiders his target.
|
||||
if ((_actualVictim == null) || _actualVictim.isDead() || !(npc.getKnownList().knowsObject(_actualVictim)) || (getRandom(10) == 0))
|
||||
{
|
||||
_actualVictim = getRandomTarget(npc);
|
||||
}
|
||||
|
||||
// If result is still null, Valakas will roam. Don't go deeper in skill AI.
|
||||
if (_actualVictim == null)
|
||||
{
|
||||
if (getRandom(10) == 0)
|
||||
{
|
||||
int x = npc.getX();
|
||||
int y = npc.getY();
|
||||
int z = npc.getZ();
|
||||
|
||||
int posX = x + getRandom(-1400, 1400);
|
||||
int posY = y + getRandom(-1400, 1400);
|
||||
|
||||
if (GeoData.getInstance().canMove(x, y, z, posX, posY, z, npc.getInstanceId()))
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(posX, posY, z, 0));
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
final Skill skill = getRandomSkill(npc).getSkill();
|
||||
|
||||
// Cast the skill or follow the target.
|
||||
if (Util.checkIfInRange((skill.getCastRange() < 600) ? 600 : skill.getCastRange(), npc, _actualVictim, true))
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
||||
npc.setIsCastingNow(true);
|
||||
npc.setTarget(_actualVictim);
|
||||
npc.doCast(skill);
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.getAI().setIntention(CtrlIntention.AI_INTENTION_FOLLOW, _actualVictim, null);
|
||||
npc.setIsCastingNow(false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pick a random skill.<br>
|
||||
* Valakas will mostly use utility skills. If Valakas feels surrounded, he will use AoE skills.<br>
|
||||
* Lower than 50% HPs, he will begin to use Meteor skill.
|
||||
* @param npc valakas
|
||||
* @return a skill holder
|
||||
*/
|
||||
private SkillHolder getRandomSkill(L2Npc npc)
|
||||
{
|
||||
final int hpRatio = (int) ((npc.getCurrentHp() / npc.getMaxHp()) * 100);
|
||||
|
||||
// Valakas Lava Skin has priority.
|
||||
if ((hpRatio < 75) && (getRandom(150) == 0) && !npc.isAffectedBySkill(VALAKAS_LAVA_SKIN.getSkillId()))
|
||||
{
|
||||
return VALAKAS_LAVA_SKIN;
|
||||
}
|
||||
|
||||
// Valakas will use mass spells if he feels surrounded.
|
||||
if (Util.getPlayersCountInRadius(1200, npc, false, false) >= 20)
|
||||
{
|
||||
return VALAKAS_AOE_SKILLS[getRandom(VALAKAS_AOE_SKILLS.length)];
|
||||
}
|
||||
|
||||
if (hpRatio > 50)
|
||||
{
|
||||
return VALAKAS_REGULAR_SKILLS[getRandom(VALAKAS_REGULAR_SKILLS.length)];
|
||||
}
|
||||
|
||||
return VALAKAS_LOWHP_SKILLS[getRandom(VALAKAS_LOWHP_SKILLS.length)];
|
||||
}
|
||||
|
||||
/**
|
||||
* Pickup a random L2Playable from the zone, deads targets aren't included.
|
||||
* @param npc
|
||||
* @return a random L2Playable.
|
||||
*/
|
||||
private L2Playable getRandomTarget(L2Npc npc)
|
||||
{
|
||||
List<L2Playable> result = new ArrayList<>();
|
||||
|
||||
for (L2Character obj : npc.getKnownList().getKnownCharacters())
|
||||
{
|
||||
if ((obj == null) || obj.isPet())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (!obj.isDead() && obj.isPlayable())
|
||||
{
|
||||
result.add((L2Playable) obj);
|
||||
}
|
||||
}
|
||||
|
||||
return (result.isEmpty()) ? null : result.get(getRandom(result.size()));
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Valakas();
|
||||
}
|
||||
}
|
||||
3
trunk/dist/game/data/scripts/ai/individual/Venom/29055.html
vendored
Normal file
3
trunk/dist/game/data/scripts/ai/individual/Venom/29055.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>Teleportation Cubic:<br>
|
||||
<a action="bypass -h npc_%objectId%_Quest Venom">Leave the prison.</a><br>
|
||||
</body></html>
|
||||
3
trunk/dist/game/data/scripts/ai/individual/Venom/35506-02.html
vendored
Normal file
3
trunk/dist/game/data/scripts/ai/individual/Venom/35506-02.html
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<html><body>
|
||||
When attacking a castle, its defenses can easily be paralyzed.... What if that demon escapes?
|
||||
</body></html>
|
||||
4
trunk/dist/game/data/scripts/ai/individual/Venom/35506.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/individual/Venom/35506.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>
|
||||
The roar of that scary demon in the dungeon always makes me want to run away! I know the dungeon is well-built, but if its defenses are broken, it could collapse!<br><p>
|
||||
<a action="bypass -h npc_%objectId%_Quest Venom">Teleport to the dungeon</a>
|
||||
</body></html>
|
||||
414
trunk/dist/game/data/scripts/ai/individual/Venom/Venom.java
vendored
Normal file
414
trunk/dist/game/data/scripts/ai/individual/Venom/Venom.java
vendored
Normal file
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.individual.Venom;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import ai.npc.AbstractNpcAI;
|
||||
|
||||
import com.l2jserver.gameserver.ai.CtrlIntention;
|
||||
import com.l2jserver.gameserver.instancemanager.CastleManager;
|
||||
import com.l2jserver.gameserver.instancemanager.GlobalVariablesManager;
|
||||
import com.l2jserver.gameserver.model.Location;
|
||||
import com.l2jserver.gameserver.model.TeleportWhereType;
|
||||
import com.l2jserver.gameserver.model.actor.L2Attackable;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeFinish;
|
||||
import com.l2jserver.gameserver.model.events.impl.sieges.castle.OnCastleSiegeStart;
|
||||
import com.l2jserver.gameserver.model.holders.SkillHolder;
|
||||
import com.l2jserver.gameserver.model.skills.Skill;
|
||||
import com.l2jserver.gameserver.model.zone.ZoneId;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.clientpackets.Say2;
|
||||
|
||||
/**
|
||||
* Venom AI on Rune Castle.
|
||||
* @author nonom, MELERIX
|
||||
*/
|
||||
public final class Venom extends AbstractNpcAI
|
||||
{
|
||||
private static final int CASTLE = 8; // Rune
|
||||
|
||||
private static final int VENOM = 29054;
|
||||
private static final int TELEPORT_CUBE = 29055;
|
||||
private static final int DUNGEON_KEEPER = 35506;
|
||||
|
||||
private static final byte ALIVE = 0;
|
||||
private static final byte DEAD = 1;
|
||||
|
||||
private static final int HOURS_BEFORE = 24;
|
||||
|
||||
private static final Location[] TARGET_TELEPORTS =
|
||||
{
|
||||
new Location(12860, -49158, 976),
|
||||
new Location(14878, -51339, 1024),
|
||||
new Location(15674, -49970, 864),
|
||||
new Location(15696, -48326, 864),
|
||||
new Location(14873, -46956, 1024),
|
||||
new Location(12157, -49135, -1088),
|
||||
new Location(12875, -46392, -288),
|
||||
new Location(14087, -46706, -288),
|
||||
new Location(14086, -51593, -288),
|
||||
new Location(12864, -51898, -288),
|
||||
new Location(15538, -49153, -1056),
|
||||
new Location(17001, -49149, -1064)
|
||||
};
|
||||
|
||||
private static final Location TRHONE = new Location(11025, -49152, -537);
|
||||
private static final Location DUNGEON = new Location(11882, -49216, -3008);
|
||||
private static final Location TELEPORT = new Location(12589, -49044, -3008);
|
||||
private static final Location CUBE = new Location(12047, -49211, -3009);
|
||||
|
||||
private static final SkillHolder VENOM_STRIKE = new SkillHolder(4993, 1);
|
||||
private static final SkillHolder SONIC_STORM = new SkillHolder(4994, 1);
|
||||
private static final SkillHolder VENOM_TELEPORT = new SkillHolder(4995, 1);
|
||||
private static final SkillHolder RANGE_TELEPORT = new SkillHolder(4996, 1);
|
||||
|
||||
private L2Npc _venom;
|
||||
private L2Npc _massymore;
|
||||
|
||||
private Location _loc;
|
||||
|
||||
private boolean _aggroMode = false;
|
||||
private boolean _prisonIsOpen = false;
|
||||
|
||||
// @formatter:off
|
||||
private static final int[] TARGET_TELEPORTS_OFFSET =
|
||||
{
|
||||
650, 100, 100, 100, 100, 650, 200, 200, 200, 200, 200, 650
|
||||
};
|
||||
// @formatter:on
|
||||
|
||||
private static List<L2PcInstance> _targets = new ArrayList<>();
|
||||
|
||||
private Venom()
|
||||
{
|
||||
super(Venom.class.getSimpleName(), "ai/individual");
|
||||
addStartNpc(DUNGEON_KEEPER, TELEPORT_CUBE);
|
||||
addFirstTalkId(DUNGEON_KEEPER, TELEPORT_CUBE);
|
||||
addTalkId(DUNGEON_KEEPER, TELEPORT_CUBE);
|
||||
addSpawnId(VENOM, DUNGEON_KEEPER);
|
||||
addSpellFinishedId(VENOM);
|
||||
addAttackId(VENOM);
|
||||
addKillId(VENOM);
|
||||
addAggroRangeEnterId(VENOM);
|
||||
setCastleSiegeStartId(this::onSiegeStart, CASTLE);
|
||||
setCastleSiegeFinishId(this::onSiegeFinish, CASTLE);
|
||||
|
||||
final long currentTime = System.currentTimeMillis();
|
||||
final long startSiegeDate = CastleManager.getInstance().getCastleById(CASTLE).getSiegeDate().getTimeInMillis();
|
||||
final long openingDungeonDate = startSiegeDate - (HOURS_BEFORE * 360000);
|
||||
if ((currentTime > openingDungeonDate) && (currentTime < startSiegeDate))
|
||||
{
|
||||
_prisonIsOpen = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onTalk(L2Npc npc, L2PcInstance talker)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case TELEPORT_CUBE:
|
||||
{
|
||||
talker.teleToLocation(TeleportWhereType.TOWN);
|
||||
break;
|
||||
}
|
||||
case DUNGEON_KEEPER:
|
||||
{
|
||||
if (_prisonIsOpen)
|
||||
{
|
||||
talker.teleToLocation(TELEPORT);
|
||||
}
|
||||
else
|
||||
{
|
||||
return "35506-02.html";
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
return super.onTalk(npc, talker);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
switch (event)
|
||||
{
|
||||
case "tower_check":
|
||||
if (CastleManager.getInstance().getCastleById(CASTLE).getSiege().getControlTowerCount() <= 1)
|
||||
{
|
||||
changeLocation(MoveTo.THRONE);
|
||||
broadcastNpcSay(_massymore, Say2.NPC_SHOUT, NpcStringId.OH_NO_THE_DEFENSES_HAVE_FAILED_IT_IS_TOO_DANGEROUS_TO_REMAIN_INSIDE_THE_CASTLE_FLEE_EVERY_MAN_FOR_HIMSELF);
|
||||
cancelQuestTimer("tower_check", npc, null);
|
||||
startQuestTimer("raid_check", 10000, npc, null, true);
|
||||
}
|
||||
break;
|
||||
case "raid_check":
|
||||
if (!npc.isInsideZone(ZoneId.SIEGE) && !npc.isTeleporting())
|
||||
{
|
||||
npc.teleToLocation(_loc);
|
||||
}
|
||||
break;
|
||||
case "cube_despawn":
|
||||
if (npc != null)
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return event;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAggroRangeEnter(L2Npc npc, L2PcInstance player, boolean isSummon)
|
||||
{
|
||||
if (isSummon)
|
||||
{
|
||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
||||
}
|
||||
|
||||
if (_aggroMode && (_targets.size() < 10) && (getRandom(3) < 1) && !player.isDead())
|
||||
{
|
||||
_targets.add(player);
|
||||
}
|
||||
return super.onAggroRangeEnter(npc, player, isSummon);
|
||||
}
|
||||
|
||||
public void onSiegeStart(OnCastleSiegeStart event)
|
||||
{
|
||||
_aggroMode = true;
|
||||
_prisonIsOpen = false;
|
||||
if ((_venom != null) && !_venom.isDead())
|
||||
{
|
||||
_venom.setCurrentHp(_venom.getMaxHp());
|
||||
_venom.setCurrentMp(_venom.getMaxMp());
|
||||
_venom.enableSkill(VENOM_TELEPORT.getSkill());
|
||||
_venom.enableSkill(RANGE_TELEPORT.getSkill());
|
||||
startQuestTimer("tower_check", 30000, _venom, null, true);
|
||||
}
|
||||
}
|
||||
|
||||
public void onSiegeFinish(OnCastleSiegeFinish event)
|
||||
{
|
||||
_aggroMode = false;
|
||||
if ((_venom != null) && !_venom.isDead())
|
||||
{
|
||||
changeLocation(MoveTo.PRISON);
|
||||
_venom.disableSkill(VENOM_TELEPORT.getSkill(), -1);
|
||||
_venom.disableSkill(RANGE_TELEPORT.getSkill(), -1);
|
||||
}
|
||||
updateStatus(ALIVE);
|
||||
cancelQuestTimer("tower_check", _venom, null);
|
||||
cancelQuestTimer("raid_check", _venom, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onSpellFinished(L2Npc npc, L2PcInstance player, Skill skill)
|
||||
{
|
||||
switch (skill.getId())
|
||||
{
|
||||
case 4222:
|
||||
npc.teleToLocation(_loc);
|
||||
break;
|
||||
case 4995:
|
||||
teleportTarget(player);
|
||||
((L2Attackable) npc).stopHating(player);
|
||||
break;
|
||||
case 4996:
|
||||
teleportTarget(player);
|
||||
((L2Attackable) npc).stopHating(player);
|
||||
if ((_targets != null) && (_targets.size() > 0))
|
||||
{
|
||||
for (L2PcInstance target : _targets)
|
||||
{
|
||||
final long x = player.getX() - target.getX();
|
||||
final long y = player.getY() - target.getY();
|
||||
final long z = player.getZ() - target.getZ();
|
||||
final long range = 250;
|
||||
if (((x * x) + (y * y) + (z * z)) <= (range * range))
|
||||
{
|
||||
teleportTarget(target);
|
||||
((L2Attackable) npc).stopHating(target);
|
||||
}
|
||||
}
|
||||
_targets.clear();
|
||||
}
|
||||
break;
|
||||
}
|
||||
return super.onSpellFinished(npc, player, skill);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final String onSpawn(L2Npc npc)
|
||||
{
|
||||
switch (npc.getId())
|
||||
{
|
||||
case DUNGEON_KEEPER:
|
||||
{
|
||||
_massymore = npc;
|
||||
break;
|
||||
}
|
||||
case VENOM:
|
||||
{
|
||||
_venom = npc;
|
||||
|
||||
_loc = _venom.getLocation();
|
||||
_venom.disableSkill(VENOM_TELEPORT.getSkill(), -1);
|
||||
_venom.disableSkill(RANGE_TELEPORT.getSkill(), -1);
|
||||
_venom.doRevive();
|
||||
broadcastNpcSay(npc, Say2.NPC_SHOUT, NpcStringId.WHO_DARES_TO_COVET_THE_THRONE_OF_OUR_CASTLE_LEAVE_IMMEDIATELY_OR_YOU_WILL_PAY_THE_PRICE_OF_YOUR_AUDACITY_WITH_YOUR_VERY_OWN_BLOOD);
|
||||
((L2Attackable) _venom).setCanReturnToSpawnPoint(false);
|
||||
if (checkStatus() == DEAD)
|
||||
{
|
||||
_venom.deleteMe();
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (checkStatus() == DEAD)
|
||||
{
|
||||
npc.deleteMe();
|
||||
}
|
||||
else
|
||||
{
|
||||
npc.doRevive();
|
||||
|
||||
}
|
||||
return super.onSpawn(npc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onAttack(L2Npc npc, L2PcInstance attacker, int damage, boolean isSummon)
|
||||
{
|
||||
final double distance = npc.calculateDistance(attacker, false, false);
|
||||
if (_aggroMode && (getRandom(100) < 25))
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(VENOM_TELEPORT.getSkill());
|
||||
}
|
||||
else if (_aggroMode && (npc.getCurrentHp() < (npc.getMaxHp() / 3)) && (getRandom(100) < 25) && !npc.isCastingNow())
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(RANGE_TELEPORT.getSkill());
|
||||
}
|
||||
else if ((distance > 300) && (getRandom(100) < 10) && !npc.isCastingNow())
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(VENOM_STRIKE.getSkill());
|
||||
}
|
||||
else if ((getRandom(100) < 10) && !npc.isCastingNow())
|
||||
{
|
||||
npc.setTarget(attacker);
|
||||
npc.doCast(SONIC_STORM.getSkill());
|
||||
}
|
||||
return super.onAttack(npc, attacker, damage, isSummon);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String onKill(L2Npc npc, L2PcInstance killer, boolean isSummon)
|
||||
{
|
||||
updateStatus(DEAD);
|
||||
broadcastNpcSay(npc, Say2.NPC_SHOUT, NpcStringId.IT_S_NOT_OVER_YET_IT_WON_T_BE_OVER_LIKE_THIS_NEVER);
|
||||
if (!CastleManager.getInstance().getCastleById(CASTLE).getSiege().isInProgress())
|
||||
{
|
||||
L2Npc cube = addSpawn(TELEPORT_CUBE, CUBE, false, 0);
|
||||
startQuestTimer("cube_despawn", 120000, cube, null);
|
||||
}
|
||||
cancelQuestTimer("raid_check", npc, null);
|
||||
return super.onKill(npc, killer, isSummon);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alters the Venom location
|
||||
* @param loc enum
|
||||
*/
|
||||
private void changeLocation(MoveTo loc)
|
||||
{
|
||||
switch (loc)
|
||||
{
|
||||
case THRONE:
|
||||
_venom.teleToLocation(TRHONE, false);
|
||||
break;
|
||||
case PRISON:
|
||||
if ((_venom == null) || _venom.isDead() || _venom.isDecayed())
|
||||
{
|
||||
_venom = addSpawn(VENOM, DUNGEON, false, 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
_venom.teleToLocation(DUNGEON, false);
|
||||
}
|
||||
cancelQuestTimer("raid_check", _venom, null);
|
||||
cancelQuestTimer("tower_check", _venom, null);
|
||||
break;
|
||||
}
|
||||
_loc.setLocation(_venom.getLocation());
|
||||
}
|
||||
|
||||
private void teleportTarget(L2PcInstance player)
|
||||
{
|
||||
if ((player != null) && !player.isDead())
|
||||
{
|
||||
final int rnd = getRandom(11);
|
||||
player.teleToLocation(TARGET_TELEPORTS[rnd], TARGET_TELEPORTS_OFFSET[rnd]);
|
||||
player.getAI().setIntention(CtrlIntention.AI_INTENTION_IDLE);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if Venom is Alive or Dead
|
||||
* @return status
|
||||
*/
|
||||
private int checkStatus()
|
||||
{
|
||||
int checkStatus = ALIVE;
|
||||
if (GlobalVariablesManager.getInstance().hasVariable("VenomStatus"))
|
||||
{
|
||||
checkStatus = GlobalVariablesManager.getInstance().getInt("VenomStatus");
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalVariablesManager.getInstance().set("VenomStatus", 0);
|
||||
}
|
||||
return checkStatus;
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the Venom status
|
||||
* @param status the new status. 0 = ALIVE, 1 = DEAD.
|
||||
*/
|
||||
private void updateStatus(int status)
|
||||
{
|
||||
GlobalVariablesManager.getInstance().set("VenomStatus", Integer.toString(status));
|
||||
}
|
||||
|
||||
private enum MoveTo
|
||||
{
|
||||
THRONE,
|
||||
PRISON
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
new Venom();
|
||||
}
|
||||
}
|
||||
13
trunk/dist/game/data/scripts/ai/individual/documentation.txt
vendored
Normal file
13
trunk/dist/game/data/scripts/ai/individual/documentation.txt
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
Individual AI:
|
||||
This folder contains AI scripts for single npc templates (one npc ID, but possibly many instances).
|
||||
That is, if a particular NPC/mob has a unique AI or something slightly different from all other generic NPCs,
|
||||
an individual AI script can be created for all occurences of that npc/mob. Such individual scripts ought to be here.
|
||||
|
||||
Individual AI scripts can be subclassed. In other words, an individual may inherit from a group or other individual.
|
||||
For example, one group template might define mobs that cast spells. A particular mob may cast spells but may also
|
||||
talk whenever it gets attacked. In that case, instead of writing all the AI for attacking and casting spells, it may
|
||||
inherit from a group template that defines AI for ALL mobs that cast spells, then add behaviours for talking onAttack.
|
||||
|
||||
"NPC registrations" refers to the addition of NPCs in the various events of the scripts, such as onAttack, onKill, etc
|
||||
Those are done by using keywords such as "addKillId" etc. For more details on registrations, see
|
||||
"scripts/quests/documentation.txt"
|
||||
174
trunk/dist/game/data/scripts/ai/npc/AbstractNpcAI.java
vendored
Normal file
174
trunk/dist/game/data/scripts/ai/npc/AbstractNpcAI.java
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
/*
|
||||
* Copyright (C) 2004-2014 L2J DataPack
|
||||
*
|
||||
* This file is part of L2J DataPack.
|
||||
*
|
||||
* L2J DataPack 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.
|
||||
*
|
||||
* L2J DataPack 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
package ai.npc;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import com.l2jserver.gameserver.model.actor.L2Character;
|
||||
import com.l2jserver.gameserver.model.actor.L2Npc;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2MonsterInstance;
|
||||
import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
|
||||
import com.l2jserver.gameserver.model.holders.MinionHolder;
|
||||
import com.l2jserver.gameserver.model.quest.Quest;
|
||||
import com.l2jserver.gameserver.network.NpcStringId;
|
||||
import com.l2jserver.gameserver.network.serverpackets.NpcSay;
|
||||
import com.l2jserver.gameserver.network.serverpackets.SocialAction;
|
||||
import com.l2jserver.gameserver.util.Broadcast;
|
||||
|
||||
/**
|
||||
* Abstract NPC AI class for datapack based AIs.
|
||||
* @author UnAfraid, Zoey76
|
||||
*/
|
||||
public abstract class AbstractNpcAI extends Quest
|
||||
{
|
||||
public final Logger _log = Logger.getLogger(getClass().getSimpleName());
|
||||
|
||||
public AbstractNpcAI(String name, String descr)
|
||||
{
|
||||
super(-1, name, descr);
|
||||
}
|
||||
|
||||
/**
|
||||
* Simple on first talk event handler.
|
||||
*/
|
||||
@Override
|
||||
public String onFirstTalk(L2Npc npc, L2PcInstance player)
|
||||
{
|
||||
return npc.getId() + ".html";
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the following events to the current script:<br>
|
||||
* <ul>
|
||||
* <li>ON_ATTACK</li>
|
||||
* <li>ON_KILL</li>
|
||||
* <li>ON_SPAWN</li>
|
||||
* <li>ON_SPELL_FINISHED</li>
|
||||
* <li>ON_SKILL_SEE</li>
|
||||
* <li>ON_FACTION_CALL</li>
|
||||
* <li>ON_AGGR_RANGE_ENTER</li>
|
||||
* </ul>
|
||||
* @param mobs
|
||||
*/
|
||||
public void registerMobs(int... mobs)
|
||||
{
|
||||
addAttackId(mobs);
|
||||
addKillId(mobs);
|
||||
addSpawnId(mobs);
|
||||
addSpellFinishedId(mobs);
|
||||
addSkillSeeId(mobs);
|
||||
addAggroRangeEnterId(mobs);
|
||||
addFactionCallId(mobs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts NpcSay packet to all known players with custom string.
|
||||
* @param npc
|
||||
* @param type
|
||||
* @param text
|
||||
*/
|
||||
protected void broadcastNpcSay(L2Npc npc, int type, String text)
|
||||
{
|
||||
Broadcast.toKnownPlayers(npc, new NpcSay(npc.getObjectId(), type, npc.getTemplate().getDisplayId(), text));
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts NpcSay packet to all known players with npc string id.
|
||||
* @param npc
|
||||
* @param type
|
||||
* @param stringId
|
||||
*/
|
||||
protected void broadcastNpcSay(L2Npc npc, int type, NpcStringId stringId)
|
||||
{
|
||||
Broadcast.toKnownPlayers(npc, new NpcSay(npc.getObjectId(), type, npc.getTemplate().getDisplayId(), stringId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts NpcSay packet to all known players with npc string id.
|
||||
* @param npc
|
||||
* @param type
|
||||
* @param stringId
|
||||
* @param parameters
|
||||
*/
|
||||
protected void broadcastNpcSay(L2Npc npc, int type, NpcStringId stringId, String... parameters)
|
||||
{
|
||||
final NpcSay say = new NpcSay(npc.getObjectId(), type, npc.getTemplate().getDisplayId(), stringId);
|
||||
if (parameters != null)
|
||||
{
|
||||
for (String parameter : parameters)
|
||||
{
|
||||
say.addStringParameter(parameter);
|
||||
}
|
||||
}
|
||||
Broadcast.toKnownPlayers(npc, say);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts NpcSay packet to all known players with custom string in specific radius.
|
||||
* @param npc
|
||||
* @param type
|
||||
* @param text
|
||||
* @param radius
|
||||
*/
|
||||
protected void broadcastNpcSay(L2Npc npc, int type, String text, int radius)
|
||||
{
|
||||
Broadcast.toKnownPlayersInRadius(npc, new NpcSay(npc.getObjectId(), type, npc.getTemplate().getDisplayId(), text), radius);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts NpcSay packet to all known players with npc string id in specific radius.
|
||||
* @param npc
|
||||
* @param type
|
||||
* @param stringId
|
||||
* @param radius
|
||||
*/
|
||||
protected void broadcastNpcSay(L2Npc npc, int type, NpcStringId stringId, int radius)
|
||||
{
|
||||
Broadcast.toKnownPlayersInRadius(npc, new NpcSay(npc.getObjectId(), type, npc.getTemplate().getDisplayId(), stringId), radius);
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts SocialAction packet to self and known players.
|
||||
* @param character
|
||||
* @param actionId
|
||||
*/
|
||||
protected void broadcastSocialAction(L2Character character, int actionId)
|
||||
{
|
||||
Broadcast.toSelfAndKnownPlayers(character, new SocialAction(character.getObjectId(), actionId));
|
||||
}
|
||||
|
||||
/**
|
||||
* Broadcasts SocialAction packet to self and known players in specific radius.
|
||||
* @param character
|
||||
* @param actionId
|
||||
* @param radius
|
||||
*/
|
||||
protected void broadcastSocialAction(L2Character character, int actionId, int radius)
|
||||
{
|
||||
Broadcast.toSelfAndKnownPlayersInRadius(character, new SocialAction(character.getObjectId(), actionId), radius);
|
||||
}
|
||||
|
||||
public void spawnMinions(final L2Npc npc, final String spawnName)
|
||||
{
|
||||
for (MinionHolder is : npc.getTemplate().getParameters().getMinionList(spawnName))
|
||||
{
|
||||
addMinion((L2MonsterInstance) npc, is.getId());
|
||||
}
|
||||
}
|
||||
}
|
||||
4
trunk/dist/game/data/scripts/ai/npc/Alarm/32367-01.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/npc/Alarm/32367-01.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Alarm System:<br>
|
||||
As the alarm rings, a window for the passcode pops up. On the screen you see the number 120, which begins counting down. It looks like the alarm system will be activated in about 2 minutes unless the passcode is successfully entered.<br>
|
||||
<a action="bypass -h Quest Alarm 2">Enter the passcode.</a>
|
||||
</body></html>
|
||||
4
trunk/dist/game/data/scripts/ai/npc/Alarm/32367-02.html
vendored
Normal file
4
trunk/dist/game/data/scripts/ai/npc/Alarm/32367-02.html
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
<html><body>Alarm System:<br>
|
||||
The alarm is ringing loudly. You should leave here immediately.<br>
|
||||
(Another person has already undertaken the quest.)
|
||||
</body></html>
|
||||
42
trunk/dist/game/data/scripts/ai/npc/Alarm/32367-184_02.html
vendored
Normal file
42
trunk/dist/game/data/scripts/ai/npc/Alarm/32367-184_02.html
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<html><body>Alarm System:<br>
|
||||
########################<br>
|
||||
Enter the passcode for communication.<br>
|
||||
Passcode :|<br>
|
||||
########################<br>
|
||||
The first number is...
|
||||
<table border="0" border color="white" width="65" height="65">
|
||||
<tr>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 32367-184_04.html">1</a>
|
||||
</td>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 32367-184_04.html">2</a>
|
||||
</td>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 3">3</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 32367-184_04.html">4</a>
|
||||
</td>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 32367-184_04.html">5</a>
|
||||
</td>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 32367-184_04.html">6</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 32367-184_04.html">7</a>
|
||||
</td>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 32367-184_04.html">8</a>
|
||||
</td>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 32367-184_04.html">9</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body></html>
|
||||
42
trunk/dist/game/data/scripts/ai/npc/Alarm/32367-184_04.html
vendored
Normal file
42
trunk/dist/game/data/scripts/ai/npc/Alarm/32367-184_04.html
vendored
Normal file
@@ -0,0 +1,42 @@
|
||||
<html><body>Alarm System:<br>
|
||||
########################<br>
|
||||
Enter the passcode for communication.<br>
|
||||
Passcode : *|<br>
|
||||
########################<br>
|
||||
The second number is...
|
||||
<table border="0" border color="white" width="65" height="65">
|
||||
<tr>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 4">1</a>
|
||||
</td>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 32367-184_06.html">2</a>
|
||||
</td>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 32367-184_06.html">3</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 32367-184_06.html">4</a>
|
||||
</td>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 32367-184_06.html">5</a>
|
||||
</td>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 32367-184_06.html">6</a>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 32367-184_06.html">7</a>
|
||||
</td>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 32367-184_06.html">8</a>
|
||||
</td>
|
||||
<td width="20" height="20" align="center">
|
||||
<a action="bypass -h Quest Alarm 32367-184_06.html">9</a>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</body></html>
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user