Template talk:Doom 3 map data

From DoomWiki.org

Source code for data collection[edit]

Primarily for error checking purposes, here is the source code I used to collect the map data.

<source lang="java"> import java.io.File; import java.io.FileNotFoundException; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Scanner; import java.util.SortedMap; import java.util.TreeMap;

public class Doom3MapData { final public static List<String> ENT_NAMES = getEntityNames(); final public static String TEMPLATE_NAME = "Doom 3 level data";

public static void main(String[] args) { // printTemplateCode(); if (args.length < 2) { System.out.println("args[0] = Folder path"); System.out.println("args[1, ..., n] = File names"); } else { final String folder = args[0]; for (int i = 1; i < args.length; i++) { final File f = new File(folder, args[i]); System.out.printf("==== %s ====%n", args[i]); try { System.out.println(parse(f)); } catch (FileNotFoundException e) { e.printStackTrace(); } } } }

public static String parse(File f) throws FileNotFoundException { final SortedMap<String, Count> map = new TreeMap<String, Count>(); final List<Entity> list = getEntityList(f); final List<String> devmapTargets = getDevmapTargets(f);

for (Entity e : list) { if (!devmapTargets.contains(e.name)) { // Exclude devmap entities if (map.containsKey(e.classname)) { map.get(e.classname).addEntity(e); } else { final Count c = new Count(); c.addEntity(e); map.put(e.classname, c); } } }

String output = String.format("{{%s%n", TEMPLATE_NAME); for (String key : map.keySet()) { if (ENT_NAMES.contains(key)) { final Count c = map.get(key); if (c.countsAreEqual()) { output += String.format("|%-33s = %d%n", key, c.getCount()); } else { output += String.format("|%-33s = %d%n", key + " easy", c.getCount(Count.Difficulty.EASY)); output += String.format("|%-33s = %d%n", key, c.getCount()); output += String.format("|%-33s = %d%n", key + " hard", c.getCount(Count.Difficulty.HARD)); } } }

for (String key : map.keySet()) { if (key.matches("(monster|weapon|ammo|item)_.+") && !ENT_NAMES.contains(key)) { System.err.printf("\"%s\" name missing%n", key); } } return output + "}}"; }

private static List<Entity> getEntityList(File f) throws FileNotFoundException { final List<Entity> list = new ArrayList<Entity>(); final Scanner sn = new Scanner(f); int braceDepth = 0;

// Entity info String classname = null, name = null; boolean notEasy = false, notMedium = false, notHard = false;

while (sn.hasNextLine()) { final String line = sn.nextLine(); final int depthChange = depthChange(line); braceDepth += depthChange; if (depthChange == 0) { if (braceDepth == 1) { if (line.matches("\\s*\"\\s*classname\\s*\"\\s*\"\\s*[^\\s]+\\s*\"\\s*")) { classname = line .replaceAll( "\\s*\"\\s*classname\\s*\"\\s*\"\\s*([^\\s]+)\\s*\"", "$1"); classname = classname.replaceAll( "^caverns_vagary[12]$", "monster_boss_vagary"); // Special case for zombie varieties if (classname.startsWith("monster_zombie_") && !classname.contains("_commando_") && !classname.endsWith("_fat") && !classname.endsWith("_bernie") && !classname.endsWith("_morgue")) { classname = "monster_zombie"; } } else if (line .matches("\\s*\"\\s*name\\s*\"\\s*\"\\s*[^\\s]+\\s*\"\\s*")) { name = line .replaceAll( "\\s*\"\\s*name\\s*\"\\s*\"\\s*([^\\s]+)\\s*\"\\s*", "$1"); } else if (line .matches("\\s*\"\\s*not_easy\\s*\"\\s*\"\\s*1\\s*\"\\s*")) { notEasy = true; } else if (line .matches("\\s*\"\\s*not_medium\\s*\"\\s*\"\\s*1\\s*\"\\s*")) { notMedium = true; } else if (line .matches("\\s*\"\\s*not_hard\\s*\"\\s*\"\\s*1\\s*\"\\s*")) { notHard = true; } } } else if (braceDepth == 0 && classname != null && name != null) { list.add(new Entity(classname, name, notEasy, notMedium, notHard)); classname = null; name = null; notEasy = false; notMedium = false; notHard = false; } } return list; }

private static List<String> getDevmapTargets(File f) throws FileNotFoundException { final Scanner sn = new Scanner(f); final List<String> targets = new ArrayList<String>(); String line; while (sn.hasNextLine()) { line = sn.nextLine(); if (line.matches("\\s*\"\\s*name\\s*\"\\s*\"\\s*devmap\\s*\"\\s*")) { break; } } while (sn.hasNextLine() && !(line = sn.nextLine()).contains("}")) { if (line.matches("\\s*\"\\s*target\\d*\\s*\"\\s*\"\\s*[^\\s]+\\s*\"\\s*")) { targets.add(line .replaceAll( "\\s*\"\\s*target\\d*\\s*\"\\s*\"\\s*([^\\s]+)\\s*\"\\s*", "$1")); } } return targets; }

public static int depthChange(String s) { int depth = 0, i = -1; while ((i = s.indexOf('{', i + 1)) > -1) { depth++; } while ((i = s.indexOf('}', i + 1)) > -1) { depth--; } return depth; }

public static List<String> getEntityNames() { final List<String> l = new ArrayList<String>(); l.add("monster_boss_cyberdemon"); l.add("monster_boss_guardian"); l.add("monster_boss_sabaoth"); l.add("monster_boss_vagary"); l.add("monster_demon_archvile"); l.add("monster_demon_cherub"); l.add("monster_demon_imp"); l.add("monster_demon_imp_crawler"); l.add("monster_demon_hellknight"); l.add("monster_demon_maggot"); l.add("monster_demon_mancubus"); l.add("monster_demon_pinky"); l.add("monster_demon_revenant"); l.add("monster_demon_tick"); l.add("monster_demon_trite"); l.add("monster_demon_wraith"); l.add("monster_flying_cacodemon"); l.add("monster_flying_lostsoul"); l.add("monster_zombie"); l.add("monster_zombie_bernie"); l.add("monster_zombie_fat"); l.add("monster_zombie_morgue"); l.add("monster_zombie_commando"); l.add("monster_zombie_commando_cgun"); l.add("monster_zsec_machinegun"); l.add("monster_zsec_pistol"); l.add("monster_zsec_shield"); l.add("monster_zsec_shotgun"); l.add("weapon_flashlight"); l.add("weapon_pistol"); l.add("weapon_shotgun"); l.add("weapon_machinegun"); l.add("weapon_chaingun"); l.add("weapon_handgrenade"); l.add("weapon_plasmagun"); l.add("weapon_rocketlauncher"); l.add("weapon_bfg"); l.add("weapon_chainsaw"); l.add("ammo_bullets_small"); l.add("ammo_bullets_large"); l.add("ammo_shells_small"); l.add("ammo_shells_large"); l.add("ammo_clip_small"); l.add("ammo_clip_large"); l.add("ammo_belt_small"); l.add("ammo_cells_small"); l.add("ammo_cells_large"); l.add("ammo_rockets_small"); l.add("ammo_rockets_large"); l.add("ammo_bfg_small"); l.add("item_aircannister"); l.add("item_backpack"); l.add("item_medkit_small"); l.add("item_medkit"); l.add("item_armor_shard"); l.add("item_armor_security"); l.add("item_pda"); l.add("item_videocd"); l.add("powerup_adrenaline"); l.add("powerup_berserk"); return l; }

public static void printTemplateCode() { for (String key : ENT_NAMES) { System.out .printf("%n| %1$s%n| style=\"text-align: center;\" | {{{%1$s}}}%n|-%n%n", key); } } }

class Entity { final public String classname, name; final public boolean notEasy, notMedium, notHard;

Entity(String classname, String name, boolean notEasy, boolean notMedium, boolean notHard) { this.classname = classname; this.name = name; this.notEasy = notEasy; this.notMedium = notMedium; this.notHard = notHard; } }

class Count { public enum Difficulty { EASY, MEDIUM, HARD };

final private Map<Difficulty, Integer> map;

Count() { map = new HashMap<Difficulty, Integer>(); for (Difficulty d : Difficulty.values()) { map.put(d, 0); } }

public void addEntity(Entity e) { if (!e.notEasy) { map.put(Difficulty.EASY, map.get(Difficulty.EASY) + 1); } if (!e.notMedium) { map.put(Difficulty.MEDIUM, map.get(Difficulty.MEDIUM) + 1); } if (!e.notHard) { map.put(Difficulty.HARD, map.get(Difficulty.HARD) + 1); } }

public int getCount() { return map.get(Difficulty.values()[0]); }

public int getCount(Difficulty d) { return map.get(d); }

public boolean countsAreEqual() { final Difficulty[] ds = Difficulty.values(); final int firstValue = map.get(ds[0]); for (int i = 1; i < ds.length; i++) { if (firstValue != map.get(ds[i])) { return false; } } return true; } } </source>

Shidou 11:40, 8 April 2012 (UTC)