
ch.sahits.game.openpatrician.engine.land.city.TavernEngine Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of OpenPatricianEngine Show documentation
Show all versions of OpenPatricianEngine Show documentation
Engine part driving the models and the game
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