package com.lucasdnd.ags.gameplay;
import java.util.ArrayList;
import java.util.Random;
import org.newdawn.slick.Font;
import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.Input;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.SpriteSheet;
import org.newdawn.slick.state.StateBasedGame;
import org.newdawn.slick.util.pathfinding.Path;
import com.lucasdnd.ags.gameplay.actions.Action;
import com.lucasdnd.ags.gameplay.actions.BuyGameAction;
import com.lucasdnd.ags.gameplay.actions.LeaveStoreAction;
import com.lucasdnd.ags.gameplay.actions.PlayGameAction;
import com.lucasdnd.ags.gameplay.actions.RentGameAction;
import com.lucasdnd.ags.gameplay.market.Market;
import com.lucasdnd.ags.gameplay.market.MarketConsole;
import com.lucasdnd.ags.gameplay.market.MarketGame;
import com.lucasdnd.ags.map.Map;
import com.lucasdnd.ags.system.GameSystem;
import com.lucasdnd.ags.ui.ViewGamesList;
public class Customer extends Character {
/** Playing Sprites */
private Image[] playingSprites;
/** States */
private static final int MOVING_FROM_PLAYER = 2; // DEBUG ONLY
public static final int WANTS_TO_PLAY = 3;
public static final int WANTS_TO_BUY = 4;
public static final int WANTS_TO_RENT = 5;
public static final int WANTS_TO_EAT = 6;
public static final int WANTS_TO_LEAVE = 7;
public static final int WAITING_TO_PLAY = 8;
public static final int WAITING_TO_BUY = 9;
public static final int WAITING_TO_RENT = 10;
public static final int WAITING_TO_EAT = 11;
private static final int MOVING_TO_PLAY = 12;
private static final int MOVING_TO_BUY = 13;
private static final int MOVING_TO_RENT = 14;
private static final int MOVING_TO_EAT = 15;
private static final int MOVING_TO_LEAVE = 16;
protected static final int PLAYING = 17;
private static final int BUYING = 18;
private static final int RENTING = 19;
private static final int EATING = 20;
/** Actions - The actions the Character will perform when inside the store */
protected ArrayList<Action> actions; // The list of Actions this Character wants to perform in the Store
protected Action currentAction; // The current action being performed
protected int maxWaitingTime; // How long the Character will wait before the Asset is ready to use
protected int currentWaitingTime;
protected int maxIdleTime; // How long the Character will wander in IDLE state between two actions
protected int currentIdleTime;
protected int visitRating; // What the character currently thinks about the store
// Each action gets a rating. Bad (-), Neutral (0), Good (+). This visitRating is the sum
// of all ratings.
protected Game gameItWantsToRent; // A reference to the game the Character wants to rent
protected Game gameItWantsToBuy; // A reference to the game the Character wants to buy
protected Game gameItWantsToPlay; // A reference to the game the Character wants to play
protected int chanceToSpeak; // The lower this number is, more often the Character will talk
/** Fair Price */
protected int sellFairPriceModifier = 0;
protected int rentFairPriceModifier = 0;
protected int playFairPriceModifier = 0;
public Customer(int id, Font font, Font shadowFont, SpriteSheet spriteSheet, SpriteSheet playingSpriteSheet,
ArrayList<Action> actions, int simulationSpeed, Store store) throws SlickException {
// Character Constructor
super(id, spriteSheet, font, shadowFont);
// There are 3 possible Character speeds: slow (4/12), normal (7/12) and fast (1/12).
int randomSpeedType = new Random().nextInt(12);
if(randomSpeedType < 1) {
// Fast
maxIdleTime = (int)((new Random().nextInt(10000) + 5000) / simulationSpeed);
movementInterval = (int)((new Random().nextInt(300) + 500) / simulationSpeed);
maxWaitingTime = 5000;
speed = 0.07f;
} else if(randomSpeedType > 0 && randomSpeedType < 5) {
// Slow
maxIdleTime = (int)((new Random().nextInt(30000) + 5000) / simulationSpeed);
movementInterval = (int)((new Random().nextInt(2000) + 500) / simulationSpeed);
maxWaitingTime = 15000;
speed = 0.03f;
} else {
// Normal
maxIdleTime = (int)((new Random().nextInt(20000) + 5000) / simulationSpeed);
movementInterval = (int)((new Random().nextInt(1000) + 500) / simulationSpeed);
maxWaitingTime = 10000;
speed = 0.05f;
}
// Fair Price Types
int fpType = getCustomerFairPriceType();
sellFairPriceModifier = getSellFairPrice(fpType);
rentFairPriceModifier = getRentFairPrice(fpType);
playFairPriceModifier = getPlayFairPrice(fpType);
// Actions received from Game and Console
this.actions = actions;
currentAction = null;
currentIdleTime = maxIdleTime; // There's no delay on the first Action
currentWaitingTime = 0;
chanceToSpeak = 10;
// Actions that belong to the Customer itself, depending on the Fair Price Type
this.generateOwnActions(fpType, store);
// Create and load the Playing
playingSprites = new Image[4];
for(int i = 0; i < playingSprites.length; i++) {
playingSprites[i] = playingSpriteSheet.getSprite(i, 0);
playingSprites[i].setFilter(Image.FILTER_NEAREST);
}
}
/**
* Fair price modifiers. Refer to the balance sheet.
* @return
*/
private int getCustomerFairPriceType() {
int randomResult = new Random().nextInt(100);
int c1 = 5;
int c2 = 15;
int c3 = 60;
int c4 = 15;
// c5 = 5;
if(randomResult < c1) return 0;
else if(randomResult < c1 + c2) return 1;
else if(randomResult < c1 + c2 + c3) return 2;
else if(randomResult < c1 + c2 + c3 + c4) return 3;
return 4;
}
private int getSellFairPrice(int fpType) {
switch(fpType) {
case 0:
return -1000;
case 1:
return -500;
case 2:
return 0;
case 3:
return 1000;
case 4:
return 2000;
}
return 0;
}
private int getRentFairPrice(int fpType) {
switch(fpType) {
case 0:
return -20;
case 1:
return 0;
case 2:
return 0;
case 3:
return 50;
case 4:
return 100;
}
return 0;
}
private int getPlayFairPrice(int fpType) {
switch(fpType) {
case 0:
return -20;
case 1:
return 0;
case 2:
return 0;
case 3:
return 50;
case 4:
return 100;
}
return 0;
}
private boolean isRentPriceFair(Game game, Market market, int month) {
int rentPrice = market.getGameRentPriceByDemand(game.getReferredMarketGame().getQuality());
int fairMarketPrice = market.getCurrentFairRentPrice(game.getReferredMarketGame().getQuality(), month);
return rentPrice <= fairMarketPrice + this.rentFairPriceModifier;
}
private boolean isSellPriceFair(Game game, Market market, int month) {
int sellPrice = market.getGamePriceByDemand(game.getReferredMarketGame().getQuality());
int fairMarketPrice = market.getCurrentFairSellPrice(game.getReferredMarketGame().getQuality(), month);
return sellPrice <= fairMarketPrice + this.sellFairPriceModifier;
}
private boolean isPlayPriceFair(MarketConsole marketConsole, Market market, int month) {
int playPrice = marketConsole.getPlayPrice();
int fairMarketPrice = market.getCurrentFairPlayPrice(marketConsole.getQuality(), month);
return playPrice <= fairMarketPrice + this.playFairPriceModifier;
}
/**
* Every customer, when generated, has a chance to have a few extra actions, not influenced by the Game or Console the player has bought, but
* by their Fair Price Type.
* @param fpType
*/
private void generateOwnActions(int fpType, Store store) {
int result = 0;
switch(fpType) {
case 0:
result = GameSystem.getRandomFrom100(5, 5, 5, 0);
break;
case 1:
result = GameSystem.getRandomFrom100(5, 10, 5, 0);
break;
case 2:
result = GameSystem.getRandomFrom100(10, 10, 5, 0);
break;
case 3:
result = GameSystem.getRandomFrom100(20, 20, 10, 0);
break;
case 4:
result = GameSystem.getRandomFrom100(20, 25, 20, 0);
break;
default:
break;
}
if (result == 0) {
MarketGame game = store.getRandomGameBasedOnQuality();
if (game != null) actions.add(new BuyGameAction(game));
} if(result == 1) {
MarketGame game = store.getRandomGameBasedOnQuality();
if (game != null) actions.add(new RentGameAction(game));
} else if(result == 2) {
MarketGame game = store.getRandomGameBasedOnQuality();
if (game != null) actions.add(new BuyGameAction(game));
game = store.getRandomGameBasedOnQuality();
if (game != null) actions.add(new RentGameAction(game));
}
}
/**
* Has Simulation Speed, which makes it differ from the super class update
* @param container
* @param game
* @param delta
* @param input
* @param leftMouseClicked
* @param mouseX
* @param mouseY
* @param business
* @param tables
* @param shelfs
* @param viewGamesList
* @param simulationSpeed
* @throws SlickException
*/
public void update(GameContainer container, StateBasedGame game, int delta, Input input,
boolean leftMouseClicked, int mouseX, int mouseY, Business business,
ArrayList<Table> tables, ArrayList<Shelf> shelfs, ViewGamesList viewGamesList,
int simulationSpeed, Market market, int month) throws SlickException {
super.update(container, game, delta, input, leftMouseClicked, mouseX, mouseY, business, tables, shelfs, viewGamesList);
// If the state is PLAYING, we don't render it. Instead, the Console becomes responsible for rendering
// the Character in the PLAYING state.
if(state == PLAYING) {
visible = false;
} else {
visible = true;
}
Map map = business.getStore().getMap();
// To which state?
if(state == IDLE) {
updateCustomerIdleTiming(delta);
updateIdleState(map, delta);
}
else if(state == WAITING_TO_PLAY || state == WAITING_TO_RENT || state == WAITING_TO_BUY || state == WAITING_TO_EAT) {
updateWaitingState(container, game, delta, simulationSpeed);
}
else if(state == WANTS_TO_PLAY) {
updateWantsToPlayState(business.getStore().getGames(), business.getStore().getTables(), map, market, month);
}
else if(state == PLAYING) {
updatePlaying(business, delta);
}
else if(state == WANTS_TO_RENT) {
updateWantsToRentState(shelfs, business.getStore().getGames(), map, market, month);
}
else if(state == RENTING) {
updateRenting(business, delta, market);
}
else if(state == WANTS_TO_BUY) {
updateWantsToBuyState(shelfs, business.getStore().getGames(), map, market, month);
}
else if(state == BUYING) {
updateBuying(business, delta, viewGamesList, market);
}
else if(state == WANTS_TO_LEAVE) {
updateWantsToLeave(map);
}
}
@Override
public void render(GameContainer container, StateBasedGame game, Graphics g, int simulationSpeed) throws SlickException {
super.render(container, game, g, simulationSpeed);
}
/**
* Deals with the time the Customers will wander around the store without performing any actions
* @param delta
*/
private void updateCustomerIdleTiming(int delta) {
// Still counting...
if(currentIdleTime < maxIdleTime) {
currentIdleTime += delta;
} else {
// Done! Perform the next Action
if(actions.size() == 0) {
actions.add(new LeaveStoreAction());
}
currentAction = actions.get(actions.size() - 1);
actions.remove(actions.size() - 1);
// Change its state accordingly
state = currentAction.getState();
// Reset action Timer
currentIdleTime = 0;
}
}
/**
* When the Character finishes moving to the next Tile, this method is called
* @throws SlickException
*/
@Override
public void finishMoving(Map map) throws SlickException {
super.finishMoving(map);
if(state == MOVING_TO_RENT || state == MOVING_TO_BUY) {
// Check if the Asset is still alive
if(targetAsset != null) {
// Then, check if the Asset is still in place
if(targetAsset.getXTile() == targetAssetXTile && targetAsset.getYTile() == targetAssetYTile
&& targetAsset.getFacingDirection() == targetAssetFacingDirection) {
// How long the customer will take to perform his current action
currentActionTimer = 0;
maxActionTimer = 2000;
// Switch state depending on what the Character wants to do
if(state == MOVING_TO_RENT) {
state = WAITING_TO_RENT;
} else if(state == MOVING_TO_BUY) {
state = WAITING_TO_BUY;
}
} else {
// In this case, the Asset exists but moved somewhere else
floatingText.show("There should be a shelf here");
targetAsset.getUsers().remove(this);
state = IDLE;
}
} else {
// Asset has been destroyed
floatingText.show("The shelf has been destroyed!");
state = IDLE;
}
}
/** Character was MOVING_TO_PLAY and reached its destination */
else if(state == MOVING_TO_PLAY) {
// Check if the Asset is still alive
if(targetAsset != null) {
// Then, check if the Asset is still in place
if(targetAsset.getXTile() == targetAssetXTile && targetAsset.getYTile() == targetAssetYTile
&& targetAsset.getFacingDirection() == targetAssetFacingDirection) {
currentActionTimer = 0;
maxActionTimer = 10000;
state = WAITING_TO_PLAY;
} else {
// In this case, the Asset exists but moved somewhere else
floatingText.show("Shouldn't there be a table here?");
((Table)targetAsset).removeCharacter(this);
this.finishMoving(map);
}
} else {
// Asset has been destroyed
floatingText.show("The table has been destroyed!");
this.finishMoving(map);
}
}
/** Character is moving out of the store and reached its destination */
else if(state == MOVING_TO_LEAVE) {
canBeDisposed = true;
}
}
/**
* Releases from asset
*/
protected void unlockAsset(Asset asset) {
if(state == WANTS_TO_PLAY) {
((Table)asset).removeCharacter(this);
if(asset.getUsers().size() == 0) {
gameItWantsToPlay.setBeingPlayed(false);
}
} else if(state == WANTS_TO_RENT) {
gameItWantsToRent.setRented(false);
} else if(state == WANTS_TO_BUY) {
gameItWantsToBuy.setRented(false);
}
}
/**
* Character is waiting for an Asset to be ready
* @throws SlickException
*/
private void updateWaitingState(GameContainer container, StateBasedGame stateBasedGame, int delta, int simulationSpeed) throws SlickException {
// Check if the Asset is already organized
if (
(targetAsset instanceof Table &&
((Table)targetAsset).getConsole() != null
) || (
targetAsset instanceof Shelf)
) {
// Move on to the next state
if(state == WAITING_TO_RENT) {
state = RENTING;
} else if(state == WAITING_TO_BUY) {
state = BUYING;
} else if(state == WAITING_TO_PLAY) {
state = PLAYING;
} else if(state == WAITING_TO_EAT) {
state = EATING;
}
// Check if we reached the max waiting time
} else if(currentWaitingTime >= maxWaitingTime) {
// Reset the Waiting Time
currentWaitingTime = 0;
// Unlock the Asset
if(targetAsset != null) {
targetAsset.getUsers().remove(this);
}
// Go back to IDLE state
state = IDLE;
this.hadNegativeReaction(false);
}
// Count towards the max waiting time
currentWaitingTime += delta;
}
/**
* Character is in WANTS_TO_PLAY state
* @param entities
* @param map
* @throws SlickException
*/
private void updateWantsToPlayState(ArrayList<Game> games, ArrayList<Table> tables, Map map, Market market, int month) throws SlickException {
// No games?
if(games == null || games.size() == 0) {
floatingText.show("There are no games to play!");
this.hadNegativeReaction(true);
state = IDLE;
return;
}
// No consoles?
boolean hasConsoles = false;
if(tables != null && tables.size() > 0) {
for(Table t : tables) {
if(t.getConsole() != null) {
hasConsoles = true;
break;
}
}
}
if(!hasConsoles) {
floatingText.show("There are no consoles!");
this.hadNegativeReaction(true);
state = IDLE;
return;
}
// Are there any games available for this Console?
gameItWantsToPlay = null;
boolean tooExpensive = false;
for(Game g : games) {
// Check if games with that demand are available for play
if (market.isPlayAvailableByDemand(g.getReferredMarketGame().getQuality()) == false) {
break;
}
// Go!
if(g.getReferredMarketGame().getMarketConsole() == ((PlayGameAction)currentAction).getReferringMarketConsole() && !g.isRented()) {
gameItWantsToPlay = g;
if(isPlayPriceFair(g.getReferredMarketGame().getMarketConsole(), market, month)) {
g.setBeingPlayed(true);
break;
} else {
tooExpensive = true;
break;
}
}
}
// Game not found
if(gameItWantsToPlay == null) {
this.visitRating += currentAction.getNegativeActionPoints();
state = IDLE;
return;
}
// Game too expensive
if(tooExpensive) {
this.hadNegativeReaction(false);
state = IDLE;
gameItWantsToPlay = null;
return;
}
// Check if the player has the required Console in store
ArrayList<Table> freeRequiredTables = new ArrayList<Table>();
ArrayList<Table> secondPlayerFreeRequiredTable = new ArrayList<Table>();
// Loop through all the tables
for(Table t : tables) {
// Check if that Table has the right Console and a TV
if(t.getConsole() != null && t.getTv() != null &&
t.getConsole().getReferringMarketConsole() == ((PlayGameAction)currentAction).getReferringMarketConsole()) {
// If the console is not being used or if the console is being used
if(t.getUsers().size() == 0) {
freeRequiredTables.add(t);
} else if(t.getUsers().size() == 1) {
secondPlayerFreeRequiredTable.add(t);
}
}
}
// Pick a random one
if(freeRequiredTables.size() > 0) {
// Get a random Table
Table chosenTable = freeRequiredTables.get(new Random().nextInt(freeRequiredTables.size()));
chosenTable.addCharacter(this);
goToAsset(chosenTable, map, MOVING_TO_PLAY);
} else if(secondPlayerFreeRequiredTable.size() > 0) {
// Character can join as a second player
floatingText.show("Let's play together!");
Table chosenTable = secondPlayerFreeRequiredTable.get(new Random().nextInt(secondPlayerFreeRequiredTable.size()));
chosenTable.addCharacter(this);
this.goToAsset(chosenTable, map, MOVING_TO_PLAY);
} else {
// Console unavailable: free the game up, go back to idle
floatingText.show("I wish I could play on a " + gameItWantsToPlay.getReferredMarketGame().getMarketConsole().getName());
gameItWantsToPlay.setBeingPlayed(false);
gameItWantsToPlay = null;
this.hadNegativeReaction(false);
state = IDLE;
}
}
/**
* Character is in WANTS_TO_RENT state
* @param entities
* @param map
* @throws SlickException
*/
private void updateWantsToRentState(ArrayList<Shelf> shelfs, ArrayList<Game> games, Map map, Market market, int month) throws SlickException {
// Check if there are any games in the store
if(games == null || games.size() <= 0) {
floatingText.show("There are no games to rent");
this.hadNegativeReaction(true);
state = IDLE;
return;
}
// Reference to that game
gameItWantsToRent = null;
boolean tooExpensive = false;
for(Game g : games) {
// Check if games with that demand are available for rent
if (market.isRentAvailableByDemand(g.getReferredMarketGame().getQuality()) == false) {
break;
}
// Check if the Player has the game the client wants to rent
if(g.getReferredMarketGame().getId() == ((RentGameAction)currentAction).getReferringMarketGame().getId()) {
// Check if that game is not already rented or being played in the store
if(!g.isRented() && !g.isBeingPlayed()) {
gameItWantsToRent = g;
if(isRentPriceFair(g, market, month)) {
g.setRented(true);
break;
} else {
tooExpensive = true;
break;
}
}
}
}
// Game not found
if(gameItWantsToRent == null) {
this.hadNegativeReaction(false);
state = IDLE;
return;
}
// Game too expensive
if(tooExpensive) {
floatingText.show(gameItWantsToRent.getReferredMarketGame().getName() + " is too expensive to rent!");
this.hadNegativeReaction(true);
state = IDLE;
gameItWantsToRent = null;
return;
}
// Go get the game
if(shelfs.size() > 0) {
Shelf chosenFurniture = shelfs.get(new Random().nextInt(shelfs.size()));
goToAsset(chosenFurniture, map, MOVING_TO_RENT);
}
}
/**
* WANTS_TO_BUY state
* @param shelfs
* @param games
* @param map
* @param chanceToAnyGameIfNotFound
* @throws SlickException
*/
private void updateWantsToBuyState(ArrayList<Shelf> shelfs, ArrayList<Game> games, Map map, Market market, int month) throws SlickException {
// PS3 HAS NO GAME
if(games == null || games.size() == 0) {
floatingText.show("There are no games to buy!");
this.hadNegativeReaction(true);
state = IDLE;
return;
}
// Reference to that game
gameItWantsToBuy = null;
boolean tooExpensive = false;
for(Game g : games) {
// Check if games with that demand are available for play
if (market.isSaleAvailableByDemand(g.getReferredMarketGame().getQuality()) == false) {
break;
}
if(g.getReferredMarketGame().getId() == ((BuyGameAction)currentAction).getReferringMarketGame().getId()) {
if(!g.isRented() && !g.isBeingPlayed()) {
gameItWantsToBuy = g;
if(isSellPriceFair(g, market, month)) {
break;
} else {
tooExpensive = true;
break;
}
}
}
}
// Game not found
if(gameItWantsToBuy == null) {
this.hadNegativeReaction(false);
state = IDLE;
return;
}
// Too expensive
if(tooExpensive) {
floatingText.show(gameItWantsToBuy.getReferredMarketGame().getName() + " is too expensive!");
this.hadNegativeReaction(true);
state = IDLE;
gameItWantsToBuy = null;
return;
}
// Go get the game
if(shelfs.size() > 0) {
Shelf chosenFurniture = shelfs.get(new Random().nextInt(shelfs.size()));
goToAsset(chosenFurniture, map, MOVING_TO_BUY);
}
}
/**
* Character had a negative reaction when performing the current action
* @throws SlickException
*/
public void hadNegativeReaction(boolean willSpeak) throws SlickException {
if (willSpeak) {
// Chance to Speak
if(new Random().nextInt(chanceToSpeak) == 0) {
floatingText.show(currentAction.getRandomNegativeTalk());
}
}
visitRating += currentAction.getNegativeActionPoints();
}
/**
* Character had a positive reaction when performing the current action
* @throws SlickException
*/
public void hadPositiveReaction() throws SlickException {
// Chance to Speak
if(new Random().nextInt(chanceToSpeak) == 0) {
floatingText.show(currentAction.getRandomPositiveTalk());
}
visitRating += currentAction.getPositiveActionPoints();
}
/**
* Character had a neutral reaction when performing the current action
* @throws SlickException
*/
public void hadNeutralReaction() throws SlickException {
// Chance to Speak
if(new Random().nextInt(chanceToSpeak) == 0) {
floatingText.show(currentAction.getRandomNeutralTalk());
}
}
/**
* Character is renting game
* @param business
* @param delta
* @throws SlickException
*/
private void updateRenting(Business business, int delta, Market market) throws SlickException {
// If we just started the action, set the correct FacingDirection
if(currentActionTimer == 0) {
if(targetAssetFacingDirection == DOWN_RIGHT) {
facingDirection = UP_LEFT;
} else if(targetAssetFacingDirection == DOWN_LEFT) {
facingDirection = UP_RIGHT;
} else if(targetAssetFacingDirection == UP_LEFT) {
facingDirection = DOWN_RIGHT;
} else { // if(targetAssetFacingDirection == UP_RIGHT) {
facingDirection = DOWN_LEFT;
}
// Add self to the List of that Asset's users
targetAsset.getUsers().add(this);
}
// Increase the Timer
currentActionTimer += delta;
// Check if we reached the time limit
if(currentActionTimer >= maxActionTimer) {
// Free up the Asset from this Character, set it to IDLE
targetAsset.getUsers().remove(this);
state = IDLE;
// PROFIT!!!
int price = market.getGameRentPriceByDemand(gameItWantsToRent.getReferredMarketGame().getQuality());
business.makeBusiness(price, Business.RENTING_GAME, true);
floatingMoney.show(GameSystem.printMoney(price, true));
// Up the Total Profit of this game. Sum the rent price of this game to its total profit
gameItWantsToRent.getReferredMarketGame().setTotalProfit(gameItWantsToRent.getReferredMarketGame().getTotalProfit() + market.getGameRentPriceByDemand(gameItWantsToRent.getReferredMarketGame().getQuality()));
}
}
/**
* Character is buying game
* @param business
* @param delta
* @throws SlickException
*/
private void updateBuying(Business business, int delta, ViewGamesList viewGamesList, Market market) throws SlickException {
// If we just started the action, set the correct FacingDirection
if(currentActionTimer == 0) {
if(targetAssetFacingDirection == DOWN_RIGHT) {
facingDirection = UP_LEFT;
} else if(targetAssetFacingDirection == DOWN_LEFT) {
facingDirection = UP_RIGHT;
} else if(targetAssetFacingDirection == UP_LEFT) {
facingDirection = DOWN_RIGHT;
} else { // if(targetAssetFacingDirection == UP_RIGHT) {
facingDirection = DOWN_LEFT;
}
// Add self to the List of that Asset's users
targetAsset.getUsers().add(this);
}
// Increase the Timer
currentActionTimer += delta;
// Check if we reached the time limit
if(currentActionTimer >= maxActionTimer) {
// Free up the Asset from this Character, set it to IDLE
targetAsset.getUsers().remove(this);
state = IDLE;
// PROFIT!!!
int price = market.getGamePriceByDemand(gameItWantsToBuy.getReferredMarketGame().getQuality());
business.makeBusiness(price, Business.SELLING_GAME, true);
floatingMoney.show(GameSystem.printMoney(price, true));
// Up the Total Profit of this game. Sum the rent price of this game to its total profit
gameItWantsToBuy.getReferredMarketGame().setTotalProfit(gameItWantsToBuy.getReferredMarketGame().getTotalProfit() + market.getGamePriceByDemand(gameItWantsToBuy.getReferredMarketGame().getQuality()));
// Check if auto restock is on
if(market.isAutoRestockAvailableByDemand(gameItWantsToBuy.getReferredMarketGame().getQuality())) {
// Make the player pay the buy price of that game (no need to make changes to the inventory)
business.makeBusiness( - gameItWantsToBuy.getReferredMarketGame().getPrice(), Business.BUYING_GAME, false);
} else {
// Otherwise, remove that game (not necessarily remove the List Row)
business.removeGame(gameItWantsToBuy);
// Updates this List
viewGamesList.updateListInfo(business, gameItWantsToBuy);
}
// Kill the reference to the game it wants to buy
gameItWantsToBuy = null;
}
}
/**
* Playing State
* @param business
* @param gameRented
* @param delta
*/
private void updatePlaying(Business business, int delta) {
// If we just started the action, set the correct FacingDirection
if(currentActionTimer == 0) {
if(targetAssetFacingDirection == DOWN_RIGHT) {
facingDirection = UP_LEFT;
} else if(targetAssetFacingDirection == DOWN_LEFT) {
facingDirection = UP_RIGHT;
} else if(targetAssetFacingDirection == UP_LEFT) {
facingDirection = DOWN_RIGHT;
} else { // if(targetAssetFacingDirection == UP_RIGHT) {
facingDirection = DOWN_LEFT;
}
}
// Increase the Timer
currentActionTimer += delta;
// Check if we reached the time limit
if(currentActionTimer >= maxActionTimer) {
// Free up the Asset from this Character, set it to IDLE
((Table)targetAsset).removeCharacter(this);
state = IDLE;
// If the Asset is now free, we set the game free too
if(targetAsset.getUsers().size() == 0) {
gameItWantsToPlay.setBeingPlayed(false);
}
// PROFIT!!!
int price = gameItWantsToPlay.getReferredMarketGame().getMarketConsole().getPlayPrice();
business.makeBusiness(price, Business.PLAYING_GAME, true);
floatingMoney.show(GameSystem.printMoney(price, true));
// Up the Total Profit of this Game. Sum the Console Play Price to the Game's total profit
gameItWantsToPlay.getReferredMarketGame().setTotalProfit(gameItWantsToPlay.getReferredMarketGame().getTotalProfit() + gameItWantsToPlay.getReferredMarketGame().getMarketConsole().getPlayPrice());
// Up the Total Profit of this Console. Sum the Console Play Price to the Console's total profit
gameItWantsToPlay.getReferredMarketGame().getMarketConsole().setTotalProfit(gameItWantsToPlay.getReferredMarketGame().getMarketConsole().getTotalProfit() + gameItWantsToPlay.getReferredMarketGame().getMarketConsole().getPlayPrice());
}
}
/**
* Character will move back to the spawning point to leave the Store
* @param map
* @throws SlickException
*/
private void updateWantsToLeave(Map map) throws SlickException {
// Let's make the Character go there
Path p = null;
// Find the Path to the Spawning Point
p = map.getPathFinder().findPath(this, this.getXTile(), this.getYTile(), map.getSpawnPoint().x, map.getSpawnPoint().y);
// Found a valid Path
if(p != null) {
// Change its state to MOVING_TO_LEAVE and make it go
state = MOVING_TO_LEAVE;
this.startMoving(p, map);
// Say something about the store
if(visitRating > 0) this.hadPositiveReaction();
else if(visitRating < 0) this.hadNegativeReaction(true);
else this.hadNeutralReaction();
} else {
// If the character is already at the spawn point, then it's ok
if(this.getXTile() == map.getSpawnPoint().x && this.getYTile() == map.getSpawnPoint().y) {
state = MOVING_TO_LEAVE;
this.stopMoving(map);
}
// Character is stuck in the Store. It will warn the Player
floatingText.show("I can't leave the store!");
state = WANTS_TO_LEAVE;
}
}
public int getVisitRating() {
return visitRating;
}
public void setVisitRating(int visitRating) {
this.visitRating = visitRating;
}
public Image[] getPlayingSprites() {
return playingSprites;
}
public void setPlayingSprites(Image[] playingSprites) {
this.playingSprites = playingSprites;
}
public ArrayList<Action> getActions() {
return actions;
}
public void setActions(ArrayList<Action> actions) {
this.actions = actions;
}
}