mirror of
https://github.com/ProjectSWGCore/NGECore2.git
synced 2026-08-01 02:16:15 -04:00
Added city update process, added city fixup process,
This commit is contained in:
@@ -91,6 +91,7 @@ public class PlayerCity implements Serializable {
|
||||
public static final int LARGE_GARDEN = 5;
|
||||
public static final int SHUTTLEPORT = 6;
|
||||
|
||||
public static final int[] citizensPerRank = new int[] { 5, 10, 15, 30, 40 };
|
||||
|
||||
private String cityName = "";
|
||||
private int planetId;
|
||||
@@ -118,11 +119,13 @@ public class PlayerCity implements Serializable {
|
||||
private boolean zoningEnabled = false;
|
||||
private transient CollidableCircle area;
|
||||
|
||||
//private final long cityUpdateSpan = 7*86400*1000;
|
||||
private final long cityUpdateSpan = 100*1000;
|
||||
|
||||
//private final long legislationPeriod = 21*86400*1000;
|
||||
private final long legislationPeriod = 100*1000;
|
||||
//public static final long cityUpdateSpan = 7*86400*1000;
|
||||
public static final long cityUpdateSpan = 100*1000;
|
||||
//public static final long cityUpdateSpan = 86400*1000;
|
||||
public static final long newCityGraceSpan = 100*1000;
|
||||
|
||||
//public static final long legislationPeriod = 21*86400*1000;
|
||||
public static final long legislationPeriod = 100*1000;
|
||||
|
||||
private Vector<Long> placedStructures = new Vector<Long>();
|
||||
private Vector<Long> citizens = new Vector<Long>();
|
||||
@@ -178,71 +181,25 @@ public class PlayerCity implements Serializable {
|
||||
|
||||
public void processCityUpdate() {
|
||||
// has something changed?
|
||||
System.out.println("processCityUpdate");
|
||||
System.out.println("processCityUpdate for " + cityName);
|
||||
|
||||
fixupCitizens();
|
||||
int censusResult = citizens.size();
|
||||
int currentRank = getRank();
|
||||
|
||||
switch (currentRank) {
|
||||
/*case NEWCITY : if (censusResult>=5){
|
||||
setRank(++currentRank); // Expand to Outpost
|
||||
sendCityExpandMail();
|
||||
}
|
||||
|
||||
if (censusResult<5){
|
||||
// kill city
|
||||
}
|
||||
break;*/
|
||||
|
||||
case OUTPOST : if (censusResult>=10){
|
||||
setRank(++currentRank); // Expand to Village
|
||||
sendCityExpandMail();
|
||||
}
|
||||
if (censusResult<5){
|
||||
setRank(--currentRank); // Contract to Deserted
|
||||
sendCityContractMail();
|
||||
}
|
||||
break;
|
||||
|
||||
case VILLAGE : if (censusResult>=15){
|
||||
setRank(++currentRank); // Expand to Township
|
||||
sendCityExpandMail();
|
||||
}
|
||||
if (censusResult<10){
|
||||
setRank(--currentRank); // Contract to Outpost
|
||||
sendCityContractMail();
|
||||
}
|
||||
break;
|
||||
|
||||
case TOWNSHIP : if (censusResult>=30){
|
||||
setRank(++currentRank); // Expand to City
|
||||
sendCityExpandMail();
|
||||
}
|
||||
if (censusResult<15){
|
||||
setRank(--currentRank); // Contract to Village
|
||||
sendCityContractMail();
|
||||
}
|
||||
break;
|
||||
|
||||
case CITY : if (censusResult>=40){
|
||||
setRank(++currentRank); // Expand to Metropolis
|
||||
sendCityExpandMail();
|
||||
}
|
||||
if (censusResult<30){
|
||||
setRank(--currentRank); // Contract to Township
|
||||
sendCityContractMail();
|
||||
}
|
||||
break;
|
||||
|
||||
case METROPOLIS : if (censusResult<40){
|
||||
setRank(--currentRank); // Contract to City
|
||||
sendCityContractMail();
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
int minCitizen = citizensPerRank[currentRank - 1];
|
||||
|
||||
if(censusResult < minCitizen) {
|
||||
contractCity();
|
||||
} else {
|
||||
if(getRank() != METROPOLIS && citizensPerRank[currentRank] <= censusResult)
|
||||
expandCity();
|
||||
}
|
||||
|
||||
NGECore core = NGECore.getInstance();
|
||||
// collect taxes
|
||||
if(core.objectService.getObject(cityHallId) == null)
|
||||
return;
|
||||
for (long citizen : citizens) {
|
||||
CreatureObject citizenObject = core.objectService.getObject(citizen) == null ? core.objectService.getCreatureFromDB(citizen) : (CreatureObject) core.objectService.getObject(citizen);
|
||||
if(citizenObject == null)
|
||||
@@ -266,11 +223,141 @@ public class PlayerCity implements Serializable {
|
||||
}
|
||||
demolishHighRankStructures();
|
||||
calculateAndPayMaintenance();
|
||||
core.playerCityService.schedulePlayerCityUpdate(this, cityUpdateSpan);
|
||||
setNextCityUpdate(System.currentTimeMillis()+cityUpdateSpan);
|
||||
}
|
||||
|
||||
public void cityFixUp(){
|
||||
public void contractCity() {
|
||||
|
||||
NGECore core = NGECore.getInstance();
|
||||
int newRank = getRank() - 1;
|
||||
CreatureObject mayor = core.objectService.getObject(getMayorID()) == null ? core.objectService.getCreatureFromDB(getMayorID()) : (CreatureObject) core.objectService.getObject(getMayorID());
|
||||
if(mayor == null)
|
||||
return;
|
||||
|
||||
if(newRank < 1) {
|
||||
core.housingService.destroyStructure((BuildingObject) core.objectService.getObject(cityHallId));
|
||||
return;
|
||||
}
|
||||
|
||||
// TODO unregister city if rank < 3
|
||||
|
||||
setRank(newRank);
|
||||
demolishCivicStructuresOutsideRadius();
|
||||
demolishHighRankStructures();
|
||||
sendCityContractMail();
|
||||
fixupCitizens();
|
||||
}
|
||||
|
||||
private void demolishCivicStructuresOutsideRadius() {
|
||||
NGECore core = NGECore.getInstance();
|
||||
List<SWGObject> remove = new ArrayList<SWGObject>();
|
||||
placedStructures.stream().map(core.objectService::getObject)
|
||||
.filter(o -> o.getAttachment("isCivicStructure") != null && (boolean) o.getAttachment("isCivicStructure"))
|
||||
.filter(o -> !area.doesCollide(o)).forEach(remove::add);
|
||||
remove.forEach(b -> core.housingService.destroyStructure((BuildingObject) b));
|
||||
}
|
||||
|
||||
public void expandCity() {
|
||||
|
||||
NGECore core = NGECore.getInstance();
|
||||
CreatureObject mayor = core.objectService.getObject(getMayorID()) == null ? core.objectService.getCreatureFromDB(getMayorID()) : (CreatureObject) core.objectService.getObject(getMayorID());
|
||||
if(mayor == null)
|
||||
return;
|
||||
|
||||
if(getRank() == METROPOLIS)
|
||||
return;
|
||||
|
||||
int newRank = getRank() + 1;
|
||||
setRank(newRank);
|
||||
sendCityExpandMail();
|
||||
fixupCitizens();
|
||||
|
||||
}
|
||||
|
||||
// cleanup in case something went wrong
|
||||
public void fixupCitizens() {
|
||||
List<Long> residents = new ArrayList<Long>();
|
||||
List<CreatureObject> added = new ArrayList<CreatureObject>();
|
||||
List<CreatureObject> removed = new ArrayList<CreatureObject>();
|
||||
// TODO: add extra mail for deleted characters
|
||||
|
||||
NGECore core = NGECore.getInstance();
|
||||
CreatureObject mayor = core.objectService.getObject(getMayorID()) == null ? core.objectService.getCreatureFromDB(getMayorID()) : (CreatureObject) core.objectService.getObject(getMayorID());
|
||||
if(mayor == null)
|
||||
return;
|
||||
|
||||
for (long structureID : new Vector<Long>(placedStructures)) {
|
||||
BuildingObject structure = (BuildingObject) NGECore.getInstance().objectService.getObject(structureID);
|
||||
if(structure == null)
|
||||
return;
|
||||
if(structure.getResidency())
|
||||
residents.add((Long) structure.getAttachment("structureOwner"));
|
||||
}
|
||||
for(long citizenId : new Vector<Long>(citizens)) {
|
||||
if(!residents.contains(citizenId)) {
|
||||
removeCitizen(citizenId, false);
|
||||
CreatureObject citizenObject = core.objectService.getObject(citizenId) == null ? core.objectService.getCreatureFromDB(citizenId) : (CreatureObject) core.objectService.getObject(citizenId);
|
||||
if(citizenObject != null)
|
||||
removed.add(citizenObject);
|
||||
}
|
||||
}
|
||||
for(long residentId : residents) {
|
||||
if(!citizens.contains(residentId)) {
|
||||
addCitizen(residentId, false);
|
||||
CreatureObject citizenObject = core.objectService.getObject(residentId) == null ? core.objectService.getCreatureFromDB(residentId) : (CreatureObject) core.objectService.getObject(residentId);
|
||||
if(citizenObject != null)
|
||||
added.add(citizenObject);
|
||||
}
|
||||
}
|
||||
|
||||
String addTT = "";
|
||||
for(CreatureObject addedCitizen : added) {
|
||||
if(added.indexOf(addedCitizen) == added.size() - 1)
|
||||
addTT += addedCitizen.getCustomName();
|
||||
else
|
||||
addTT += (addedCitizen.getCustomName() + ", ");
|
||||
}
|
||||
|
||||
String removedTT = "";
|
||||
for(CreatureObject removedCitizen : removed) {
|
||||
if(removed.indexOf(removedCitizen) == removed.size() - 1)
|
||||
removedTT += removedCitizen.getCustomName();
|
||||
else
|
||||
removedTT += (removedCitizen.getCustomName() + ", ");
|
||||
}
|
||||
|
||||
if(added.size() > 0) {
|
||||
Mail mail = new Mail();
|
||||
mail.setMailId(core.chatService.generateMailId());
|
||||
mail.setRecieverId(getMayorID());
|
||||
mail.setStatus(Mail.NEW);
|
||||
mail.setTimeStamp((int) (new Date().getTime() / 1000));
|
||||
mail.setSubject("@city/city:city_fixup_add_citizens_subject");
|
||||
mail.setSenderName("@city/city:new_city_from");
|
||||
mail.addProseAttachment(new ProsePackage("@city/city:city_fixup_add_citizens_body", "TT", addTT));
|
||||
|
||||
core.chatService.storePersistentMessage(mail);
|
||||
if(mayor.getClient() != null)
|
||||
core.chatService.sendPersistentMessageHeader(mayor.getClient(), mail);
|
||||
}
|
||||
|
||||
if(removed.size() > 0) {
|
||||
Mail mail = new Mail();
|
||||
mail.setMailId(core.chatService.generateMailId());
|
||||
mail.setRecieverId(getMayorID());
|
||||
mail.setStatus(Mail.NEW);
|
||||
mail.setTimeStamp((int) (new Date().getTime() / 1000));
|
||||
mail.setSubject("@city/city:city_fixup_remove_citizens_subject");
|
||||
mail.setSenderName("@city/city:new_city_from");
|
||||
mail.addProseAttachment(new ProsePackage("@city/city:city_fixup_remove_citizens_body", "TT", removedTT));
|
||||
|
||||
core.chatService.storePersistentMessage(mail);
|
||||
if(mayor.getClient() != null)
|
||||
core.chatService.sendPersistentMessageHeader(mayor.getClient(), mail);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
public void demolishHighRankStructures() {
|
||||
@@ -278,7 +365,7 @@ public class PlayerCity implements Serializable {
|
||||
// that require a higher rank than the current one
|
||||
synchronized(placedStructures){
|
||||
Vector<SWGObject> wreckingBall = new Vector<SWGObject>();
|
||||
for (long structureID : placedStructures){
|
||||
for (long structureID : placedStructures) {
|
||||
SWGObject structure = NGECore.getInstance().objectService.getObject(structureID);
|
||||
int structureCode = (int) structure.getAttachment("CityStructureCode");
|
||||
|
||||
@@ -526,19 +613,34 @@ public class PlayerCity implements Serializable {
|
||||
}
|
||||
|
||||
public void addCitizen(long citizen) {
|
||||
citizens.add(citizen);
|
||||
CreatureObject citizenObject = (CreatureObject) NGECore.getInstance().objectService.getObject(citizen);
|
||||
sendNewCitizenMailAll(citizenObject);
|
||||
sendNewCitizenMail(citizenObject);
|
||||
addCitizen(citizen, true);
|
||||
}
|
||||
|
||||
public void removeCitizen(long citizen) {
|
||||
removeCitizen(citizen, true);
|
||||
}
|
||||
|
||||
public void addCitizen(long citizen, boolean sendMail) {
|
||||
citizens.add(citizen);
|
||||
NGECore core = NGECore.getInstance();
|
||||
CreatureObject citizenObject = core.objectService.getObject(citizen) == null ? core.objectService.getCreatureFromDB(citizen) : (CreatureObject) core.objectService.getObject(citizen);
|
||||
if(citizenObject == null)
|
||||
return;
|
||||
if(sendMail) {
|
||||
sendNewCitizenMailAll(citizenObject);
|
||||
sendNewCitizenMail(citizenObject);
|
||||
}
|
||||
}
|
||||
|
||||
public void removeCitizen(long citizen, boolean sendMail) {
|
||||
citizens.remove(citizen);
|
||||
NGECore core = NGECore.getInstance();
|
||||
CreatureObject citizenObject = core.objectService.getObject(citizen) == null ? core.objectService.getCreatureFromDB(citizen) : (CreatureObject) core.objectService.getObject(citizen);
|
||||
if(citizenObject == null)
|
||||
return;
|
||||
sendCitizenLeftMailAll(citizenObject);
|
||||
if(sendMail) {
|
||||
sendCitizenLeftMailAll(citizenObject);
|
||||
}
|
||||
}
|
||||
|
||||
public long getNextElectionDate() {
|
||||
|
||||
@@ -66,37 +66,11 @@ public class PlayerCityService implements INetworkDispatch {
|
||||
public PlayerCityService(NGECore core) {
|
||||
this.core = core;
|
||||
core.scriptService.callScript("scripts/", "cityRankCaps", "addCityRankCaps", core);
|
||||
scheduler.scheduleAtFixedRate(() -> {
|
||||
administratePlayerCities();
|
||||
}, 0, 1, TimeUnit.MINUTES);
|
||||
}
|
||||
|
||||
public void addCityRankCap(String planetName, int[] caps) {
|
||||
cityRankCaps.put(planetName, caps);
|
||||
}
|
||||
|
||||
public void administratePlayerCities() {
|
||||
synchronized(playerCities){
|
||||
Vector<PlayerCity> unfoundedCities = new Vector<PlayerCity>();
|
||||
for (PlayerCity city : playerCities){
|
||||
|
||||
if (city.getNextCityUpdate() <= System.currentTimeMillis())
|
||||
city.processCityUpdate();
|
||||
|
||||
if (city.getNextElectionDate() <= System.currentTimeMillis())
|
||||
city.processElection();
|
||||
|
||||
if (! city.isFounded() && city.getFoundationTime()<=System.currentTimeMillis()-(60*60*24*1000)){
|
||||
if (! city.checkFoundationSuccess())
|
||||
unfoundedCities.add(city);
|
||||
}
|
||||
}
|
||||
|
||||
if (unfoundedCities.size()>0){
|
||||
unfoundedCities.forEach(this::destroyCity);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean isRankCapped(Planet planet, int rank) {
|
||||
if(cityRankCaps.get(planet.getName()) == null)
|
||||
@@ -128,7 +102,7 @@ public class PlayerCityService implements INetworkDispatch {
|
||||
return;
|
||||
|
||||
if(isRankCapped(actor.getPlanet(), PlayerCity.OUTPOST)) {
|
||||
actor.sendSystemMessage("This Planet can not support any more cities", (byte) 0);
|
||||
actor.sendSystemMessage("This Planet can not support any more cities.", (byte) 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -164,6 +138,7 @@ public class PlayerCityService implements INetworkDispatch {
|
||||
}
|
||||
|
||||
PlayerCity playerCity = addNewPlayerCity(actor, cityHall);
|
||||
PlayerCityService.this.schedulePlayerCityUpdate(playerCity, PlayerCity.newCityGraceSpan);
|
||||
cityHall.setAttachment("structureCity", playerCity.getCityID());
|
||||
actor.setAttachment("residentCity", playerCity.getCityID());
|
||||
core.housingService.declareResidency(actor, cityHall);
|
||||
@@ -397,5 +372,11 @@ public class PlayerCityService implements INetworkDispatch {
|
||||
|
||||
playerCities.remove(city);
|
||||
|
||||
}
|
||||
|
||||
public void schedulePlayerCityUpdate(PlayerCity playerCity, long time) {
|
||||
scheduler.schedule(() -> {
|
||||
playerCity.processCityUpdate();
|
||||
}, time, TimeUnit.MILLISECONDS);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user