Skip to content

Commit

Permalink
New class for calculating healer fees using player level & amount of...
Browse files Browse the repository at this point in the history
...HP to restore
  • Loading branch information
AntumDeluge committed Jun 22, 2024
1 parent bb2a63d commit e6e76a7
Show file tree
Hide file tree
Showing 2 changed files with 217 additions and 59 deletions.
72 changes: 72 additions & 0 deletions src/games/stendhal/server/entity/npc/HealerNPC.java
Original file line number Diff line number Diff line change
@@ -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.entity.npc;

import games.stendhal.server.entity.player.Player;
import games.stendhal.server.entity.status.PoisonStatus;

/**
* NPC that services player HP.
*/
public class HealerNPC extends AttributeServicerNPC {

/* The lowest possible price for a level 0 player. */
private static Integer MIN_OFFER;


/**
* Creates a new healer NPC.
*
* @param name
* The NPC's name (please note that names should be unique).
*/
public HealerNPC(final String name) {
super(name, "hp");
}

@Override
public double fullService(final Player player) {
final double unitsServiced = super.fullService(player);
// healing also cures poison
player.getStatusList().removeAll(PoisonStatus.class);
return unitsServiced;
}

/**
* Restores player's HP to full value and cures poison.
*
* @param player
* Player to be healed.
* @return
* Amount of HP restored.
*/
public int heal(final Player player) {
return (int) fullService(player);
}

/**
* This is for registering a `games.stendhal.server.entity.npc.behaviour.impl.HealerBehaviour`
* with `games.stendhal.server.entity.npc.behaviour.journal.ServicersRegister`.
*
* @return
* The lowest possible price for a level 0 player.
*/
public int getMinOffer() {
if (HealerNPC.MIN_OFFER == null) {
// create a temporary level 0 player
final Player dummyPlayer = Player.createZeroLevelPlayer("_dummy_", null);
dummyPlayer.setHP(dummyPlayer.getHP()-1);
HealerNPC.MIN_OFFER = calculateOffer(dummyPlayer);
}
return HealerNPC.MIN_OFFER;
}
}
204 changes: 145 additions & 59 deletions src/games/stendhal/server/entity/npc/behaviour/adder/HealerAdder.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
***************************************************************************/
package games.stendhal.server.entity.npc.behaviour.adder;

import org.apache.log4j.Logger;

import games.stendhal.common.constants.SoundID;
import games.stendhal.common.constants.SoundLayer;
import games.stendhal.common.grammar.ItemParserResult;
Expand All @@ -21,6 +23,7 @@
import games.stendhal.server.entity.npc.ConversationPhrases;
import games.stendhal.server.entity.npc.ConversationStates;
import games.stendhal.server.entity.npc.EventRaiser;
import games.stendhal.server.entity.npc.HealerNPC;
import games.stendhal.server.entity.npc.SpeakerNPC;
import games.stendhal.server.entity.npc.behaviour.impl.HealerBehaviour;
import games.stendhal.server.entity.npc.behaviour.journal.ServicersRegister;
Expand Down Expand Up @@ -59,14 +62,105 @@ public class HealerAdder {
*/
public void addHealer(final SpeakerNPC npc, final int cost) {
final HealerBehaviour healerBehaviour = new HealerBehaviour(cost);
// FIXME: should registration be moved to main `addHealer` method
servicersRegister.add(npc.getName(), healerBehaviour);
addHealer(npc, createCalculateCostAction(healerBehaviour), createHealAction(healerBehaviour));
}

/**
* Makes the NPC a healer.
*
* @param npc
* SpeakerNPC who does the healing.
* @param calculateCostAction
* Action to take to determine cost.
* @param healAction
* Action to take when player is healed.
*/
public void addHealer(final SpeakerNPC npc, final ChatAction calculateCostAction, final ChatAction healAction) {
// Give attribute to healers
npc.put("job_healer", "");

final Engine engine = npc.getEngine();

engine.add(ConversationStates.ATTENDING,
ConversationPhrases.OFFER_MESSAGES,
null,
false,
ConversationStates.ATTENDING,
"I can #heal you.",
null);

engine.add(ConversationStates.ATTENDING,
"heal",
null,
false,
ConversationStates.ATTENDING,
null,
calculateCostAction);

engine.add(ConversationStates.HEAL_OFFERED,
ConversationPhrases.YES_MESSAGES,
null,
false,
ConversationStates.ATTENDING,
null,
healAction);

final ChatAction calculateCostAction = new ChatAction() {
engine.add(ConversationStates.HEAL_OFFERED,
ConversationPhrases.NO_MESSAGES,
null,
false,
ConversationStates.ATTENDING,
"OK, how else may I help you?",
null);
}

/**
* Makes the NPC a healer.
*
* @param npc
* NPC who does the healing.
*/
public void addHealer(final HealerNPC npc) {
// FIXME:
// - should registration be moved to main `addHealer` method
// - registration doesn't support dynamic pricing of `HealerNPC` class.
servicersRegister.add(npc.getName(), new HealerBehaviour(npc.getMinOffer()));
addHealer(npc, createCalculateCostAction(npc), createHealAction(npc));
}

/**
* Creates action to calculate cost.
*
* @param obj
* `HealerBehaviour` or `HealerNPC` instance.
* @return
* Action executed when player asks to be healed.
*/
private ChatAction createCalculateCostAction(final Object obj) {
final HealerBehaviour healerBehaviour = obj instanceof HealerBehaviour ? (HealerBehaviour) obj : null;
final HealerNPC healer = obj instanceof HealerNPC ? (HealerNPC) obj : null;
final boolean usingBehaviour = healerBehaviour != null;

if (!usingBehaviour && healer == null) {
Logger.getLogger(HealerAdder.class).error("Parameter type must be of `" + HealerBehaviour.class.getName()
+ "` or `" + HealerNPC.class.getName() + "`", new Throwable());
return null;
}

return new ChatAction() {
@SuppressWarnings("null")
@Override
public void fire(final Player player, final Sentence sentence, final EventRaiser raiser) {
int cost = 0;
ItemParserResult res = new ItemParserResult(true, "heal", 1, null);

int cost = healerBehaviour.getCharge(res, player);
if (usingBehaviour) {
cost = healerBehaviour.getCharge(res, player);
} else {
healer.setOffer(healer.calculateOffer(player));
cost = healer.getOffer();
}
currentBehavRes = res;

String badboymsg = "";
Expand All @@ -92,6 +186,10 @@ public void fire(final Player player, final Sentence sentence, final EventRaiser

raiser.setCurrentState(ConversationStates.HEAL_OFFERED); // success
} else {
if (!usingBehaviour) {
raiser.say("You do not need to be healed.");
return;
}
if ((player.getAtk() > 35) || (player.getDef() > 35)) {
raiser.say("Sorry, I cannot heal you because you are way too strong for my limited powers.");
} else if ((!player.isNew()
Expand All @@ -104,82 +202,70 @@ public void fire(final Player player, final Sentence sentence, final EventRaiser
// (low atk, low def AND low level)
raiser.say("Sorry, but you have a bad aura, so that I am unable to heal you right now.");
} else {
healerBehaviour.heal(player);
if (usingBehaviour) {
healerBehaviour.heal(player);
} else {
healer.heal(player);
}
raiser.addEvent(new SoundEvent(SoundID.HEAL, SoundLayer.CREATURE_NOISE));
raiser.say("There, you are healed. How else may I help you?");
}
}
}
};
}

final ChatAction healAction = new ChatAction() {
/**
* Creates action to heal player.
*
* @param obj
* `HealerBehaviour` or `HealerNPC` instance.
* @return
* Action executed when player confirms to be healed.
*/
private ChatAction createHealAction(final Object obj) {
final HealerBehaviour healerBehaviour = obj instanceof HealerBehaviour ? (HealerBehaviour) obj : null;
final HealerNPC healer = obj instanceof HealerNPC ? (HealerNPC) obj : null;
final boolean usingBehaviour = healerBehaviour != null;

if (!usingBehaviour && healer == null) {
Logger.getLogger(HealerAdder.class).error("Parameter type must be of `" + HealerBehaviour.class.getName()
+ "` or `" + HealerNPC.class.getName() + "`", new Throwable());
return null;
}

return new ChatAction() {
@SuppressWarnings("null")
@Override
public void fire(final Player player, final Sentence sentence, final EventRaiser raiser) {
int cost = healerBehaviour.getCharge(currentBehavRes, player);
int cost = 0;
if (usingBehaviour) {
cost = healerBehaviour.getCharge(currentBehavRes, player);
} else {
cost = healer.calculateOffer(player);
if (healer.offerChanged(cost)) {
raiser.say("I cannot heal you while you are actively fighting. Ask me again later.");
raiser.setCurrentState(ConversationStates.ATTENDING);
healer.resetOffer();
return;
}
}
if (cost < 0) {
cost = player.getLevel() * Math.abs(cost) + 1;
}
if (player.drop("money", cost)) {
healerBehaviour.heal(player);
if (usingBehaviour) {
healerBehaviour.heal(player);
} else {
healer.heal(player);
}
raiser.addEvent(new SoundEvent(SoundID.HEAL, SoundLayer.CREATURE_NOISE));
raiser.say("There, you are healed. How else may I help you?");
} else {
raiser.say("I'm sorry, but it looks like you can't afford it.");
}

currentBehavRes = null;
}
};

addHealer(npc, calculateCostAction, healAction);
}

/**
* Makes the NPC a healer.
*
* @param npc
* SpeakerNPC who does the healing.
* @param calculateCostAction
* Action to take to determine cost.
* @param healAction
* Action to take when player is healed.
*/
public void addHealer(final SpeakerNPC npc, final ChatAction calculateCostAction, final ChatAction healAction) {
// Give attribute to healers
npc.put("job_healer", "");

final Engine engine = npc.getEngine();

engine.add(ConversationStates.ATTENDING,
ConversationPhrases.OFFER_MESSAGES,
null,
false,
ConversationStates.ATTENDING,
"I can #heal you.",
null);

engine.add(ConversationStates.ATTENDING,
"heal",
null,
false,
ConversationStates.ATTENDING,
null,
calculateCostAction);

engine.add(ConversationStates.HEAL_OFFERED,
ConversationPhrases.YES_MESSAGES,
null,
false,
ConversationStates.ATTENDING,
null,
healAction);

engine.add(ConversationStates.HEAL_OFFERED,
ConversationPhrases.NO_MESSAGES,
null,
false,
ConversationStates.ATTENDING,
"OK, how else may I help you?",
null);
}
}

0 comments on commit e6e76a7

Please sign in to comment.