var fs = require('fs'); var path = require('path'); var data = require('./data/combatant.json') var list = { uses: 0, content: [] } var weaponLists = null; function getSpeciesList(set, category, species) { if(typeof(species) !== 'undefined') { var spList = species.split(','); var selections = []; for(var i = 0; i < spList.length; ++i) { var spName = category + '/' + spList[i]; var gen = set.getGenerator(spName); if(gen != null) { selections.push(gen); } } if(selections.length > 0) { return selections; } } if(--list.uses >= 0) { return list.content; } list.content = []; var keys = Object.keys(set.generators); for(var i = 0; i < keys.length; ++i) { var key = keys[i]; if(key.indexOf(category + '/') == 0) { var enabled = set.getMeta(key, 'combatant.enabled', false) var chance = set.getMeta(key, 'combatant.chance', 1.00); if(enabled == false) { continue; } if(chance <= 0.999 && Math.random() >= chance) { continue; } list.content.push(set.getGenerator(key)); } } if(list.content.length > 0) { list.uses = 32; return list.content; } else { return null; } } function getWeapons(set, fullId) { var weapons = data[fullId.split('/')[0]].weapons; var types = Object.keys(weapons); var hasWeapon = false; var result = {}; if(weaponLists == null) { weaponLists = {}; for(var i = 0; i < types.length; ++i) { var type = types[i]; var weaponNames = Object.keys(weapons[type]); var entry = {total: 0, items: []}; for(var j = 0; j < weaponNames.length; ++j) { entry.total += weapons[type][weaponNames[j]].chance; entry.items.push({name: weaponNames[j], data: weapons[type][weaponNames[j]]}); } weaponLists[type] = entry; } } while(!hasWeapon) { for(var i = 0; i < types.length; ++i) { var type = types[i]; var chance = set.getMeta(fullId, 'combatant.weapon.' + type + '.chance', 0.5); var weightList = weaponLists[type]; result[type] = null; if(Math.random() < chance) { var r = Math.random() * weightList.total; for(var j = 0; j < weightList.items.length; ++j) { var item = weightList.items[j]; r -= item.data.chance; if(r <= 0) { result[type] = item; hasWeapon = true; break; } } } } } return result; } function getItems(category) { var items = data[category].items; var keys = Object.keys(items); var result = []; for(var i = 0; i < keys.length; ++i) { var key = keys[i]; var item = items[key]; var amount = 0; if(Math.random() < item.chance) { amount = 1; while(amount < item.max) { if(Math.random() < item.more) { ++amount; } else { break; } } } if(amount > 0) { result.push({name: key, amount: amount}); } } return result; } function getAbiltiies(set, fullId) { var abilities = data[fullId.split('/')[0]].abilities; var abilityTypes = Object.keys(abilities); var sentinelPenalty = set.getMeta(fullId, 'combatant.ability.penalty.sentinel', 0.10); var sentinel = false; var result = []; for(var i = 0; i < abilityTypes.length; ++i) { var abilityType = abilityTypes[i]; var abilityChances = abilities[abilityType]; if(Math.random() > set.getMeta(fullId, 'combatant.ability.chance.' + abilityType, 0.10)) { continue; } var initialPenalty = set.getMeta(fullId, 'combatant.ability.penalty.initial.' + abilityType, 0.10); var incrementalPenalty = set.getMeta(fullId, 'combatant.ability.penalty.increment.' + abilityType, 0.10); var keys = Object.keys(abilityChances); for(var j = 0; j < keys.length; ++j) { var key = keys[j]; var penalty = initialPenalty + (incrementalPenalty * result.length) + (sentinel ? sentinelPenalty : 0) if(Math.random() < abilityChances[key] - penalty) { result.push(key); } } sentinel = true; } return result; } function makeSoldier(req, res, set) { var category = req.params.cat; var species = req.params.species; var agent = req.headers['user-agent']; var selections = []; var result = {}; // Validate input if(!data.hasOwnProperty(req.params.cat)) { res.status(404); res.send('ERROR 404: No combatant-generator data available for this category!\n'); return; } // Get generator to use var spList = getSpeciesList(set, category, species); if(spList == null || spList.length == 0) { res.status(500); res.send('ERROR 500: Somehow ended up with no species to pick from. That is not supposed to happen. D:\n'); return; } var gen = spList[Math.floor(Math.random() * spList.length)]; // Determine gender randomly. If it discrimates, blame Math.random! if(gen.genders.length > 1) { result.gender = gen.genders[Math.floor(Math.random() * gen.genders.length)]; } else { result.gender = null; } result.name = gen.generate('full_name', result.gender); result.species = gen.name; result.weapons = getWeapons(set, category + '/' + gen.id, req.query.hasOwnProperty('v')); result.abilities = getAbiltiies(set, category + '/' + gen.id, req.query.hasOwnProperty('v')); result.items = getItems(category); if(agent.indexOf('curl/') != -1 || req.query.hasOwnProperty('t')) { var text = result.name + " - " + result.species; if(result.gender != null) { text += ' ' + result.gender; } if(result.abilities.length > 0) { text += '\n\t' + result.abilities.join(', '); } if(result.weapons.primary != null) { var wp = result.weapons.primary; text += '\n\t' + wp.name + ' ' + wp.data.ammo + '/' + wp.data.ammo; } if(result.weapons.secondary != null) { var wp = result.weapons.secondary; text += '\n\t' + wp.name + ' ' + wp.data.ammo + '/' + wp.data.ammo; } for(var i = 0; i < result.items.length; ++i) { text += '\n\t' + result.items[i].name + ' x' + result.items[i].amount; } res.status(200); res.header("Content-Type", "text/plain; charset=utf-8"); res.end(text + '\n'); } else { res.status(200); res.header("Content-Type", "application/json; charset=utf-8"); res.end(JSON.stringify(result)); } } module.exports = function(set, app, data, scriptMethods) { app.get('/c/:cat', function(req, res) {makeSoldier(req, res, set)}); app.get('/c/:cat/:species', function(req, res) {makeSoldier(req, res, set)}); }