All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.rpgframework.random.RollTableGenerator Maven / Gradle / Ivy

The newest version!
package de.rpgframework.random;

import java.io.InputStream;
import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Random;
import java.util.StringTokenizer;

import org.prelle.simplepersist.Persister;

import de.rpgframework.MultiLanguageResourceBundle;
import de.rpgframework.classification.ActorRole;
import de.rpgframework.classification.Classification;
import de.rpgframework.classification.Gender;
import de.rpgframework.classification.Genre;
import de.rpgframework.classification.TagAge;
import de.rpgframework.genericrpg.data.Decision;
import de.rpgframework.genericrpg.modification.Modification;
import de.rpgframework.genericrpg.modification.ValueModification;

/**
 * @author prelle
 *
 */
public abstract class RollTableGenerator {

	private final static Logger logger = System.getLogger("rpgframework.random");

	protected static Persister serializer;
	protected static Random random = new Random();

	protected Map tables;
	protected MultiLanguageResourceBundle res;

	//-------------------------------------------------------------------
	static {
		serializer   = new Persister();
	}

	//-------------------------------------------------------------------
	/**
	 */
	public RollTableGenerator(MultiLanguageResourceBundle res) {
		this.res = res;
		tables = new HashMap<>();
	}

	//-------------------------------------------------------------------
	protected void loadTables(InputStream stream) {
		try {
			RollTableList loaded = serializer.read(RollTableList.class, stream);
			logger.log(Level.INFO, "Loaded "+loaded.size()+" tables");
			for (RollTable tmp : loaded) {
				tables.put(tmp.id, tmp);
			}
		} catch (Exception e) {
			logger.log(Level.ERROR, "Failed loading roll tables",e);
		}
	}

	//-------------------------------------------------------------------
	protected abstract GeneratorVariable resolveModifier(String name);

	//-------------------------------------------------------------------
	protected List> parseVariables(String line) {
		List> ret = new ArrayList<>();
		StringTokenizer tok = new StringTokenizer(line, ",; ");
		while (tok.hasMoreTokens()) {
			String keyValue = tok.nextToken();
			String[] pair = keyValue.split(":");
			switch (pair[0]) {
			case "AGE"   : ret.add(TagAge.valueOf(pair[1])); break;
			case "GENDER": ret.add(Gender.valueOf(pair[1])); break;
			case "GENRE" : ret.add(Genre.valueOf(pair[1])); break;
			case "ROLE"  : ret.add(ActorRole.valueOf(pair[1])); break;
			}
		}
		return ret;
	}

	//-------------------------------------------------------------------
	protected List parseModifier(String line) {
		List ret = new ArrayList<>();
		StringTokenizer tok = new StringTokenizer(line, ",; ");
		while (tok.hasMoreTokens()) {
			String keyValue = tok.nextToken();
			String[] pair = keyValue.split(":");
			try {
				GeneratorVariable var = resolveModifier(pair[0]);
				logger.log(Level.INFO,"-----------> "+var+" = "+pair[1]);
			} catch (IllegalArgumentException e) {
			}
		}
		return ret;
	}

//	//-------------------------------------------------------------------
//	protected void loadTables(String resourceName) {
//		loadTables(getClass().getResourceAsStream(resourceName));
//	}

	//-------------------------------------------------------------------
	public static int rollD6(int amount) {
		int sum = 0;
		for (int i=0; i> hints = new ArrayList<>(List.of(instr.getRole()));
			hints.addAll( node.getHints());
			if (instr.getVariables()!=null && !instr.getVariables().isBlank()) {
				// Parse as variables
				hints.addAll(parseVariables(instr.getVariables()));
//				// Parse as modifier
//				parseModifier(instr.getVariables());
			}
			Actor actor = (Actor) RandomGeneratorRegistry.generate(GeneratorType.NSC, List.of(), hints, node.getVariables());
			logger.log(Level.DEBUG, "Actor = "+actor);
			node.addActor(actor);
			subNode = actor;
		}


		/*
		 * Check for existence of subtables
		 */
		for (RollTable sub : result.getSubtables()) {
			logger.log(Level.DEBUG, "Execute subtable "+sub.id);
			rollSubtable(sub, subNode, loc, line, i18nKey);
		}

		// Find text
		String nextTable = table.nextTable;
		if (result.getNextTable()!=null)
			nextTable = result.getNextTable();

		if (nextTable==null) {
			logger.log(Level.DEBUG, "No next table - stop after "+table.id);
			return;
		} else {
			RollTable next = tables.get(nextTable);
			if ( next==null) {
				logger.log(Level.ERROR, "After table '"+table.id+"' the next table '"+nextTable+"' cannot be found");
				return;
			}

			roll(next, node, loc);
		}
	}

	//-------------------------------------------------------------------
	public void simpleRoll(RollTable table, VariableHolderNode node, Locale loc) {
		int count = table.draw>0 ? table.draw : 1;

		RollResult result = null;
		for (int i=0; i0) value += rollD6(table.d6);
			if (table.d20>0) value += rollD20(table.d20);
			if (table.d00>0) value += rollD100(table.d00);

			// Modifiers
			for (String modName : table.getModifierNames()) {
				GeneratorVariable mod = resolveModifier(modName);
				if (mod!=null) {
					int modVal = node.getVariable(mod);
					logger.log(Level.DEBUG,"Modify result by "+modName+"="+modVal);
					value += modVal;
				}
			}

			result = table.getResultFor(value);
			if (result==null) {
				logger.log(Level.ERROR, "Failed on table {0} - no result for {1}",table.id, value);
				return;
			}
			logger.log(Level.INFO, "Roll {0} resulted in {1}", value, result);

			String i18nKey = result.getId();
			//Derive variable name from table
			String varName = table.id.toUpperCase(loc);
			GeneratorVariable variable = resolveModifier(varName);
			node.setVariable(variable, new StringGeneratorVariableValue(null, variable, i18nKey));

//			/*
//			 * Check for existence of subtables
//			 */
//			logger.log(Level.DEBUG, "Now subtables of "+result.getId());
//			for (RollTable sub : result.getSubtables()) {
//				int dice = random.nextInt(sub.getResults().size());
//				RollResult subResult = sub.getResults().get(dice);
//				logger.log(Level.INFO, "  {0} = {1}", sub.getId(), subResult.getId());
//				i18nKey = subResult.getId();
//				String varName2 = sub.id.toUpperCase(loc);
//				node.setVariable(resolveModifier(varName2), i18nKey);
//			}
		}

//		// Variables
//		for (Modification mod : result.getModifications()) {
//			if (mod instanceof ValueModification) {
//				ValueModification vMod = (ValueModification)mod;
//				if ("VARIABLE".equals(vMod.type)) {
//					String var = vMod.getVariable();
//					GeneratorVariable modifier = resolveModifier(var);
//					if (modifier==null) {
//						logger.log(Level.WARNING, "Unknown variable '"+var+"' in rolltable '"+table.id+"'");
//					} else {
//						Object val = vMod.getValue();
//						if (Integer.class.isAssignableFrom(val.getClass())) {
//							node.addVariable(modifier, (int)val);
//							logger.log(Level.DEBUG, "Added variable "+var+" "+vMod.getRawValue()+" to node "+node.getI18n());
//						} else {
//							try {
//								int ii = Integer.parseInt(String.valueOf(val));
//								node.addVariable(modifier, ii);
//								logger.log(Level.DEBUG, "Added variable "+var+" "+ii+" to node "+node.getI18n());
//							} catch (NumberFormatException e) {
//								logger.log(Level.DEBUG, "Failed to addvariable "+var+" ("+var.getClass()+") "+vMod.getRawValue()+" to node "+node.getI18n());
//							}
//						}
//					}
//				}
//			}
//		}

		/*
		 * Shall actors be created?
		 */
//		VariableHolderNode subNode = node;
//		if (result.getAddActor()!=null) {
//			AddActorInstruction instr = result.getAddActor();
//			logger.log(Level.INFO, "All hints so far: "+node.getHints());
//			List> hints = new ArrayList<>(List.of(instr.getRole()));
//			hints.addAll( node.getHints());
//			if (instr.getVariables()!=null && !instr.getVariables().isBlank()) {
//				// Parse as variables
//				hints.addAll(parseVariables(instr.getVariables()));
////				// Parse as modifier
////				parseModifier(instr.getVariables());
//			}
//			Actor actor = (Actor) RandomGeneratorRegistry.generate(GeneratorType.NSC, List.of(), hints, node.getVariables());
//			logger.log(Level.DEBUG, "Actor = "+actor);
//			node.addActor(actor);
//			subNode = actor;
//		}


		// Find text
		String nextTable = table.nextTable;
		if (result.getNextTable()!=null)
			nextTable = result.getNextTable();

		if (nextTable==null) {
			logger.log(Level.DEBUG, "No next table - stop after "+table.id);
			return;
		} else {
			RollTable next = tables.get(nextTable);
			if ( next==null) {
				logger.log(Level.ERROR, "After table '"+table.id+"' the next table '"+nextTable+"' cannot be found");
				return;
			}

			simpleRoll(next, node, loc);
		}
	}

	//-------------------------------------------------------------------
	private void rollSubtable(RollTable table, VariableHolderNode node, Locale loc, TextLine line, String prefix) {
		int d6 = table.d6;
		int value = rollD6(d6);
		RollResult result = table.getResultFor(value);
		if (result==null) {
			logger.log(Level.ERROR, "Failed on table "+table.id);
			return;
		}

		String i18nKey = prefix+"."+ table.id+"."+result.getId();

		logger.log(Level.INFO, res.getString(i18nKey, loc));
		line.addText(i18nKey);

		// Variables
		for (Modification mod : result.getOutgoingModifications()) {
			if (mod instanceof ValueModification) {
				ValueModification vMod = (ValueModification)mod;
				logger.log(Level.ERROR, "TODO: "+vMod);
//				if ("VARIABLE".equals(vMod.type)) {
//					String var = vMod.getVariable();
//					GeneratorVariable modifier = resolveModifier(var);
//					if (modifier==null) {
//						logger.log(Level.WARNING, "Unknown modifier '"+var+"' in rolltable '"+table.id+"'");
//					} else {
//						Object val = vMod.getValue();
//						if (val instanceof Integer)
//							node.addVariable(null, (int)val);
//						logger.log(Level.DEBUG, "Added modifier "+var+" "+vMod.getRawValue());
//					}
//				}
			}
		}
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy