From 1c9e068f2e216f09e6789c1a32f1c5d1733cff3d Mon Sep 17 00:00:00 2001 From: Waverunner Date: Fri, 8 Nov 2013 20:35:25 -0500 Subject: [PATCH] Added travel fares, landing sequence for shuttles Also added Console resource for time stamped messages --- scripts/commands/boardshuttle.py | 20 +-- scripts/commands/purchaseticket.py | 8 +- scripts/commands/serverdestroyobject.py | 4 +- .../npc/theme_park/player_transport.py | 2 + .../swg/PlanetTravelPointListResponse.java | 4 +- src/resources/common/Console.java | 35 +++++ src/services/SkillModService.java | 16 --- src/services/travel/TravelPoint.java | 11 +- src/services/travel/TravelService.java | 125 ++++++++++++++++-- 9 files changed, 178 insertions(+), 47 deletions(-) create mode 100644 src/resources/common/Console.java diff --git a/scripts/commands/boardshuttle.py b/scripts/commands/boardshuttle.py index b452c65d..cc928a09 100644 --- a/scripts/commands/boardshuttle.py +++ b/scripts/commands/boardshuttle.py @@ -1,3 +1,4 @@ +from resources.common import Console import sys def setup(): @@ -8,13 +9,12 @@ def run(core, actor, target, commandString): ticketList = trvSvc.getTicketList(actor) nearestPoint = trvSvc.getNearestTravelPoint(actor) - print (nearestPoint.getName()) - if nearestPoint.isShuttleAvailable: - print ('inside nearestPoint if') + #print (nearestPoint.getName()) + + if nearestPoint.isShuttleAvailable() is True: + if ticketList.size() >= 1: - print ('inside list >= 1') trvSvc.sendTicketWindow(actor, target) - print ('sent ticket window') return elif ticketList.isEmpty: @@ -22,10 +22,14 @@ def run(core, actor, target, commandString): return return - + elif nearestPoint.isShuttleLanding() is True: + actor.sendSystemMessage('The next shuttle is about to begin boarding.', 0) + return else: - actor.sendSystemMessage('The next shuttle will arrive in 60 seconds.', 0) - return + + actor.sendSystemMessage('The next shuttle will arrive in 60 seconds.', 0) + #TODO: Counter for time when shuttle will arrive + return return # NOTE: In NGE video from Jan. 4th, 2010, ticket purchase window is shown with just 1 ticket and does not # automatically transport the player. diff --git a/scripts/commands/purchaseticket.py b/scripts/commands/purchaseticket.py index 1f6de430..9e6998ef 100644 --- a/scripts/commands/purchaseticket.py +++ b/scripts/commands/purchaseticket.py @@ -4,8 +4,6 @@ def setup(): return def run(core, actor, target, commandString): - #print ('Command string: ' + commandString) - trvSvc = core.travelService cmdArgs = commandString.split(" ") @@ -14,8 +12,8 @@ def run(core, actor, target, commandString): departureLoc = cmdArgs[1].replace("_"," ") arrivalPlanet = cmdArgs[2] arrivalLoc = cmdArgs[3].replace("_", " ") - # 4 int - # 5 int - trvSvc.purchaseTravelTicket(actor, departurePlanet, departureLoc, arrivalPlanet, arrivalLoc, '1') + roundTrip = cmdArgs[4] + + trvSvc.purchaseTravelTicket(actor, departurePlanet, departureLoc, arrivalPlanet, arrivalLoc, roundTrip) return \ No newline at end of file diff --git a/scripts/commands/serverdestroyobject.py b/scripts/commands/serverdestroyobject.py index ae58c794..e3541bce 100644 --- a/scripts/commands/serverdestroyobject.py +++ b/scripts/commands/serverdestroyobject.py @@ -1,3 +1,4 @@ +from resources.common import Console import sys def setup(): @@ -18,8 +19,7 @@ def run(core, actor, target, commandString): if not target.getPermissions().canRemove(actor, target): return if parent and not parent.getPermissions().canRemove(actor, parent): - return - if not target.isSubChildOf(actor): + Console.println("Doesn't have permission!") return parent.remove(target) diff --git a/scripts/object/creature/npc/theme_park/player_transport.py b/scripts/object/creature/npc/theme_park/player_transport.py index 3e7b455f..30d15cfb 100644 --- a/scripts/object/creature/npc/theme_park/player_transport.py +++ b/scripts/object/creature/npc/theme_park/player_transport.py @@ -4,4 +4,6 @@ def setup(core, object): object.setPosture(0) # land = 0 : away = 2 tp = core.travelService.getNearestTravelPoint(object) tp.setShuttle(object) + tp.setShuttleAvailable(True) + tp.setShuttleLanding(False) return \ No newline at end of file diff --git a/src/protocol/swg/PlanetTravelPointListResponse.java b/src/protocol/swg/PlanetTravelPointListResponse.java index 131551fd..46d37683 100644 --- a/src/protocol/swg/PlanetTravelPointListResponse.java +++ b/src/protocol/swg/PlanetTravelPointListResponse.java @@ -53,8 +53,8 @@ public class PlanetTravelPointListResponse extends SWGMessage { IoBuffer result = IoBuffer.allocate(travelPoints.size() * 2).order(ByteOrder.LITTLE_ENDIAN); result.setAutoExpand(true); - result.putShort((short) 6); //2 - result.putInt(0x4D32541F); //4 + result.putShort((short) 6); + result.putInt(0x4D32541F); result.put(getAsciiString(planetString)); diff --git a/src/resources/common/Console.java b/src/resources/common/Console.java new file mode 100644 index 00000000..292e78e3 --- /dev/null +++ b/src/resources/common/Console.java @@ -0,0 +1,35 @@ +/******************************************************************************* + * Copyright (c) 2013 + * + * This File is part of NGECore2. + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see . + * + * Using NGEngine to work with NGECore2 is making a combined work based on NGEngine. + * Therefore all terms and conditions of the GNU Lesser General Public License cover the combination. + ******************************************************************************/ +package resources.common; + +import java.util.Calendar; + +public class Console { + public static void println(String string) { + Calendar cal = Calendar.getInstance(); + System.out.println(cal.getTime() + ": " + string); + } + public static void print(String string) { + Calendar cal = Calendar.getInstance(); + System.out.print(cal.getTime() + ": " + string); + } +} diff --git a/src/services/SkillModService.java b/src/services/SkillModService.java index d84576b0..f7fabe0e 100644 --- a/src/services/SkillModService.java +++ b/src/services/SkillModService.java @@ -49,22 +49,6 @@ public class SkillModService implements INetworkDispatch { core.scriptService.callScript("scripts/skillMods/", skillMod, "deduct", core, creature, skillMod, value); } - - public boolean hasSkillMod(CreatureObject creature, String skillMod) { - - SWGList skillMods = creature.getSkillMods(); - - if (skillMods.isEmpty()) { return false; } - - for (SkillMod skill : skillMods) { - if (skill.getSkillModString() == skillMod) { - return true; - } - else { return false; } - } - - return false; - } @Override public void insertOpcodes(Map arg0, Map arg1) { diff --git a/src/services/travel/TravelPoint.java b/src/services/travel/TravelPoint.java index c6f58870..1c0a4266 100644 --- a/src/services/travel/TravelPoint.java +++ b/src/services/travel/TravelPoint.java @@ -34,6 +34,7 @@ public class TravelPoint { private int ticketPrice; private CreatureObject shuttle; private boolean shuttleAvailable; + private boolean shuttleLanding; public TravelPoint() { } @@ -43,6 +44,7 @@ public class TravelPoint { this.location = new Point3D(x, y, z); this.spawnLocation = new SpawnPoint(this.location, 0, 1); this.shuttleAvailable = false; + this.shuttleLanding = false; } public String getName() { @@ -91,7 +93,6 @@ public class TravelPoint { public void setShuttle(CreatureObject shuttleObj) { this.shuttle = shuttleObj; - this.shuttleAvailable = true; } public boolean isShuttleAvailable() { @@ -101,4 +102,12 @@ public class TravelPoint { public void setShuttleAvailable(boolean shuttleAvailable) { this.shuttleAvailable = shuttleAvailable; } + + public boolean isShuttleLanding() { + return shuttleLanding; + } + + public void setShuttleLanding(boolean shuttleLanding) { + this.shuttleLanding = shuttleLanding; + } } diff --git a/src/services/travel/TravelService.java b/src/services/travel/TravelService.java index 5408a92d..0aad702d 100644 --- a/src/services/travel/TravelService.java +++ b/src/services/travel/TravelService.java @@ -30,6 +30,7 @@ import java.util.Vector; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import org.apache.commons.lang3.text.WordUtils; @@ -38,6 +39,8 @@ import org.apache.mina.core.session.IoSession; import protocol.swg.PlanetTravelPointListRequest; import protocol.swg.PlanetTravelPointListResponse; +import engine.clientdata.ClientFileManager; +import engine.clientdata.visitors.DatatableVisitor; import engine.clients.Client; import engine.resources.container.Traverser; import engine.resources.objects.SWGObject; @@ -48,6 +51,7 @@ import engine.resources.scene.quadtree.QuadTree; import engine.resources.service.INetworkDispatch; import engine.resources.service.INetworkRemoteEvent; import main.NGECore; +import resources.common.Console; import resources.common.Opcodes; import resources.objects.creature.CreatureObject; import resources.objects.player.PlayerObject; @@ -63,6 +67,7 @@ public class TravelService implements INetworkDispatch { private NGECore core; private Map> travelMap = new ConcurrentHashMap>(); + private Map> fareMap = new ConcurrentHashMap>(); private final ScheduledExecutorService scheduler = Executors.newScheduledThreadPool(1); public TravelService(NGECore core) { @@ -119,15 +124,17 @@ public class TravelService implements INetworkDispatch { if (tp.getShuttle() == null) continue; else { + if (tp.isShuttleAvailable() == false) { tp.getShuttle().setPosture((byte) 0); - tp.setShuttleAvailable(true); - System.out.println("Shuttle is available"); + tp.setShuttleLanding(true); + handleShuttleLanding(); } - else { + else { tp.getShuttle().setPosture((byte) 2); tp.setShuttleAvailable(false); - System.out.println("Shuttle is not available."); + tp.setShuttleLanding(false); + Console.println("Shuttle is not available."); } } } @@ -139,6 +146,27 @@ public class TravelService implements INetworkDispatch { scheduler.scheduleAtFixedRate(shuttleRun, 60, 60, TimeUnit.SECONDS); } + + public void handleShuttleLanding() { + scheduler.schedule(new Runnable() { + + @Override + public void run() { + for (Entry> entry : travelMap.entrySet()) { + for(TravelPoint tp : entry.getValue()) { + if (tp.isShuttleLanding()) { + tp.setShuttleLanding(false); + tp.setShuttleAvailable(true); + Console.println("Shuttle has landed!"); + } + } + } + } + + }, 26, TimeUnit.SECONDS); + + } + public TravelPoint getNearestTravelPoint(SWGObject obj) { TravelPoint returnedPoint = null; Vector planetTp = travelMap.get(obj.getPlanet()); @@ -180,7 +208,7 @@ public class TravelService implements INetworkDispatch { public void addTravelPoint(Planet planet, String name, float x, float y, float z) { // z should be y for 2d map - TravelPoint travelPoint = new TravelPoint(name, x, y, z, 100); + TravelPoint travelPoint = new TravelPoint(name, x, y, z, 150); travelPoint.setPlanetName(WordUtils.capitalize(planet.getName())); @@ -216,6 +244,7 @@ public class TravelService implements INetworkDispatch { for (Planet planet : planetList) { addPlanet(planet); } + populateTravelFares(); } public SWGObject createTravelTicket(String departurePlanet, String departureLoc, String arrivalPlanet, String arrivalLoc) { @@ -230,23 +259,46 @@ public class TravelService implements INetworkDispatch { travelTicket.setStringAttribute("@obj_attr_n:travel_arrival_point", arrivalLoc); travelTicket.setAttachment("objType", "ticket"); - System.out.println("Object type: " + travelTicket.getAttachment("objType")); return travelTicket; } - public void purchaseTravelTicket(SWGObject player, String departurePlanet, String departureLoc, String arrivalPlanet, String arrivalLoc, String cost) { + public void purchaseTravelTicket(SWGObject player, String departurePlanet, String departureLoc, String arrivalPlanet, String arrivalLoc, String roundTrip) { CreatureObject creatureObj = (CreatureObject) player; + int fare = fareMap.get(player.getPlanet()).get(arrivalPlanet); + if (roundTrip.equals("1")) { + fare += fareMap.get(player.getPlanet()).get(arrivalPlanet); + } + int playerBankCredits = creatureObj.getBankCredits(); + if (playerBankCredits < fare) { + int cashDifference = fare - playerBankCredits; + + if (cashDifference > creatureObj.getCashCredits()) { + SUIWindow window = core.suiService.createMessageBox(MessageBoxType.MESSAGE_BOX_OK, "STAR WARS GALAXIES", "You do not have enough to purchase that." + , player, null, 0); + core.suiService.openSUIWindow(window); + return; + } + + creatureObj.setBankCredits(0); + creatureObj.setCashCredits(cashDifference); + } else { + creatureObj.setBankCredits(playerBankCredits - fare); + } + + if (roundTrip.equals("1")) { + SWGObject tripTicket = createTravelTicket(arrivalPlanet, arrivalLoc, departurePlanet, departureLoc); + creatureObj.getSlottedObject("inventory").add(tripTicket); + } SWGObject travelTicket = createTravelTicket(departurePlanet, departureLoc, arrivalPlanet, arrivalLoc); creatureObj.getSlottedObject("inventory").add(travelTicket); - travelTicket.isSubChildOf(player); - + Console.println("Total cost: " + fare); SUIWindow window = core.suiService.createMessageBox(MessageBoxType.MESSAGE_BOX_OK, "STAR WARS GALAXIES", "Ticket purchase complete.", player, null, 0); core.suiService.openSUIWindow(window); - creatureObj.sendSystemMessage("You successfully make a payment of " + cost + "credits to the Galactic Travel Commission.", (byte) 0); + creatureObj.sendSystemMessage("You successfully make a payment of " + fare + " credits to the Galactic Travel Commission.", (byte) 0); } // This returns all ticket objects in a players inventory @@ -265,7 +317,7 @@ public class TravelService implements INetworkDispatch { if (obj.getAttachment("objType") != null) { String objType = (String) obj.getAttachment("objType"); String ticket = "ticket"; - System.out.println("Nearest Point: " + nearestPoint.getName()); + //System.out.println("Nearest Point: " + nearestPoint.getName()); if (objType.equals(ticket) && obj.getStringAttribute("@obj_attr_n:travel_departure_point").equals(nearestPoint.getName())) { ticketList.add(obj); } @@ -282,7 +334,10 @@ public class TravelService implements INetworkDispatch { core.simulationService.teleport(actor, tp.getSpawnLocation().getPosition(), tp.getSpawnLocation().getOrientation(), 0); } - else { core.simulationService.transferToPlanet(actor, core.terrainService.getPlanetByName(tp.getPlanetName()), tp.getSpawnLocation().getPosition(), tp.getSpawnLocation().getOrientation(), actor); } + else { + Planet planet = core.terrainService.getPlanetByName(tp.getPlanetName()); + core.simulationService.transferToPlanet(actor, planet, tp.getSpawnLocation().getPosition(), tp.getSpawnLocation().getOrientation(), null); + } } @@ -311,7 +366,6 @@ public class TravelService implements INetworkDispatch { int index = Integer.parseInt(returnList.get(0)); SWGObject selectedTicket = core.objectService.getObject(window.getObjectIdByIndex(index)); - System.out.println("Selected ticket obj: " + window.getObjectIdByIndex(index)); TravelPoint arrivalPoint = getTravelPointByName(selectedTicket.getStringAttribute("@obj_attr_n:travel_arrival_planet").toLowerCase(), selectedTicket.getStringAttribute("@obj_attr_n:travel_arrival_point")); @@ -330,6 +384,51 @@ public class TravelService implements INetworkDispatch { } + private void populateTravelFares() { + try { + DatatableVisitor travelFares = ClientFileManager.loadFile("datatables/travel/travel.iff", DatatableVisitor.class); + + for (int f = 0; f < travelFares.getRowCount(); f++) { + Planet planet = core.terrainService.getPlanetByName((String) travelFares.getObject(f, 0)); + if (travelMap.containsKey(planet)) { + int corellia = ((Integer) travelFares.getObject(f, 1)); + int dantooine = ((int) travelFares.getObject(f, 2)); + int dathomir = ((int) travelFares.getObject(f, 3)); + int endor = ((int) travelFares.getObject(f, 4)); + int lok = ((int) travelFares.getObject(f, 5)); + int naboo = ((int) travelFares.getObject(f, 6)); + int rori = ((int) travelFares.getObject(f, 7)); + int talus = ((int) travelFares.getObject(f, 8)); + int tatooine = ((int) travelFares.getObject(f, 9)); + int yavin4 = ((int) travelFares.getObject(f, 10)); + int mustafar = ((int) travelFares.getObject(f, 11)); + int kashyyyk_main = ((int) travelFares.getObject(f, 12)); + + Map planetFares = new ConcurrentHashMap(); + + planetFares.put("corellia", corellia); + planetFares.put("dantooine", dantooine); + planetFares.put("dathomir", dathomir); + planetFares.put("endor", endor); + planetFares.put("lok", lok); + planetFares.put("naboo", naboo); + planetFares.put("rori", rori); + planetFares.put("talus", talus); + planetFares.put("tatooine", tatooine); + planetFares.put("yavin4", yavin4); + planetFares.put("mustafar", mustafar); + planetFares.put("kashyyyk_main", kashyyyk_main); + + fareMap.put(planet, planetFares); + Console.println("Loaded the travel fares for " + planet.getName()); + } + } + } + catch (InstantiationException | IllegalAccessException e) { + e.printStackTrace(); + } + } + @Override public void shutdown() {