Files
zp1/backend/src/main/java/com/zombie/game/template/TemplateManager.java
2026-05-02 18:07:11 +08:00

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();
}
}