Skip to content

Instantly share code, notes, and snippets.

@VlLight
Last active December 28, 2015 20:39
Show Gist options
  • Save VlLight/7558927 to your computer and use it in GitHub Desktop.
Save VlLight/7558927 to your computer and use it in GitHub Desktop.
Support for "scripted" spawn in universe or instance The main idea is to unhardcode script spawn. Instead of describing spawn in script, now we can create XML spawnlist for this puprose with <spawn name="someName" scripted="true">. Scripted spawns will not be initialized, when server boots; just readed and stored. Now it is possible to spawn NPC…
Index: java/com/l2jserver/gameserver/datatables/SpawnTable.java
===================================================================
--- java/com/l2jserver/gameserver/datatables/SpawnTable.java (revision 6302)
+++ java/com/l2jserver/gameserver/datatables/SpawnTable.java (working copy)
@@ -22,8 +22,10 @@
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
+import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.logging.Level;
@@ -39,10 +41,13 @@
import com.l2jserver.L2DatabaseFactory;
import com.l2jserver.gameserver.engines.DocumentParser;
import com.l2jserver.gameserver.instancemanager.DayNightSpawnManager;
+import com.l2jserver.gameserver.instancemanager.InstanceManager;
import com.l2jserver.gameserver.instancemanager.ZoneManager;
import com.l2jserver.gameserver.model.L2Spawn;
import com.l2jserver.gameserver.model.StatsSet;
+import com.l2jserver.gameserver.model.actor.L2Npc;
import com.l2jserver.gameserver.model.actor.templates.L2NpcTemplate;
+import com.l2jserver.gameserver.model.entity.Instance;
import com.l2jserver.gameserver.model.interfaces.IL2Procedure;
/**
@@ -57,6 +62,7 @@
private static final String SELECT_CUSTOM_SPAWNS = "SELECT count, npc_templateid, locx, locy, locz, heading, respawn_delay, respawn_random, loc_id, periodOfDay FROM custom_spawnlist";
private static final Map<Integer, Set<L2Spawn>> _spawnTable = new FastMap<Integer, Set<L2Spawn>>().shared();
+ private static final Map<String, List<L2Spawn>> _scriptedSpawn = new HashMap<>();
private int _xmlSpawnCount = 0;
@@ -127,6 +133,7 @@
{
String territoryName = null;
String spawnName = null;
+ boolean isScripted = false;
Map<String, Integer> map = null;
// Check, if spawn name specified
@@ -139,6 +146,14 @@
{
territoryName = parseString(attrs, "zone");
}
+ // check, if scripted flag is specified
+ isScripted = (attrs.getNamedItem("scripted") != null) && Boolean.parseBoolean(attrs.getNamedItem("scripted").getNodeValue());
+ // Also check, if name is set for spawn, if it is defined as scripted, because name is key parameter to operate with this kind of spawn
+ if (isScripted && (spawnName == null))
+ {
+ _log.warning(getClass().getSimpleName() + ": spawn is defined as scripted, but name isn't specified in " + getCurrentFile().getName() + ". Skipped.");
+ continue;
+ }
for (Node npctag = param.getFirstChild(); npctag != null; npctag = npctag.getNextSibling())
{
@@ -205,6 +220,7 @@
spawnInfo.set("z", z);
spawnInfo.set("territoryName", territoryName);
spawnInfo.set("spawnName", spawnName);
+ spawnInfo.set("isScripted", isScripted);
// trying to read optional parameters
if (attrs.getNamedItem("heading") != null)
@@ -323,22 +339,30 @@
}
// Register AI Data for this spawn
NpcPersonalAIData.getInstance().storeData(spawnDat, AIData);
- switch (spawnInfo.getInt("periodOfDay", 0))
+ // spawn immediate, if spawn isn't defined as scripted; just store otherwise
+ if (spawnInfo.getBoolean("isScripted", false))
{
- case 0: // default
- ret += spawnDat.init();
- break;
- case 1: // Day
- DayNightSpawnManager.getInstance().addDayCreature(spawnDat);
- ret = 1;
- break;
- case 2: // Night
- DayNightSpawnManager.getInstance().addNightCreature(spawnDat);
- ret = 1;
- break;
+ addScriptedSpawn(spawnDat);
}
-
- addSpawn(spawnDat);
+ else
+ {
+ switch (spawnInfo.getInt("periodOfDay", 0))
+ {
+ case 0: // default
+ ret += spawnDat.init();
+ break;
+ case 1: // Day
+ DayNightSpawnManager.getInstance().addDayCreature(spawnDat);
+ ret = 1;
+ break;
+ case 2: // Night
+ DayNightSpawnManager.getInstance().addNightCreature(spawnDat);
+ ret = 1;
+ break;
+ }
+
+ addSpawn(spawnDat);
+ }
}
catch (Exception e)
{
@@ -359,6 +383,252 @@
return addSpawn(spawnInfo, null);
}
+ /**
+ * Add a spawn to the scripted spawn set if present, otherwise add a spawn set and add the spawn to the newly created spawn set.
+ * @param spawnDat the NPC spawn to add
+ */
+ private void addScriptedSpawn(L2Spawn spawnDat)
+ {
+ if (!_scriptedSpawn.containsKey(spawnDat.getName()))
+ {
+ _scriptedSpawn.put(spawnDat.getName(), new ArrayList<L2Spawn>());
+ }
+ _scriptedSpawn.get(spawnDat.getName()).add(spawnDat);
+ }
+
+ /**
+ * Initializes previously stored scripted spawn of given name
+ * @param spawnName name of spawn
+ */
+ public void spawnScripted(String spawnName)
+ {
+ if (!_scriptedSpawn.containsKey(spawnName))
+ {
+ _log.warning(getClass().getSimpleName() + ": Could't find scripted spawn with name: \"" + spawnName + "\".");
+ return;
+ }
+ // spawn
+ try
+ {
+ for (L2Spawn spawnDat : _scriptedSpawn.get(spawnName))
+ {
+ spawnDat.init();
+ addSpawn(spawnDat);
+ }
+ _log.info(getClass().getSimpleName() + ": Scripted spawn with name: \"" + spawnName + "\" spawned succesfully.");
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.WARNING, getClass().getSimpleName() + ": Scripted spawn \"" + spawnName + "\" could not be initialized: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Initializes previously stored scripted spawn of given names
+ * @param spawnNames names of spawn
+ */
+ public void spawnScripted(String... spawnNames)
+ {
+ for (String spawnName : spawnNames)
+ {
+ spawnScripted(spawnName);
+ }
+ }
+
+ /**
+ * Initializes previously stored scripted spawn of given name in instance
+ * @param instanceId id of instance to spawn
+ * @param spawnName name of spawn
+ */
+ public void spawnScripted(int instanceId, String spawnName)
+ {
+ final Instance inst = InstanceManager.getInstance().getInstance(instanceId);
+ if (inst == null)
+ {
+ _log.warning(getClass().getSimpleName() + ": Could't spawn scripted group \"" + spawnName + "\" in instance ID " + instanceId + ". No instance found.");
+ return;
+ }
+
+ if (!_scriptedSpawn.containsKey(spawnName))
+ {
+ _log.warning(getClass().getSimpleName() + ": Could't find scripted spawn: \"" + spawnName + "\".");
+ return;
+ }
+
+ List<L2Spawn> spawnList = new ArrayList<>(_scriptedSpawn.get(spawnName).size());
+ try
+ {
+ for (L2Spawn spawn : _scriptedSpawn.get(spawnName))
+ {
+ // Clone origin L2Spawn objects for every instance
+ L2Spawn clonedSpawn = spawn.cloneSpawn();
+ clonedSpawn.setInstanceId(instanceId);
+ clonedSpawn.init();
+ spawnList.add(clonedSpawn);
+ }
+ // Store spawned list for every instance
+ inst.storeScriptedSpawn(spawnName, spawnList);
+ _log.info(getClass().getSimpleName() + ": Scripted spawn: \"" + spawnName + "\" spawned succesfully for instance ID: " + instanceId);
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.WARNING, getClass().getSimpleName() + ": Scripted spawn \"" + spawnName + "\" could not be initialized for instance ID " + instanceId + ": " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Initializes previously stored scripted spawn of given names in instance
+ * @param instanceId id of instance to spawn
+ * @param spawnNames names of spawn
+ */
+ public void spawnScripted(int instanceId, String... spawnNames)
+ {
+ for (String spawnName : spawnNames)
+ {
+ spawnScripted(instanceId, spawnName);
+ }
+ }
+
+ /**
+ * Deinitializes previously stored scripted spawn of given name
+ * @param spawnName name of spawn
+ */
+ public void despawnScripted(String spawnName)
+ {
+ if (!_scriptedSpawn.containsKey(spawnName))
+ {
+ _log.warning(getClass().getSimpleName() + ": Could't find scripted spawn with name: \"" + spawnName + "\".");
+ return;
+ }
+
+ try
+ {
+ for (L2Spawn spawnDat : _scriptedSpawn.get(spawnName))
+ {
+ spawnDat.stopRespawn();
+ for (L2Npc npc : spawnDat.getSpawnedNpcs())
+ {
+ if (npc != null)
+ {
+ npc.deleteMe();
+ }
+ }
+ removeSpawn(spawnDat);
+ }
+ _log.info(getClass().getSimpleName() + ": Scripted spawn with name: \"" + spawnName + "\" despawned succesfully.");
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.WARNING, getClass().getSimpleName() + ": Scripted spawn \"" + spawnName + "\" could not be deinitialized: " + e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Deinitializes previously stored scripted spawn of given name
+ * @param spawnNames names of spawn
+ */
+ public void despawnScripted(String... spawnNames)
+ {
+ for (String spawnName : spawnNames)
+ {
+ despawnScripted(spawnName);
+ }
+ }
+
+ /**
+ * Deinitializes previously stored scripted spawn of given name in instance
+ * @param instanceId id of instance to despawn
+ * @param spawnName name of spawn
+ */
+ public void despawnScripted(int instanceId, String spawnName)
+ {
+ final Instance inst = InstanceManager.getInstance().getInstance(instanceId);
+
+ if (inst == null)
+ {
+ _log.warning(getClass().getSimpleName() + ": Could't despawn scripted group \"" + spawnName + "\" in instance ID " + instanceId + ". No instance found.");
+ return;
+ }
+
+ List<L2Spawn> spawnList = getScriptedSpawn(spawnName, instanceId);
+
+ if (spawnList != null)
+ {
+ try
+ {
+ for (L2Spawn spawnDat : spawnList)
+ {
+ spawnDat.stopRespawn();
+ for (L2Npc npc : spawnDat.getSpawnedNpcs())
+ {
+ if (npc != null)
+ {
+ npc.deleteMe();
+ }
+ }
+ }
+ spawnList.clear();
+ _log.info(getClass().getSimpleName() + ": Scripted spawn \"" + spawnName + "\" despawned succesfully in instance ID " + instanceId);
+ }
+ catch (Exception e)
+ {
+ _log.log(Level.WARNING, getClass().getSimpleName() + ": Scripted spawn \"" + spawnName + "\" could not be deinitialized in instance ID " + instanceId + ": " + e.getMessage(), e);
+ }
+ }
+ }
+
+ /**
+ * Deinitializes previously stored scripted spawn of given names in instance
+ * @param instanceId id of instance to despawn
+ * @param spawnNames names of spawn
+ */
+ public void despawnScripted(int instanceId, String... spawnNames)
+ {
+ for (String spawnName : spawnNames)
+ {
+ despawnScripted(instanceId, spawnName);
+ }
+ }
+
+ /**
+ * Get the scripted spawns for given spawn name
+ * @param spawnName spawn name to use
+ * @return the spawn list for the given spawnName
+ */
+ public List<L2Spawn> getScriptedSpawn(String spawnName)
+ {
+ if (!_scriptedSpawn.containsKey(spawnName))
+ {
+ _log.warning(getClass().getSimpleName() + ": Could't find scripted spawn with name: \"" + spawnName + "\".");
+ }
+
+ return _scriptedSpawn.get(spawnName);
+ }
+
+ /**
+ * Get the scripted spawns for given spawn name in instance
+ * @param spawnName spawn name to use
+ * @param instanceId id of instance to use
+ * @return the spawn list for the given spawnName in given instanceId
+ */
+ public List<L2Spawn> getScriptedSpawn(String spawnName, int instanceId)
+ {
+ final Instance inst = InstanceManager.getInstance().getInstance(instanceId);
+
+ if (inst == null)
+ {
+ _log.warning(getClass().getSimpleName() + ": Could't find instance ID: " + instanceId + ". getScriptedSpawn() failed for \"" + spawnName + "\"");
+ return null;
+ }
+
+ if (inst.getScriptedSpawn(spawnName) == null)
+ {
+ _log.warning(getClass().getSimpleName() + ": Could't find scripted spawn: \"" + spawnName + "\" in instance ID " + instanceId);
+ }
+
+ return inst.getScriptedSpawn(spawnName);
+ }
+
public Map<Integer, Set<L2Spawn>> getSpawnTable()
{
return _spawnTable;
Index: java/com/l2jserver/gameserver/model/entity/Instance.java
===================================================================
--- java/com/l2jserver/gameserver/model/entity/Instance.java (revision 6302)
+++ java/com/l2jserver/gameserver/model/entity/Instance.java (working copy)
@@ -84,6 +84,7 @@
private final List<L2Npc> _npcs = new L2FastList<>(true);
private final Map<Integer, L2DoorInstance> _doors = new L2FastMap<>(true);
private final Map<String, List<L2Spawn>> _manualSpawn = new HashMap<>();
+ private final Map<String, List<L2Spawn>> _scriptedSpawn = new HashMap<>();
private Location _spawnLoc = null;
private boolean _allowSummon = true;
private long _emptyDestroyTime = -1;
@@ -357,6 +358,7 @@
}
_npcs.clear();
_manualSpawn.clear();
+ _scriptedSpawn.clear();
}
public void removeDoors()
@@ -406,6 +408,26 @@
return ret;
}
+ /**
+ * Stores list of active scripted spawns for instance
+ * @param spawnName name of spawn
+ * @param spawnList List to store
+ */
+ public void storeScriptedSpawn(String spawnName, List<L2Spawn> spawnList)
+ {
+ _scriptedSpawn.put(spawnName, spawnList);
+ }
+
+ /**
+ * Get the scripted spawns for given spawn name
+ * @param spawnName spawn name to use
+ * @return the spawn list for the given spawnName
+ */
+ public List<L2Spawn> getScriptedSpawn(String spawnName)
+ {
+ return _scriptedSpawn.get(spawnName);
+ }
+
public void loadInstanceTemplate(String filename)
{
Document doc = null;
Index: java/com/l2jserver/gameserver/model/L2Spawn.java
===================================================================
--- java/com/l2jserver/gameserver/model/L2Spawn.java (revision 6302)
+++ java/com/l2jserver/gameserver/model/L2Spawn.java (working copy)
@@ -825,4 +825,29 @@
{
_isNoRndWalk = value;
}
+
+ /**
+ * Creates new L2Spawn object with initial parameters of this L2Spawn
+ * @return copy of this L2Spawn
+ */
+ public L2Spawn cloneSpawn()
+ {
+ try
+ {
+ L2Spawn clonedSpawn = new L2Spawn(getTemplate());
+ clonedSpawn.setAmount(getAmount());
+ clonedSpawn.setLocation(getLocation());
+ clonedSpawn.setRespawnMinDelay(getRespawnMinDelay());
+ clonedSpawn.setRespawnMaxDelay(getRespawnMaxDelay());
+ clonedSpawn.setLocationId(getLocationId());
+ clonedSpawn.setCustom(isCustom());
+ clonedSpawn.setName(getName());
+ clonedSpawn.setSpawnTerritory(getSpawnTerritory());
+ return clonedSpawn;
+ }
+ catch(Exception e)
+ {
+ return null;
+ }
+ }
}
Index: dist/game/data/instances/ScriptedInstance.xml
===================================================================
--- dist/game/data/instances/ScriptedInstance.xml (revision 0)
+++ dist/game/data/instances/ScriptedInstance.xml (working copy)
@@ -0,0 +1,10 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<instance name="Scripted Instance" ejectTime="120" allowRandomWalk="false" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/instance.xsd">
+ <activityTime val="90" /> <!-- 90 minutes -->
+ <emptyDestroyTime val="900" /> <!-- 15 minutes -->
+ <spawnlist>
+ <group name="general">
+ <spawn npcId="32502" x="125536" y="-40928" z="-3780" heading="8192" respawn="0" />
+ </group>
+ </spawnlist>
+</instance>
\ No newline at end of file
Index: dist/game/data/scripts.cfg
===================================================================
--- dist/game/data/scripts.cfg (revision 10055)
+++ dist/game/data/scripts.cfg (working copy)
@@ -718,3 +718,6 @@
#events/FreyaCelebration/FreyaCelebration.java
#events/MasterOfEnchanting/MasterOfEnchanting.java
#events/LoveYourGatekeeper/LoveYourGatekeeper.java
+
+demo/ScriptedSpawn/ScriptedSpawn.java
+demo/ScriptedInstance/ScriptedInstance.java
\ No newline at end of file
Index: dist/game/data/scripts/demo/ScriptedInstance/1.html
===================================================================
--- dist/game/data/scripts/demo/ScriptedInstance/1.html (revision 0)
+++ dist/game/data/scripts/demo/ScriptedInstance/1.html (working copy)
@@ -0,0 +1,4 @@
+<html><body>
+Greetings to you! I can show you the show.<br>
+<a action="bypass -h Quest ScriptedInstance tele">Enter instance</a>
+</body></html>
\ No newline at end of file
Index: dist/game/data/scripts/demo/ScriptedInstance/2.html
===================================================================
--- dist/game/data/scripts/demo/ScriptedInstance/2.html (revision 0)
+++ dist/game/data/scripts/demo/ScriptedInstance/2.html (working copy)
@@ -0,0 +1,4 @@
+<html><body>
+<a action="bypass -h Quest ScriptedInstance spawn">Spawn mobs</a><br>
+<a action="bypass -h Quest ScriptedInstance leave">Leave instance</a>
+</body></html>
\ No newline at end of file
Index: dist/game/data/scripts/demo/ScriptedInstance/3.html
===================================================================
--- dist/game/data/scripts/demo/ScriptedInstance/3.html (revision 0)
+++ dist/game/data/scripts/demo/ScriptedInstance/3.html (working copy)
@@ -0,0 +1,4 @@
+<html><body>
+<a action="bypass -h Quest ScriptedInstance despawn">Despawn mobs</a><br>
+<a action="bypass -h Quest ScriptedInstance leave">Leave instance</a>
+</body></html>
\ No newline at end of file
Index: dist/game/data/scripts/demo/ScriptedInstance/ScriptedInstance.java
===================================================================
--- dist/game/data/scripts/demo/ScriptedInstance/ScriptedInstance.java (revision 0)
+++ dist/game/data/scripts/demo/ScriptedInstance/ScriptedInstance.java (working copy)
@@ -0,0 +1,143 @@
+/*
+ * Copyright (C) 2004-2013 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 demo.ScriptedInstance;
+
+import com.l2jserver.gameserver.datatables.SpawnTable;
+import com.l2jserver.gameserver.instancemanager.InstanceManager;
+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.entity.Instance;
+import com.l2jserver.gameserver.model.instancezone.InstanceWorld;
+import com.l2jserver.gameserver.model.quest.Quest;
+import com.l2jserver.gameserver.network.SystemMessageId;
+
+/**
+ * Scripted Instance.
+ * @author GKR
+ */
+public final class ScriptedInstance extends Quest
+{
+ private static final Location SPAWN_POINT = new Location(125738, -40933, -3770);
+ private static final Location RETURN_POINT = new Location(147725, -56517, -2780);
+ private static final int TELEPORTER = 32499;
+ private static final int SUPPORTER = 32502;
+ private static final int INSTANCE_ID = 999;
+
+ private ScriptedInstance()
+ {
+ super(-1, ScriptedInstance.class.getSimpleName(), "demo");
+ addStartNpc(TELEPORTER, SUPPORTER);
+ addTalkId(TELEPORTER, SUPPORTER);
+ addFirstTalkId(TELEPORTER, SUPPORTER);
+ }
+
+ @Override
+ public final String onFirstTalk(L2Npc npc, L2PcInstance player)
+ {
+ InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
+ switch(npc.getId())
+ {
+ case TELEPORTER:
+ return "1.html";
+ case SUPPORTER:
+ {
+ switch(world.getStatus())
+ {
+ case 0:
+ return "2.html";
+ case 1:
+ return "3.html";
+ }
+ }
+ }
+
+ return null;
+ }
+
+ @Override
+ public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
+ {
+ InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
+ switch(event)
+ {
+ case "tele":
+ {
+ enterInstance(player);
+ break;
+ }
+ case "leave":
+ {
+ teleportPlayer(player, RETURN_POINT, 0);
+ break;
+ }
+ case "spawn":
+ {
+ SpawnTable.getInstance().spawnScripted(world.getInstanceId(), "testInstanceScripted");
+ world.setStatus(1);
+ break;
+ }
+ case "despawn":
+ {
+ SpawnTable.getInstance().despawnScripted(world.getInstanceId(), "testInstanceScripted");
+ world.setStatus(0);
+ break;
+ }
+
+ }
+
+ return null;
+ }
+
+ private void enterInstance(L2PcInstance player)
+ {
+ InstanceWorld world = InstanceManager.getInstance().getPlayerWorld(player);
+ if (world != null)
+ {
+ if (world.getTemplateId() != INSTANCE_ID)
+ {
+ player.sendPacket(SystemMessageId.ALREADY_ENTERED_ANOTHER_INSTANCE_CANT_ENTER);
+ return;
+ }
+ Instance inst = InstanceManager.getInstance().getInstance(world.getInstanceId());
+ if (inst != null)
+ {
+ teleportPlayer(player, SPAWN_POINT, world.getInstanceId());
+ }
+ }
+ else
+ {
+ final int instanceId = InstanceManager.getInstance().createDynamicInstance("ScriptedInstance.xml");
+ world = new InstanceWorld();
+ world.setInstanceId(instanceId);
+ world.setTemplateId(INSTANCE_ID);
+ world.setStatus(0);
+ InstanceManager.getInstance().addWorld(world);
+
+ world.addAllowed(player.getObjectId());
+ teleportPlayer(player, SPAWN_POINT, instanceId);
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new ScriptedInstance();
+ }
+}
+
Index: dist/game/data/scripts/demo/ScriptedSpawn/1.htm
===================================================================
--- dist/game/data/scripts/demo/ScriptedSpawn/1.htm (revision 0)
+++ dist/game/data/scripts/demo/ScriptedSpawn/1.htm (working copy)
@@ -0,0 +1,4 @@
+<html><body>
+Greetings to you! I can show you the show.<br>
+<a action="bypass -h Quest ScriptedSpawn show">Show me the show</a>
+</body></html>
\ No newline at end of file
Index: dist/game/data/scripts/demo/ScriptedSpawn/2.htm
===================================================================
--- dist/game/data/scripts/demo/ScriptedSpawn/2.htm (revision 0)
+++ dist/game/data/scripts/demo/ScriptedSpawn/2.htm (working copy)
@@ -0,0 +1,4 @@
+<html><body>
+Ary you frightened? I can say them go away.<br>
+<a action="bypass -h Quest ScriptedSpawn away">Say them go away!</a>
+</body></html>
\ No newline at end of file
Index: dist/game/data/scripts/demo/ScriptedSpawn/3.htm
===================================================================
--- dist/game/data/scripts/demo/ScriptedSpawn/3.htm (revision 0)
+++ dist/game/data/scripts/demo/ScriptedSpawn/3.htm (working copy)
@@ -0,0 +1,3 @@
+<html><body>
+I'm a bold guy, yeah!
+</body></html>
\ No newline at end of file
Index: dist/game/data/scripts/demo/ScriptedSpawn/4.htm
===================================================================
--- dist/game/data/scripts/demo/ScriptedSpawn/4.htm (revision 0)
+++ dist/game/data/scripts/demo/ScriptedSpawn/4.htm (working copy)
@@ -0,0 +1,3 @@
+<html><body>
+I hear a noise from somewhere!
+</body></html>
\ No newline at end of file
Index: dist/game/data/scripts/demo/ScriptedSpawn/ScriptedSpawn.java
===================================================================
--- dist/game/data/scripts/demo/ScriptedSpawn/ScriptedSpawn.java (revision 0)
+++ dist/game/data/scripts/demo/ScriptedSpawn/ScriptedSpawn.java (working copy)
@@ -0,0 +1,122 @@
+/*
+ * Copyright (C) 2004-2013 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 demo.ScriptedSpawn;
+
+import com.l2jserver.gameserver.ai.CtrlIntention;
+import com.l2jserver.gameserver.datatables.SpawnTable;
+import com.l2jserver.gameserver.model.Location;
+import com.l2jserver.gameserver.model.L2Spawn;
+import com.l2jserver.gameserver.model.actor.L2Npc;
+import com.l2jserver.gameserver.model.actor.instance.L2PcInstance;
+import com.l2jserver.gameserver.model.base.ClassId;
+import com.l2jserver.gameserver.model.quest.Quest;
+import com.l2jserver.gameserver.network.clientpackets.Say2;
+import com.l2jserver.gameserver.network.serverpackets.NpcSay;
+import com.l2jserver.gameserver.util.Util;
+
+/**
+ * Scripted spawn demonstration
+ * @author GKR
+ */
+
+public class ScriptedSpawn extends Quest
+{
+ private int status = 1;
+
+ private ScriptedSpawn()
+ {
+ super(-1, ScriptedSpawn.class.getSimpleName(), "demo");
+ addStartNpc(109);
+ addFirstTalkId(109);
+ addTalkId(109);
+ addMoveFinishedId(22782);
+ }
+
+ @Override
+ public String onAdvEvent(String event, L2Npc npc, L2PcInstance player)
+ {
+ switch(event)
+ {
+ case "show" :
+ SpawnTable.getInstance().spawnScripted("scriptedSpawnTest");
+ status = 2;
+ break;
+ case "away" :
+ for (L2Spawn spawn : SpawnTable.getInstance().getScriptedSpawn("scriptedSpawnTest"))
+ {
+ final L2Npc mob = spawn.getLastSpawn();
+ mob.setIsRunning(true);
+ mob.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(spawn.getX() + 170, spawn.getY() + 2527, spawn.getZ()));
+ }
+ status = 3;
+ startQuestTimer("return", 15000, npc, null);
+ break;
+ case "return" :
+ for (L2Spawn spawn : SpawnTable.getInstance().getScriptedSpawn("scriptedSpawnTest"))
+ {
+ final L2Npc mob = spawn.getLastSpawn();
+ mob.setIsRunning(false);
+ mob.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, spawn.getLocation());
+ }
+ startQuestTimer("flee", 32000, npc, null);
+ status = 4;
+ break;
+ case "flee" :
+ npc.broadcastPacket(new NpcSay(npc, Say2.NPC_SHOUT, "They are coming! Ruuuun!"));
+ npc.setIsRunning(true);
+ npc.getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(npc.getX() - 170, npc.getY() - 2527, npc.getZ()));
+ npc.scheduleDespawn(5000);
+ break;
+ case "pursuit" :
+ npc.broadcastPacket(new NpcSay(npc, Say2.NPC_ALL, "Folllow him!"));
+ for (L2Spawn spawn : SpawnTable.getInstance().getScriptedSpawn("scriptedSpawnTest"))
+ {
+ spawn.getLastSpawn().getAI().setIntention(CtrlIntention.AI_INTENTION_MOVE_TO, new Location(spawn.getX() - 170, spawn.getY() - 2527, spawn.getZ()));
+ }
+ startQuestTimer("despawn", 5000, null, null);
+ break;
+ case "despawn" :
+ SpawnTable.getInstance().despawnScripted("scriptedSpawnTest");
+ break;
+ }
+
+ return null;
+ }
+
+ @Override
+ public String onFirstTalk(L2Npc npc, L2PcInstance player)
+ {
+ return status + ".htm";
+ }
+
+ @Override
+ public void onMoveFinished(L2Npc npc)
+ {
+ if ((status < 5) && npc.staysInSpawnLoc())
+ {
+ status = 5;
+ startQuestTimer("pursuit", 5000, npc, null);
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ new ScriptedSpawn();
+ }
+}
\ No newline at end of file
Index: dist/game/data/spawnlist/scripted_instance_test.xml
===================================================================
--- dist/game/data/spawnlist/scripted_instance_test.xml (revision 0)
+++ dist/game/data/spawnlist/scripted_instance_test.xml (working copy)
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<list enabled="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/spawnlist.xsd">
+ <spawn>
+ <npc id="32499" x="143472" y="-3472" z="-3694" heading="40959" />
+ </spawn>
+ <spawn name="testInstanceScripted" scripted="true">
+ <npc id="32499" x="125614" y="-40156" z="-3759" />
+ <npc id="32499" x="125714" y="-40156" z="-3759" />
+ <npc id="32499" x="125814" y="-40156" z="-3759" />
+ </spawn>
+</list>
\ No newline at end of file
Index: dist/game/data/spawnlist/scripted_spawn_test.xml
===================================================================
--- dist/game/data/spawnlist/scripted_spawn_test.xml (revision 0)
+++ dist/game/data/spawnlist/scripted_spawn_test.xml (working copy)
@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<list enabled="true" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="../xsd/spawnlist.xsd">
+ <spawn name="scriptedSpawnTest" scripted="true">
+ <AIData>
+ <disableRandomAnimation>true</disableRandomAnimation>
+ <disableRandomWalk>true</disableRandomWalk>
+ </AIData>
+ <npc id="22782" x="75142" y="145686" z="-3688" heading="45500" /> <!-- Sel Mahum Recruit -->
+ <npc id="22782" x="75057" y="145707" z="-3680" heading="45500" /> <!-- Sel Mahum Recruit -->
+ <npc id="22782" x="74998" y="145741" z="-3674" heading="45500" /> <!-- Sel Mahum Recruit -->
+ <npc id="22782" x="74934" y="145776" z="-3666" heading="45500" /> <!-- Sel Mahum Recruit -->
+ </spawn>
+ <spawn>
+ <npc id="109" x="75371" y="145798" z="-3694" heading="32761" />
+ </spawn>
+</list>
\ No newline at end of file
Index: dist/game/data/xsd/spawnlist.xsd
===================================================================
--- dist/game/data/xsd/spawnlist.xsd (revision 10055)
+++ dist/game/data/xsd/spawnlist.xsd (working copy)
@@ -45,6 +45,7 @@
</xs:sequence>
<xs:attribute type="xs:string" name="name" use="optional" />
<xs:attribute type="xs:string" name="zone" use="optional" />
+ <xs:attribute type="xs:boolean" name="scripted" use="optional" />
</xs:complexType>
</xs:element>
</xs:sequence>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment