diff --git a/README.txt b/README.txt index 475afbeb02..0ded1397e2 100644 --- a/README.txt +++ b/README.txt @@ -39,12 +39,12 @@ Java is included in most Linux distributions. Both Sun Java and OpenJDK are supp Please download Stendhal from http://arianne.sourceforge.net Then unzip the client zip into a new folder. -You can double click on stendhal-0.92.5.jar and the client will run. +You can double click on stendhal-0.93.1.jar and the client will run. If you prefer to run from command line, then just execute this command in the stendhal folder: - java -jar stendhal-0.92.5.jar + java -jar stendhal-0.93.1.jar Alternatively you can run it using Java Webstart technology at: diff --git a/build.ant.properties b/build.ant.properties index dd584f9d23..a2f562d88e 100644 --- a/build.ant.properties +++ b/build.ant.properties @@ -72,8 +72,8 @@ updates_server = http://arianne.sourceforge.net/stendhal/updates version_server = http://arianne.sourceforge.net/stendhal.version # current version of stendhal -version.old = 0.92 -version = 0.92.5 +version.old = 0.93 +version = 0.93.1 # javac options javac.deprecation = true diff --git a/runserver.bat b/runserver.bat index dfef766871..cdb76a2b1d 100644 --- a/runserver.bat +++ b/runserver.bat @@ -1,3 +1,3 @@ -set STENDHAL_VERSION=0.92.5 +set STENDHAL_VERSION=0.93.1 set LOCALCLASSPATH=.;data\script;data\conf;stendhal-server-%STENDHAL_VERSION%.jar;marauroa.jar;mysql-connector.jar;log4j.jar;commons-lang.jar;h2.jar java -Xmx400m -cp "%LOCALCLASSPATH%" marauroa.server.marauroad -c server.ini -l diff --git a/runserver.sh b/runserver.sh index 7d6e8b1ec4..9ebc4484a6 100644 --- a/runserver.sh +++ b/runserver.sh @@ -1,5 +1,5 @@ #!/bin/sh -STENDHAL_VERSION="0.92.5" +STENDHAL_VERSION="0.93.1" LOCALCLASSPATH=.:data/script/:data/conf/:stendhal-server-$STENDHAL_VERSION.jar:marauroa.jar:mysql-connector.jar:log4j.jar:commons-lang.jar:h2.jar diff --git a/src/games/stendhal/client/gui/ItemPanel.java b/src/games/stendhal/client/gui/ItemPanel.java index 30dbc9f72d..2e74188ed1 100644 --- a/src/games/stendhal/client/gui/ItemPanel.java +++ b/src/games/stendhal/client/gui/ItemPanel.java @@ -157,6 +157,8 @@ public class ItemPanel extends JComponent implements DropTarget { } else { setCursor(null); } + // The old popup menu is no longer valid + popupMenu = null; } /** diff --git a/src/games/stendhal/client/update/Version.java b/src/games/stendhal/client/update/Version.java index d77ee3f410..3895ff2c64 100644 --- a/src/games/stendhal/client/update/Version.java +++ b/src/games/stendhal/client/update/Version.java @@ -10,7 +10,7 @@ package games.stendhal.client.update; public class Version { /** Version Number. */ - private static final String VERSION = "0.92.5"; + private static final String VERSION = "0.93.1"; /** * Extract the specified number of parts from a version-string. diff --git a/src/games/stendhal/common/Debug.java b/src/games/stendhal/common/Debug.java index a47d85dc65..e649bfa59b 100644 --- a/src/games/stendhal/common/Debug.java +++ b/src/games/stendhal/common/Debug.java @@ -26,7 +26,7 @@ public class Debug { /** version. */ // Note: This line is updated by build.xml using a regexp so be sure to adjust it in case you modify this line. - public static final String VERSION = "0.92.5"; + public static final String VERSION = "0.93.1"; public static final String PRE_RELEASE_VERSION = null; diff --git a/src/games/stendhal/server/actions/equip/SourceObject.java b/src/games/stendhal/server/actions/equip/SourceObject.java index ddfb9bb246..c883135fd9 100644 --- a/src/games/stendhal/server/actions/equip/SourceObject.java +++ b/src/games/stendhal/server/actions/equip/SourceObject.java @@ -65,10 +65,11 @@ class SourceObject extends MoveableObject { } SourceObject source; - if (action.has(EquipActionConsts.SOURCE_PATH)) { + /* TODO: disabled because of + * if (action.has(EquipActionConsts.SOURCE_PATH)) { source = createSource(action, player); // Otherwise use compatibility mode - } else if (action.has(EquipActionConsts.BASE_OBJECT)) { + } else*/if (action.has(EquipActionConsts.BASE_OBJECT)) { source = createSourceForContainedItem(action, player); } else { source = createSourceForNonContainedItem(action, player); diff --git a/src/games/stendhal/server/core/engine/GenerateINI.java b/src/games/stendhal/server/core/engine/GenerateINI.java index b5b075fb1d..9d017dd449 100644 --- a/src/games/stendhal/server/core/engine/GenerateINI.java +++ b/src/games/stendhal/server/core/engine/GenerateINI.java @@ -271,7 +271,7 @@ public class GenerateINI { out.println(); out.println("server_typeGame=" + gameName); out.println("server_name=" + gameName + " Marauroa server"); - out.println("server_version=0.92.5"); + out.println("server_version=0.93.1"); out.println("server_contact=https://sourceforge.net/tracker/?atid=514826&group_id=66537&func=browse"); out.println(); out.println("# Extensions configured on the server. Enable at will."); diff --git a/src/games/stendhal/server/core/engine/StendhalRPRuleProcessor.java b/src/games/stendhal/server/core/engine/StendhalRPRuleProcessor.java index 6bcd4c6e16..ffef286f71 100644 --- a/src/games/stendhal/server/core/engine/StendhalRPRuleProcessor.java +++ b/src/games/stendhal/server/core/engine/StendhalRPRuleProcessor.java @@ -262,24 +262,41 @@ public class StendhalRPRuleProcessor implements IRPRuleProcessor { final long start = System.nanoTime(); try { - destroyObsoleteZones(); - - logNumberOfPlayersOnline(); - - handleKilledEntities(); - - executePlayerLogic(); - - executeNPCsPreLogic(); - - handlePlayersRmTexts(); - } catch (final Exception e) { logger.error("error in beginTurn", e); - } finally { - logger.debug("Begin turn: " + (System.nanoTime() - start) / 1000000.0); } + + try { + logNumberOfPlayersOnline(); + } catch (final Exception e) { + logger.error("error in beginTurn", e); + } + + try { + handleKilledEntities(); + } catch (final Exception e) { + logger.error("error in beginTurn", e); + } + + try { + executePlayerLogic(); + } catch (final Exception e) { + logger.error("error in beginTurn", e); + } + + try { + executeNPCsPreLogic(); + } catch (final Exception e) { + logger.error("error in beginTurn", e); + } + + try { + handlePlayersRmTexts(); + } catch (final Exception e) { + logger.error("error in beginTurn", e); + } + logger.debug("Begin turn: " + (System.nanoTime() - start) / 1000000.0); } private void destroyObsoleteZones() { diff --git a/src/games/stendhal/server/core/rp/achievement/factory/KilledSharedAllCreaturesCondition.java b/src/games/stendhal/server/core/rp/achievement/factory/KilledSharedAllCreaturesCondition.java index 390114a3d2..6d7811208b 100644 --- a/src/games/stendhal/server/core/rp/achievement/factory/KilledSharedAllCreaturesCondition.java +++ b/src/games/stendhal/server/core/rp/achievement/factory/KilledSharedAllCreaturesCondition.java @@ -26,7 +26,6 @@ import org.apache.commons.lang.builder.HashCodeBuilder; /** * Did the player kill all creatures, shared? (excluding rare) * - * @author kymara */ public class KilledSharedAllCreaturesCondition implements ChatCondition { @@ -35,7 +34,7 @@ public class KilledSharedAllCreaturesCondition implements ChatCondition { final Collection creatures = SingletonRepository.getEntityManager().getCreatures(); for (Creature creature : creatures) { if (!creature.isRare()) { - if (!player.hasKilled(creature.getName())) { + if (!player.hasKilledShared(creature.getName())) { return false; } } diff --git a/src/games/stendhal/server/entity/item/StackableItem.java b/src/games/stendhal/server/entity/item/StackableItem.java index cfa4307050..f443fb758e 100644 --- a/src/games/stendhal/server/entity/item/StackableItem.java +++ b/src/games/stendhal/server/entity/item/StackableItem.java @@ -102,6 +102,9 @@ public class StackableItem extends Item implements Stackable { public int add(final StackableItem other) { if (this.isStackable(other)) { setQuantity(other.getQuantity() + getQuantity()); + // set flag to false to prevent abuse by adding to a stackable in a corpse + // leading to a too high number awarded when looting + this.setFromCorpse(false); } return getQuantity(); } diff --git a/src/games/stendhal/server/entity/npc/action/DropInfostringItemAction.java b/src/games/stendhal/server/entity/npc/action/DropInfostringItemAction.java index bb74d6bad8..0b70e6a200 100644 --- a/src/games/stendhal/server/entity/npc/action/DropInfostringItemAction.java +++ b/src/games/stendhal/server/entity/npc/action/DropInfostringItemAction.java @@ -32,6 +32,7 @@ public class DropInfostringItemAction implements ChatAction { private static Logger logger = Logger.getLogger(DropItemAction.class); private final String itemName; private final String infostring; + private final int amount; /** * Creates a new DropInfostringItemAction. @@ -43,6 +44,23 @@ public class DropInfostringItemAction implements ChatAction { */ public DropInfostringItemAction(final String itemName, final String infostring) { this.itemName = itemName; + this.amount = 1; + this.infostring = infostring; + } + + /** + * Creates a new DropInfostringItemAction. + * + * @param itemName + * name of item + * @param amount + * amount of item + * @param infostring + * infostring of the dropped item + */ + public DropInfostringItemAction(final String itemName, final int amount, final String infostring) { + this.itemName = itemName; + this.amount = amount; this.infostring = infostring; } @@ -51,7 +69,7 @@ public class DropInfostringItemAction implements ChatAction { boolean res = false; for (final Item item : items) { if (infostring.equalsIgnoreCase(item.getInfoString())) { - res = player.drop(item); + res = player.drop(item.getName(), amount); break; } } @@ -64,7 +82,7 @@ public class DropInfostringItemAction implements ChatAction { @Override public String toString() { - return "drop item <" + itemName + "> with infostring <" + infostring + ">"; + return "drop " + amount + " of item <" + itemName + "> with infostring <" + infostring + ">"; } @Override @@ -87,6 +105,9 @@ public class DropInfostringItemAction implements ChatAction { if (!infostring.equals(other.infostring)) { return false; } + if (amount != other.amount) { + return false; + } if (itemName == null) { if (other.itemName != null) { return false; diff --git a/src/games/stendhal/server/entity/npc/parser/NameSearch.java b/src/games/stendhal/server/entity/npc/parser/NameSearch.java index 59b3c072e7..b1663bacc4 100644 --- a/src/games/stendhal/server/entity/npc/parser/NameSearch.java +++ b/src/games/stendhal/server/entity/npc/parser/NameSearch.java @@ -49,18 +49,31 @@ public final class NameSearch { boolean found = false; final String itemName = item.getNormalized(); + for(Map.Entry e : parsedNames.entrySet()) { Sentence parsed = e.getValue(); - - if (itemName.endsWith(parsed.getOriginalText()) || - itemName.endsWith(parsed.getNormalized()) || - parsed.matchesNormalized(itemName)) { + + if (parsed.matchesNormalized(itemName)) { name = e.getKey(); found = true; break; } } - + + if (!found) { + // see if instead the end matches, this is deliberately done afterwards because of bug #3285554 + for(Map.Entry e : parsedNames.entrySet()) { + Sentence parsed = e.getValue(); + + if (itemName.endsWith(parsed.getOriginalText()) || + itemName.endsWith(parsed.getNormalized())) { + name = e.getKey(); + found = true; + break; + } + } + } + if (!found) { // see if instead the plural matches final String pluralName = Grammar.plural(itemName); diff --git a/src/games/stendhal/server/entity/trade/Market.java b/src/games/stendhal/server/entity/trade/Market.java index 63e80adb20..9c0915b894 100644 --- a/src/games/stendhal/server/entity/trade/Market.java +++ b/src/games/stendhal/server/entity/trade/Market.java @@ -219,7 +219,7 @@ public class Market extends PassiveEntity { * @param acceptingPlayer */ public boolean acceptOffer(final Offer offer, final Player acceptingPlayer) { - if (getSlot(OFFERS_SLOT_NAME).has(offer.getID())) { + if (getSlot(OFFERS_SLOT_NAME).has(offer.getID()) && offer.hasItem()) { int price = offer.getPrice().intValue(); // Take the money; free items should always succeed if ((price == 0) || acceptingPlayer.drop("money", price)) { @@ -337,6 +337,8 @@ public class Market extends PassiveEntity { */ public void removeOffer(Offer o, Player p) { Item item = o.getItem(); + String itemName = item.getName(); + o.getSlot(Offer.OFFER_ITEM_SLOT_NAME).remove(item.getID()); p.equipOrPutOnGround(item); @@ -354,9 +356,8 @@ public class Market extends PassiveEntity { slotName = item.getContainerSlot().getName(); target = "slot"; } - new ItemLogger() - .addLogItemEventCommand(new LogSimpleItemEventCommand(item, p, - "market-to-" + target, item.get("name"), Integer + new ItemLogger().addLogItemEventCommand(new LogSimpleItemEventCommand(item, p, + "market-to-" + target, itemName, Integer .toString(getQuantity(item)), "remove offer", slotName)); } @@ -371,8 +372,11 @@ public class Market extends PassiveEntity { this.getSlot(OFFERS_SLOT_NAME).remove(o.getID()); this.getSlot(EXPIRED_OFFERS_SLOT_NAME).add(o); this.getZone().storeToDatabase(); - new GameEvent("market", "expire-offer", o.getOfferer(), o.getItem() - .getName(), o.getPrice().toString()).raise(); + String itemname = "null"; + if (o.hasItem()) { + itemname = o.getItem().getName(); + } + new GameEvent("market", "expire-offer", o.getOfferer(), itemname, o.getPrice().toString()).raise(); } /** @@ -395,8 +399,10 @@ public class Market extends PassiveEntity { this.getSlot(EXPIRED_OFFERS_SLOT_NAME).remove(offerToRemove.getID()); Item item = offerToRemove.getItem(); - new ItemLogger().destroy(null, this.getSlot(EXPIRED_OFFERS_SLOT_NAME), - item, "timeout"); + if (item != null) { + new ItemLogger().destroy(null, this.getSlot(EXPIRED_OFFERS_SLOT_NAME), + item, "timeout"); + } this.getZone().storeToDatabase(); } diff --git a/src/games/stendhal/server/entity/trade/Offer.java b/src/games/stendhal/server/entity/trade/Offer.java index f0295c2513..dd32956985 100644 --- a/src/games/stendhal/server/entity/trade/Offer.java +++ b/src/games/stendhal/server/entity/trade/Offer.java @@ -112,9 +112,33 @@ public class Offer extends Entity implements Dateable { * @return the Item for sale */ public final Item getItem() { + if (getSlot(OFFER_ITEM_SLOT_NAME).size() == 0) { + return null; + } return (Item) getSlot(OFFER_ITEM_SLOT_NAME).iterator().next(); } + /** + * checks if an item is attached to this offer. + * @return true, if this offer has an item + */ + public boolean hasItem() { + return (hasSlot(OFFER_ITEM_SLOT_NAME) && getSlot(OFFER_ITEM_SLOT_NAME).size() != 0); + } + + /** + * gets the name of the item + * + * @return name of item or "null", if there is no item in this offer + */ + public String getItemName() { + if (hasItem()) { + return getItem().getName(); + } + logger.error("Trying to get item name from empty slot", new Throwable()); + return "null"; + } + /** * @return the price to pay for this offer when accepting it */ @@ -180,4 +204,5 @@ public class Offer extends Entity implements Dateable { return cid; } } + } diff --git a/src/games/stendhal/server/maps/fado/forest/OldWitchNPC.java b/src/games/stendhal/server/maps/fado/forest/OldWitchNPC.java index 2f4caad885..3417ec8c69 100644 --- a/src/games/stendhal/server/maps/fado/forest/OldWitchNPC.java +++ b/src/games/stendhal/server/maps/fado/forest/OldWitchNPC.java @@ -48,20 +48,20 @@ public class OldWitchNPC implements ZoneConfigurator { @Override protected void createDialog() { addGreeting("Hello *Cough*"); - addJob("I had been a powerful witch before I risked too much and lost my powers while fighting against some #werwolfes."); - addReply("werwolfes", "They are really dangerous! I met some on the way to Kikareukin earlier and have been deeply poisoned. That is why I have to rest here."); - addQuest("Oh dear, you seem to be really nice and trustful but I can't give you any work at the moment."); - addHelp("My daughter #Imorgen outside can maybe help you. She knows lots of people around Faiumoni."); - addReply("Imorgen", "She will hopefully become a powerful witch like me in the future. But she still has to learn a lot."); + addJob("I was once a powerful witch. But I took a great risk and lost my powers, fighting against some #werewolves."); + addReply("werewolves", "They are really dangerous! I met some on the way to Kikareukin earlier and have been deeply poisoned. That is why I have to rest here."); + addQuest("Oh dear, you seem to be really nice and trustful, but I can't give you any work at the moment."); + addHelp("Maybe my daughter #Imorgen outside can help you. She knows lots of people around Faiumoni."); + addReply("Imorgen", "Hopefully she'll become a powerful witch like me in the future. But she still has to learn a lot."); addOffer("I would like to sell you one of my famous drinks but I can't *cough*."); - addGoodbye("I hope we'll see us again soon *sigh*."); + addGoodbye("I hope we'll meet again soon *sigh*."); } }; npc.setEntityClass("oldwitchnpc"); npc.setPosition(12, 4); npc.initHP(100); - npc.setDescription("You see Mircea. She is an old asthenic witch who seems to become weaken each second."); + npc.setDescription("You see Mircea. She is an old thin witch, who seems to become weaker each second."); zone.add(npc); } } diff --git a/src/games/stendhal/server/maps/fado/forest/WitchNPC.java b/src/games/stendhal/server/maps/fado/forest/WitchNPC.java index cb91177297..477416437b 100644 --- a/src/games/stendhal/server/maps/fado/forest/WitchNPC.java +++ b/src/games/stendhal/server/maps/fado/forest/WitchNPC.java @@ -53,12 +53,12 @@ public class WitchNPC implements ZoneConfigurator { @Override protected void createDialog() { addGreeting("Hello wanderer!"); - addJob("I'm a witch and pratice each day to become a powerful one soon."); - addQuest("My grandma inside is quite concerned... She is ill and afraid and I need to help her and will figure out, #how..."); - addReply("how", "The question really is what may help here... Maybe I'll ask her later about it, I first have to finish my new #receipe..."); - addReply("receipe", "Oh I doubt that you can eat or drink what I prepare at the moment... But I know two really nice women who can make some tasty #soup for you."); + addJob("I'm a witch and practice each day, I hope to become a powerful one soon."); + addQuest("My grandma inside is quite concerned... She is ill and afraid and I need to help her. I just need to figure out #how..."); + addReply("how", "The question really is what may help... Maybe I'll ask her later about it, I first have to finish my new #recipe..."); + addReply("recipe", "Oh I doubt that you can eat or drink what I prepare at the moment... But I know two really nice women who can make some tasty #soup for you."); addReply("soup", "Florence Boullabaisse and Mother Helena are awesome soup cooks. You'll find them on the Ados market and in the Fado tavern."); - addHelp("Aldrin sells some honey, you will love to eat it with bread."); + addHelp("Aldrin sells some honey, you would love to eat it with bread."); addOffer("I'm sorry but I can't sell you anything."); addGoodbye("Bye bye and take care around here!"); } @@ -67,7 +67,7 @@ public class WitchNPC implements ZoneConfigurator { npc.setEntityClass("youngwitchnpc"); npc.setPosition(59, 29); npc.initHP(100); - npc.setDescription("You see Imorgin. She is a young witch whose mystical aura can be felt over a long distance."); + npc.setDescription("You see Imorgen. She is a young witch whose mystical aura can be felt over a long distance."); zone.add(npc); } } diff --git a/src/games/stendhal/server/maps/semos/tavern/market/AcceptOfferHandler.java b/src/games/stendhal/server/maps/semos/tavern/market/AcceptOfferHandler.java index 2124f8984e..d8771699fa 100644 --- a/src/games/stendhal/server/maps/semos/tavern/market/AcceptOfferHandler.java +++ b/src/games/stendhal/server/maps/semos/tavern/market/AcceptOfferHandler.java @@ -68,11 +68,13 @@ public class AcceptOfferHandler extends OfferHandler { } if(offerMap.containsKey(offerNumber)) { Offer o = offerMap.get(offerNumber); - setOffer(o); - int quantity = getQuantity(o.getItem()); - npc.say("Do you want to buy " + Grammar.quantityplnoun(quantity, o.getItem().getName(), "a") + " for " + o.getPrice() + " money?"); - npc.setCurrentState(ConversationStates.BUY_PRICE_OFFERED); - return; + if (o.hasItem()) { + setOffer(o); + int quantity = getQuantity(o.getItem()); + npc.say("Do you want to buy " + Grammar.quantityplnoun(quantity, o.getItem().getName(), "a") + " for " + o.getPrice() + " money?"); + npc.setCurrentState(ConversationStates.BUY_PRICE_OFFERED); + return; + } } npc.say("Sorry, please choose a number from those I told you to accept an offer."); } catch (NumberFormatException e) { @@ -85,11 +87,12 @@ public class AcceptOfferHandler extends OfferHandler { public void fire (Player player, Sentence sentence, EventRaiser npc) { Offer offer = getOffer(); Market m = TradeCenterZoneConfigurator.getShopFromZone(player.getZone()); + String itemname = offer.getItemName(); if (m.acceptOffer(offer,player)) { // Successful trade. Tell the offerer StringBuilder earningToFetchMessage = new StringBuilder(); earningToFetchMessage.append("Your "); - earningToFetchMessage.append(offer.getItem().getName()); + earningToFetchMessage.append(itemname); earningToFetchMessage.append(" was sold. You can now fetch your earnings from me."); logger.debug("sending a notice to '" + offer.getOfferer() + "': " + earningToFetchMessage.toString()); @@ -97,7 +100,7 @@ public class AcceptOfferHandler extends OfferHandler { npc.say("Thanks."); // Obsolete the offers, since the list has changed - ((MarketManagerNPC) npc.getEntity()).getOfferMap().put(player.getName(), null); + ((MarketManagerNPC) npc.getEntity()).getOfferMap().clear(); } else { // Trade failed for some reason. Check why, and inform the player if (!m.contains(offer)) { diff --git a/src/games/stendhal/server/maps/semos/tavern/market/ExamineOfferChatAction.java b/src/games/stendhal/server/maps/semos/tavern/market/ExamineOfferChatAction.java index 614a7e83b2..a1884ffe41 100644 --- a/src/games/stendhal/server/maps/semos/tavern/market/ExamineOfferChatAction.java +++ b/src/games/stendhal/server/maps/semos/tavern/market/ExamineOfferChatAction.java @@ -42,10 +42,11 @@ public class ExamineOfferChatAction extends KnownOffersChatAction { } if(offerMap.containsKey(offerNumber)) { Offer o = offerMap.get(offerNumber); - - player.sendPrivateText(o.getItem().describe()); - showImage(player, o.getItem()); - return; + if (o.hasItem()) { + player.sendPrivateText(o.getItem().describe()); + showImage(player, o.getItem()); + return; + } } npc.say("Sorry, please choose a number from those I told you."); } catch (NumberFormatException e) { diff --git a/src/games/stendhal/server/maps/semos/tavern/market/OfferExpirer.java b/src/games/stendhal/server/maps/semos/tavern/market/OfferExpirer.java index 3dde119896..5dc4498e1b 100644 --- a/src/games/stendhal/server/maps/semos/tavern/market/OfferExpirer.java +++ b/src/games/stendhal/server/maps/semos/tavern/market/OfferExpirer.java @@ -120,7 +120,11 @@ public class OfferExpirer implements TurnListener{ market.expireOffer(offer); StringBuilder builder = new StringBuilder(); builder.append("Your offer of "); - builder.append(Grammar.a_noun(offer.getItem().getName())); + String itemname = "unknown item"; + if (offer.hasItem()) { + itemname = offer.getItem().getName(); + } + builder.append(Grammar.a_noun(itemname)); builder.append(" has expired. You have "); builder.append(TimeUtil.approxTimeUntil((int) ((offer.getTimestamp() - System.currentTimeMillis() + 1000 * TIME_TO_REMOVING) / 1000))); @@ -139,7 +143,7 @@ public class OfferExpirer implements TurnListener{ market.removeExpiredOffer(offer); StringBuilder builder = new StringBuilder(); builder.append("Your offer of "); - builder.append(Grammar.a_noun(offer.getItem().getName())); + builder.append(Grammar.a_noun(offer.getItemName())); builder.append(" has been removed permanently from the market."); sendMessage(offer.getOfferer(), builder); } @@ -163,7 +167,7 @@ public class OfferExpirer implements TurnListener{ StringBuilder builder = new StringBuilder(); builder.append("Your offer of "); - builder.append(Grammar.a_noun(offer.getItem().getName())); + builder.append(Grammar.a_noun(offer.getItemName())); builder.append(" will expire in "); builder.append(TimeUtil.approxTimeUntil((int) ((offer.getTimestamp() - time) / 1000 + TIME_TO_EXPIRING))); builder.append("."); diff --git a/src/games/stendhal/server/maps/semos/tavern/market/ProlongOfferHandler.java b/src/games/stendhal/server/maps/semos/tavern/market/ProlongOfferHandler.java index ebe30e877e..e18c2ba752 100644 --- a/src/games/stendhal/server/maps/semos/tavern/market/ProlongOfferHandler.java +++ b/src/games/stendhal/server/maps/semos/tavern/market/ProlongOfferHandler.java @@ -62,12 +62,15 @@ public class ProlongOfferHandler extends OfferHandler { Offer o = offerMap.get(offerNumber); if(o.getOfferer().equals(player.getName())) { setOffer(o); - int quantity = getQuantity(o.getItem()); + int quantity = 1; + if (o.hasItem()) { + quantity = getQuantity(o.getItem()); + } StringBuilder message = new StringBuilder(); if (TradeCenterZoneConfigurator.getShopFromZone(player.getZone()).contains(o)) { message.append("Your offer of "); - message.append(Grammar.quantityplnoun(quantity, o.getItem().getName(), "one")); + message.append(Grammar.quantityplnoun(quantity, o.getItemName(), "one")); message.append(" would expire in "); message.append(TimeUtil.approxTimeUntil((int) ((o.getTimestamp() - System.currentTimeMillis() + 1000 * OfferExpirer.TIME_TO_EXPIRING) / 1000))); message.append(". Do you want to prolong it to last for "); @@ -77,7 +80,7 @@ public class ProlongOfferHandler extends OfferHandler { message.append(" money?"); } else { message.append("Do you want to prolong your offer of "); - message.append(Grammar.quantityplnoun(quantity, o.getItem().getName(), "one")); + message.append(Grammar.quantityplnoun(quantity, o.getItemName(), "one")); message.append(" at a price of "); message.append(o.getPrice()); message.append(" for a fee of "); @@ -112,7 +115,7 @@ public class ProlongOfferHandler extends OfferHandler { npc.say("Sorry, that offer has already been removed from the market."); } // Changed the status, or it has been changed by expiration. Obsolete the offers - ((MarketManagerNPC) npc.getEntity()).getOfferMap().put(player.getName(), null); + ((MarketManagerNPC) npc.getEntity()).getOfferMap().clear(); } else { npc.say("You cannot afford the trading fee of "+fee.toString()); } diff --git a/src/games/stendhal/server/maps/semos/tavern/market/RemoveOfferHandler.java b/src/games/stendhal/server/maps/semos/tavern/market/RemoveOfferHandler.java index 539c831f3c..0e8c446252 100644 --- a/src/games/stendhal/server/maps/semos/tavern/market/RemoveOfferHandler.java +++ b/src/games/stendhal/server/maps/semos/tavern/market/RemoveOfferHandler.java @@ -51,7 +51,7 @@ public class RemoveOfferHandler extends OfferHandler { try { String offerNumber = getOfferNumberFromSentence(sentence).toString(); Map offerMap = manager.getOfferMap(); - if (offerMap == null) { + if (offerMap.isEmpty()) { npc.say("Please check your offers first."); return; } @@ -61,11 +61,16 @@ public class RemoveOfferHandler extends OfferHandler { setOffer(o); // Ask for confirmation only if the offer is still active if (TradeCenterZoneConfigurator.getShopFromZone(player.getZone()).contains(o)) { - int quantity = getQuantity(o.getItem()); - npc.say("Do you want to remove your offer of " + Grammar.quantityplnoun(quantity, o.getItem().getName(), "one") + "?"); + int quantity = 1; + if (o.hasItem()) { + quantity = getQuantity(o.getItem()); + } + npc.say("Do you want to remove your offer of " + Grammar.quantityplnoun(quantity, o.getItemName(), "one") + "?"); npc.setCurrentState(ConversationStates.QUESTION_1); } else { removeOffer(player, npc); + // Changed the status, or it has been changed by expiration. Obsolete the offers + ((MarketManagerNPC) npc.getEntity()).getOfferMap().clear(); } return; } @@ -82,6 +87,8 @@ public class RemoveOfferHandler extends OfferHandler { protected class ConfirmRemoveOfferChatAction implements ChatAction { public void fire(Player player, Sentence sentence, EventRaiser npc) { removeOffer(player, npc); + // Changed the status, or it has been changed by expiration. Obsolete the offers + ((MarketManagerNPC) npc.getEntity()).getOfferMap().clear(); } } diff --git a/src/games/stendhal/server/maps/semos/tavern/market/ShowOfferItemsChatAction.java b/src/games/stendhal/server/maps/semos/tavern/market/ShowOfferItemsChatAction.java index 74fe2b1fdb..6730db7790 100644 --- a/src/games/stendhal/server/maps/semos/tavern/market/ShowOfferItemsChatAction.java +++ b/src/games/stendhal/server/maps/semos/tavern/market/ShowOfferItemsChatAction.java @@ -70,7 +70,7 @@ public class ShowOfferItemsChatAction implements ChatAction { private Set buildItemList(List offers) { Set items = new TreeSet(); for (Offer offer : offers) { - items.add(offer.getItem().getName()); + items.add(offer.getItemName()); } return items; } diff --git a/src/games/stendhal/server/maps/semos/tavern/market/ShowOffersChatAction.java b/src/games/stendhal/server/maps/semos/tavern/market/ShowOffersChatAction.java index 4439ec7a0c..c46148b900 100644 --- a/src/games/stendhal/server/maps/semos/tavern/market/ShowOffersChatAction.java +++ b/src/games/stendhal/server/maps/semos/tavern/market/ShowOffersChatAction.java @@ -168,10 +168,12 @@ public class ShowOffersChatAction implements ChatAction { private void filterForWord(List offers, String word) { Iterator it = offers.iterator(); while (it.hasNext()) { - Item item = it.next().getItem(); - - if (!(item.getName().indexOf(word) != -1 || word.equals(item.getItemClass()))) { - it.remove(); + Offer o = it.next(); + if (o.hasItem()) { + Item item = o.getItem(); + if (!(item.getName().indexOf(word) != -1 || word.equals(item.getItemClass()))) { + it.remove(); + } } } } @@ -207,7 +209,7 @@ public class ShowOffersChatAction implements ChatAction { message.append(counter); message.append(": "); - message.append(Grammar.quantityplnoun(quantity, item.getName(), "a")); + message.append(Grammar.quantityplnoun(quantity, offer.getItemName(), "a")); message.append(" for "); message.append(offer.getPrice()); message.append(" money"); diff --git a/stendhal.jnlp b/stendhal.jnlp index 94f78f3e1e..2a9b485aeb 100644 --- a/stendhal.jnlp +++ b/stendhal.jnlp @@ -22,7 +22,7 @@ Some of these people are NPC, they will give you tasks to accomplish and hints t - +