mirror of
https://bitbucket.org/projectswg/holocore.git
synced 2026-01-16 23:04:20 -05:00
Buildout overhaul
This commit is contained in:
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -25,4 +25,4 @@ tansarii dungeon1 du1_npe_dungeon hangarbay1 76.70 0.80 55.70 5
|
||||
heroic_ek dungeon1 du1_heroic_ek r1 -11.70 0.20 -116.50 5
|
||||
heroic_isd dungeon1 du1_heroic_isd mainhangar 0.10 172.30 326.30 5
|
||||
nova_orion dungeon1 du1_nova_orion hangarbay1 76.70 0.80 55.70 5
|
||||
dev_area dev_area 3525 4 -4807 5
|
||||
dev_area dev_area 3525 4 -4807 5
|
||||
|
||||
@@ -1,117 +0,0 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2018 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore 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 Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
package com.projectswg.holocore.resources.support.data.server_info.loader;
|
||||
|
||||
import com.projectswg.common.data.location.Terrain;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader.SdbResultSet;
|
||||
import com.projectswg.holocore.resources.support.objects.buildout.BuildoutArea;
|
||||
import com.projectswg.holocore.resources.support.objects.buildout.BuildoutArea.BuildoutAreaBuilder;
|
||||
import me.joshlarson.jlcommon.log.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
|
||||
public final class AreaLoader {
|
||||
|
||||
private final Map<String, BuildoutArea> areasByName;
|
||||
private final Map<Integer, BuildoutArea> areasById;
|
||||
private final List<BuildoutArea> areaList;
|
||||
private final Collection<String> events;
|
||||
|
||||
private AreaLoader(Collection<String> events) {
|
||||
this.areasByName = new HashMap<>();
|
||||
this.areasById = new HashMap<>();
|
||||
this.areaList = new ArrayList<>();
|
||||
this.events = events;
|
||||
}
|
||||
|
||||
public BuildoutArea getArea(String areaName) {
|
||||
return areasByName.get(areaName);
|
||||
}
|
||||
|
||||
public BuildoutArea getArea(int areaId) {
|
||||
return areasById.get(areaId);
|
||||
}
|
||||
|
||||
public List<BuildoutArea> getAreaList() {
|
||||
return areaList;
|
||||
}
|
||||
|
||||
public Map<String, BuildoutArea> getAreasByName() {
|
||||
return areasByName;
|
||||
}
|
||||
|
||||
public Map<Integer, BuildoutArea> getAreasById() {
|
||||
return areasById;
|
||||
}
|
||||
|
||||
private void loadFromFile() {
|
||||
BuildoutArea area;
|
||||
try (SdbResultSet set = SdbLoader.load(new File("serverdata/buildout/areas.sdb"))) {
|
||||
while (set.next()) {
|
||||
area = new BuildoutAreaBuilder()
|
||||
.setId((int) set.getInt(0))
|
||||
.setTerrain(Terrain.getTerrainFromName(set.getText(1)))
|
||||
.setName(set.getText(2))
|
||||
.setEvent(set.getText(3))
|
||||
.setX1(set.getReal(4))
|
||||
.setZ1(set.getReal(5))
|
||||
.setX2(set.getReal(6))
|
||||
.setZ2(set.getReal(7))
|
||||
.setAdjustCoordinates(set.getInt(8) != 0)
|
||||
.setTranslationX(set.getReal(9))
|
||||
.setTranslationX(set.getReal(10))
|
||||
.build();
|
||||
BuildoutArea replaced = areasByName.get(area.getName());
|
||||
if ((replaced == null && area.getEvent().isEmpty()) || (!area.getEvent().isEmpty() && events.contains(area.getEvent()))) {
|
||||
areasByName.put(area.getName(), area);
|
||||
areasById.put(area.getId(), area);
|
||||
areaList.add(area);
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
Log.e(e);
|
||||
}
|
||||
}
|
||||
|
||||
static AreaLoader load() {
|
||||
return load(Collections.emptySet());
|
||||
}
|
||||
|
||||
static AreaLoader load(String ... events) {
|
||||
return load(Arrays.asList(events));
|
||||
}
|
||||
|
||||
static AreaLoader load(Collection<String> events) {
|
||||
AreaLoader loader = new AreaLoader(events);
|
||||
loader.loadFromFile();
|
||||
return loader;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -31,10 +31,8 @@ import com.projectswg.common.data.location.Location;
|
||||
import com.projectswg.common.data.location.Terrain;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader.SdbResultSet;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.BuildingLoader.BuildingLoaderInfo;
|
||||
import com.projectswg.holocore.resources.support.objects.ObjectCreator;
|
||||
import com.projectswg.holocore.resources.support.objects.ObjectCreator.ObjectCreationException;
|
||||
import com.projectswg.holocore.resources.support.objects.buildout.BuildoutArea;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.SWGObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.building.BuildingObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.cell.CellObject;
|
||||
@@ -42,22 +40,22 @@ import me.joshlarson.jlcommon.log.Log;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
|
||||
public final class BuildoutLoader {
|
||||
|
||||
private static final CrcDatabase CRC_DATABASE = CrcDatabase.getInstance();
|
||||
|
||||
private final Map<Long, SWGObject> objectMap;
|
||||
private final Map<String, BuildingObject> buildingMap;
|
||||
private final EnumMap<Terrain, Map<Long, SWGObject>> terrainMap;
|
||||
private final AreaLoader areaLoader;
|
||||
private final Set<String> events;
|
||||
|
||||
private BuildoutLoader(AreaLoader areaLoader) {
|
||||
private BuildoutLoader(Collection<String> events) {
|
||||
this.objectMap = new HashMap<>();
|
||||
this.buildingMap = new HashMap<>();
|
||||
this.terrainMap = new EnumMap<>(Terrain.class);
|
||||
this.areaLoader = areaLoader;
|
||||
this.events = new HashSet<>(events);
|
||||
|
||||
for (Terrain terrain : Terrain.values()) {
|
||||
terrainMap.put(terrain, new HashMap<>());
|
||||
@@ -65,7 +63,11 @@ public final class BuildoutLoader {
|
||||
}
|
||||
|
||||
public Map<Long, SWGObject> getObjects() {
|
||||
return objectMap;
|
||||
return Collections.unmodifiableMap(objectMap);
|
||||
}
|
||||
|
||||
public Map<String, BuildingObject> getBuildings() {
|
||||
return Collections.unmodifiableMap(buildingMap);
|
||||
}
|
||||
|
||||
public Map<Long, SWGObject> getObjects(Terrain terrain) {
|
||||
@@ -78,32 +80,29 @@ public final class BuildoutLoader {
|
||||
}
|
||||
|
||||
private void loadStandardBuildouts() {
|
||||
int areaId;
|
||||
AreaLoader areaLoader = this.areaLoader;
|
||||
BuildoutArea currentArea = areaLoader.getAreaList().get(0);
|
||||
Set<String> events = this.events;
|
||||
try (SdbResultSet set = SdbLoader.load(new File("serverdata/buildout/objects.sdb"))) {
|
||||
while (set.next()) {
|
||||
areaId = (int) set.getInt(1);
|
||||
if (currentArea.getId() != areaId) {
|
||||
BuildoutArea area = areaLoader.getArea(areaId);
|
||||
if (area == null) { // usually for events
|
||||
continue;
|
||||
}
|
||||
currentArea = area;
|
||||
}
|
||||
// "id", "template_crc", "container_id", "event", "terrain", "x", "y", "z", "orientation_x", "orientation_y", "orientation_z", "orientation_w", "cell_index", "tag"
|
||||
String event = set.getText(3);
|
||||
if (!event.isEmpty() && !events.contains(event))
|
||||
continue;
|
||||
|
||||
SWGObject obj = ObjectCreator.createObjectFromTemplate(set.getInt(0), CRC_DATABASE.getString((int) set.getInt(2)));
|
||||
SWGObject obj = ObjectCreator.createObjectFromTemplate(set.getInt(0), CRC_DATABASE.getString((int) set.getInt(1)));
|
||||
obj.setGenerated(false);
|
||||
obj.setLocation(Location.builder().setPosition(set.getReal(4), set.getReal(5), set.getReal(6)).setOrientation(set.getReal(7), set.getReal(8), set.getReal(9), set.getReal(10))
|
||||
.setTerrain(currentArea.getTerrain()).build());
|
||||
obj.setLocation(Location.builder().setPosition(set.getReal(5), set.getReal(6), set.getReal(7)).setOrientation(set.getReal(8), set.getReal(9), set.getReal(10), set.getReal(11))
|
||||
.setTerrain(Terrain.valueOf(set.getText(4))).build());
|
||||
obj.setBuildoutTag(set.getText(13));
|
||||
if (set.getInt(12) != 0) {
|
||||
BuildingObject building = (BuildingObject) objectMap.get(set.getInt(3));
|
||||
BuildingObject building = (BuildingObject) objectMap.get(set.getInt(2));
|
||||
CellObject cell = building.getCellByNumber((int) set.getInt(12));
|
||||
obj.systemMove(cell);
|
||||
} else if (obj instanceof BuildingObject) {
|
||||
((BuildingObject) obj).populateCells();
|
||||
for (SWGObject cell : obj.getContainedObjects())
|
||||
objectMap.put(cell.getObjectId(), cell);
|
||||
if (!obj.getBuildoutTag().isEmpty())
|
||||
buildingMap.put(obj.getBuildoutTag(), (BuildingObject) obj);
|
||||
}
|
||||
objectMap.put(set.getInt(0), obj);
|
||||
}
|
||||
@@ -144,25 +143,15 @@ public final class BuildoutLoader {
|
||||
}
|
||||
|
||||
private void checkParent(SWGObject obj, String buildingName, int cellId) {
|
||||
BuildingLoaderInfo building = DataLoader.buildings().getBuilding(buildingName);
|
||||
if (buildingName.endsWith("_world"))
|
||||
return;
|
||||
BuildingObject building = buildingMap.get(buildingName);
|
||||
if (building == null) {
|
||||
Log.e("Building not found in map: %s", buildingName);
|
||||
return;
|
||||
}
|
||||
long buildingId = building.getId();
|
||||
if (buildingId == 0)
|
||||
return; // World
|
||||
|
||||
SWGObject buildingUncasted = objectMap.get(buildingId);
|
||||
if (buildingUncasted == null) {
|
||||
Log.e("Building not found in map: %s", buildingName);
|
||||
return;
|
||||
}
|
||||
if (!(buildingUncasted instanceof BuildingObject)) {
|
||||
Log.e("Building is not an instance of BuildingObject: %s", buildingName);
|
||||
return;
|
||||
}
|
||||
CellObject cell = ((BuildingObject) buildingUncasted).getCellByNumber(cellId);
|
||||
CellObject cell = building.getCellByNumber(cellId);
|
||||
if (cell == null) {
|
||||
Log.e("Cell is not found! Building: %s Cell: %d", buildingName, cellId);
|
||||
return;
|
||||
@@ -170,8 +159,8 @@ public final class BuildoutLoader {
|
||||
obj.systemMove(cell);
|
||||
}
|
||||
|
||||
static BuildoutLoader load(AreaLoader areaLoader) {
|
||||
BuildoutLoader loader = new BuildoutLoader(areaLoader);
|
||||
static BuildoutLoader load(Collection<String> events) {
|
||||
BuildoutLoader loader = new BuildoutLoader(events);
|
||||
loader.loadFromFile();
|
||||
return loader;
|
||||
}
|
||||
|
||||
@@ -9,7 +9,6 @@ import java.util.function.Supplier;
|
||||
|
||||
enum CachedLoader {
|
||||
BUILDING_CELLS (BuildingCellLoader::new),
|
||||
BUILDOUT_BUILDINGS (BuildingLoader::new),
|
||||
NPC_LOADER (NpcLoader::new),
|
||||
NPC_PATROL_ROUTES (NpcPatrolRouteLoader::new),
|
||||
NPC_STATS (NpcStatLoader::new),
|
||||
@@ -18,7 +17,8 @@ enum CachedLoader {
|
||||
STATIC_SPAWNS (NpcStaticSpawnLoader::new),
|
||||
OBJECT_DATA (ObjectDataLoader::new),
|
||||
COMMANDS (CommandLoader::new),
|
||||
SLOT_DEFINITIONS (SlotDefinitionLoader::new);
|
||||
SLOT_DEFINITIONS (SlotDefinitionLoader::new),
|
||||
ZONE_INSERTIONS (TerrainZoneInsertionLoader::new);
|
||||
|
||||
private final AtomicReference<SoftReference<DataLoader>> cachedLoader;
|
||||
private final Supplier<DataLoader> supplier;
|
||||
|
||||
@@ -2,6 +2,7 @@ package com.projectswg.holocore.resources.support.data.server_info.loader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
|
||||
public abstract class DataLoader {
|
||||
|
||||
@@ -18,19 +19,15 @@ public abstract class DataLoader {
|
||||
}
|
||||
|
||||
public static BuildoutLoader buildouts() {
|
||||
return BuildoutLoader.load(AreaLoader.load());
|
||||
return BuildoutLoader.load(List.of());
|
||||
}
|
||||
|
||||
public static BuildoutLoader buildouts(String ... events) {
|
||||
return BuildoutLoader.load(AreaLoader.load(events));
|
||||
return BuildoutLoader.load(List.of(events));
|
||||
}
|
||||
|
||||
public static BuildoutLoader buildouts(Collection<String> events) {
|
||||
return BuildoutLoader.load(AreaLoader.load(events));
|
||||
}
|
||||
|
||||
public static BuildingLoader buildings() {
|
||||
return (BuildingLoader) CachedLoader.BUILDOUT_BUILDINGS.load();
|
||||
return BuildoutLoader.load(events);
|
||||
}
|
||||
|
||||
public static BuildingCellLoader buildingCells() {
|
||||
@@ -73,4 +70,8 @@ public abstract class DataLoader {
|
||||
return (SlotDefinitionLoader) CachedLoader.SLOT_DEFINITIONS.load();
|
||||
}
|
||||
|
||||
public static TerrainZoneInsertionLoader zoneInsertions() {
|
||||
return (TerrainZoneInsertionLoader) CachedLoader.ZONE_INSERTIONS.load();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
***********************************************************************************/
|
||||
package com.projectswg.holocore.resources.support.data.server_info.loader;
|
||||
|
||||
import com.projectswg.common.data.location.Terrain;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader.SdbResultSet;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.custom.AIBehavior;
|
||||
@@ -65,6 +66,7 @@ public final class NpcStaticSpawnLoader extends DataLoader {
|
||||
public static class StaticSpawnInfo {
|
||||
|
||||
private final int id;
|
||||
private final Terrain terrain;
|
||||
private final double x;
|
||||
private final double y;
|
||||
private final double z;
|
||||
@@ -84,6 +86,7 @@ public final class NpcStaticSpawnLoader extends DataLoader {
|
||||
|
||||
private StaticSpawnInfo(SdbResultSet set) {
|
||||
this.id = (int) set.getInt("spawn_id");
|
||||
this.terrain = Terrain.valueOf(set.getText("terrain"));
|
||||
this.x = set.getReal("x");
|
||||
this.y = set.getReal("y");
|
||||
this.z = set.getReal("z");
|
||||
@@ -107,6 +110,10 @@ public final class NpcStaticSpawnLoader extends DataLoader {
|
||||
return id;
|
||||
}
|
||||
|
||||
public Terrain getTerrain() {
|
||||
return terrain;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
@@ -36,14 +36,14 @@ import java.util.Map;
|
||||
|
||||
public final class SlotDefinitionLoader extends DataLoader {
|
||||
|
||||
private final Map<String, SlotDefinition> buildingMap;
|
||||
private final Map<String, SlotDefinition> slotDefinitions;
|
||||
|
||||
SlotDefinitionLoader() {
|
||||
this.buildingMap = new HashMap<>();
|
||||
this.slotDefinitions = new HashMap<>();
|
||||
}
|
||||
|
||||
public SlotDefinition getSlotDefinition(String slotName) {
|
||||
return buildingMap.get(slotName);
|
||||
return slotDefinitions.get(slotName);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -51,7 +51,7 @@ public final class SlotDefinitionLoader extends DataLoader {
|
||||
try (SdbResultSet set = SdbLoader.load(new File("serverdata/abstract/slot_definitions.sdb"))) {
|
||||
while (set.next()) {
|
||||
SlotDefinition def = new SlotDefinition(set);
|
||||
buildingMap.put(def.getName(), def);
|
||||
slotDefinitions.put(def.getName(), def);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
|
||||
package com.projectswg.holocore.resources.support.data.server_info.loader;
|
||||
|
||||
import com.projectswg.common.data.location.Terrain;
|
||||
@@ -33,46 +34,55 @@ import com.projectswg.holocore.resources.support.data.server_info.SdbLoader.SdbR
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
|
||||
public final class BuildingLoader extends DataLoader {
|
||||
public class TerrainZoneInsertionLoader extends DataLoader {
|
||||
|
||||
private final Map<String, BuildingLoaderInfo> buildingMap;
|
||||
private final Map<String, ZoneInsertion> zoneInsertions;
|
||||
|
||||
BuildingLoader() {
|
||||
this.buildingMap = new HashMap<>();
|
||||
TerrainZoneInsertionLoader() {
|
||||
this.zoneInsertions = new HashMap<>();
|
||||
}
|
||||
|
||||
public BuildingLoaderInfo getBuilding(String buildingName) {
|
||||
return buildingMap.get(buildingName);
|
||||
public ZoneInsertion getInsertion(String id) {
|
||||
return zoneInsertions.get(id);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void load() throws IOException {
|
||||
try (SdbResultSet set = SdbLoader.load(new File("serverdata/building/buildings.sdb"))) {
|
||||
try (SdbResultSet set = SdbLoader.load(new File("serverdata/player/player_spawns.sdb"))) {
|
||||
while (set.next()) {
|
||||
buildingMap.put(set.getText(0), new BuildingLoaderInfo(set));
|
||||
ZoneInsertion def = new ZoneInsertion(set);
|
||||
zoneInsertions.put(def.getId(), def);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static class BuildingLoaderInfo {
|
||||
public static class ZoneInsertion {
|
||||
|
||||
private final String name;
|
||||
private final long id;
|
||||
private final String id;
|
||||
private final Terrain terrain;
|
||||
private final String buildingId;
|
||||
private final String cell;
|
||||
private final double x;
|
||||
private final double y;
|
||||
private final double z;
|
||||
private final double radius;
|
||||
|
||||
public BuildingLoaderInfo(SdbResultSet set) {
|
||||
this.name = set.getText(0).intern();
|
||||
this.id = set.getInt(2);
|
||||
this.terrain = Terrain.valueOf(set.getText(1));
|
||||
private ZoneInsertion(SdbResultSet set) {
|
||||
// id terrain building_id cell x y z radius
|
||||
this.id = set.getText("id");
|
||||
this.terrain = Terrain.valueOf(set.getText("terrain").toUpperCase(Locale.US));
|
||||
this.buildingId = set.getText("building_id");
|
||||
this.cell = set.getText("cell");
|
||||
this.x = set.getReal("x");
|
||||
this.y = set.getReal("y");
|
||||
this.z = set.getReal("z");
|
||||
this.radius = set.getReal("radius");
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public long getId() {
|
||||
public String getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@@ -80,6 +90,40 @@ public final class BuildingLoader extends DataLoader {
|
||||
return terrain;
|
||||
}
|
||||
|
||||
public String getBuildingId() {
|
||||
return buildingId;
|
||||
}
|
||||
|
||||
public String getCell() {
|
||||
return cell;
|
||||
}
|
||||
|
||||
public double getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public double getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public double getZ() {
|
||||
return z;
|
||||
}
|
||||
|
||||
public double getRadius() {
|
||||
return radius;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode() {
|
||||
return id.hashCode();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
return o instanceof ZoneInsertion && ((ZoneInsertion) o).id.equals(id);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -28,15 +28,13 @@ package com.projectswg.holocore.resources.support.global.commands.callbacks.admi
|
||||
|
||||
import com.projectswg.common.data.location.Location;
|
||||
import com.projectswg.holocore.intents.support.global.chat.SystemMessageIntent;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.BuildingLoader.BuildingLoaderInfo;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.DataLoader;
|
||||
import com.projectswg.holocore.resources.support.global.commands.ICmdCallback;
|
||||
import com.projectswg.holocore.resources.support.global.player.Player;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.SWGObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.building.BuildingObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.cell.CellObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.cell.Portal;
|
||||
import com.projectswg.holocore.services.support.objects.ObjectStorageService.ObjectLookup;
|
||||
import com.projectswg.holocore.services.support.objects.ObjectStorageService.BuildingLookup;
|
||||
import me.joshlarson.jlcommon.log.Log;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -52,7 +50,7 @@ public class CmdGoto implements ICmdCallback {
|
||||
String [] parts = args.split(" ");
|
||||
if (parts.length == 0 || parts[0].trim().isEmpty())
|
||||
return;
|
||||
BuildingLoaderInfo building = DataLoader.buildings().getBuilding(parts[0].trim());
|
||||
BuildingObject building = BuildingLookup.getBuildingByTag(parts[0].trim());
|
||||
if (building == null) {
|
||||
SystemMessageIntent.broadcastPersonal(player, "Unknown building: " + parts[0]);
|
||||
return;
|
||||
@@ -69,16 +67,10 @@ public class CmdGoto implements ICmdCallback {
|
||||
new SystemMessageIntent(player, err).broadcast();
|
||||
}
|
||||
|
||||
private String teleportToGoto(SWGObject obj, BuildingLoaderInfo building, int cellNumber) {
|
||||
SWGObject parent = ObjectLookup.getObjectById(building.getId());
|
||||
if (!(parent instanceof BuildingObject)) {
|
||||
String err = String.format("Invalid parent! Either null or not a building: %s BUID: %d", parent, building.getId());
|
||||
Log.e(err);
|
||||
return err;
|
||||
}
|
||||
CellObject cell = ((BuildingObject) parent).getCellByNumber(cellNumber);
|
||||
private String teleportToGoto(SWGObject obj, BuildingObject building, int cellNumber) {
|
||||
CellObject cell = building.getCellByNumber(cellNumber);
|
||||
if (cell == null) {
|
||||
String err = String.format("Building '%s' does not have cell %d", building.getName(), cellNumber);
|
||||
String err = String.format("Building '%s' does not have cell %d", building, cellNumber);
|
||||
Log.e(err);
|
||||
return err;
|
||||
}
|
||||
@@ -91,7 +83,7 @@ public class CmdGoto implements ICmdCallback {
|
||||
z = (portal.getFrame1().getZ() + portal.getFrame2().getZ()) / 2;
|
||||
}
|
||||
obj.moveToContainer(cell, Location.builder().setPosition(x, y, z).setTerrain(building.getTerrain()).build());
|
||||
return "Successfully teleported "+obj.getObjectName()+" to "+building.getId();
|
||||
return "Successfully teleported "+obj.getObjectName()+" to "+building.getBuildoutTag();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2018 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore 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 Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
package com.projectswg.holocore.resources.support.global.zone;
|
||||
|
||||
import com.projectswg.common.data.info.RelationalServerData;
|
||||
import com.projectswg.common.data.info.RelationalServerFactory;
|
||||
import com.projectswg.common.data.location.Location;
|
||||
import com.projectswg.common.data.location.Location.LocationBuilder;
|
||||
import com.projectswg.common.data.location.Terrain;
|
||||
import com.projectswg.holocore.ProjectSWG;
|
||||
import me.joshlarson.jlcommon.log.Log;
|
||||
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
|
||||
public class TerrainZoneInsertion {
|
||||
|
||||
private final RelationalServerData insertions;
|
||||
|
||||
public TerrainZoneInsertion() {
|
||||
insertions = RelationalServerFactory.getServerData("player/player_spawns.db", "building/buildings", "player_spawns");
|
||||
if (insertions == null)
|
||||
throw new ProjectSWG.CoreException("Failed to load SDBs for TerrainZoneInsertion");
|
||||
}
|
||||
|
||||
public SpawnInformation generateSpawnLocation(String id) {
|
||||
final String whereClause = "(player_spawns.id = ?) AND (player_spawns.building_id = '' OR buildings.building_id = player_spawns.building_id)";
|
||||
try (ResultSet set = insertions.selectFromTable("player_spawns, buildings", new String[]{"player_spawns.*", "buildings.object_id"}, whereClause, id)) {
|
||||
if (!set.next())
|
||||
return null;
|
||||
String building = set.getString("building_id");
|
||||
Location l = generateRandomLocation(Terrain.getTerrainFromName(set.getString("terrain")), set.getDouble("x"), set.getDouble("y"), set.getDouble("z"), set.getDouble("radius"));
|
||||
return new SpawnInformation(!building.isEmpty(), l, set.getLong("object_id"), set.getString("cell"));
|
||||
} catch (SQLException e) {
|
||||
Log.e(e);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private static Location generateRandomLocation(Terrain terrain, double x, double y, double z, double delta) {
|
||||
LocationBuilder location = Location.builder();
|
||||
location.setTerrain(terrain);
|
||||
location.setX(x + (Math.random()-.5) * delta);
|
||||
location.setY(y);
|
||||
location.setZ(z + (Math.random()-.5) * delta);
|
||||
location.setOrientationX(0);
|
||||
location.setOrientationY(0);
|
||||
location.setOrientationZ(0);
|
||||
location.setOrientationW(1);
|
||||
return location.build();
|
||||
}
|
||||
|
||||
public static class SpawnInformation {
|
||||
public final boolean building;
|
||||
public final Location location;
|
||||
public final long buildingId;
|
||||
public final String cell;
|
||||
|
||||
public SpawnInformation(boolean building, Location location, long buildingId, String cell) {
|
||||
this.building = building;
|
||||
this.location = location;
|
||||
this.buildingId = buildingId;
|
||||
this.cell = cell;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -29,13 +29,14 @@ package com.projectswg.holocore.resources.support.global.zone.creation;
|
||||
import com.projectswg.common.data.customization.CustomizationString;
|
||||
import com.projectswg.common.data.encodables.tangible.PvpFlag;
|
||||
import com.projectswg.common.data.encodables.tangible.Race;
|
||||
import com.projectswg.common.data.location.Location;
|
||||
import com.projectswg.common.data.swgfile.ClientFactory;
|
||||
import com.projectswg.common.data.swgfile.visitors.ProfTemplateData;
|
||||
import com.projectswg.common.network.packets.swg.login.creation.ClientCreateCharacter;
|
||||
import com.projectswg.holocore.intents.gameplay.player.experience.skills.GrantSkillIntent;
|
||||
import com.projectswg.holocore.intents.support.objects.swg.ObjectCreatedIntent;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.TerrainZoneInsertionLoader.ZoneInsertion;
|
||||
import com.projectswg.holocore.resources.support.global.player.AccessLevel;
|
||||
import com.projectswg.holocore.resources.support.global.zone.TerrainZoneInsertion.SpawnInformation;
|
||||
import com.projectswg.holocore.resources.support.objects.ObjectCreator;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.SWGObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.building.BuildingObject;
|
||||
@@ -45,7 +46,7 @@ import com.projectswg.holocore.resources.support.objects.swg.player.PlayerObject
|
||||
import com.projectswg.holocore.resources.support.objects.swg.tangible.TangibleObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.weapon.WeaponObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.weapon.WeaponType;
|
||||
import com.projectswg.holocore.services.support.objects.ObjectStorageService.ObjectLookup;
|
||||
import com.projectswg.holocore.services.support.objects.ObjectStorageService.BuildingLookup;
|
||||
import me.joshlarson.jlcommon.utilities.Arguments;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -61,7 +62,7 @@ public class CharacterCreation {
|
||||
this.create = create;
|
||||
}
|
||||
|
||||
public CreatureObject createCharacter(AccessLevel accessLevel, SpawnInformation info) {
|
||||
public CreatureObject createCharacter(AccessLevel accessLevel, ZoneInsertion info) {
|
||||
Race race = Race.getRaceByFile(create.getRace());
|
||||
CreatureObject creatureObj = createCreature(race.getFilename(), info);
|
||||
PlayerObject playerObj = createPlayer(creatureObj);
|
||||
@@ -76,26 +77,26 @@ public class CharacterCreation {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CreatureObject createCreature(String template, SpawnInformation info) {
|
||||
if (info.building)
|
||||
private CreatureObject createCreature(String template, ZoneInsertion info) {
|
||||
if (!info.getBuildingId().isEmpty())
|
||||
return createCreatureBuilding(template, info);
|
||||
SWGObject obj = ObjectCreator.createObjectFromTemplate(template);
|
||||
assert obj instanceof CreatureObject;
|
||||
obj.setLocation(info.location);
|
||||
obj.setLocation(generateRandomLocation(info));
|
||||
return (CreatureObject) obj;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private CreatureObject createCreatureBuilding(String template, SpawnInformation info) {
|
||||
SWGObject parent = ObjectLookup.getObjectById(info.buildingId);
|
||||
Arguments.validate(parent instanceof BuildingObject, String.format("Invalid parent! Either null or not a building: %s BUID: %d", parent, info.buildingId));
|
||||
private CreatureObject createCreatureBuilding(String template, ZoneInsertion info) {
|
||||
BuildingObject building = BuildingLookup.getBuildingByTag(info.getBuildingId());
|
||||
Arguments.validate(building != null, String.format("Invalid building: %s", info.getBuildingId()));
|
||||
|
||||
CellObject cell = ((BuildingObject) parent).getCellByName(info.cell);
|
||||
Arguments.validate(cell != null, String.format("Invalid cell! Cell does not exist: %s B-Template: %s BUID: %d", info.cell, parent.getTemplate(), info.buildingId));
|
||||
CellObject cell = building.getCellByName(info.getCell());
|
||||
Arguments.validate(cell != null, String.format("Invalid cell! Cell does not exist: %s Building: %s", info.getCell(), building));
|
||||
|
||||
SWGObject obj = ObjectCreator.createObjectFromTemplate(template);
|
||||
assert obj instanceof CreatureObject;
|
||||
obj.moveToContainer(cell, info.location);
|
||||
obj.moveToContainer(cell, generateRandomLocation(info));
|
||||
return (CreatureObject) obj;
|
||||
}
|
||||
|
||||
@@ -178,4 +179,17 @@ public class CharacterCreation {
|
||||
createDefaultObject(inventory, "object/tangible/npe/shared_npe_uniform_box.iff");
|
||||
}
|
||||
|
||||
private static Location generateRandomLocation(ZoneInsertion info) {
|
||||
return Location.builder()
|
||||
.setTerrain(info.getTerrain())
|
||||
.setX(info.getX() + (Math.random()-.5) * info.getRadius())
|
||||
.setY(info.getY())
|
||||
.setZ(info.getZ() + (Math.random()-.5) * info.getRadius())
|
||||
.setOrientationX(0)
|
||||
.setOrientationY(0)
|
||||
.setOrientationZ(0)
|
||||
.setOrientationW(1)
|
||||
.build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -28,7 +28,6 @@ package com.projectswg.holocore.resources.support.npc.spawn;
|
||||
|
||||
import com.projectswg.common.data.encodables.tangible.PvpFaction;
|
||||
import com.projectswg.common.data.location.Location;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.BuildingLoader.BuildingLoaderInfo;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.DataLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.NpcLoader.*;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.NpcPatrolRouteLoader.PatrolRouteWaypoint;
|
||||
@@ -41,7 +40,7 @@ import com.projectswg.holocore.resources.support.objects.swg.SWGObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.building.BuildingObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.creature.CreatureDifficulty;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.custom.AIBehavior;
|
||||
import com.projectswg.holocore.services.support.objects.ObjectStorageService.ObjectLookup;
|
||||
import com.projectswg.holocore.services.support.objects.ObjectStorageService.BuildingLookup;
|
||||
import me.joshlarson.jlcommon.log.Log;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -69,10 +68,8 @@ public final class Spawner {
|
||||
this.npcStat = DataLoader.npcStats().getNpcStats(npc.getCombatLevel());
|
||||
Objects.requireNonNull(npcStat, "Invalid npc combat lebel: " + npc.getCombatLevel());
|
||||
|
||||
BuildingLoaderInfo building = DataLoader.buildings().getBuilding(spawn.getBuildingId());
|
||||
Objects.requireNonNull(building, "Invalid building id: " + spawn.getBuildingId());
|
||||
this.location = Location.builder()
|
||||
.setTerrain(building.getTerrain())
|
||||
.setTerrain(spawn.getTerrain())
|
||||
.setPosition(spawn.getX(), spawn.getY(), spawn.getZ())
|
||||
.setHeading(spawn.getHeading())
|
||||
.build();
|
||||
@@ -383,29 +380,18 @@ public final class Spawner {
|
||||
}
|
||||
|
||||
private static SWGObject getPatrolWaypointParent(PatrolRouteWaypoint waypoint) {
|
||||
if (waypoint.getBuildingId().isEmpty()) {
|
||||
Log.w("PatrolRouteWaypoint: Undefined building id for patrol id: %d and group id: %d", waypoint.getPatrolId(), waypoint.getGroupId());
|
||||
if (waypoint.getBuildingId().isEmpty() || waypoint.getBuildingId().endsWith("_world"))
|
||||
return null;
|
||||
}
|
||||
|
||||
BuildingLoaderInfo buildingInfo = DataLoader.buildings().getBuilding(waypoint.getBuildingId());
|
||||
if (buildingInfo == null) {
|
||||
BuildingObject building = BuildingLookup.getBuildingByTag(waypoint.getBuildingId());
|
||||
if (building == null) {
|
||||
Log.w("PatrolRouteWaypoint: Invalid building id for patrol id: %d and group id: %d", waypoint.getPatrolId(), waypoint.getGroupId());
|
||||
return null;
|
||||
}
|
||||
|
||||
if (buildingInfo.getId() == 0)
|
||||
return null;
|
||||
|
||||
SWGObject building = ObjectLookup.getObjectById(buildingInfo.getId());
|
||||
if (!(building instanceof BuildingObject)) {
|
||||
Log.w("PatrolRouteWaypoint: Invalid building [%d] for patrol id: %d and group id: %d", buildingInfo.getId(), waypoint.getPatrolId(), waypoint.getGroupId());
|
||||
return null;
|
||||
}
|
||||
|
||||
SWGObject cell = ((BuildingObject) building).getCellByNumber(waypoint.getCellId());
|
||||
SWGObject cell = building.getCellByNumber(waypoint.getCellId());
|
||||
if (cell == null) {
|
||||
Log.w("PatrolRouteWaypoint: Invalid cell [%d] for building: %d, patrol id: %d and group id: %d", waypoint.getCellId(), buildingInfo.getId(), waypoint.getPatrolId(), waypoint.getGroupId());
|
||||
Log.w("PatrolRouteWaypoint: Invalid cell [%d] for building: %s, patrol id: %d and group id: %d", waypoint.getCellId(), waypoint.getBuildingId(), waypoint.getPatrolId(), waypoint.getGroupId());
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -61,7 +61,7 @@ import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public final class ObjectCreator {
|
||||
|
||||
private static final AtomicLong OBJECT_ID = new AtomicLong(0);
|
||||
private static final AtomicLong OBJECT_ID = new AtomicLong(150000);
|
||||
|
||||
/*
|
||||
Misc helper methods
|
||||
|
||||
@@ -101,6 +101,8 @@ public abstract class SWGObject extends BaselineObject implements Comparable<SWG
|
||||
private float complexity = 1;
|
||||
private int containerType = 0;
|
||||
private int areaId = -1;
|
||||
private String buildoutEvent = "";
|
||||
private String buildoutTag = "";
|
||||
private int slotArrangement = -1;
|
||||
private boolean observeWithParent = true;
|
||||
private boolean generated = true;
|
||||
@@ -556,6 +558,14 @@ public abstract class SWGObject extends BaselineObject implements Comparable<SWG
|
||||
this.areaId = areaId;
|
||||
}
|
||||
|
||||
public void setBuildoutEvent(String event) {
|
||||
this.buildoutEvent = event;
|
||||
}
|
||||
|
||||
public void setBuildoutTag(String tag) {
|
||||
this.buildoutTag = tag;
|
||||
}
|
||||
|
||||
public void setArrangement(List<List<String>> arrangement) {
|
||||
this.arrangement = arrangement;
|
||||
}
|
||||
@@ -681,6 +691,14 @@ public abstract class SWGObject extends BaselineObject implements Comparable<SWG
|
||||
return areaId;
|
||||
}
|
||||
|
||||
public String getBuildoutEvent() {
|
||||
return buildoutEvent;
|
||||
}
|
||||
|
||||
public String getBuildoutTag() {
|
||||
return buildoutTag;
|
||||
}
|
||||
|
||||
public Object getServerAttribute(ServerAttribute key) {
|
||||
return serverAttributes.get(key);
|
||||
}
|
||||
|
||||
@@ -357,9 +357,9 @@ public class CreatureObject extends TangibleObject {
|
||||
|
||||
public void setPosture(Posture posture) {
|
||||
this.posture = posture;
|
||||
sendDelta(3, 13, posture.getId());
|
||||
if (isPlayer())
|
||||
sendObservers(new PostureUpdate(getObjectId(), posture));
|
||||
sendDelta(3, 13, posture.getId());
|
||||
}
|
||||
|
||||
public void setRace(Race race) {
|
||||
|
||||
@@ -89,11 +89,11 @@ public class AIObject extends CreatureObject {
|
||||
return;
|
||||
}
|
||||
CreatureObject player = (CreatureObject) aware;
|
||||
if (!player.isLoggedInPlayer() || player.getPosture() == Posture.INCAPACITATED || player.getPosture() == Posture.DEAD)
|
||||
if (!player.isLoggedInPlayer())
|
||||
return;
|
||||
double distance = getLocation().flatDistanceTo(aware.getLocation());
|
||||
NpcMode activeMode = this.activeMode;
|
||||
if (distance <= 100) {
|
||||
if (distance <= 100 && player.getPosture() != Posture.INCAPACITATED && player.getPosture() != Posture.DEAD) {
|
||||
if (playersNearby.add(player)) {
|
||||
if (activeMode != null)
|
||||
activeMode.onPlayerEnterAware(player, distance);
|
||||
|
||||
@@ -110,8 +110,8 @@ public class CombatDeathblowService extends Service {
|
||||
}
|
||||
|
||||
private void incapacitatePlayer(CreatureObject incapacitator, CreatureObject incapacitated) {
|
||||
incapacitated.setPosture(Posture.INCAPACITATED);
|
||||
incapacitated.setCounter(INCAP_TIMER);
|
||||
incapacitated.setPosture(Posture.INCAPACITATED);
|
||||
|
||||
StandardLog.onPlayerEvent(this, incapacitated, "was incapacitated by %s", incapacitator);
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ import com.projectswg.holocore.intents.gameplay.combat.CreatureRevivedIntent;
|
||||
import com.projectswg.holocore.intents.gameplay.combat.EnterCombatIntent;
|
||||
import com.projectswg.holocore.intents.gameplay.combat.ExitCombatIntent;
|
||||
import com.projectswg.holocore.intents.support.global.command.ExecuteCommandIntent;
|
||||
import com.projectswg.holocore.intents.support.global.zone.PlayerEventIntent;
|
||||
import com.projectswg.holocore.resources.support.global.commands.CombatCommand;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.creature.CreatureObject;
|
||||
import me.joshlarson.jlcommon.concurrency.ScheduledThreadPool;
|
||||
@@ -35,8 +36,22 @@ public class CombatRegenerationService extends Service {
|
||||
@Override
|
||||
public boolean stop() {
|
||||
executor.stop();
|
||||
executor.awaitTermination(1000);
|
||||
return true;
|
||||
return executor.awaitTermination(1000);
|
||||
}
|
||||
|
||||
@IntentHandler
|
||||
private void handlePlayerEventIntent(PlayerEventIntent pei) {
|
||||
CreatureObject creature = pei.getPlayer().getCreatureObject();
|
||||
switch (pei.getEvent()) {
|
||||
case PE_ZONE_IN_SERVER:
|
||||
if (!creature.isInCombat()) {
|
||||
startHealthRegeneration(creature);
|
||||
startActionRegeneration(creature);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@IntentHandler
|
||||
|
||||
@@ -36,6 +36,7 @@ import com.projectswg.holocore.intents.support.global.zone.PlayerEventIntent;
|
||||
import com.projectswg.holocore.resources.gameplay.combat.buff.BuffData;
|
||||
import com.projectswg.holocore.resources.gameplay.combat.buff.BuffMap;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.StandardLog;
|
||||
import com.projectswg.holocore.resources.support.global.player.Player;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.creature.Buff;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.creature.CreatureObject;
|
||||
import me.joshlarson.jlcommon.concurrency.BasicScheduledThread;
|
||||
@@ -286,7 +287,11 @@ public class BuffService extends Service {
|
||||
// TODO stack counts upon add/remove need to be defined on a per-buff basis due to skillmod influence. Scripts might not be a bad idea.
|
||||
int stackCount = 1;
|
||||
int buffDuration = (int) buffData.getDefaultDuration();
|
||||
Log.d("buff %s applied to %s from %s; applyTime: %d, buffDuration: %d", buffData.getName(), receiver.getObjectName(), buffer.getObjectName(), applyTime, buffDuration);
|
||||
{
|
||||
Player bufferPlayer = buffer.getOwner();
|
||||
String bufferUsername = bufferPlayer == null ? "NULL" : bufferPlayer.getUsername();
|
||||
StandardLog.onPlayerTrace(this, receiver, "received buff '%s' from %s/%s; applyTime: %d, buffDuration: %d", buffData.getName(), bufferUsername, buffer.getObjectName(), applyTime, buffDuration);
|
||||
}
|
||||
Buff buff = new Buff(buffData.getCrc(), applyTime + buffDuration, buffData.getEffectValue(0), buffDuration, buffer.getObjectId(), stackCount);
|
||||
|
||||
checkSkillMods(buffData, receiver, 1);
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.projectswg.holocore.intents.support.global.zone.PlayerEventIntent;
|
||||
import com.projectswg.holocore.intents.support.objects.swg.DestroyObjectIntent;
|
||||
import com.projectswg.holocore.intents.support.objects.swg.ObjectCreatedIntent;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.StandardLog;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.DataLoader;
|
||||
import com.projectswg.holocore.resources.support.global.player.Player;
|
||||
import com.projectswg.holocore.resources.support.global.zone.sui.SuiButtons;
|
||||
import com.projectswg.holocore.resources.support.global.zone.sui.SuiListBox;
|
||||
@@ -29,7 +28,7 @@ import com.projectswg.holocore.resources.support.objects.swg.SWGObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.building.BuildingObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.cell.CellObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.creature.CreatureObject;
|
||||
import com.projectswg.holocore.services.support.objects.ObjectStorageService.ObjectLookup;
|
||||
import com.projectswg.holocore.services.support.objects.ObjectStorageService.BuildingLookup;
|
||||
import me.joshlarson.jlcommon.concurrency.ScheduledThreadPool;
|
||||
import me.joshlarson.jlcommon.control.IntentHandler;
|
||||
import me.joshlarson.jlcommon.control.Service;
|
||||
@@ -391,8 +390,7 @@ public class CloningService extends Service {
|
||||
}
|
||||
|
||||
private static BuildingObject getDefaultCloner() {
|
||||
long clonerId = DataLoader.buildings().getBuilding("tat_moseisley_cloning1").getId();
|
||||
BuildingObject defaultCloner = (clonerId == 0) ? null : (BuildingObject) ObjectLookup.getObjectById(clonerId);
|
||||
BuildingObject defaultCloner = BuildingLookup.getBuildingByTag("tat_moseisley_cloning1");
|
||||
if (defaultCloner == null)
|
||||
Log.e("No default cloner found with building id: 'tat_moseisley_cloning1'");
|
||||
|
||||
|
||||
@@ -39,13 +39,13 @@ import com.projectswg.holocore.intents.support.objects.swg.DestroyObjectIntent;
|
||||
import com.projectswg.holocore.resources.support.data.config.ConfigFile;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.DataManager;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.StandardLog;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.DataLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.TerrainZoneInsertionLoader.ZoneInsertion;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.mongodb.users.PswgUserDatabase;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.mongodb.users.PswgUserDatabase.CharacterMetadata;
|
||||
import com.projectswg.holocore.resources.support.global.player.AccessLevel;
|
||||
import com.projectswg.holocore.resources.support.global.player.Player;
|
||||
import com.projectswg.holocore.resources.support.global.player.PlayerState;
|
||||
import com.projectswg.holocore.resources.support.global.zone.TerrainZoneInsertion;
|
||||
import com.projectswg.holocore.resources.support.global.zone.TerrainZoneInsertion.SpawnInformation;
|
||||
import com.projectswg.holocore.resources.support.global.zone.creation.CharacterCreation;
|
||||
import com.projectswg.holocore.resources.support.global.zone.creation.CharacterCreationRestriction;
|
||||
import com.projectswg.holocore.resources.support.global.zone.name_filter.NameFilter;
|
||||
@@ -69,7 +69,6 @@ public class CharacterCreationService extends Service {
|
||||
private final NameFilter nameFilter;
|
||||
private final SWGNameGenerator nameGenerator;
|
||||
private final CharacterCreationRestriction creationRestriction;
|
||||
private final TerrainZoneInsertion insertion;
|
||||
private final PswgUserDatabase userDatabase;
|
||||
|
||||
public CharacterCreationService() {
|
||||
@@ -79,7 +78,6 @@ public class CharacterCreationService extends Service {
|
||||
this.nameFilter = new NameFilter(getClass().getResourceAsStream("/namegen/bad_word_list.txt"), getClass().getResourceAsStream("/namegen/reserved_words.txt"), getClass().getResourceAsStream("/namegen/fiction_reserved.txt"));
|
||||
this.nameGenerator = new SWGNameGenerator(nameFilter);
|
||||
this.creationRestriction = new CharacterCreationRestriction(2);
|
||||
this.insertion = new TerrainZoneInsertion();
|
||||
this.userDatabase = new PswgUserDatabase();
|
||||
}
|
||||
|
||||
@@ -270,7 +268,7 @@ public class CharacterCreationService extends Service {
|
||||
|
||||
private CreatureObject createCharacter(Player player, ClientCreateCharacter create) {
|
||||
String spawnLocation = DataManager.getConfig(ConfigFile.PRIMARY).getString("PRIMARY-SPAWN-LOCATION", "tat_moseisley");
|
||||
SpawnInformation info = insertion.generateSpawnLocation(spawnLocation);
|
||||
ZoneInsertion info = DataLoader.zoneInsertions().getInsertion(spawnLocation);
|
||||
if (info == null) {
|
||||
Log.e("Failed to get spawn information for location: " + spawnLocation);
|
||||
return null;
|
||||
|
||||
@@ -32,7 +32,6 @@ import com.projectswg.holocore.intents.support.objects.swg.ObjectCreatedIntent;
|
||||
import com.projectswg.holocore.resources.support.data.config.ConfigFile;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.DataManager;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.StandardLog;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.BuildingLoader.BuildingLoaderInfo;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.DataLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.NpcPatrolRouteLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.NpcPatrolRouteLoader.PatrolRouteWaypoint;
|
||||
@@ -45,7 +44,7 @@ import com.projectswg.holocore.resources.support.objects.permissions.AdminPermis
|
||||
import com.projectswg.holocore.resources.support.objects.swg.SWGObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.building.BuildingObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.custom.AIObject;
|
||||
import com.projectswg.holocore.services.support.objects.ObjectStorageService.ObjectLookup;
|
||||
import com.projectswg.holocore.services.support.objects.ObjectStorageService.BuildingLookup;
|
||||
import me.joshlarson.jlcommon.concurrency.ScheduledThreadPool;
|
||||
import me.joshlarson.jlcommon.control.IntentHandler;
|
||||
import me.joshlarson.jlcommon.control.Service;
|
||||
@@ -118,33 +117,25 @@ public final class SpawnerService extends Service {
|
||||
|
||||
private static SWGObject createEgg(StaticSpawnInfo spawn) {
|
||||
SpawnerType spawnerType = SpawnerType.valueOf(spawn.getSpawnerType());
|
||||
BuildingLoaderInfo building = DataLoader.buildings().getBuilding(spawn.getBuildingId());
|
||||
SWGObject egg = ObjectCreator.createObjectFromTemplate(spawnerType.getObjectTemplate());
|
||||
egg.setContainerPermissions(AdminPermissions.getPermissions());
|
||||
egg.systemMove(getCell(spawn.getId(), spawn.getCellId(), building), Location.builder().setTerrain(building.getTerrain()).setPosition(spawn.getX(), spawn.getY(), spawn.getZ()).setHeading(spawn.getHeading()).build());
|
||||
egg.systemMove(getCell(spawn.getId(), spawn.getCellId(), spawn.getBuildingId()), Location.builder().setTerrain(spawn.getTerrain()).setPosition(spawn.getX(), spawn.getY(), spawn.getZ()).setHeading(spawn.getHeading()).build());
|
||||
ObjectCreatedIntent.broadcast(egg);
|
||||
return egg;
|
||||
}
|
||||
|
||||
private static SWGObject getCell(int spawnId, int cellId, BuildingLoaderInfo buildingInfo) {
|
||||
if (buildingInfo.getId() != 0 && cellId == 0) {
|
||||
Log.e("No cell ID specified for spawner with ID %d", spawnId);
|
||||
private static SWGObject getCell(int spawnId, int cellId, String buildingTag) {
|
||||
if (buildingTag.isEmpty() || buildingTag.endsWith("_world"))
|
||||
return null;
|
||||
} else if (buildingInfo.getId() == 0) {
|
||||
if (cellId != 0)
|
||||
Log.w("Unnecessary cell ID specified for spawner with ID %d", spawnId);
|
||||
return null; // No cell to find
|
||||
}
|
||||
|
||||
SWGObject building = ObjectLookup.getObjectById(buildingInfo.getId());
|
||||
if (!(building instanceof BuildingObject)) {
|
||||
Log.w("Skipping spawner with ID %d - building_id %d didn't reference a BuildingObject!", spawnId, buildingInfo.getId());
|
||||
BuildingObject building = BuildingLookup.getBuildingByTag(buildingTag);
|
||||
if (building == null) {
|
||||
Log.w("Skipping spawner with ID %d - building_id %s didn't reference a BuildingObject!", spawnId, buildingTag);
|
||||
return null;
|
||||
}
|
||||
|
||||
SWGObject cellObject = ((BuildingObject) building).getCellByNumber(cellId);
|
||||
SWGObject cellObject = building.getCellByNumber(cellId);
|
||||
if (cellObject == null) {
|
||||
Log.e("Spawner with ID %d - building %d didn't have cell ID %d!", spawnId, buildingInfo.getId(), cellId);
|
||||
Log.e("Spawner with ID %d - building %s didn't have cell ID %d!", spawnId, buildingTag, cellId);
|
||||
}
|
||||
return cellObject;
|
||||
}
|
||||
@@ -170,261 +161,22 @@ public final class SpawnerService extends Service {
|
||||
}
|
||||
|
||||
private static SWGObject getPatrolWaypointParent(PatrolRouteWaypoint waypoint) {
|
||||
if (waypoint.getBuildingId().isEmpty()) {
|
||||
Log.w("PatrolRouteWaypoint: Undefined building id for patrol id: %d and group id: %d", waypoint.getPatrolId(), waypoint.getGroupId());
|
||||
if (waypoint.getBuildingId().isEmpty() || waypoint.getBuildingId().endsWith("_world"))
|
||||
return null;
|
||||
|
||||
BuildingObject building = BuildingLookup.getBuildingByTag(waypoint.getBuildingId());
|
||||
if (building == null) {
|
||||
Log.w("PatrolRouteWaypoint: Invalid building [%s] for patrol id: %d and group id: %d", waypoint.getBuildingId(), waypoint.getPatrolId(), waypoint.getGroupId());
|
||||
return null;
|
||||
}
|
||||
|
||||
BuildingLoaderInfo buildingInfo = DataLoader.buildings().getBuilding(waypoint.getBuildingId());
|
||||
if (buildingInfo == null) {
|
||||
Log.w("PatrolRouteWaypoint: Invalid building id for patrol id: %d and group id: %d", waypoint.getPatrolId(), waypoint.getGroupId());
|
||||
return null;
|
||||
}
|
||||
|
||||
if (buildingInfo.getId() == 0)
|
||||
return null;
|
||||
|
||||
SWGObject building = ObjectLookup.getObjectById(buildingInfo.getId());
|
||||
if (!(building instanceof BuildingObject)) {
|
||||
Log.w("PatrolRouteWaypoint: Invalid building [%d] for patrol id: %d and group id: %d", buildingInfo.getId(), waypoint.getPatrolId(), waypoint.getGroupId());
|
||||
return null;
|
||||
}
|
||||
|
||||
SWGObject cell = ((BuildingObject) building).getCellByNumber(waypoint.getCellId());
|
||||
SWGObject cell = building.getCellByNumber(waypoint.getCellId());
|
||||
if (cell == null) {
|
||||
Log.w("PatrolRouteWaypoint: Invalid cell [%d] for building: %d, patrol id: %d and group id: %d", waypoint.getCellId(), buildingInfo.getId(), waypoint.getPatrolId(), waypoint.getGroupId());
|
||||
Log.w("PatrolRouteWaypoint: Invalid cell [%d] for building: %s, patrol id: %d and group id: %d", waypoint.getCellId(), waypoint.getBuildingId(), waypoint.getPatrolId(), waypoint.getGroupId());
|
||||
return null;
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
//
|
||||
// private static class SpawnLoader {
|
||||
//
|
||||
// private final Consumer<Spawner> npcSpawner;
|
||||
//
|
||||
// // Loaders
|
||||
// private BuildingLoader buildingLoader;
|
||||
// private NpcStatLoader npcStatLoader;
|
||||
// private NpcLoader npcLoader;
|
||||
// private NpcStaticSpawnLoader npcStaticSpawnLoader;
|
||||
// private NpcPatrolRouteLoader npcPatrolRouteLoader;
|
||||
//
|
||||
// // Spawn info
|
||||
// private BuildingLoaderInfo building;
|
||||
// private NpcInfo npc;
|
||||
// private NpcStatInfo npcStat;
|
||||
// private List<ResolvedPatrolWaypoint> waypoints;
|
||||
//
|
||||
// public SpawnLoader(Consumer<Spawner> npcSpawner) {
|
||||
// this.npcSpawner = npcSpawner;
|
||||
// this.buildingLoader = null;
|
||||
// this.npcStatLoader = null;
|
||||
// this.npcLoader = null;
|
||||
// this.npcStaticSpawnLoader = null;
|
||||
// this.npcPatrolRouteLoader = null;
|
||||
//
|
||||
// this.building = null;
|
||||
// this.npc = null;
|
||||
// this.npcStat = null;
|
||||
// this.waypoints = null;
|
||||
// }
|
||||
//
|
||||
// public void load() {
|
||||
// buildingLoader = DataLoader.buildings();
|
||||
// npcStatLoader = DataLoader.npcStats();
|
||||
// npcLoader = DataLoader.npcs();
|
||||
// npcStaticSpawnLoader = DataLoader.npcStaticSpawns();
|
||||
// npcPatrolRouteLoader = DataLoader.npcPatrolRoutes();
|
||||
//
|
||||
// npcStaticSpawnLoader.iterate(this::loadStaticSpawn);
|
||||
// }
|
||||
//
|
||||
// private void loadStaticSpawn(StaticSpawnInfo spawn) {
|
||||
// building = buildingLoader.getBuilding(spawn.getBuildingId());
|
||||
// if (building == null) {
|
||||
// Log.e("Invalid entry for spawn id [%d] - unknown building: '%s'", spawn.getId(), spawn.getBuildingId());
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// npc = npcLoader.getNpc(spawn.getNpcId());
|
||||
// if (npc == null) {
|
||||
// Log.w("Invalid entry for spawn id [%d] - unknown NPC: '%s'", spawn.getId(), spawn.getNpcId());
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// npcStat = npcStatLoader.getNpcStats(npc.getCombatLevel());
|
||||
// if (npcStat == null) {
|
||||
// Log.w("Invalid entry for spawn id [%d], NPC id [%d] - unknown NPC stat for level: %d", spawn.getId(), npc.getId(), npc.getCombatLevel());
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// if (spawn.getPatrolId() < 1000) {
|
||||
// waypoints = null;
|
||||
// } else {
|
||||
// waypoints = npcPatrolRouteLoader.getPatrolRoute(spawn.getPatrolId())
|
||||
// .stream()
|
||||
// .map(route -> new ResolvedPatrolWaypoint(getPatrolWaypointParent(route), getPatrolWaypointLocation(route), route.getDelay(), route.getPatrolType()))
|
||||
// .collect(Collectors.toList());
|
||||
// }
|
||||
//
|
||||
// loadSpawner(spawn);
|
||||
// }
|
||||
//
|
||||
// private void loadSpawner(StaticSpawnInfo spawn) {
|
||||
// Spawner spawner = new Spawner(spawn.getId());
|
||||
// spawner.setCreatureId(npc.getId());
|
||||
// spawner.setIffTemplates(createTemplateList(npc.getIff()));
|
||||
// spawner.setCreatureName(npc.getName());
|
||||
// spawner.setCombatLevel((short) npc.getCombatLevel());
|
||||
// spawner.setSpawnerFlag(npc.getSpawnerFlag());
|
||||
// spawner.setPatrolRoute(waypoints);
|
||||
// spawner.setFormation(spawn.getPatrolFormation());
|
||||
// spawner.setAttackSpeed(npc.getAttackSpeed());
|
||||
// spawner.setMovementSpeed(npc.getMovementSpeed());
|
||||
// setRespawnDelay(spawner, spawn);
|
||||
// setDifficulty(spawner);
|
||||
// setMoodAnimation(spawner, spawn);
|
||||
// setAiBehavior(spawner, spawn);
|
||||
// setLocation(spawner, spawn);
|
||||
// setFaction(spawner);
|
||||
// createEgg(spawner, spawn);
|
||||
//
|
||||
// for (int i = 0; i < spawn.getAmount(); i++) {
|
||||
// npcSpawner.accept(spawner);
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private void createEgg(Spawner spawner, StaticSpawnInfo spawn) {
|
||||
// SpawnerType spawnerType = SpawnerType.valueOf(spawn.getSpawnerType());
|
||||
// SWGObject egg = ObjectCreator.createObjectFromTemplate(spawnerType.getObjectTemplate());
|
||||
// egg.setContainerPermissions(ContainerPermissionsType.ADMIN);
|
||||
// egg.setLocation(spawner.getLocation());
|
||||
// egg.moveToContainer(getCell(spawner.getSpawnerId(), spawn.getCellId(), building));
|
||||
// spawner.setSpawnerObject(egg);
|
||||
// ObjectCreatedIntent.broadcast(egg);
|
||||
// }
|
||||
//
|
||||
// private void setRespawnDelay(Spawner spawner, StaticSpawnInfo spawn) {
|
||||
// int minRespawnDelay = spawn.getMinSpawnTime();
|
||||
// int maxRespawnDelay = spawn.getMaxSpawnTime();
|
||||
//
|
||||
// if (minRespawnDelay > maxRespawnDelay) {
|
||||
// Log.e("Spawner with ID %d has a minimum respawn time larger than the maximum respawn time", spawner.getSpawnerId());
|
||||
// maxRespawnDelay = minRespawnDelay;
|
||||
// }
|
||||
// spawner.setMinRespawnDelay(minRespawnDelay);
|
||||
// spawner.setMaxRespawnDelay(maxRespawnDelay);
|
||||
// }
|
||||
//
|
||||
// private void setDifficulty(Spawner spawner) {
|
||||
// char difficultyChar = npc.getDifficulty().charAt(0);
|
||||
//
|
||||
// CreatureDifficulty difficulty;
|
||||
// DetailNpcStatInfo detailInfo; // undefined to trigger warnings if not defined below
|
||||
// switch (difficultyChar) {
|
||||
// default:
|
||||
// Log.w("Unknown creature difficulty: %s", difficultyChar);
|
||||
// case 'N':
|
||||
// difficulty = CreatureDifficulty.NORMAL;
|
||||
// detailInfo = npcStat.getNormalDetailStat();
|
||||
// break;
|
||||
// case 'E':
|
||||
// difficulty = CreatureDifficulty.ELITE;
|
||||
// detailInfo = npcStat.getEliteDetailStat();
|
||||
// break;
|
||||
// case 'B':
|
||||
// difficulty = CreatureDifficulty.BOSS;
|
||||
// detailInfo = npcStat.getBossDetailStat();
|
||||
// break;
|
||||
// }
|
||||
// spawner.setMaxHealth(detailInfo.getHealth());
|
||||
// spawner.setMaxAction(detailInfo.getAction());
|
||||
// spawner.setCreatureDifficulty(difficulty);
|
||||
// }
|
||||
//
|
||||
// private void setLocation(Spawner spawner, StaticSpawnInfo spawn) {
|
||||
// Location loc = Location.builder()
|
||||
// .setTerrain(building.getTerrain())
|
||||
// .setPosition(spawn.getX(), spawn.getY(), spawn.getZ())
|
||||
// .setHeading(spawn.getHeading())
|
||||
// .build();
|
||||
// spawner.setLocation(loc);
|
||||
// }
|
||||
//
|
||||
// private void setFaction(Spawner spawner) {
|
||||
// PvpFaction faction;
|
||||
//
|
||||
// switch (npc.getFaction()) {
|
||||
// case "rebel": faction = PvpFaction.REBEL; break;
|
||||
// case "imperial": faction = PvpFaction.IMPERIAL; break;
|
||||
// default: return;
|
||||
// }
|
||||
//
|
||||
// spawner.setFaction(faction, npc.isSpecForce());
|
||||
// }
|
||||
//
|
||||
// private void setMoodAnimation(Spawner spawner, StaticSpawnInfo spawn) {
|
||||
// String moodAnimation = spawn.getMood();
|
||||
//
|
||||
// if (moodAnimation.equals(IDLE_MOOD))
|
||||
// moodAnimation = "neutral";
|
||||
//
|
||||
// spawner.setMoodAnimation(moodAnimation);
|
||||
// }
|
||||
//
|
||||
// private void setAiBehavior(Spawner spawner, StaticSpawnInfo spawn) {
|
||||
// AIBehavior aiBehavior = AIBehavior.valueOf(spawn.getBehavior());
|
||||
// spawner.setAIBehavior(aiBehavior);
|
||||
// if (aiBehavior == AIBehavior.LOITER) {
|
||||
// spawner.setFloatRadius(spawn.getLoiterRadius());
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// private SWGObject getCell(int spawnId, int cellId, BuildingLoaderInfo buildingInfo) {
|
||||
// if (buildingInfo.getId() != 0 && cellId == 0) {
|
||||
// Log.e("No cell ID specified for spawner with ID %d", spawnId);
|
||||
// return null;
|
||||
// } else if (buildingInfo.getId() == 0) {
|
||||
// if (cellId != 0)
|
||||
// Log.w("Unnecessary cell ID specified for spawner with ID %d", spawnId);
|
||||
// return null; // No cell to find
|
||||
// }
|
||||
//
|
||||
// SWGObject building = ObjectLookup.getObjectById(buildingInfo.getId());
|
||||
// if (!(building instanceof BuildingObject)) {
|
||||
// Log.w("Skipping spawner with ID %d - building_id %d didn't reference a BuildingObject!", spawnId, buildingInfo.getId());
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// SWGObject cellObject = ((BuildingObject) building).getCellByNumber(cellId);
|
||||
// if (cellObject == null) {
|
||||
// Log.e("Spawner with ID %d - building %d didn't have cell ID %d!", spawnId, buildingInfo.getId(), cellId);
|
||||
// }
|
||||
// return cellObject;
|
||||
// }
|
||||
//
|
||||
// private String [] createTemplateList(String templates) {
|
||||
// int count = 0;
|
||||
// int ind = -1;
|
||||
// while (ind < templates.length()) {
|
||||
// ind = templates.indexOf(';', ind + 1);
|
||||
// count++;
|
||||
// if (ind == -1)
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// ind = 0;
|
||||
// String[] templateList = new String[count];
|
||||
// for (int i = 0; i < count; i++) {
|
||||
// int next = templates.indexOf(';', ind);
|
||||
// if (next == -1)
|
||||
// next = templates.length();
|
||||
// templateList[i] = ClientFactory.formatToSharedFile("object/mobile/" + templates.substring(ind, next));
|
||||
// ind = next + 1;
|
||||
// }
|
||||
// return templateList;
|
||||
// }
|
||||
//
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import com.projectswg.holocore.resources.support.data.server_info.CachedObjectDa
|
||||
import com.projectswg.holocore.resources.support.data.server_info.DataManager;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.ObjectDatabase;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.StandardLog;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.BuildoutLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.loader.DataLoader;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.SWGObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.building.BuildingObject;
|
||||
@@ -21,10 +22,7 @@ import me.joshlarson.jlcommon.control.Service;
|
||||
import me.joshlarson.jlcommon.log.Log;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
@@ -35,18 +33,21 @@ public class ObjectStorageService extends Service {
|
||||
private final ObjectDatabase<SWGObject> database;
|
||||
private final Map<Long, SWGObject> objectMap;
|
||||
private final Map<Long, SWGObject> buildouts;
|
||||
private final Map<String, BuildingObject> buildingLookup;
|
||||
private final AtomicBoolean started;
|
||||
|
||||
public ObjectStorageService() {
|
||||
this.database = new CachedObjectDatabase<>("odb/objects.db", SWGObjectFactory::create, SWGObjectFactory::save);
|
||||
this.objectMap = new ConcurrentHashMap<>(256*1024, 0.8f, Runtime.getRuntime().availableProcessors());
|
||||
this.buildouts = new ConcurrentHashMap<>(256*1024, 0.8f, 1);
|
||||
this.buildingLookup = new HashMap<>();
|
||||
this.started = new AtomicBoolean(false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean initialize() {
|
||||
ObjectLookup.setObjectAuthority(this::getObjectById);
|
||||
BuildingLookup.setBuildingAuthority(buildingLookup::get);
|
||||
|
||||
{
|
||||
long startTime = StandardLog.onStartLoad("players");
|
||||
@@ -59,8 +60,10 @@ public class ObjectStorageService extends Service {
|
||||
|
||||
{
|
||||
long startTime = StandardLog.onStartLoad("client objects");
|
||||
buildouts.putAll(DataLoader.buildouts(createEventList()).getObjects());
|
||||
BuildoutLoader loader = DataLoader.buildouts(createEventList());
|
||||
buildouts.putAll(loader.getObjects());
|
||||
objectMap.putAll(buildouts);
|
||||
buildingLookup.putAll(loader.getBuildings());
|
||||
StandardLog.onEndLoad(buildouts.size(), "client objects", startTime);
|
||||
}
|
||||
return true;
|
||||
@@ -206,4 +209,19 @@ public class ObjectStorageService extends Service {
|
||||
|
||||
}
|
||||
|
||||
public static class BuildingLookup {
|
||||
|
||||
private static final AtomicReference<Function<String, BuildingObject>> AUTHORITY = new AtomicReference<>(null);
|
||||
|
||||
static void setBuildingAuthority(Function<String, BuildingObject> authority) {
|
||||
AUTHORITY.set(authority);
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public static BuildingObject getBuildingByTag(String buildoutTag) {
|
||||
return AUTHORITY.get().apply(buildoutTag);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ import com.projectswg.utility.clientdata.Converters;
|
||||
public class ClientdataConvertSpecific {
|
||||
|
||||
public static void main(String [] args) {
|
||||
Converters.OBJECTS_OBJECT_DATA.load();
|
||||
Converters.BUILDOUT_OBJECTS.load();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -44,9 +44,10 @@ public class ConvertBuildingList implements Converter {
|
||||
System.out.println("Converting building list...");
|
||||
Collection<SWGObject> objects = DataLoader.buildouts().getObjects().values();
|
||||
try (SdbGenerator gen = new SdbGenerator(new File("serverdata/building/buildings.sdb"))) {
|
||||
gen.writeColumnNames("building_id", "terrain_name", "object_id", "iff", "building_name", "total_cells", "x", "y", "z");
|
||||
gen.writeColumnNames("building_id", "terrain_name", "object_id");
|
||||
for (SWGObject obj : objects) {
|
||||
if (obj instanceof BuildingObject) {
|
||||
|
||||
String template = obj.getTemplate().substring(obj.getTemplate().lastIndexOf('/') + 1);
|
||||
Terrain terrain = obj.getTerrain();
|
||||
String name = terrain.name().charAt(0) + terrain.name().toLowerCase(Locale.US).substring(1);
|
||||
|
||||
@@ -32,33 +32,45 @@ import com.projectswg.common.data.location.Quaternion;
|
||||
import com.projectswg.common.data.location.Terrain;
|
||||
import com.projectswg.common.data.swgfile.ClientFactory;
|
||||
import com.projectswg.common.data.swgfile.visitors.DatatableData;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader;
|
||||
import com.projectswg.holocore.resources.support.data.server_info.SdbLoader.SdbResultSet;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.SWGObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.cell.CellObject;
|
||||
import com.projectswg.holocore.utilities.SdbGenerator;
|
||||
import com.projectswg.utility.clientdata.buildouts.BuildoutLoader;
|
||||
import com.projectswg.utility.clientdata.buildouts.SnapshotLoader;
|
||||
import com.projectswg.utility.clientdata.buildouts.SwgBuildoutArea;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.*;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
@SuppressWarnings({ "UseOfSystemOutOrSystemErr", "CallToPrintStackTrace" }) // Converter class that's not meant to be used by Holocore
|
||||
public class ConvertBuildouts implements Converter{
|
||||
|
||||
private static final String [][] AREA_COLUMNS = {
|
||||
{"id", "terrain", "area_name", "event", "min_x", "min_z", "max_x", "max_z", "adjust_coordinates", "translate_x", "translate_z"}
|
||||
};
|
||||
private static final String [][] OBJECT_COLUMNS = {
|
||||
{"id", "area_id", "template_crc", "container_id", "x", "y", "z", "orientation_x", "orientation_y", "orientation_z", "orientation_w", "radius", "cell_index"}
|
||||
{"id", "template_crc", "container_id", "event", "terrain", "x", "y", "z", "orientation_x", "orientation_y", "orientation_z", "orientation_w", "cell_index", "tag"}
|
||||
};
|
||||
|
||||
private final List<GenBuildoutArea> areas;
|
||||
private final List<GenBuildoutArea> fallbackAreas;
|
||||
private final Map<Long, String> objectTagMap;
|
||||
private final BuildoutLoader buildoutLoader;
|
||||
private final SnapshotLoader snapshotLoader;
|
||||
|
||||
public ConvertBuildouts() {
|
||||
this.areas = new ArrayList<>();
|
||||
this.fallbackAreas = new ArrayList<>(Terrain.values().length);
|
||||
this.objectTagMap = new HashMap<>();
|
||||
AtomicLong objectIdGenerator = new AtomicLong(1);
|
||||
AtomicLong cellIdGenerator = new AtomicLong(1000000);
|
||||
this.buildoutLoader = new BuildoutLoader(objectIdGenerator, cellIdGenerator);
|
||||
this.snapshotLoader = new SnapshotLoader(objectIdGenerator, cellIdGenerator);
|
||||
int areaId = -1;
|
||||
for (Terrain t : Terrain.values()) {
|
||||
fallbackAreas.add(new GenBuildoutArea(null, t, -8196, -8196, 8196, 8196, areaId, false));
|
||||
@@ -85,6 +97,11 @@ public class ConvertBuildouts implements Converter{
|
||||
}
|
||||
|
||||
private void createObjects() throws IOException {
|
||||
try (SdbResultSet set = SdbLoader.load(new File("serverdata/buildout/object_tag_map.sdb"))) {
|
||||
while (set.next()) {
|
||||
objectTagMap.put(set.getInt(1), set.getText(0));
|
||||
}
|
||||
}
|
||||
System.out.println("Generating objects...");
|
||||
List<SWGObject> objects = new LinkedList<>();
|
||||
System.out.println(" Creating buildouts...");
|
||||
@@ -96,70 +113,33 @@ public class ConvertBuildouts implements Converter{
|
||||
}
|
||||
|
||||
private void createBuildouts(List <SWGObject> objects) {
|
||||
BuildoutLoader loader = new BuildoutLoader();
|
||||
loader.loadAllBuildouts();
|
||||
for (Entry<String, List<SWGObject>> areaObjects : loader.getObjects().entrySet()) {
|
||||
GenBuildoutArea area = null;
|
||||
for (GenBuildoutArea a : areas) {
|
||||
if (a.area.getName().equals(areaObjects.getKey())) {
|
||||
area = a;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (area == null) {
|
||||
System.err.println("Unknown area! Name: " + areaObjects.getKey());
|
||||
continue;
|
||||
}
|
||||
for (SWGObject obj : areaObjects.getValue()) {
|
||||
obj.setBuildoutAreaId(area.id);
|
||||
addClientObject(objects, obj);
|
||||
}
|
||||
}
|
||||
buildoutLoader.loadAllBuildouts();
|
||||
objects.addAll(buildoutLoader.getObjects());
|
||||
}
|
||||
|
||||
private void createSnapshots(List<SWGObject> objects) {
|
||||
SnapshotLoader snapLoader = new SnapshotLoader();
|
||||
snapLoader.loadAllSnapshots();
|
||||
List<SWGObject> snapshots = new LinkedList<>();
|
||||
for (SWGObject obj : snapLoader.getObjects()) {
|
||||
addClientObject(snapshots, obj);
|
||||
}
|
||||
setSnapshotData(snapshots, objects);
|
||||
}
|
||||
|
||||
private void setSnapshotData(List<SWGObject> snapshots, List<SWGObject> objects) {
|
||||
for (SWGObject snap : snapshots) {
|
||||
GenBuildoutArea area = getAreaForObject(snap);
|
||||
snapshotLoader.loadAllSnapshots();
|
||||
for (SWGObject snap : snapshotLoader.getObjects()) {
|
||||
GenBuildoutArea area = fallbackAreas.stream().filter(a -> a.terrain.equals(snap.getTerrain())).findFirst().orElse(null);
|
||||
if (area != null)
|
||||
snap.setBuildoutAreaId(area.id);
|
||||
else
|
||||
System.err.println("No area for: " + snap.getObjectId() + " / " + snap.getTerrain());
|
||||
objects.add(snap);
|
||||
}
|
||||
objects.addAll(snapshots);
|
||||
}
|
||||
|
||||
private void generateObjectFile(List<SWGObject> objects) throws IOException {
|
||||
isValidBuildoutAreas(objects);
|
||||
try (SdbGenerator gen = new SdbGenerator(new File("serverdata/buildout/objects.sdb"))) {
|
||||
gen.writeColumnNames(OBJECT_COLUMNS[0]);
|
||||
int objNum = 0;
|
||||
int percent = 0;
|
||||
objects.sort((o1, o2) -> {
|
||||
int comp;
|
||||
comp = Integer.compare(o1.getBuildoutAreaId(), o2.getBuildoutAreaId());
|
||||
if (comp != 0)
|
||||
return comp;
|
||||
comp = Long.compare(o1.getSuperParent() != null ? o1.getSuperParent().getObjectId() : o1.getObjectId(), o2.getSuperParent() != null ? o2.getSuperParent().getObjectId() : o2.getObjectId());
|
||||
if (comp != 0)
|
||||
return comp;
|
||||
comp = Integer.compare(getBuildoutDepth(o1), getBuildoutDepth(o2));
|
||||
if (comp != 0)
|
||||
return comp;
|
||||
return 0;
|
||||
});
|
||||
isValidBuildoutAreas(objects);
|
||||
objects.sort(Comparator.comparingLong(SWGObject::getObjectId));
|
||||
for (SWGObject obj : objects) {
|
||||
if (obj instanceof CellObject)
|
||||
continue;
|
||||
|
||||
writeObject(gen, obj);
|
||||
while (percent / 100.0 * objects.size() <= objNum) {
|
||||
System.out.print(".");
|
||||
@@ -171,29 +151,24 @@ public class ConvertBuildouts implements Converter{
|
||||
}
|
||||
}
|
||||
|
||||
private int getBuildoutDepth(SWGObject object) {
|
||||
if (object.getParent() == null)
|
||||
return 0;
|
||||
return getBuildoutDepth(object.getParent()) + 1;
|
||||
}
|
||||
|
||||
private void addClientObject(List<SWGObject> objects, SWGObject obj) {
|
||||
objects.add(obj);
|
||||
for (SWGObject child : obj.getContainedObjects()) {
|
||||
addClientObject(objects, child);
|
||||
}
|
||||
for (SWGObject child : obj.getSlots().values()) {
|
||||
if (child != null)
|
||||
addClientObject(objects, child);
|
||||
}
|
||||
}
|
||||
|
||||
private void writeAreas(SdbGenerator gen) throws IOException {
|
||||
DatatableData table = (DatatableData) ClientFactory.getInfoFromFile("datatables/buildout/buildout_scenes.iff");
|
||||
areas.clear();
|
||||
for (int sceneRow = 0; sceneRow < table.getRowCount(); sceneRow++) {
|
||||
Terrain t = Terrain.getTerrainFromName((String) table.getCell(sceneRow, 0));
|
||||
getArea(t, sceneRow, (Boolean) table.getCell(sceneRow, 1));
|
||||
{
|
||||
DatatableData table = (DatatableData) ClientFactory.getInfoFromFile("datatables/buildout/buildout_scenes.iff");
|
||||
int areaId = 1;
|
||||
for (int sceneRow = 0; sceneRow < table.getRowCount(); sceneRow++) {
|
||||
Terrain t = Terrain.getTerrainFromName((String) table.getCell(sceneRow, 0));
|
||||
boolean adjust = (Boolean) table.getCell(sceneRow, 1);
|
||||
|
||||
String file = "datatables/buildout/areas_"+t.getName()+".iff";
|
||||
DatatableData areaTable = (DatatableData) ClientFactory.getInfoFromFile(file);
|
||||
for (int row = 0; row < areaTable.getRowCount(); row++) {
|
||||
SwgBuildoutArea area = new SwgBuildoutArea();
|
||||
area.load(areaTable.getRow(row), sceneRow, row);
|
||||
areas.add(new GenBuildoutArea(area, t, area.getX1(), area.getZ1(), area.getX2(), area.getZ2(), areaId, adjust));
|
||||
areaId++;
|
||||
}
|
||||
}
|
||||
}
|
||||
Collections.sort(areas);
|
||||
for (int i = fallbackAreas.size()-1; i >= 0; i--) {
|
||||
@@ -217,16 +192,6 @@ public class ConvertBuildouts implements Converter{
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private void getArea(Terrain t, int sceneRow, boolean adjust) {
|
||||
String file = "datatables/buildout/areas_"+t.getName()+".iff";
|
||||
DatatableData areaTable = (DatatableData) ClientFactory.getInfoFromFile(file);
|
||||
for (int row = 0; row < areaTable.getRowCount(); row++) {
|
||||
SwgBuildoutArea area = new SwgBuildoutArea();
|
||||
area.load(areaTable.getRow(row), sceneRow, row);
|
||||
areas.add(new GenBuildoutArea(area, t, area.getX1(), area.getZ1(), area.getX2(), area.getZ2(), sceneRow*100+row, adjust));
|
||||
}
|
||||
}
|
||||
|
||||
private void writeArea(SdbGenerator gen, GenBuildoutArea area, String substituteName) throws IOException {
|
||||
if (substituteName == null)
|
||||
substituteName = area.area.getName();
|
||||
@@ -249,53 +214,28 @@ public class ConvertBuildouts implements Converter{
|
||||
|
||||
private void writeObject(SdbGenerator gen, SWGObject object) throws IOException {
|
||||
long id = object.getObjectId();
|
||||
long originalId = buildoutLoader.getPreviousId(id);
|
||||
if (originalId == 0)
|
||||
originalId = snapshotLoader.getPreviousId(id);
|
||||
int crc = CRC.getCrc(object.getTemplate());
|
||||
long container = (object.getParent() != null) ? object.getParent().getObjectId() : 0;
|
||||
if (object.getParent() instanceof CellObject)
|
||||
if (object.getParent() instanceof CellObject) {
|
||||
assert object.getParent().getParent() != null;
|
||||
container = object.getParent().getParent().getObjectId();
|
||||
}
|
||||
String event = object.getBuildoutEvent();
|
||||
Location l = object.getLocation();
|
||||
Quaternion q = l.getOrientation();
|
||||
double radius = object.getLoadRange();
|
||||
int cellIndex = (object.getParent() instanceof CellObject) ? ((CellObject) object.getParent()).getNumber() : 0;
|
||||
Terrain terrain = l.getTerrain();
|
||||
float x = (float) l.getX(), y = (float) l.getY(), z = (float) l.getZ();
|
||||
float oX = (float) q.getX(), oY = (float) q.getY(), oZ = (float) q.getZ(), oW = (float) q.getW();
|
||||
gen.writeLine(id, object.getBuildoutAreaId(), crc, container, x, y, z, oX, oY, oZ, oW, radius, cellIndex);
|
||||
}
|
||||
|
||||
private GenBuildoutArea getAreaForObject(SWGObject obj) {
|
||||
SWGObject superParent = obj.getSuperParent();
|
||||
Location l = superParent == null ? obj.getLocation() : superParent.getLocation();
|
||||
double x = l.getX();
|
||||
double z = l.getZ();
|
||||
int ind = Collections.binarySearch(areas, new GenBuildoutArea(null, obj.getTerrain(), x, z, x, z, 0, false), (area1, area2) -> {
|
||||
int comp = area1.terrain.getName().compareTo(area2.terrain.getName());
|
||||
if (comp != 0)
|
||||
return comp;
|
||||
if (area2.x1 < area1.x1)
|
||||
return 1;
|
||||
if (area2.x2 > area1.x2)
|
||||
return -1;
|
||||
if (area2.z1 < area1.z1)
|
||||
return 1;
|
||||
if (area2.z2 > area1.z2)
|
||||
return -1;
|
||||
return Integer.compare(area1.getSorting(), area2.getSorting());
|
||||
});
|
||||
if (ind < 0) {
|
||||
for (GenBuildoutArea fallback : fallbackAreas) {
|
||||
if (fallback.terrain == obj.getTerrain())
|
||||
return fallback;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return areas.get(ind);
|
||||
gen.writeLine(id, crc, container, event, terrain.name(), x, y, z, oX, oY, oZ, oW, cellIndex, objectTagMap.getOrDefault(originalId, ""));
|
||||
}
|
||||
|
||||
private void isValidBuildoutAreas(List<SWGObject> objects) {
|
||||
for (SWGObject obj : objects) {
|
||||
GenBuildoutArea area = getAreaForObject(obj);
|
||||
assert area != null : "no buildout area found for object: " + obj;
|
||||
assert obj.getBuildoutAreaId() == area.id : "invalid buildout area for object " + obj;
|
||||
assert fallbackAreas.stream().mapToInt(area -> area.id).anyMatch(id -> obj.getBuildoutAreaId() == id) || areas.stream().mapToInt(area -> area.id).anyMatch(id -> obj.getBuildoutAreaId() == id) : "no area found: " + obj.getBuildoutAreaId();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -313,10 +253,7 @@ public class ConvertBuildouts implements Converter{
|
||||
public GenBuildoutArea(SwgBuildoutArea area, Terrain terrain, double x1, double z1, double x2, double z2, int id, boolean adjust) {
|
||||
this.area = area;
|
||||
this.terrain = terrain;
|
||||
if (area != null)
|
||||
this.index = area.getIndex();
|
||||
else
|
||||
this.index = -1;
|
||||
this.index = area != null ? area.getIndex() : -1;
|
||||
this.x1 = (int) x1;
|
||||
this.z1 = (int) z1;
|
||||
this.x2 = (int) x2;
|
||||
@@ -326,7 +263,7 @@ public class ConvertBuildouts implements Converter{
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(GenBuildoutArea area) {
|
||||
public int compareTo(@NotNull GenBuildoutArea area) {
|
||||
int comp = Integer.compare(index, area.index);
|
||||
if (comp != 0)
|
||||
return comp;
|
||||
|
||||
@@ -26,66 +26,99 @@
|
||||
***********************************************************************************/
|
||||
package com.projectswg.utility.clientdata.buildouts;
|
||||
|
||||
import com.projectswg.common.data.location.Location;
|
||||
import com.projectswg.common.data.location.Terrain;
|
||||
import com.projectswg.common.data.swgfile.ClientFactory;
|
||||
import com.projectswg.common.data.swgfile.visitors.CrcStringTableData;
|
||||
import com.projectswg.common.data.swgfile.visitors.DatatableData;
|
||||
import com.projectswg.holocore.resources.support.objects.ObjectCreator;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.SWGObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.cell.CellObject;
|
||||
import me.joshlarson.jlcommon.log.Log;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public class BuildoutLoader {
|
||||
|
||||
private static final CrcStringTableData crcTable = (CrcStringTableData) ClientFactory.getInfoFromFile("misc/object_template_crc_string_table.iff");
|
||||
private static final String BASE_PATH = "datatables/buildout/";
|
||||
|
||||
private final Map <Long, SWGObject> objectTable;
|
||||
private final Map<String, List <SWGObject>> objects;
|
||||
private final Map<Long, Long> idMapping;
|
||||
private final Set<SWGObject> objects;
|
||||
private final AtomicLong objectIdGenerator;
|
||||
private final AtomicLong cellIdGenerator;
|
||||
|
||||
public BuildoutLoader() {
|
||||
objectTable = new HashMap<>();
|
||||
objects = new Hashtable<>();
|
||||
public BuildoutLoader(AtomicLong objectIdGenerator, AtomicLong cellIdGenerator) {
|
||||
this.idMapping = new HashMap<>();
|
||||
this.objects = new HashSet<>();
|
||||
this.objectIdGenerator = objectIdGenerator;
|
||||
this.cellIdGenerator = cellIdGenerator;
|
||||
}
|
||||
|
||||
public void loadAllBuildouts() {
|
||||
for (Terrain t : getTerrainsToLoad())
|
||||
loadBuildoutsForTerrain(t);
|
||||
}
|
||||
|
||||
public void loadBuildoutsForTerrain(Terrain terrain) {
|
||||
DatatableData table = (DatatableData) ClientFactory.getInfoFromFile("datatables/buildout/buildout_scenes.iff");
|
||||
for (int row = 0; row < table.getRowCount(); row++) {
|
||||
if (table.getCell(row, 0).equals(terrain.name().toLowerCase(Locale.ENGLISH))) {
|
||||
TerrainBuildoutLoader loader = new TerrainBuildoutLoader(crcTable, terrain);
|
||||
loader.load(row);
|
||||
objects.putAll(loader.getObjects());
|
||||
objectTable.putAll(loader.getObjectTable());
|
||||
return;
|
||||
DatatableData table = (DatatableData) ClientFactory.getInfoFromFile(BASE_PATH+"buildout_scenes.iff");
|
||||
int areaId = 1;
|
||||
for (int sceneRow = 0; sceneRow < table.getRowCount(); sceneRow++) {
|
||||
Terrain t = Terrain.getTerrainFromName((String) table.getCell(sceneRow, 0));
|
||||
|
||||
String file = "datatables/buildout/areas_"+t.getName()+".iff";
|
||||
DatatableData areaTable = (DatatableData) ClientFactory.getInfoFromFile(file);
|
||||
for (int row = 0; row < areaTable.getRowCount(); row++) {
|
||||
SwgBuildoutArea area = new SwgBuildoutArea();
|
||||
area.load(areaTable.getRow(row), sceneRow, row);
|
||||
loadArea(area, t, areaId);
|
||||
areaId++;
|
||||
}
|
||||
}
|
||||
System.err.println("Could not find buildouts for terrain: " + terrain);
|
||||
Log.e("Could not find buildouts for terrain: %s", terrain);
|
||||
}
|
||||
|
||||
public Map <Long, SWGObject> getObjectTable() {
|
||||
return objectTable;
|
||||
public long getPreviousId(long id) {
|
||||
return idMapping.getOrDefault(id, 0L);
|
||||
}
|
||||
|
||||
public Map<String, List <SWGObject>> getObjects() {
|
||||
return objects;
|
||||
public Set<SWGObject> getObjects() {
|
||||
return Collections.unmodifiableSet(objects);
|
||||
}
|
||||
|
||||
private static List <Terrain> getTerrainsToLoad() {
|
||||
DatatableData table = (DatatableData) ClientFactory.getInfoFromFile("datatables/buildout/buildout_scenes.iff");
|
||||
List <Terrain> terrains = new LinkedList<>();
|
||||
for (int row = 0; row < table.getRowCount(); row++) {
|
||||
Terrain t = Terrain.getTerrainFromName((String) table.getCell(row, 0));
|
||||
if (t != null)
|
||||
terrains.add(t);
|
||||
else
|
||||
System.err.println("Couldn't find terrain: " + table.getCell(row, 0));
|
||||
private void loadArea(SwgBuildoutArea area, Terrain terrain, int areaId) {
|
||||
DatatableData areaTable = (DatatableData) ClientFactory.getInfoFromFile(BASE_PATH+terrain.getName()+"/"+area.getName().replace("server", "client")+".iff");
|
||||
|
||||
SwgBuildoutRow buildoutRow = new SwgBuildoutRow(area);
|
||||
Map<Long, SWGObject> officialBuildoutTable = new HashMap<>();
|
||||
for (int row = 0; row < areaTable.getRowCount(); row++) {
|
||||
buildoutRow.load(areaTable.getRow(row), crcTable);
|
||||
|
||||
long id = buildoutRow.getTemplate().equals("object/cell/shared_cell.iff") ? cellIdGenerator.getAndIncrement() : objectIdGenerator.getAndIncrement();
|
||||
SWGObject object = ObjectCreator.createObjectFromTemplate(id, buildoutRow.getTemplate());
|
||||
Location l = buildoutRow.getLocation();
|
||||
object.setPosition(terrain, l.getX(), l.getY(), l.getZ());
|
||||
object.setOrientation(l.getOrientationX(), l.getOrientationY(), l.getOrientationZ(), l.getOrientationW());
|
||||
object.setBuildoutAreaId(areaId);
|
||||
object.setBuildoutEvent(area.getEventRequired());
|
||||
|
||||
setCellInformation(object, buildoutRow.getCellIndex());
|
||||
addObject(officialBuildoutTable, object, buildoutRow.getObjectId(), buildoutRow.getContainerId());
|
||||
}
|
||||
}
|
||||
|
||||
private void setCellInformation(SWGObject object, int cellIndex) {
|
||||
if (!(object instanceof CellObject))
|
||||
return;
|
||||
CellObject cell = (CellObject) object;
|
||||
cell.setNumber(cellIndex);
|
||||
}
|
||||
|
||||
private void addObject(Map<Long, SWGObject> objectTable, SWGObject object, long objectId, long containerId) {
|
||||
objects.add(object);
|
||||
idMapping.put(object.getObjectId(), objectId);
|
||||
objectTable.put(objectId, object);
|
||||
if (containerId != 0) {
|
||||
SWGObject container = objectTable.get(containerId);
|
||||
object.systemMove(container);
|
||||
if (container == null)
|
||||
Log.e("Failed to load object: " + object.getTemplate());
|
||||
}
|
||||
return terrains;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -26,10 +26,19 @@
|
||||
***********************************************************************************/
|
||||
package com.projectswg.utility.clientdata.buildouts;
|
||||
|
||||
import com.projectswg.common.data.location.Location;
|
||||
import com.projectswg.common.data.location.Terrain;
|
||||
import com.projectswg.common.data.swgfile.ClientFactory;
|
||||
import com.projectswg.common.data.swgfile.visitors.WorldSnapshotData;
|
||||
import com.projectswg.common.data.swgfile.visitors.WorldSnapshotData.Node;
|
||||
import com.projectswg.holocore.resources.support.objects.ObjectCreator;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.SWGObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.building.BuildingObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.cell.CellObject;
|
||||
import me.joshlarson.jlcommon.log.Log;
|
||||
|
||||
import java.util.*;
|
||||
import java.util.concurrent.atomic.AtomicLong;
|
||||
|
||||
public class SnapshotLoader {
|
||||
|
||||
@@ -39,34 +48,87 @@ public class SnapshotLoader {
|
||||
Terrain.NABOO, Terrain.RORI, Terrain.TALUS,
|
||||
Terrain.TATOOINE, Terrain.YAVIN4
|
||||
);
|
||||
private static final String BASE_PATH = "snapshot/";
|
||||
|
||||
private final Map <Long, SWGObject> objectTable;
|
||||
private final List <SWGObject> objects;
|
||||
private final Map<Long, SWGObject> snapshotTable;
|
||||
private final Map<Long, Long> idMapping;
|
||||
private final List<SWGObject> objects;
|
||||
private final AtomicLong objectIdGenerator;
|
||||
private final AtomicLong cellIdGenerator;
|
||||
|
||||
public SnapshotLoader() {
|
||||
objectTable = new HashMap<>();
|
||||
objects = new LinkedList<>();
|
||||
public SnapshotLoader(AtomicLong objectIdGenerator, AtomicLong cellIdGenerator) {
|
||||
this.snapshotTable = new HashMap<>();
|
||||
this.idMapping = new HashMap<>();
|
||||
this.objects = new ArrayList<>();
|
||||
this.objectIdGenerator = objectIdGenerator;
|
||||
this.cellIdGenerator = cellIdGenerator;
|
||||
}
|
||||
|
||||
public void loadAllSnapshots() {
|
||||
for (Terrain t : TERRAINS) {
|
||||
loadSnapshotsForTerrain(t);
|
||||
loadTerrain(t);
|
||||
}
|
||||
}
|
||||
|
||||
public void loadSnapshotsForTerrain(Terrain t) {
|
||||
TerrainSnapshotLoader loader = new TerrainSnapshotLoader(t);
|
||||
loader.load();
|
||||
objects.addAll(loader.getObjects());
|
||||
objectTable.putAll(loader.getObjectTable());
|
||||
public long getPreviousId(long id) {
|
||||
return idMapping.getOrDefault(id, 0L);
|
||||
}
|
||||
|
||||
public Map<Long, SWGObject> getObjectTable() {
|
||||
return objectTable;
|
||||
public List<SWGObject> getObjects() {
|
||||
return Collections.unmodifiableList(objects);
|
||||
}
|
||||
|
||||
public List <SWGObject> getObjects() {
|
||||
return objects;
|
||||
private void loadTerrain(Terrain terrain) {
|
||||
String path = BASE_PATH + terrain.getName() + ".ws";
|
||||
WorldSnapshotData data = (WorldSnapshotData) ClientFactory.getInfoFromFile(path);
|
||||
Map <Integer, String> templates = data.getObjectTemplateNames();
|
||||
for (Node node : data.getNodes()) {
|
||||
createFromNode(templates, terrain, node);
|
||||
}
|
||||
}
|
||||
|
||||
private void createFromNode(Map<Integer, String> templates, Terrain terrain, Node node) {
|
||||
SWGObject object = createObject(templates, terrain, node);
|
||||
object.setBuildoutAreaId(-1);
|
||||
setCellInformation(object, node.getCellIndex());
|
||||
addObject(object, node.getId(), node.getContainerId());
|
||||
|
||||
for (Node child : node.getChildren()) {
|
||||
createFromNode(templates, terrain, child);
|
||||
}
|
||||
}
|
||||
|
||||
private SWGObject createObject(Map <Integer, String> templateMap, Terrain terrain, Node row) {
|
||||
String template = templateMap.get(row.getObjectTemplateNameIndex());
|
||||
long id = template.equals("object/cell/shared_cell.iff") ? cellIdGenerator.getAndIncrement() : objectIdGenerator.getAndIncrement();
|
||||
SWGObject object = ObjectCreator.createObjectFromTemplate(id, template);
|
||||
Location l = row.getLocation();
|
||||
object.setPosition(terrain, l.getX(), l.getY(), l.getZ());
|
||||
object.setOrientation(l.getOrientationX(), l.getOrientationY(), l.getOrientationZ(), l.getOrientationW());
|
||||
return object;
|
||||
}
|
||||
|
||||
private void addObject(SWGObject object, long objectId, long containerId) {
|
||||
objects.add(object);
|
||||
snapshotTable.put(objectId, object);
|
||||
idMapping.put(object.getObjectId(), objectId);
|
||||
if (containerId != 0) {
|
||||
SWGObject container = snapshotTable.get(containerId);
|
||||
if (!(object instanceof CellObject) && container instanceof BuildingObject) {
|
||||
Log.w("Not adding: %s to %s - invalid type for BuildingObject", object, container);
|
||||
return;
|
||||
}
|
||||
object.systemMove(container);
|
||||
if (container == null)
|
||||
Log.e("Failed to load object: " + object.getTemplate());
|
||||
}
|
||||
}
|
||||
|
||||
private void setCellInformation(SWGObject object, int cellIndex) {
|
||||
if (!(object instanceof CellObject))
|
||||
return;
|
||||
CellObject cell = (CellObject) object;
|
||||
cell.setNumber(cellIndex);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,125 +0,0 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2018 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore 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 Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
package com.projectswg.utility.clientdata.buildouts;
|
||||
|
||||
import com.projectswg.common.data.location.Location;
|
||||
import com.projectswg.common.data.location.Terrain;
|
||||
import com.projectswg.common.data.swgfile.ClientFactory;
|
||||
import com.projectswg.common.data.swgfile.visitors.CrcStringTableData;
|
||||
import com.projectswg.common.data.swgfile.visitors.DatatableData;
|
||||
import com.projectswg.holocore.resources.support.objects.ObjectCreator;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.SWGObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.cell.CellObject;
|
||||
import me.joshlarson.jlcommon.log.Log;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
class TerrainBuildoutLoader {
|
||||
|
||||
private static final String BASE_PATH = "datatables/buildout/";
|
||||
|
||||
private final CrcStringTableData crcTable;
|
||||
private final Terrain terrain;
|
||||
private final Map <Long, SWGObject> objectTable;
|
||||
private final Map<String, List <SWGObject>> objects;
|
||||
|
||||
public TerrainBuildoutLoader(CrcStringTableData crcTable, Terrain terrain) {
|
||||
this.crcTable = crcTable;
|
||||
this.terrain = terrain;
|
||||
this.objectTable = new Hashtable<>(512);
|
||||
this.objects = new Hashtable<>();
|
||||
}
|
||||
|
||||
public void load(int sceneNumber) {
|
||||
objects.clear();
|
||||
loadAreas(sceneNumber);
|
||||
}
|
||||
|
||||
public Map <Long, SWGObject> getObjectTable() {
|
||||
return objectTable;
|
||||
}
|
||||
|
||||
public Map<String, List <SWGObject>> getObjects() {
|
||||
return objects;
|
||||
}
|
||||
|
||||
private void loadAreas(int sceneNumber) {
|
||||
String file = BASE_PATH+"areas_"+terrain.getName()+".iff";
|
||||
DatatableData areaTable = (DatatableData) ClientFactory.getInfoFromFile(file);
|
||||
for (int row = 0; row < areaTable.getRowCount(); row++) {
|
||||
SwgBuildoutArea area = new SwgBuildoutArea();
|
||||
area.load(areaTable.getRow(row), sceneNumber, row);
|
||||
loadArea(area);
|
||||
}
|
||||
}
|
||||
|
||||
private void loadArea(SwgBuildoutArea area) {
|
||||
String file = BASE_PATH+terrain.getName()+"/"+area.getName().replace("server", "client")+".iff";
|
||||
DatatableData areaTable = (DatatableData) ClientFactory.getInfoFromFile(file);
|
||||
SwgBuildoutRow buildoutRow = new SwgBuildoutRow(area);
|
||||
objectTable.clear();
|
||||
for (int row = 0; row < areaTable.getRowCount(); row++) {
|
||||
buildoutRow.load(areaTable.getRow(row), crcTable);
|
||||
SWGObject object = createObject(buildoutRow);
|
||||
object.setBuildoutAreaId(area.getIndex());
|
||||
setCellInformation(object, buildoutRow.getCellIndex());
|
||||
addObject(area.getName(), object, buildoutRow.getContainerId());
|
||||
}
|
||||
}
|
||||
|
||||
private SWGObject createObject(SwgBuildoutRow row) {
|
||||
SWGObject object = ObjectCreator.createObjectFromTemplate(row.getObjectId(), row.getTemplate());
|
||||
Location l = row.getLocation();
|
||||
object.setPosition(terrain, l.getX(), l.getY(), l.getZ());
|
||||
object.setOrientation(l.getOrientationX(), l.getOrientationY(), l.getOrientationZ(), l.getOrientationW());
|
||||
return object;
|
||||
}
|
||||
|
||||
private void addObject(String areaName, SWGObject object, long containerId) {
|
||||
objectTable.put(object.getObjectId(), object);
|
||||
if (containerId != 0) {
|
||||
SWGObject container = objectTable.get(containerId);
|
||||
object.systemMove(container);
|
||||
if (container == null)
|
||||
Log.e("Failed to load object: " + object.getTemplate());
|
||||
} else {
|
||||
List<SWGObject> list = objects.computeIfAbsent(areaName, k -> new LinkedList<>());
|
||||
list.add(object);
|
||||
}
|
||||
}
|
||||
|
||||
private void setCellInformation(SWGObject object, int cellIndex) {
|
||||
if (!(object instanceof CellObject))
|
||||
return;
|
||||
CellObject cell = (CellObject) object;
|
||||
cell.setNumber(cellIndex);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
/***********************************************************************************
|
||||
* Copyright (c) 2018 /// Project SWG /// www.projectswg.com *
|
||||
* *
|
||||
* ProjectSWG is the first NGE emulator for Star Wars Galaxies founded on *
|
||||
* July 7th, 2011 after SOE announced the official shutdown of Star Wars Galaxies. *
|
||||
* Our goal is to create an emulator which will provide a server for players to *
|
||||
* continue playing a game similar to the one they used to play. We are basing *
|
||||
* it on the final publish of the game prior to end-game events. *
|
||||
* *
|
||||
* This file is part of Holocore. *
|
||||
* *
|
||||
* --------------------------------------------------------------------------------*
|
||||
* *
|
||||
* Holocore is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Affero General Public License as *
|
||||
* published by the Free Software Foundation, either version 3 of the *
|
||||
* License, or (at your option) any later version. *
|
||||
* *
|
||||
* Holocore 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 Affero General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU Affero General Public License *
|
||||
* along with Holocore. If not, see <http://www.gnu.org/licenses/>. *
|
||||
***********************************************************************************/
|
||||
package com.projectswg.utility.clientdata.buildouts;
|
||||
|
||||
import com.projectswg.common.data.location.Location;
|
||||
import com.projectswg.common.data.location.Terrain;
|
||||
import com.projectswg.common.data.swgfile.ClientFactory;
|
||||
import com.projectswg.common.data.swgfile.visitors.WorldSnapshotData;
|
||||
import com.projectswg.common.data.swgfile.visitors.WorldSnapshotData.Node;
|
||||
import com.projectswg.holocore.resources.support.objects.ObjectCreator;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.SWGObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.building.BuildingObject;
|
||||
import com.projectswg.holocore.resources.support.objects.swg.cell.CellObject;
|
||||
import me.joshlarson.jlcommon.log.Log;
|
||||
|
||||
import java.util.Hashtable;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
public class TerrainSnapshotLoader {
|
||||
|
||||
private static final String BASE_PATH = "snapshot/";
|
||||
|
||||
private final Terrain terrain;
|
||||
private final Map <Long, SWGObject> objectTable;
|
||||
private final List <SWGObject> objects;
|
||||
|
||||
public TerrainSnapshotLoader(Terrain terrain) {
|
||||
this.terrain = terrain;
|
||||
this.objectTable = new Hashtable<>(12 * 1024);
|
||||
this.objects = new LinkedList<>();
|
||||
}
|
||||
|
||||
public Map <Long, SWGObject> getObjectTable() {
|
||||
return objectTable;
|
||||
}
|
||||
|
||||
public List <SWGObject> getObjects() {
|
||||
return objects;
|
||||
}
|
||||
|
||||
public void load() {
|
||||
objects.clear();
|
||||
String path = BASE_PATH + terrain.getName() + ".ws";
|
||||
WorldSnapshotData data = (WorldSnapshotData) ClientFactory.getInfoFromFile(path);
|
||||
Map <Integer, String> templates = data.getObjectTemplateNames();
|
||||
for (Node node : data.getNodes()) {
|
||||
createFromNode(templates, node);
|
||||
}
|
||||
}
|
||||
|
||||
private void createFromNode(Map<Integer, String> templates, Node node) {
|
||||
SWGObject object = createObject(templates, node);
|
||||
object.setBuildoutAreaId(-1);
|
||||
setCellInformation(object, node.getCellIndex());
|
||||
addObject(object, node.getContainerId());
|
||||
|
||||
for (Node child : node.getChildren()) {
|
||||
createFromNode(templates, child);
|
||||
}
|
||||
}
|
||||
|
||||
private SWGObject createObject(Map <Integer, String> templateMap, Node row) {
|
||||
SWGObject object = ObjectCreator.createObjectFromTemplate(row.getId(), templateMap.get(row.getObjectTemplateNameIndex()));
|
||||
Location l = row.getLocation();
|
||||
object.setPosition(terrain, l.getX(), l.getY(), l.getZ());
|
||||
object.setOrientation(l.getOrientationX(), l.getOrientationY(), l.getOrientationZ(), l.getOrientationW());
|
||||
return object;
|
||||
}
|
||||
|
||||
private void addObject(SWGObject object, long containerId) {
|
||||
objectTable.put(object.getObjectId(), object);
|
||||
if (containerId != 0) {
|
||||
SWGObject container = objectTable.get(containerId);
|
||||
if (!(object instanceof CellObject) && container instanceof BuildingObject) {
|
||||
Log.w("Not adding: %s to %s - invalid type for BuildingObject", object, container);
|
||||
return;
|
||||
}
|
||||
object.systemMove(container);
|
||||
if (container == null)
|
||||
Log.e("Failed to load object: " + object.getTemplate());
|
||||
} else {
|
||||
objects.add(object);
|
||||
}
|
||||
}
|
||||
|
||||
private void setCellInformation(SWGObject object, int cellIndex) {
|
||||
if (!(object instanceof CellObject))
|
||||
return;
|
||||
CellObject cell = (CellObject) object;
|
||||
cell.setNumber(cellIndex);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user