Convert Unicorn Horns for Zelan to QuestManuscript
This commit is contained in:
parent
29bad6ce2e
commit
fac1d43535
7 changed files with 215 additions and 82 deletions
|
|
@ -1033,6 +1033,7 @@ Entrance fee is 10 money</attribute>
|
|||
|
||||
<!-- NPCs -->
|
||||
<configurator class-name="games.stendhal.server.maps.atlantis.cityoutside.GreeterNPC"/>
|
||||
<configurator class-name="games.stendhal.server.maps.atlantis.cityoutside.ZelanNPC"/>
|
||||
|
||||
<portal x="104" y="41" ref="potions_shop">
|
||||
<destination zone="int_atlantis_potions_shop" ref="entrance"/>
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
--[[
|
||||
***************************************************************************
|
||||
* Copyright © 2020 - Arianne *
|
||||
***************************************************************************
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program 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 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************
|
||||
]]
|
||||
|
||||
|
||||
local zoneName = "-7_deniran_atlantis"
|
||||
|
||||
if game:setZone(zoneName) then
|
||||
local zelan = entities:createSpeakerNPC("Zelan")
|
||||
|
||||
-- NPC appearance & behavior
|
||||
zelan:setEntityClass("atlantismale01npc")
|
||||
zelan:setCollisionAction(CollisionAction.STOP)
|
||||
|
||||
-- NPC location & path
|
||||
local nodes = {
|
||||
{63, 66},
|
||||
{75, 66},
|
||||
}
|
||||
zelan:setPathAndPosition(nodes, true)
|
||||
|
||||
-- NPC dialog
|
||||
zelan:addGreeting()
|
||||
zelan:addGoodbye()
|
||||
|
||||
-- add Zelan to the world
|
||||
game:add(zelan)
|
||||
|
||||
|
||||
-- quest
|
||||
local quest = quests.simple:create("unicorn_horns_for_zelan", "Unicorn Horns for Zelan", "Zelan")
|
||||
quest:setDescription("Zelan needs help gathering unicorn horns.")
|
||||
|
||||
quest:setReply(quests.simple.ID_REQUEST,
|
||||
"Hello! I'm in need of some unicorn horns to make some daggers."
|
||||
.. " It is really dangerous in the woods surrounding Atlantis. If you are a brave sort"
|
||||
.. " I could really use some help gathering unicorn horns. Will you help me?")
|
||||
quest:setReply(quests.simple.ID_ACCEPT,
|
||||
"Great! Be careful out there lots of large monsters, and those centaurs are really nasty")
|
||||
quest:setReply(quests.simple.ID_REWARD, "Thanks a bunch!")
|
||||
quest:setReply(quests.simple.ID_REJECT, "Thats ok, I will find someone else to help me.")
|
||||
|
||||
quest:setItemToCollect("unicorn horn", 10)
|
||||
quest:setXPReward(50000)
|
||||
quest:setKarmaReward(5.0)
|
||||
quest:addItemReward("soup", 3)
|
||||
quest:addItemReward("money", 20000)
|
||||
quest:setRegion(Region.ATLANTIS)
|
||||
|
||||
quests:register(quest)
|
||||
else
|
||||
logger:error("Could not set zone: " .. zoneName)
|
||||
end
|
||||
|
|
@ -186,6 +186,7 @@ public class StendhalQuestSystem {
|
|||
loadQuest(new TrapsForKlaas());
|
||||
//loadQuest(new TutorialIsland());
|
||||
loadQuest(new UltimateCollector());
|
||||
loadQuest(new UnicornHornsForZelan());
|
||||
loadQuest(new VampireSword());
|
||||
loadQuest(new WaterForXhiphin());
|
||||
loadQuest(new WeaponsCollector());
|
||||
|
|
|
|||
|
|
@ -552,6 +552,15 @@ public abstract class UpdateConverter {
|
|||
}
|
||||
}
|
||||
|
||||
// 1.43: Unicorn Horns for Zelan converted to QuestManuscript
|
||||
final String zelanQName = "unicorn_horns_for_zelan";
|
||||
if (player.hasQuest(zelanQName)) {
|
||||
final String[] zelanSlots = player.getQuest(zelanQName).split(";");
|
||||
if (zelanSlots.length == 2) {
|
||||
player.setQuest(zelanQName, zelanSlots[0] + ";;" + zelanSlots[1]);
|
||||
}
|
||||
}
|
||||
|
||||
// fix quest slots for kills quests.
|
||||
fixKillQuestsSlots(player);
|
||||
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
/***************************************************************************
|
||||
* (C) Copyright 2003-2022 - Stendhal *
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation; either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
package games.stendhal.server.maps.atlantis.cityoutside;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Map;
|
||||
|
||||
import games.stendhal.server.core.config.ZoneConfigurator;
|
||||
import games.stendhal.server.core.engine.StendhalRPZone;
|
||||
import games.stendhal.server.core.pathfinder.FixedPath;
|
||||
import games.stendhal.server.core.pathfinder.Node;
|
||||
import games.stendhal.server.entity.CollisionAction;
|
||||
import games.stendhal.server.entity.npc.SpeakerNPC;
|
||||
|
||||
|
||||
public class ZelanNPC implements ZoneConfigurator {
|
||||
|
||||
@Override
|
||||
public void configureZone(final StendhalRPZone zone, final Map<String, String> attributes) {
|
||||
zone.add(buildNPC());
|
||||
}
|
||||
|
||||
private SpeakerNPC buildNPC() {
|
||||
final SpeakerNPC zelan = new SpeakerNPC("Zelan");
|
||||
|
||||
// appearance & behavior
|
||||
zelan.setEntityClass("atlantismale01npc");
|
||||
zelan.setCollisionAction(CollisionAction.STOP);
|
||||
|
||||
// location & path
|
||||
zelan.setPathAndPosition(new FixedPath(Arrays.asList(
|
||||
new Node(63, 66),
|
||||
new Node(75, 66)), true));
|
||||
|
||||
// dialog
|
||||
zelan.addGreeting();
|
||||
zelan.addGoodbye();
|
||||
|
||||
return zelan;
|
||||
}
|
||||
}
|
||||
113
src/games/stendhal/server/maps/quests/UnicornHornsForZelan.java
Normal file
113
src/games/stendhal/server/maps/quests/UnicornHornsForZelan.java
Normal file
|
|
@ -0,0 +1,113 @@
|
|||
/***************************************************************************
|
||||
* Copyright © 2003-2023 - Arianne *
|
||||
***************************************************************************
|
||||
***************************************************************************
|
||||
* *
|
||||
* This program 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 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
package games.stendhal.server.maps.quests;
|
||||
|
||||
import games.stendhal.server.entity.npc.action.EquipItemAction;
|
||||
import games.stendhal.server.entity.npc.action.IncreaseKarmaAction;
|
||||
import games.stendhal.server.entity.npc.action.IncreaseXPAction;
|
||||
import games.stendhal.server.entity.npc.quest.BringItemTask;
|
||||
import games.stendhal.server.entity.npc.quest.QuestBuilder;
|
||||
import games.stendhal.server.entity.npc.quest.QuestManuscript;
|
||||
import games.stendhal.server.maps.Region;
|
||||
|
||||
|
||||
/**
|
||||
* QUEST: Unicorn Horns for Zelan
|
||||
*
|
||||
* PARTICIPANTS:
|
||||
* <ul>
|
||||
* <li>Zelan</li>
|
||||
* </ul>
|
||||
*
|
||||
* STEPS:
|
||||
* <ul>
|
||||
* <li>Zelan needs 10 unicorn horns.</li>
|
||||
* <li>Bring the unicorn horns to him for a reward.</li>
|
||||
* </ul>
|
||||
*
|
||||
* REWARD:
|
||||
* <ul>
|
||||
* <li>50000 xp</li>
|
||||
* <li>5 karma</li>
|
||||
* <li>3 soup</li>
|
||||
* <li>20000 money</li>
|
||||
* </ul>
|
||||
*
|
||||
* REPETITIONS:
|
||||
* <ul>
|
||||
* <li>never</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class UnicornHornsForZelan implements QuestManuscript {
|
||||
|
||||
@Override
|
||||
public QuestBuilder<?> story() {
|
||||
QuestBuilder<BringItemTask> quest = new QuestBuilder<>(new BringItemTask());
|
||||
|
||||
final String npcName = "Zelan";
|
||||
final int quantity = 10;
|
||||
final String itemName = "unicorn horn";
|
||||
final String plItemName = itemName + "s";
|
||||
final int rewardSoup = 3;
|
||||
final int rewardMoney = 20000;
|
||||
|
||||
quest.info()
|
||||
.name("Unicorn Horns for Zelan")
|
||||
.internalName("unicorn_horns_for_zelan")
|
||||
.description("Zelan needs help gathering unicorn horns.")
|
||||
.region(Region.ATLANTIS)
|
||||
.questGiverNpc(npcName)
|
||||
.notRepeatable();
|
||||
|
||||
quest.history()
|
||||
.whenNpcWasMet(npcName + " asked me to get " + quantity
|
||||
+ " " + plItemName + ".")
|
||||
.whenQuestWasRejected("I do not want to help " + npcName + ".")
|
||||
.whenQuestWasAccepted("I have not found what I am looking for yet.")
|
||||
.whenTaskWasCompleted("I have what " + npcName + " asked for.")
|
||||
.whenQuestWasCompleted("I found " + quantity
|
||||
+ " " + plItemName + " for " + npcName + ".");
|
||||
|
||||
quest.offer()
|
||||
.respondToRequest("Hello! I'm in need of some unicorn horns to"
|
||||
+ " make some daggers. It is really dangerous in the woods"
|
||||
+ " surrounding Atlantis. If you are a brave sort I could"
|
||||
+ " really use some help gathering unicorn horns. Will you"
|
||||
+ " help me?")
|
||||
.respondToUnrepeatableRequest("Thanks, but I don't need any more"
|
||||
+ " help.")
|
||||
.respondToAccept("Great! Be careful out there lots of large"
|
||||
+ " monsters, and those centaurs are really nasty.")
|
||||
.respondToReject("Thats ok, I will find someone else to help me.")
|
||||
.rejectionKarmaPenalty(0)
|
||||
//~ .remind("I have already asked you to get " + quantity
|
||||
//~ + " " + plItemName + ". Are you #done?");
|
||||
.remind("I asked you to bring me " + quantity + " " + plItemName
|
||||
+ ".");
|
||||
|
||||
quest.task()
|
||||
.requestItem(quantity, itemName);
|
||||
|
||||
quest.complete()
|
||||
.greet("Did you find the " + plItemName + "?")
|
||||
.respondToReject("I asked you to bring me " + quantity + " "
|
||||
+ plItemName + ".")
|
||||
.respondToAccept("Thanks a bunch! As a reward I will give you "
|
||||
+ rewardSoup + " soups and " + rewardMoney + " money.")
|
||||
.rewardWith(new IncreaseXPAction(50000))
|
||||
.rewardWith(new IncreaseKarmaAction(5.0))
|
||||
.rewardWith(new EquipItemAction("soup", rewardSoup))
|
||||
.rewardWith(new EquipItemAction("money", rewardMoney));
|
||||
|
||||
return quest;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,5 +1,5 @@
|
|||
/***************************************************************************
|
||||
* (C) Copyright 2003-2022 - Arianne *
|
||||
* Copyright © 2003-2023 - Arianne *
|
||||
***************************************************************************
|
||||
***************************************************************************
|
||||
* *
|
||||
|
|
@ -9,7 +9,7 @@
|
|||
* (at your option) any later version. *
|
||||
* *
|
||||
***************************************************************************/
|
||||
package scripts.quest;
|
||||
package games.stendhal.server.maps.quests;
|
||||
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.junit.Assert.assertFalse;
|
||||
|
|
@ -21,28 +21,31 @@ import org.junit.Before;
|
|||
import org.junit.Test;
|
||||
|
||||
import games.stendhal.server.core.engine.SingletonRepository;
|
||||
import games.stendhal.server.core.engine.StendhalRPZone;
|
||||
import games.stendhal.server.entity.npc.ConversationStates;
|
||||
import games.stendhal.server.entity.npc.SpeakerNPC;
|
||||
import games.stendhal.server.entity.npc.fsm.Engine;
|
||||
import utilities.LuaTestHelper;
|
||||
import utilities.PlayerTestHelper;
|
||||
import games.stendhal.server.entity.player.Player;
|
||||
import games.stendhal.server.maps.atlantis.cityoutside.ZelanNPC;
|
||||
import utilities.QuestHelper;
|
||||
|
||||
|
||||
public class UnicornHornsForZelanTest extends LuaTestHelper {
|
||||
public class UnicornHornsForZelanTest extends QuestHelper {
|
||||
|
||||
private SpeakerNPC zelan;
|
||||
private Player player;
|
||||
|
||||
private final String slot = "unicorn_horns_for_zelan";
|
||||
|
||||
|
||||
@Before
|
||||
public void setUp() {
|
||||
setUpZone("-7_deniran_atlantis");
|
||||
load("data/script/region/atlantis/city/exterior/ZelanNPC.lua");
|
||||
loadCachedQuests();
|
||||
|
||||
addPlayerToWorld();
|
||||
player = createPlayer("tester");
|
||||
// load Zelan
|
||||
new ZelanNPC().configureZone(new StendhalRPZone("testzone"), null);
|
||||
zelan = SingletonRepository.getNPCList().get("Zelan");
|
||||
// load quest
|
||||
quests.loadQuest(new UnicornHornsForZelan());
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
@ -57,6 +60,8 @@ public class UnicornHornsForZelanTest extends LuaTestHelper {
|
|||
}
|
||||
|
||||
private void testQuest() {
|
||||
assertTrue(quests.isLoaded(quests.getQuestFromSlot(slot)));
|
||||
|
||||
final Engine en = zelan.getEngine();
|
||||
|
||||
assertFalse(player.hasQuest(slot));
|
||||
|
|
@ -72,11 +77,13 @@ public class UnicornHornsForZelanTest extends LuaTestHelper {
|
|||
assertEquals(ConversationStates.ATTENDING, en.getCurrentState());
|
||||
|
||||
en.step(player, "quest");
|
||||
assertEquals(ConversationStates.QUEST_OFFERED, en.getCurrentState());
|
||||
assertEquals(ConversationStates.QUEST_OFFERED,
|
||||
en.getCurrentState());
|
||||
assertEquals(
|
||||
"Hello! I'm in need of some unicorn horns to make some daggers."
|
||||
+ " It is really dangerous in the woods surrounding Atlantis. If you are a brave sort"
|
||||
+ " I could really use some help gathering unicorn horns. Will you help me?",
|
||||
+ " It is really dangerous in the woods surrounding Atlantis. If"
|
||||
+ " you are a brave sort I could really use some help gathering"
|
||||
+ " unicorn horns. Will you help me?",
|
||||
getReply(zelan));
|
||||
en.step(player, "no");
|
||||
assertEquals(ConversationStates.ATTENDING, en.getCurrentState());
|
||||
|
|
@ -90,36 +97,52 @@ public class UnicornHornsForZelanTest extends LuaTestHelper {
|
|||
en.step(player, "yes");
|
||||
assertEquals(ConversationStates.ATTENDING, en.getCurrentState());
|
||||
assertEquals(
|
||||
"Great! Be careful out there lots of large monsters, and those centaurs are really nasty",
|
||||
"Great! Be careful out there lots of large monsters, and those"
|
||||
+ " centaurs are really nasty.",
|
||||
getReply(zelan));
|
||||
assertEquals("start", player.getQuest(slot, 0));
|
||||
assertTrue(player.getKarma() == playerKarma);
|
||||
en.step(player, "bye");
|
||||
assertEquals(ConversationStates.IDLE, en.getCurrentState());
|
||||
|
||||
PlayerTestHelper.equipWithStackableItem(player, "unicorn horn", 9);
|
||||
equipWithStackableItem(player, "unicorn horn", 9);
|
||||
|
||||
en.step(player, "hi");
|
||||
assertEquals(ConversationStates.ATTENDING, en.getCurrentState());
|
||||
en.step(player, "done");
|
||||
assertEquals("I asked you to bring me 10 unicorn horns.", getReply(zelan));
|
||||
assertEquals(
|
||||
"I asked you to bring me 10 unicorn horns.",
|
||||
getReply(zelan));
|
||||
en.step(player, "bye");
|
||||
|
||||
PlayerTestHelper.equipWithStackableItem(player, "unicorn horn", 1);
|
||||
equipWithStackableItem(player, "unicorn horn", 1);
|
||||
|
||||
en.step(player, "hi");
|
||||
en.step(player, "done");
|
||||
assertEquals(ConversationStates.QUEST_ITEM_BROUGHT,
|
||||
en.getCurrentState());
|
||||
assertEquals("Did you find the unicorn horns?", getReply(zelan));
|
||||
en.step(player, "yes");
|
||||
assertEquals(
|
||||
"Thanks a bunch! As a reward I will give you 3 soups and 20000 money.",
|
||||
"Thanks a bunch! As a reward I will give you 3 soups and 20000"
|
||||
+ " money.",
|
||||
getReply(zelan));
|
||||
en.step(player, "bye");
|
||||
assertEquals(ConversationStates.IDLE, en.getCurrentState());
|
||||
|
||||
assertEquals("done", player.getQuest(slot, 0));
|
||||
assertEquals("1", player.getQuest(slot, 2));
|
||||
assertTrue(player.getKarma() == playerKarma + 5);
|
||||
assertEquals(playerXP + 50000, player.getXP());
|
||||
assertEquals(0, player.getNumberOfEquipped("unicorn horn"));
|
||||
assertEquals(3, player.getNumberOfEquipped("soup"));
|
||||
assertEquals(20000, player.getNumberOfEquipped("money"));
|
||||
|
||||
en.step(player, "hi");
|
||||
en.step(player, "quest");
|
||||
assertEquals(ConversationStates.ATTENDING, en.getCurrentState());
|
||||
assertEquals(
|
||||
"Thanks, but I don't need any more help.",
|
||||
getReply(zelan));
|
||||
en.step(player, "bye");
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue