164 lines
6.4 KiB
Java
164 lines
6.4 KiB
Java
package com.zombie.game.template;
|
|
|
|
import com.fasterxml.jackson.databind.JsonNode;
|
|
import com.fasterxml.jackson.databind.ObjectMapper;
|
|
import org.slf4j.Logger;
|
|
import org.slf4j.LoggerFactory;
|
|
|
|
import java.io.InputStream;
|
|
import java.util.*;
|
|
|
|
/**
|
|
* 模板管理器
|
|
*
|
|
* 负责从 JSON 配置文件加载和管理所有游戏模板(僵尸、武器、玩家)。
|
|
* 单例模式,在服务器启动时加载一次。
|
|
*/
|
|
public class TemplateManager {
|
|
private static final Logger logger = LoggerFactory.getLogger(TemplateManager.class);
|
|
private static TemplateManager instance;
|
|
|
|
private final Map<String, ZombieTemplate> zombieTemplates = new LinkedHashMap<>();
|
|
private final Map<String, WeaponTemplate> weaponTemplates = new LinkedHashMap<>();
|
|
private PlayerTemplate playerTemplate;
|
|
|
|
private TemplateManager() {
|
|
loadAll();
|
|
}
|
|
|
|
public static synchronized TemplateManager getInstance() {
|
|
if (instance == null) {
|
|
instance = new TemplateManager();
|
|
}
|
|
return instance;
|
|
}
|
|
|
|
private void loadAll() {
|
|
loadZombies();
|
|
loadWeapons();
|
|
loadPlayer();
|
|
logger.info("Templates loaded: {} zombies, {} weapons, 1 player base",
|
|
zombieTemplates.size(), weaponTemplates.size());
|
|
}
|
|
|
|
private void loadZombies() {
|
|
try (InputStream is = getClass().getResourceAsStream("/data/zombies.json")) {
|
|
ObjectMapper mapper = new ObjectMapper();
|
|
JsonNode root = mapper.readTree(is);
|
|
JsonNode types = root.get("types");
|
|
for (JsonNode node : types) {
|
|
ZombieTemplate t = new ZombieTemplate(
|
|
node.get("id").asText(),
|
|
node.get("name").asText(),
|
|
(float) node.get("baseHealth").asDouble(),
|
|
(float) node.get("baseSpeed").asDouble(),
|
|
(float) node.get("damage").asDouble(),
|
|
(float) node.get("attackRate").asDouble(),
|
|
node.get("canRangedAttack").asBoolean(),
|
|
(float) node.get("rangedRange").asDouble(),
|
|
node.get("rangedDamage").asInt(),
|
|
(float) node.get("rangedBulletSpeed").asDouble(),
|
|
node.get("canSplit").asBoolean(),
|
|
node.get("minSplit").asInt(),
|
|
node.get("maxSplit").asInt(),
|
|
(float) node.get("spawnWeight").asDouble()
|
|
);
|
|
zombieTemplates.put(t.getId(), t);
|
|
}
|
|
} catch (Exception e) {
|
|
throw new RuntimeException("Failed to load zombie templates", e);
|
|
}
|
|
}
|
|
|
|
private void loadWeapons() {
|
|
try (InputStream is = getClass().getResourceAsStream("/data/weapons.json")) {
|
|
ObjectMapper mapper = new ObjectMapper();
|
|
JsonNode root = mapper.readTree(is);
|
|
JsonNode types = root.get("types");
|
|
for (JsonNode node : types) {
|
|
WeaponTemplate t = new WeaponTemplate(
|
|
node.get("id").asText(),
|
|
node.get("name").asText(),
|
|
node.has("category") ? node.get("category").asText() : "firearm",
|
|
node.get("damage").asInt(),
|
|
node.get("fireRate").asLong(),
|
|
node.get("pelletCount").asInt(),
|
|
(float) node.get("spread").asDouble(),
|
|
(float) node.get("bulletSpeed").asDouble(),
|
|
(float) node.get("range").asDouble(),
|
|
node.get("maxAmmo").asInt(),
|
|
node.get("chargeable").asBoolean(),
|
|
node.get("explosive").asBoolean(),
|
|
(float) node.get("explosionRadius").asDouble(),
|
|
node.has("fireZoneRadius") ? (float) node.get("fireZoneRadius").asDouble() : 0,
|
|
node.has("fireZoneDamage") ? (float) node.get("fireZoneDamage").asDouble() : 0,
|
|
node.has("fireZoneDuration") ? (float) node.get("fireZoneDuration").asDouble() : 0,
|
|
node.has("turretHealth") ? (float) node.get("turretHealth").asDouble() : 0,
|
|
node.has("turretRange") ? (float) node.get("turretRange").asDouble() : 0,
|
|
node.has("turretFireRate") ? node.get("turretFireRate").asLong() : 0,
|
|
node.has("turretDamage") ? node.get("turretDamage").asInt() : 0,
|
|
node.has("turretBulletSpeed") ? (float) node.get("turretBulletSpeed").asDouble() : 0
|
|
);
|
|
weaponTemplates.put(t.getId(), t);
|
|
}
|
|
} catch (Exception e) {
|
|
throw new RuntimeException("Failed to load weapon templates", e);
|
|
}
|
|
}
|
|
|
|
private void loadPlayer() {
|
|
try (InputStream is = getClass().getResourceAsStream("/data/players.json")) {
|
|
ObjectMapper mapper = new ObjectMapper();
|
|
JsonNode root = mapper.readTree(is);
|
|
JsonNode base = root.get("base");
|
|
playerTemplate = new PlayerTemplate(
|
|
(float) base.get("speed").asDouble(),
|
|
(float) base.get("maxHealth").asDouble(),
|
|
(float) base.get("invulnerableTime").asDouble(),
|
|
(float) base.get("respawnTime").asDouble(),
|
|
(float) base.get("size").asDouble()
|
|
);
|
|
} catch (Exception e) {
|
|
throw new RuntimeException("Failed to load player template", e);
|
|
}
|
|
}
|
|
|
|
public ZombieTemplate getZombieTemplate(String id) {
|
|
return zombieTemplates.get(id);
|
|
}
|
|
|
|
public Collection<ZombieTemplate> getAllZombieTemplates() {
|
|
return zombieTemplates.values();
|
|
}
|
|
|
|
public WeaponTemplate getWeaponTemplate(String id) {
|
|
return weaponTemplates.get(id);
|
|
}
|
|
|
|
public Collection<WeaponTemplate> getAllWeaponTemplates() {
|
|
return weaponTemplates.values();
|
|
}
|
|
|
|
public PlayerTemplate getPlayerTemplate() {
|
|
return playerTemplate;
|
|
}
|
|
|
|
public int getWeaponIndex(String id) {
|
|
int idx = 0;
|
|
for (String key : weaponTemplates.keySet()) {
|
|
if (key.equals(id)) return idx;
|
|
idx++;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
public String getWeaponId(int index) {
|
|
int idx = 0;
|
|
for (String key : weaponTemplates.keySet()) {
|
|
if (idx == index) return key;
|
|
idx++;
|
|
}
|
|
return weaponTemplates.keySet().iterator().next();
|
|
}
|
|
}
|