From f5fd93da1dffda1ead9ecf76decb3e9981bae04b Mon Sep 17 00:00:00 2001 From: Jordan Irwin Date: Tue, 9 Jul 2024 18:53:47 -0700 Subject: [PATCH] New NPC Tinny https://github.com/arianne/stendhal/issues/256 --- data/conf/zones/deniran.xml | 1 + doc/CHANGES.txt | 1 + .../tannery/LeatherCrafterNPC.java | 93 +++++++++++++++++++ .../tannery/LeatherCrafterNPCTest.java | 72 ++++++++++++++ 4 files changed, 167 insertions(+) create mode 100644 src/games/stendhal/server/maps/deniran/cityinterior/tannery/LeatherCrafterNPC.java create mode 100644 tests/games/stendhal/server/maps/deniran/cityinterior/tannery/LeatherCrafterNPCTest.java diff --git a/data/conf/zones/deniran.xml b/data/conf/zones/deniran.xml index 043d84d280c..9f2390acdf7 100644 --- a/data/conf/zones/deniran.xml +++ b/data/conf/zones/deniran.xml @@ -1429,6 +1429,7 @@ Entrance fee is 10 money + diff --git a/doc/CHANGES.txt b/doc/CHANGES.txt index d856bf38f30..f786c8d239d 100644 --- a/doc/CHANGES.txt +++ b/doc/CHANGES.txt @@ -10,6 +10,7 @@ Changelog - Mayor Chalmers won't accept experimental sandwiches for Daily Item Quest - touched up and added equipment to many entity sprites - new player selectable hair +- new NPC Tinny *web client* - added visuals tab to settings dialog diff --git a/src/games/stendhal/server/maps/deniran/cityinterior/tannery/LeatherCrafterNPC.java b/src/games/stendhal/server/maps/deniran/cityinterior/tannery/LeatherCrafterNPC.java new file mode 100644 index 00000000000..9f18250dc63 --- /dev/null +++ b/src/games/stendhal/server/maps/deniran/cityinterior/tannery/LeatherCrafterNPC.java @@ -0,0 +1,93 @@ +/*************************************************************************** + * Copyright © 2024 - Faiumoni e. V. * + *************************************************************************** + *************************************************************************** + * * + * 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.deniran.cityinterior.tannery; + +import java.awt.Color; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import games.stendhal.common.constants.SkinColor; +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.ChatCondition; +import games.stendhal.server.entity.npc.ConversationPhrases; +import games.stendhal.server.entity.npc.ConversationStates; +import games.stendhal.server.entity.npc.SpeakerNPC; +import games.stendhal.server.entity.npc.condition.NotCondition; +import games.stendhal.server.entity.npc.condition.QuestRegisteredCondition; + + +public class LeatherCrafterNPC implements ZoneConfigurator { + + @Override + public void configureZone(StendhalRPZone zone, Map attributes) { + zone.add(buildNPC()); + } + + private SpeakerNPC buildNPC() { + final SpeakerNPC npc = new SpeakerNPC("Tinny"); + npc.setDescription("You see Tinny, the leather crafter."); + + buildOutfit(npc); + buildPath(npc); + buildDialogue(npc); + + return npc; + } + + private void buildOutfit(final SpeakerNPC npc) { + npc.setOutfit("body=0,head=0,eyes=3,hair=57,dress=968,mask=5,detail=16"); + npc.setOutfitColor("body", SkinColor.LIGHT); + npc.setOutfitColor("eyes", Color.BLUE); + } + + private void buildPath(final SpeakerNPC npc) { + final List nodes = new LinkedList<>(); + nodes.add(new Node(30, 4)); + nodes.add(new Node(20, 4)); + nodes.add(new Node(20, 13)); + nodes.add(new Node(30, 13)); + npc.setPath(new FixedPath(nodes, true)); + npc.setPosition(30, 4); + npc.setCollisionAction(CollisionAction.STOP); + } + + private void buildDialogue(final SpeakerNPC npc) { + npc.addGreeting("Hello, how can I help you?"); + npc.addGoodbye("Goodbye."); + npc.addJob("I am a leather crafter. I recently completed my apprenticeship under Skinner and" + + " will one day take over responsibility of the tannery."); + + final String questSlot = "items_for_tinny"; + final ChatCondition questNotRegistered = new NotCondition(new QuestRegisteredCondition(questSlot)); + + npc.add( + ConversationStates.ATTENDING, + ConversationPhrases.HELP_MESSAGES, + questNotRegistered, + ConversationStates.ATTENDING, + "If you are interested in a pouch to carry your money in, speak to Skinner.", + null); + + npc.add( + ConversationStates.ATTENDING, + ConversationPhrases.QUEST_MESSAGES, + questNotRegistered, + ConversationStates.ATTENDING, + "There is nothing I need help with at this time.", + null); + } +} diff --git a/tests/games/stendhal/server/maps/deniran/cityinterior/tannery/LeatherCrafterNPCTest.java b/tests/games/stendhal/server/maps/deniran/cityinterior/tannery/LeatherCrafterNPCTest.java new file mode 100644 index 00000000000..0dc8d3d3dfa --- /dev/null +++ b/tests/games/stendhal/server/maps/deniran/cityinterior/tannery/LeatherCrafterNPCTest.java @@ -0,0 +1,72 @@ +/*************************************************************************** + * Copyright © 2024 - Faiumoni e. V. * + *************************************************************************** + *************************************************************************** + * * + * 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.deniran.cityinterior.tannery; + +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.notNullValue; +import static org.junit.Assert.assertThat; +import static utilities.SpeakerNPCTestHelper.getReply; + +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import games.stendhal.server.core.engine.SingletonRepository; +import games.stendhal.server.entity.npc.SpeakerNPC; +import games.stendhal.server.entity.npc.fsm.Engine; +import games.stendhal.server.entity.player.Player; +import utilities.PlayerTestHelper; +import utilities.QuestHelper; +import utilities.ZonePlayerAndNPCTestImpl; + + +public class LeatherCrafterNPCTest extends ZonePlayerAndNPCTestImpl { + + @BeforeClass + public static void setUpBeforeClass() throws Exception { + QuestHelper.setUpBeforeClass(); + setupZone("testzone"); + } + + @Override + @Before + public void setUp() throws Exception { + setZoneForPlayer("testzone"); + setNpcNames("Tinny"); + addZoneConfigurator(new LeatherCrafterNPC(), "testzone"); + + super.setUp(); + } + + @Test + public void testDialogue() { + final Player player = PlayerTestHelper.createPlayer("player"); + final SpeakerNPC npc = SingletonRepository.getNPCList().get("Tinny"); + + assertThat(player, notNullValue()); + assertThat(npc, notNullValue()); + + final Engine en = npc.getEngine(); + en.step(player, "hi"); + assertThat(getReply(npc), is("Hello, how can I help you?")); + en.step(player, "job"); + assertThat(getReply(npc), is("I am a leather crafter. I recently completed my apprenticeship" + + " under Skinner and will one day take over responsibility of the tannery.")); + en.step(player, "help"); + assertThat(getReply(npc), is("If you are interested in a pouch to carry your money in, speak to" + + " Skinner.")); + en.step(player, "task"); + assertThat(getReply(npc), is("There is nothing I need help with at this time.")); + en.step(player, "bye"); + assertThat(getReply(npc), is("Goodbye.")); + } +}