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

ch.sahits.game.openpatrician.engine.land.city.TavernEngine 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.ClockTickDayChange;
import ch.sahits.game.openpatrician.annotation.ClassCategory;
import ch.sahits.game.openpatrician.annotation.DependentInitialisation;
import ch.sahits.game.openpatrician.annotation.EClassCategory;
import ch.sahits.game.openpatrician.engine.AbstractEngine;
import ch.sahits.game.openpatrician.engine.land.CaptainEngine;
import ch.sahits.game.openpatrician.model.IUpdatableCityRelatedState;
import ch.sahits.game.openpatrician.model.IUpdateableState;
import ch.sahits.game.openpatrician.model.city.EPopulationClass;
import ch.sahits.game.openpatrician.model.city.ICity;
import ch.sahits.game.openpatrician.model.city.impl.TavernState;
import ch.sahits.game.openpatrician.model.collection.CityTavernRegistry;
import ch.sahits.game.openpatrician.model.people.IPerson;
import ch.sahits.game.openpatrician.model.people.ISailorState;
import ch.sahits.game.openpatrician.model.people.ITavernPerson;
import ch.sahits.game.openpatrician.util.StartNewGameBean;
import com.google.common.eventbus.AsyncEventBus;
import com.google.common.eventbus.Subscribe;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.util.List;
import java.util.Map.Entry;
import java.util.Random;

import static com.google.common.collect.Lists.newArrayList;

/**
 * Every city has a corresponding tavern engine. The guests in
 * a tavern may change on a daily basis
 * @author Andi Hotz, (c) Sahits GmbH, 2013
 * Created on Jan 19, 2013
 *
 */
@Component
@Lazy
@DependentInitialisation(StartNewGameBean.class)
@ClassCategory(EClassCategory.SINGLETON_BEAN)
public class TavernEngine  extends AbstractEngine {
	@Autowired
	private Random rnd;
	@Value("${beggar.salior.ratio}")
	private int beggarSailorRation;
	@Autowired
	private CaptainEngine captainEngine;
    @Autowired
    @Qualifier("serverClientEventBus")
    private AsyncEventBus clientServerEventBus;

	@Autowired
	private CityTavernRegistry cities;


	public void addCity(TavernState state, ICity city) {
        cities.put(city, state);
        int nbSailors = computeNumbersOfSailors(city);
        final ISailorState sailors = state.getSailors();
        sailors.setNumberOfSailors(nbSailors);
        handlePersonsBecomingAbsent(state);
        handlePersonsBecomingPresent(city, state);
    }

    @Override
    public List getChildren() {
        return newArrayList(new AbstractEngine[]{captainEngine});
    }

    @PostConstruct
	private void init() {

        clientServerEventBus.register(this);
	}
	@PreDestroy
	private void unregister() {
		clientServerEventBus.unregister(this);
	}

	private int computeNumbersOfSailors(ICity city) {
		int nbBeggars = city.getPopulation(EPopulationClass.BEGGAR);
		int nbSailors = (int)(nbBeggars / beggarSailorRation*rnd.nextDouble()*2);
		return nbSailors;
	}

    @Subscribe
    public void handleDayChange(ClockTickDayChange event) {
        for (Entry entry : cities.entrySet()) {
            ICity city = entry.getKey();
            TavernState state = entry.getValue();
            int nbSailors = computeNumbersOfSailors(city);
            state.getSailors().setNumberOfSailors(nbSailors);
            handlePersonsBecomingAbsent(state);
            handlePersonsBecomingPresent(city, state);
        }

    }
	/**
	 * Randomized state update for persons that are not present.
	 */
	private void handlePersonsBecomingAbsent(TavernState state) {
		List present = state.presentPersonsProperty();
        List leavingPersons = newArrayList();
		for (IPerson p : present) {
			if (p instanceof ITavernPerson) {
				ITavernPerson person = (ITavernPerson) p;
				double maxPresence = Math.abs(person.getMaxDaysPresent());
				double presenceTime = Math.abs(person.getNumberOfDaysSinceArrival());
				double absence = rnd.nextDouble()*2*maxPresence/presenceTime;
				if (absence > 0.5) {
                    leavingPersons.add(person);
                }
			}
			// non tavern persons cannot become absent on their own
		} // end for present
		synchronized (state) {
			for (ITavernPerson person : leavingPersons) {
				person.leave();
			}
		}
    }
	/**
	 * Randomized state update for persons that are present.
	 */
	private void handlePersonsBecomingPresent(ICity city, TavernState state) {
		List absent = state.absentPersonProperty();
        List arrivingPersons = newArrayList();
		for (ITavernPerson person : absent) {
			double maxPresence = Math.abs(person.getMaxDaysPresent());
			double maxNbAbsence = Math.abs(person.getMaxDaysAbsent());
			double absentTime = person.getNumberOfDaysSinceArrival()-maxPresence;
			double presence = rnd.nextDouble()*2*(absentTime/maxNbAbsence);
			if (presence > 0.5) {
				if (person instanceof IUpdateableState) {
					((IUpdateableState)person).update();
				} else if (person instanceof IUpdatableCityRelatedState) {
					((IUpdatableCityRelatedState)person).update(city);
				} else {
					throw new IllegalArgumentException("Person is not updatable: "+person);
				}
                arrivingPersons.add(person);
            }
		} // end for absent
		synchronized (state) {
			for (ITavernPerson person : arrivingPersons) {
				person.arrive();
			}
		}
    }

    public TavernState getTavernState(ICity city ) {
        return cities.get(city);
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy