All Downloads are FREE. Search and download functionalities are using the official Maven repository.

ch.sahits.game.openpatrician.engine.land.city.LoanerEngine Maven / Gradle / Ivy

There is a newer version: 1.0.1
Show newest version
package ch.sahits.game.openpatrician.engine.land.city;

import ch.sahits.game.event.data.PeriodicalDailyUpdate;
import ch.sahits.game.event.data.PeriodicalTimeWeekUpdate;
import ch.sahits.game.openpatrician.annotation.ClassCategory;
import ch.sahits.game.openpatrician.annotation.EClassCategory;
import ch.sahits.game.openpatrician.annotation.LazySingleton;
import ch.sahits.game.openpatrician.dialog.ButtonTemplate;
import ch.sahits.game.openpatrician.dialog.DialogTemplate;
import ch.sahits.game.openpatrician.engine.AbstractEngine;
import ch.sahits.game.openpatrician.model.Date;
import ch.sahits.game.openpatrician.model.DisplayMessage;
import ch.sahits.game.openpatrician.model.ICitizen;
import ch.sahits.game.openpatrician.model.IPlayer;
import ch.sahits.game.openpatrician.model.city.ICity;
import ch.sahits.game.openpatrician.model.city.ILoaner;
import ch.sahits.game.openpatrician.model.city.LoanerList;
import ch.sahits.game.openpatrician.model.city.impl.IDebt;
import ch.sahits.game.openpatrician.model.event.RemitLoanEvent;
import ch.sahits.game.openpatrician.model.factory.StateFactory;
import ch.sahits.game.openpatrician.model.personal.ESocialRank;
import ch.sahits.game.openpatrician.model.ship.IShip;
import ch.sahits.game.openpatrician.util.l10n.Locale;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.Subscribe;
import org.joda.time.DateTime;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.MessageSource;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Random;

/**
 * Engine for controlling all the loaners.
 * @author Andi Hotz, (c) Sahits GmbH, 2014
 *         Created on Dec 30, 2014
 */
@LazySingleton
@ClassCategory(EClassCategory.SINGLETON_BEAN)
public class LoanerEngine extends AbstractEngine {
    @Autowired
    @Qualifier("serverClientEventBus")
    private AsyncEventBus clientServerEventBus;
// fixme: andi 1/3/15: use the factory to ensure they are initialized on first call
//    @Autowired
//    @Qualifier("periodicalWeeklyUpdater")
//    private PeriodicalTimeUpdaterV2 weeklyUpdater;
//    @Autowired
//    @Qualifier("periodicalEndOfDayUpdater")
//    private PeriodicalTimeUpdaterV2 dailyUpdater;
    @Autowired
    private StateFactory factory;
    @Autowired
    private Date date;
    @Autowired
    private Random rnd;
    @Autowired
    private Locale locale;
    @Autowired
    private MessageSource messageSource;
    @Autowired
    private LoanerList loaners;


    @PostConstruct
    private void init() {
        clientServerEventBus.register(this);
    }
    @PreDestroy
    private void unregister() {
        clientServerEventBus.unregister(this);
    }
    @Subscribe
    public void handleWeeklyUpdate(PeriodicalTimeWeekUpdate event) {
        for (ILoaner loaner : loaners) {
            loaner.update();
        }
    }
    @Subscribe
    public void handleDailyUpdate(PeriodicalDailyUpdate event) { // todo: andi 1/2/15: end of day event (singleton)
        DateTime now = date.getCurrentDate();
        for (ILoaner loaner : loaners) {
            List debts = loaner.getDebts();
            for (Iterator iterator = debts.iterator(); iterator.hasNext(); ) {
                IDebt debt = iterator.next();
                if (debt.getDueDate().isBefore(now)) {
                    ICitizen debitor = debt.getDebitor();
                    int cash = (int) (debt.getAmount() * debt.getInterest());
                    if (debitor instanceof IPlayer) {
                        IPlayer player = (IPlayer) debitor;
                        if (player.getCompany().getCash() > cash) {
                            player.updateCash(-cash);
                            if (debt.getCreditor() instanceof IPlayer) {
                                ((IPlayer)debt.getCreditor()).updateCash(cash);
                            }
                        } else {
                            postMessageDebtNotFulfillable(debt);
                        }
                    } else {  // Debitor is not a player
                        if (debitor.getRank().equals(ESocialRank.BARGAINER) ||
                                debitor.getRank().equals(ESocialRank.CHANDLER) ||
                                debitor.getRank().equals(ESocialRank.MERCHANT) ||
                                debitor.getRank().equals(ESocialRank.TRADESMAN) ) {
                            int payBack = rnd.nextInt(4);
                            if (payBack == 0) {
                                postMessageDebtNotFulfillable(debt);
                            } else {
                                if (debt.getCreditor() instanceof IPlayer) {
                                    ((IPlayer)debt.getCreditor()).updateCash(cash);
                                }
                            }
                        } else {
                            // Can always pay back
                            if (debt.getCreditor() instanceof IPlayer) {
                                ((IPlayer)debt.getCreditor()).updateCash(cash);
                            }
                        }
                    }
                    iterator.remove();
                }
            }
        }
    }
    @VisibleForTesting
    void postMessageDebtNotFulfillable(final IDebt debt) {
        String titleTemplate = "ch.sahits.game.openpatrician.engine.land.city.LoanerEngine.paybackTitle";
        String messageTemplate = "ch.sahits.game.openpatrician.engine.land.city.LoanerEngine.paybackMessage";
        String remitBtnLbl = "ch.sahits.game.openpatrician.engine.land.city.LoanerEngine.remitBtn";
        String pawnBtnLbl = "ch.sahits.game.openpatrician.engine.land.city.LoanerEngine.pawnBtn";
        int sum = (int) (debt.getAmount() * debt.getInterest());
        Object[] messageArgs = new Object[] {debt.getDebitor().getName(), debt.getDebitor().getLastName(), sum};
        Runnable remit = createRemitRunnable(debt);
        Runnable pawn = createPawnRunnable(debt);
        List buttons = new ArrayList<>();
        ButtonTemplate remitBtn = ButtonTemplate.builder()
                .action(remit)
                .labelKey(remitBtnLbl)
                .largeButton(true)
                .build();
        ButtonTemplate pawnBtn = ButtonTemplate.builder()
                .action(pawn)
                .labelKey(pawnBtnLbl)
                .largeButton(true)
                .build();
        buttons.add(remitBtn);
        buttons.add(pawnBtn);
        DialogTemplate dialogTemplate = DialogTemplate.builder()
                .titleKey(titleTemplate)
                .messageKey(messageTemplate)
                .messageArgs(messageArgs)
                .buttons(buttons)
                .closable(false)
                .build();
        DisplayMessage displayMessage = new DisplayMessage(messageSource.getMessage(titleTemplate, new Object[]{}, locale.getCurrentLocal()));
        displayMessage.setDialogTemplate(dialogTemplate);
        clientServerEventBus.post(displayMessage);

    }
    @VisibleForTesting
    Runnable createRemitRunnable(final IDebt debt) {
        return new Runnable() {
            @Override
            public void run() {
                if (debt.getCreditor() instanceof IPlayer) {
                    RemitLoanEvent remitLoan = new RemitLoanEvent(debt.getDebitor().getHometown(), debt);
                    clientServerEventBus.post(remitLoan);
                }
            }
        };
    }
    @VisibleForTesting
    Runnable createPawnRunnable(final IDebt debt) {
        return new Runnable() {
            @Override
            public void run() {
                if (debt.getDebitor() instanceof IPlayer) {
                    // pawn a ship and auction it
                    int sum = (int) (debt.getAmount() * debt.getInterest());
                    IPlayer player = (IPlayer) debt.getDebitor();
                    IShip shipMatch = null;
                    int maxDelta = Integer.MAX_VALUE;
                    for (IShip ship : player.getFleet()) {
                       int shipValue = ship.getValue();
                        if  (Math.abs(shipValue - sum) < maxDelta) {
                            maxDelta = Math.abs(shipValue - sum);
                            shipMatch = ship;
                        }
                    }
                    // todo: andi 1/2/15: auction the ship: Ticket: 146
                    // Auction ship postponed
                } else if (debt.getCreditor() instanceof IPlayer){
                    int value = rnd.nextInt(debt.getAmount()/2) + debt.getAmount();
                    value = (int) Math.min(value, debt.getAmount()*debt.getInterest());
                    ((IPlayer)debt.getCreditor()).updateCash(value);
                    ICitizen debitor = debt.getDebitor();

                    DisplayMessage msg  = new DisplayMessage(messageSource.getMessage("ch.sahits.game.openpatrician.engine.land.city.LoanerEngine.pawnMsg1", new Object[]{debitor.getName(), debitor.getLastName(), value}, locale.getCurrentLocal()));
                    clientServerEventBus.post(msg);
                }
            }
        };
    }

    void addNewLoaner(ICity city) {
        factory.createLoaner(city);
    }

    @Override
    public List getChildren() {
        return new ArrayList<>();
    }

    /**
     * Retrieve the loaner for the city. If the loaner cannot be found null
     * will be returned.
     * @param city
     * @return
     */
    public ILoaner getLoaner(ICity city) {
        for (ILoaner loaner : loaners) {
            if (city.equals(loaner.getCity())) {
                return loaner;
            }
        }
        return null;
    }

    /**
     * Find all the debt of a player with a given loaner.
     * @param loaner
     * @param player
     * @return
     */
    public List findDebts(ILoaner loaner, IPlayer player) {
        ArrayList filteredList = new ArrayList<>();
        for (IDebt debt : loaner.getDebts()) {
            if (player.equals(debt.getDebitor())) {
                filteredList.add(debt);
            }
        }
        return filteredList;
    }

    /**
     * Find all the debts that were granted by a player.
     * @param loaner
     * @param creditor
     * @return
     */
    public List findLoans(ILoaner loaner, IPlayer creditor) {
        ArrayList filteredList = new ArrayList<>();
        for (IDebt debt : loaner.getDebts()) {
            if (creditor.equals(debt.getCreditor())) {
                filteredList.add(debt);
            }
        }
        return filteredList;    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy