@ -12,7 +12,7 @@ function handleIframeLoad(frameName)
if ( frame != null )
{
result = frame . document . getElementsByTagName ( "pre" ) [ 0 ] . innerHTML ;
// The form's onload handler gets called when the main page is first loaded as well.
// We detect this condition by checking if the iframes contents are not empty.
if ( result . length > 0 ) {
@ -32,7 +32,7 @@ function handleIframeLoad(frameName)
scope . loadCurrentCharacterFromStruct ( charStruct ) ;
}
) ;
}
}
catch ( e ) {
console . log ( "Loading character failed: " + e ) ;
scope . $apply (
@ -72,7 +72,7 @@ burningModule.run(function($rootScope, $location, $anchorScroll, $routeParams) {
$rootScope . $on ( '$routeChangeSuccess' , function ( newRoute , oldRoute ) {
if ( $routeParams . scrollTo ) {
$location . hash ( $routeParams . scrollTo ) ;
$anchorScroll ( ) ;
$anchorScroll ( ) ;
}
} ) ;
} ) ;
@ -92,7 +92,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
selected item at that level .
index : The starting level in the hierarchy for which we should recalculate the lower levels
of the lists .
* /
* /
$scope . calculateHierarchyListForSelectN = function ( listForSelect , currentItem , index ) {
if ( index < 1 )
return ;
@ -100,7 +100,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
while ( index < 3 ) {
if ( ! currentItem [ index - 1 ] || ! currentItem [ index - 1 ] . resources ) {
listForSelect [ index ] = [ ] ;
listForSelect [ index ] = [ ] ;
currentItem [ index ] = { } ;
}
else {
@ -118,7 +118,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
$scope . enforcePointLimits = settings . enforcePointLimits
/* A list of DisplayLifepath. */
$scope . selectedLifepaths = [ ] ;
$scope . selectedLifepaths = [ ] ;
$scope . statNames = [ "Will" , "Perception" , "Power" , "Forte" , "Agility" , "Speed" ] ;
$scope . stats = [ ] ;
@ -160,7 +160,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
}
} ;
// Setting names for use in the Add Lifepath section
$scope . settingNames = [ "Loading..." ]
$scope . settingNames = [ ] ;
$scope . currentSettingLifepathNames = [ ] ;
// The currently selected lifepath
$scope . currentSettingLifepath = "Loading..." ;
@ -195,7 +195,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
$scope . reputations = { } ;
// Hash containing total stat points categorized by
// Hash containing total stat points categorized by
// type (physical, mental, either)
$scope . totalStatPoints = { "physical" : 0 , "mental" : 0 , "either" : 0 }
$scope . unspentStatPoints = { "physical" : 0 , "mental" : 0 , "either" : 0 }
@ -206,12 +206,6 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
// Character name
$scope . name = "" ;
// Character stock. One of man, dwarf, orc, elf
if ( ! isValidStock ( stock ) ) {
console . log ( "Invalid stock '" + stock + "' passed to BurningCtrl.initialize. Defaulting to man" ) ;
stock = "man" ;
}
$scope . stock = stock ;
// Character id (server side id)
@ -247,7 +241,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
/* Traits that are on the character's lifepaths, but not necessarily taken */
$scope . lifepathTraits = { } ;
/ * M o d i f i e r s t o a t t r i b u t e s b a s e d o n t h e a n s w e r s t o q u e s t i o n s . T h i s a p p l i e s t o G r e e d , S t e e l , e t c .
/ * M o d i f i e r s t o a t t r i b u t e s b a s e d o n t h e a n s w e r s t o q u e s t i o n s . T h i s a p p l i e s t o G r e e d , S t e e l , e t c .
The hash is keyed by attribute name , and the value is a list of yes / no questions , their answers ,
and the modifier applied for a yes answer .
* /
@ -255,11 +249,11 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
$scope . attributeBonuses = { } ;
/ * U s e d t o k e e p t r a c k o f w h e t h e r t h e u s e r s h a d e - s h i f t e d a n a t t r i b u t e , f o r t h o s e a t t r i b u t e s t h a t
/ * U s e d t o k e e p t r a c k o f w h e t h e r t h e u s e r s h a d e - s h i f t e d a n a t t r i b u t e , f o r t h o s e a t t r i b u t e s t h a t
allow shade shifting * /
$scope . attributeShade = { 'Steel' : 'B' , 'Grief' : 'B' , 'Greed' : 'B' , 'Hatred' : 'B' , 'Spite' : 'B' } ;
$scope . ptgs = new PTGS ( ) ;
$scope . ptgs = new PTGS ( ) ;
/* List of traits to show in the Choose Special Trait dropdown */
$scope . specialTraitsForDisplay = [ ] ;
@ -287,22 +281,22 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
} ;
$scope . characterStorage = characterStorage
$scope . resourceAdderToShow = 'gear' ;
// If this is true, then the user had added a lifepath to an Orc character that added a
// If this is true, then the user had added a lifepath to an Orc character that added a
// brutal life trait, and then the character removed that lifepath. According to the rules
// they can never gain more lifepaths after this action.
$scope . brutalLifeWithdrawn = false ;
calculateGearSelectionLists ( $scope , burningData ) ;
calculatePropertySelectionLists ( $scope , burningData ) ;
$scope . serverSettings = serverSettings ;
}
$scope . initialize ( "man" ) ;
$scope . initialize ( ) ;
if ( characterStorage . currentCharacter ) {
//console.log("Loading current character");
@ -354,7 +348,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
}
return result ;
}
$scope . onGenderChange = function ( ) {
if ( $scope . name . length == 0 ) {
@ -364,20 +358,32 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
}
$scope . onStockChange = function ( ) {
if ( ! $scope . stock ) return ;
if ( ! $scope . stockSelected ) {
$scope . stocks . shift ( ) ;
$scope . stockSelected = true ;
}
var oldName = $scope . name ;
// Make a blank character sheet
$scope . initialize ( $scope . stock ) ;
if ( oldName . length == 0 ) {
$scope . generateName ( ) ;
} else {
$scope . name = oldName ;
if ( ! burningData . lifepaths [ $scope . stock ] ) {
burningData . loadLifepathsForStock ( $scope . stock ) ;
}
if ( ! burningData . resources [ $scope . stock ] ) {
burningData . loadResourcesForStock ( $scope . stock ) ;
}
// TODO: technically a bug — only want this registered once per stock...
burningData . registerStockEvent ( $scope . stock , "lifepathsLoaded" , function ( ) {
// Make a blank character sheet
$scope . initialize ( $scope . stock ) ;
calculateSettingNames ( $scope , burningData ) ;
calculateCurrentSettingLifepathNames ( $scope , burningData ) ;
calculateSpecialTraitsForDisplay ( $scope , burningData ) ;
if ( oldName . length == 0 ) {
$scope . generateName ( ) ;
} else {
$scope . name = oldName ;
}
calculateSettingNames ( $scope , burningData ) ;
calculateCurrentSettingLifepathNames ( $scope , burningData ) ;
calculateSpecialTraitsForDisplay ( $scope , burningData ) ;
} ) ;
}
$scope . onSettingChange = function ( ) {
@ -403,8 +409,10 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
calculateUnspentSkillPoints ( $scope ) ;
}
burningData . registerOnAllDatasetsLoaded ( function ( ) {
onLifepathsLoad ( $scope , burningData ) ;
burningData . registerEvent ( "stocksLoaded" , function ( ) {
$scope . stocks = [ { name : "Select a stock" } ]
$scope . stocks = $scope . stocks . concat ( Object . values ( burningData . stocks ) ) ;
$scope . stockSelected = false ;
} ) ;
$scope . $on ( '$locationChangeStart' , function ( event , nextUrl , currentUrl ) {
@ -426,11 +434,11 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
$scope . onAddLifepathClick = function ( ) {
// Find the current lifepath info in the lifepaths
var setting = burningData . lifepaths [ $scope . stock ] [ $scope . currentSetting ] ;
if ( ! setting )
if ( ! setting )
return ;
var lifepath = setting [ $scope . currentSettingLifepath ] ;
if ( ! lifepath )
if ( ! lifepath )
return ;
displayLp = new DisplayLifepath ( $scope . currentSetting , $scope . currentSettingLifepath , lifepath ) ;
@ -449,7 +457,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
$scope . chooseStatPenalties ( displayLp , - penalty ) ;
}
// If the lifepath contains 'Appropriate Weapons', ask the
// If the lifepath contains 'Appropriate Weapons', ask the
// user to choose those weapons.
if ( appropriateWeapons . hasAppropriateWeapons ( displayLp ) ) {
var appropriate = appropriateWeapons . appropriateWeapons [ displayLp . name ] ;
@ -466,7 +474,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
}
}
// If the lifepath contains 'Weapon Of Choice', ask the
// If the lifepath contains 'Weapon Of Choice', ask the
// user to choose the weapon.
if ( weaponOfChoice . hasWeaponOfChoice ( displayLp ) ) {
weaponOfChoice . selectWeaponOfChoice ( displayLp , function ( ) {
@ -487,7 +495,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
displayLp . calculateResourcePoints ( prevLifepath ) ;
displayLp . calculateGeneralSkillPoints ( prevLifepath ) ;
displayLp . modifyForDiminishingReturns ( $scope . selectedLifepaths ) ;
displayLp . modifyForDiminishingReturns ( $scope . selectedLifepaths ) ;
if ( $scope . stock == "orc" ) {
displayLp . applyBrutalLife ( $scope . selectedLifepaths ) ;
}
@ -551,7 +559,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
calculateUnspentResourcePoints ( $scope ) ;
applyBonusesFromTraits ( $scope ) ;
}
$scope . incrementStat = function ( stat ) {
// Man stock has max 8 pts in any stat
@ -578,7 +586,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
if ( specificStatPoints <= 0 && eitherStatPoints <= 0 && $scope . enforcePointLimits )
return ;
if ( specificStatPoints > 0 ) {
specificStatPoints -= 1 ;
stat . setSpecificPointsSpent ( stat . specificPointsSpent ( ) + 1 ) ;
@ -591,10 +599,10 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
$scope . unspentStatPoints . either = eitherStatPoints ;
if ( "m" == stat . type ) {
$scope . unspentStatPoints . mental = specificStatPoints ;
}
}
else if ( "p" == stat . type ) {
$scope . unspentStatPoints . physical = specificStatPoints ;
}
}
calculatePTGS ( $scope ) ;
}
@ -611,15 +619,15 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
}
else {
var specificStatPoints = 0 ;
stat . setSpecificPointsSpent ( stat . specificPointsSpent ( ) - 1 ) ;
if ( "m" == stat . type ) {
$scope . unspentStatPoints . mental += 1 ;
}
}
else if ( "p" == stat . type ) {
$scope . unspentStatPoints . physical += 1 ;
}
}
else {
console . log ( "Error: Unknown stat type " + stat . type + " passed to decrementStat for stat " + stat . name ) ;
// Undo the decrement
@ -672,10 +680,10 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
$scope . unspentStatPoints . either = eitherStatPoints ;
if ( "m" == stat . type ) {
$scope . unspentStatPoints . mental = specificStatPoints ;
}
}
else if ( "p" == stat . type ) {
$scope . unspentStatPoints . physical = specificStatPoints ;
}
}
}
var toBlack = function ( stat ) {
@ -690,7 +698,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
else {
console . log ( "Error: Unknown stat type " + stat . type + " passed to incrementStat for stat " + stat . name ) ;
return ;
}
}
var cost = 5 ;
@ -773,7 +781,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
cost -= toTake ;
}
if ( cost > 0 && ( $scope . unspentSkillPoints [ "general" ] > 0 || ! $scope . enforcePointLimits ) )
{
$scope . unspentSkillPoints [ "general" ] -= cost ;
@ -789,11 +797,11 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
// If this skill is required to be open, do not allow
// unchecking
var required = skillsRequiredToBeOpened ( $scope . selectedLifepaths )
if ( skill . name in required ) {
if ( skill . name in required ) {
checkbox . checked = true ;
return ;
}
if ( skill . generalPointsSpent > 0 ) {
$scope . unspentSkillPoints . general += skill . generalPointsSpent ;
skill . generalPointsSpent = 0 ;
@ -889,7 +897,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
if ( endsWith ( wiseName , "-wise" ) ) {
wiseName = wiseName . substring ( 0 , wiseName . length - 5 ) ;
}
wiseName = capitalizeEachWord ( wiseName ) + "-wise" ;
$scope . generalSkills [ wiseName ] = new DisplaySkill ( wiseName , burningData . skills ) ;
@ -899,7 +907,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
general skills selected by the user * /
$scope . isGeneralSkill = function ( displaySkill ) {
return ( displaySkill . name in $scope . generalSkills ) ;
}
/* Given the passed display skill, remove it from the list of general skills */
@ -908,7 +916,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
calculateUnspentSkillPoints ( $scope ) ;
}
// Return a hash containing all skills
// Return a hash containing all skills
$scope . allSelectedSkills = function ( ) {
var result = { }
for ( var key in $scope . lifepathSkills ) {
@ -921,15 +929,15 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
}
// Return a list of skill names that the character can choose
// from to add a general skill. This is all skills less the
// skills the character already has, and less the skills that
// from to add a general skill. This is all skills less the
// skills the character already has, and less the skills that
// are not allowed for the character's stock.
$scope . selectableGeneralSkills = function ( ) {
var result = [ ] ;
for ( var key in burningData . skills ) {
if ( ! ( key in $scope . lifepathSkills ) && ! ( key in $scope . generalSkills ) ) {
var displaySkill = burningData . skills [ key ] ;
if ( ! displaySkill . stock || restrictionStockToValidStock ( displaySkill . stock ) == $scope . stock ) {
if ( ! displaySkill . stock || restrictionStockToValidStock ( burningData . stocks , displaySkill . stock ) == $scope . stock ) {
result . push ( key ) ;
}
}
@ -1024,20 +1032,9 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
return { "shade" : "" , "exp" : 10 - $scope . statsByName [ "Will" ] . exp ( ) + bonus } ;
}
else if ( "Stride" == name ) {
var stride = 0 ;
if ( $scope . stock == 'dwarf' )
stride = 6 ;
else if ( $scope . stock == 'elf' )
stride = 8 ;
else if ( $scope . stock == 'roden' )
stride = 8 ;
else if ( $scope . stock == 'wolf' )
stride = 11 ;
else
stride = 7 ;
// This is a hack: if stock is unselected, use 0 for stride to not throw error; it shouldn't be displayed anyway
var stride = $scope . stock ? burningData . stocks [ $scope . stock ] . stride : 0 ;
stride += bonus ;
return { "shade" : "" , "exp" : stride } ;
}
else if ( "Circles" == name ) {
@ -1054,13 +1051,13 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
for ( var i = 0 ; i < property . length ; i ++ ) {
sum += property [ i ] . cost ;
}
if ( sum >= 50 ) {
v += 1 ;
}
v += bonus ;
return { "shade" : "B" , "exp" : v } ;
}
else if ( "Resources" == name ) {
@ -1140,7 +1137,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
// Divide physical between each physical stat
var physicalBuckets = divideIntoBuckets ( $scope . totalStatPoints . physical , 4 ) ;
var physicalEitherBuckets = divideIntoBuckets ( eitherBuckets [ 1 ] , 4 ) ;
$scope . statsByName . Will . mentalPointsSpent = mentalBuckets [ 0 ] ;
$scope . statsByName . Will . eitherPointsSpent = mentalEitherBuckets [ 1 ] ;
$scope . statsByName . Perception . mentalPointsSpent = mentalBuckets [ 1 ] ;
@ -1162,7 +1159,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
}
if ( sum != $scope . totalStatPoints . either + $scope . totalStatPoints . mental + $scope . totalStatPoints . physical ) {
console . log ( "Error: Calculation in distributeStats is incorrect." ) ;
for ( var i = 0 ; i < $scope . stats . length ; i ++ ) {
$scope . stats [ i ] . physicalPointsSpent = 0 ;
$scope . stats [ i ] . mentalPointsSpent = 0 ;
@ -1189,30 +1186,6 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
return list ;
}
/ *
$scope . specialTraitsForDisplay = function ( ) {
var list = [ ] ;
for ( var traitName in burningData . traits ) {
var trait = burningData . traits [ traitName ] ;
if ( 'restrict' in trait ) {
if ( trait . restrict . indexOf ( validStockToRestrictionStock ( $scope . stock ) ) >= 0 &&
( trait . restrict . indexOf ( "special" ) >= 0 || trait . restrict . indexOf ( "character" ) >= 0 ) ) {
list . push ( new DisplayTrait ( traitName , burningData . traits ) ) ;
}
} else {
// No restriction! As long as cost > 0 (cost 0 is for traits with no cost; not purchaseable)
if ( trait . cost > 0 ) {
list . push ( new DisplayTrait ( traitName , burningData . traits ) ) ;
}
}
}
return list ;
}
* /
$scope . addLifepathTrait = function ( traitName ) {
if ( $scope . unspentTraitPoints < 1 && $scope . enforcePointLimits )
@ -1403,7 +1376,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
} ) ;
}
// Launch a download for the current character. Since Javascript can't really
// Launch a download for the current character. Since Javascript can't really
// launch a download using data from javascript, we need to pass the current character
// to the server which sends a filename back to a hidden iframe which then launches the download.
$scope . downloadCurrentCharacter = function ( ) {
@ -1534,7 +1507,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
}
$scope . addResource = function ( type ) {
var resource = null ;
var resourceHash = null ;
if ( type == 'relationship' ) {
@ -1603,7 +1576,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
calculateUnspentResourcePoints ( $scope ) ;
}
$scope . addSelectListGear = function ( ) {
var name = "" ;
var cost = 0 ;
@ -1623,7 +1596,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
}
}
}
$scope . currentGearDesc = name ;
$scope . currentGearCost = cost ;
$scope . addResource ( 'gear' ) ;
@ -1648,7 +1621,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
}
}
}
$scope . currentPropertyDesc = name ;
$scope . currentPropertyCost = cost ;
$scope . addResource ( 'property' ) ;
@ -1713,7 +1686,7 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
}
$scope . answerEmotionalAttributeQuestions = function ( attributeName ) {
// If the character already has some or all of the questions answered, pass those in.
// Otherwise generate new ones.
@ -1738,9 +1711,9 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
displayEmotionalMath : function ( ) {
return serverSettings . displayAttrMath ;
} ,
}
}
} ) ;
modalInstance . result . then ( function ( selected ) {
$scope . attributeModifierQuestionResults [ attributeName ] = selected ;
} , function ( ) {
@ -1838,12 +1811,12 @@ function BurningCtrl($scope, $http, $modal, $timeout, settings, appropriateWeapo
}
$scope . showUploadCharacterModal = function ( ) {
var modalInstance = $modal . open ( {
templateUrl : '/upload_character_partial' ,
controller : UploadCharacterModalCtrl
} ) ;
modalInstance . result . then ( function ( ) {
console . log ( "Modal: Uploaded character" ) ;
} , function ( ) {
@ -1953,7 +1926,7 @@ function calculateAge($scope){
function calculateSettingNames ( $scope , burningData ) {
var settingNames = null ;
var lastCurrentSetting = $scope . currentSetting ;
var lastCurrentSetting = $scope . currentSetting ;
if ( ! $scope . enforceLifepathReqts ) {
// Display all settings and subsettings
@ -2030,8 +2003,8 @@ function calculateCurrentSettingLifepathNames($scope, burningData){
var currentSettingLifepathNames = null ;
if ( $scope . enforceLifepathReqts ) {
//console.log("calculateCurrentSettingLifepathNames: enforce lifepath requirements is enabled");
currentSettingLifepathNames = [ ] ;
//console.log("calculateCurrentSettingLifepathNames: enforce lifepath requirements is enabled");
currentSettingLifepathNames = [ ] ;
var all = Object . keys ( burningData . lifepaths [ $scope . stock ] [ $scope . currentSetting ] )
// Filter out the names that are not allowed based on the character's lifepaths.
if ( $scope . selectedLifepaths . length == 0 ) {
@ -2056,11 +2029,11 @@ function calculateCurrentSettingLifepathNames($scope, burningData){
//console.log(settingName + ":" + lifepathName + " allowed: " + (result[0] ? "yes" : "no"));
//console.log("rexpr: " + rexpr);
if ( result [ 0 ] ) {
//console.log("calculateCurrentSettingLifepathNames: added because lifepath has reqts, which are met: " + lifepathName);
//console.log("calculateCurrentSettingLifepathNames: added because lifepath has reqts, which are met: " + lifepathName);
currentSettingLifepathNames . push ( lifepathName ) ;
}
else {
//console.log("calculateCurrentSettingLifepathNames: not added because lifepath has reqts, which not are met: " + lifepathName);
//console.log("calculateCurrentSettingLifepathNames: not added because lifepath has reqts, which not are met: " + lifepathName);
}
}
else {
@ -2069,7 +2042,7 @@ function calculateCurrentSettingLifepathNames($scope, burningData){
}
}
}
}
else {
currentSettingLifepathNames = Object . keys ( burningData . lifepaths [ $scope . stock ] [ $scope . currentSetting ] ) ;
}
@ -2092,7 +2065,7 @@ function calculateCurrentSettingLifepathNames($scope, burningData){
}
function calculateTotalStatPoints ( $scope , burningData ) {
var totalStatPoints = { "physical" : 0 , "mental" : 0 , "either" : 0 } ;
$scope . totalStatPoints = { "physical" : 0 , "mental" : 0 , "either" : 0 } ;
@ -2123,10 +2096,10 @@ function calculateTotalStatPoints($scope, burningData){
Preconditions : totalStatPoints is up to date .
* /
function calculateUnspentStatPoints ( $scope ) {
var unspentStatPoints = {
"physical" : $scope . totalStatPoints . physical ,
"mental" : $scope . totalStatPoints . mental ,
"physical" : $scope . totalStatPoints . physical ,
"mental" : $scope . totalStatPoints . mental ,
"either" : $scope . totalStatPoints . either
}
@ -2149,7 +2122,7 @@ function calculateLifepathSkills($scope, burningData, appropriateWeapons){
for ( var i = 0 ; i < $scope . selectedLifepaths . length ; i ++ ) {
var displayLp = $scope . selectedLifepaths [ i ] ;
appropriateWeapons . replaceAppropriateWeaponsUsingSaved ( displayLp ) ;
displayLp . replaceWeaponOfChoice ( ) ;
@ -2158,7 +2131,7 @@ function calculateLifepathSkills($scope, burningData, appropriateWeapons){
if ( name != "General" ) {
lifepathSkills [ name ] = new DisplaySkill ( name , burningData . skills ) ;
}
}
}
}
$scope . lifepathSkills = lifepathSkills ;
@ -2178,20 +2151,20 @@ function calculateTotalSkillPoints($scope){
function calculateUnspentSkillPoints ( $scope ) {
var unspentSkillPoints = {
"lifepath" : $scope . totalSkillPoints . lifepath ,
"lifepath" : $scope . totalSkillPoints . lifepath ,
"general" : $scope . totalSkillPoints . general
}
for ( var key in $scope . lifepathSkills ) {
var skill = $scope . lifepathSkills [ key ]
unspentSkillPoints . lifepath -= skill . lifepathPointsSpent ;
unspentSkillPoints . general -= skill . generalPointsSpent ;
}
for ( var key in $scope . generalSkills ) {
var skill = $scope . generalSkills [ key ]
unspentSkillPoints . lifepath -= skill . lifepathPointsSpent ;
unspentSkillPoints . general -= skill . generalPointsSpent ;
}
@ -2203,7 +2176,7 @@ function openRequiredSkills($scope){
var required = skillsRequiredToBeOpened ( $scope . selectedLifepaths ) ;
var unspentSkillPoints = {
"lifepath" : $scope . unspentSkillPoints . lifepath ,
"lifepath" : $scope . unspentSkillPoints . lifepath ,
"general" : $scope . unspentSkillPoints . general
}
@ -2241,13 +2214,13 @@ function skillsRequiredToBeOpened(lifepaths){
break ;
}
}
}
}
return skillHash ;
}
/ *
When a lifepath is removed , the stat points spent may be more than the available ,
When a lifepath is removed , the stat points spent may be more than the available ,
leading to a negative amount available . This method attempts to correct the situation
by lowering the spent points .
* /
@ -2258,10 +2231,10 @@ function correctStatPoints($scope){
}
/ *
Helper function used by correctStatPoints . This function tries to correct the deficit in
Helper function used by correctStatPoints . This function tries to correct the deficit in
$scope . unspentStatPoints for the specified 'unspentStatField' ( one of physical , mental , or either )
by unspending points from the stats , using the field 'displayStatField'
( one of physicalPointsSpent , mentalPointsSpent , eitherPointsSpent )
by unspending points from the stats , using the field 'displayStatField'
( one of physicalPointsSpent , mentalPointsSpent , eitherPointsSpent )
* /
function correctStatPointsHelperLowerPointsOfType ( $scope , unspentStatField , displayStatField ) {
if ( $scope . unspentStatPoints [ unspentStatField ] < 0 ) {
@ -2284,7 +2257,7 @@ function correctStatPointsHelperLowerPointsOfType($scope, unspentStatField, disp
}
}
}
}
/ * I f t h e u s e r a d d s s o m e g e n e r a l s k i l l s t o t h e c h a r a c t e r a n d t h e n a d d s a l i f e p a t h t h a t h a s t h o s e s k i l l s ,
@ -2307,14 +2280,14 @@ function calculateLifepathTraits($scope, burningData){
for ( var i = 0 ; i < $scope . selectedLifepaths . length ; i ++ ) {
var displayLp = $scope . selectedLifepaths [ i ] ;
totalTraitPoints += displayLp . traitPts ;
for ( var j = 0 ; j < displayLp . traits . length ; j ++ ) {
var name = displayLp . traits [ j ] ;
lifepathTraits [ name ] = new DisplayTrait ( name , burningData . traits ) ;
}
}
}
$scope . lifepathTraits = lifepathTraits ;
@ -2328,7 +2301,7 @@ function setCommonTraits($scope, burningData){
if ( $scope . selectedLifepaths . length == 0 )
return ;
var common = $scope . selectedLifepaths [ 0 ] . commonT raits;
var common = burningData . stocks [ $scope . stock ] . common _t raits;
if ( common . length > 0 ) {
for ( var j = 0 ; j < common . length ; j ++ ) {
var name = common [ j ] ;
@ -2377,7 +2350,7 @@ function traitsRequiredToBeOpened(lifepaths){
break ;
}
}
}
}
return traitHash ;
}
@ -2404,17 +2377,17 @@ function calculateUnspentTraitPoints($scope){
/ *
rexpr are the requires _expr . Returns a two - element list .
The first element is true if the requirements are satisifed , false
otherwise . The second element are any extra conditions if the first
rexpr are the requires _expr . Returns a two - element list .
The first element is true if the requirements are satisifed , false
otherwise . The second element are any extra conditions if the first
element is true . These extra conditions semantically descibe extra conditions
that must _later _ be met , for example " the requirements are satisfied as long as
that must _later _ be met , for example " the requirements are satisfied as long as
the character takes the trait 'your grace' "
The extra conditions supported so far are only a list of trait names .
* /
function areLifepathRequirementsSatisfied ( $scope , rexpr ) {
// make lookup tables
var selectedLifepathsByName = { }
for ( var i = 0 ; i < $scope . selectedLifepaths . length ; i ++ ) {
@ -2424,7 +2397,7 @@ function areLifepathRequirementsSatisfied($scope, rexpr){
for ( var i = 0 ; i < $scope . selectedLifepaths . length ; i ++ ) {
selectedLifepathsBySettingAndName [ $scope . selectedLifepaths [ i ] . setting . toLowerCase ( ) + ":" + $scope . selectedLifepaths [ i ] . name . toLowerCase ( ) ] = true ;
}
var checkHasLifepathIn = function ( rexpr ) {
// This is a [+has_lifepath_in, lp1, lp2, ...] OR [lifepath, lifepath] array.
@ -2509,7 +2482,7 @@ function areLifepathRequirementsSatisfied($scope, rexpr){
console . log ( "Error in areLifepathRequirementsSatisfied when evaluating expression: age_less_than predicate is length < 2 when it must be 2" ) ;
return [ false , [ ] ] ;
}
return [ $scope . age < rexpr [ 1 ] , [ ] ] ;
}
@ -2518,7 +2491,7 @@ function areLifepathRequirementsSatisfied($scope, rexpr){
console . log ( "Error in areLifepathRequirementsSatisfied when evaluating expression: age_greater_than predicate is length < 2 when it must be 2" ) ;
return [ false , [ ] ] ;
}
return [ $scope . age > rexpr [ 1 ] , [ ] ] ;
}
@ -2586,7 +2559,7 @@ function areLifepathRequirementsSatisfied($scope, rexpr){
console . log ( "Error in areLifepathRequirementsSatisfied when evaluating expression: '" + type + "' expression is length " + rexpr . length + " when it must exactly 2" ) ;
return [ false , [ ] ] ;
}
var evalResult = areLifepathRequirementsSatisfied ( $scope , rexpr [ 1 ] ) ;
return [ ! evalResult [ 0 ] , evalResult [ 1 ] ] ;
@ -2664,7 +2637,7 @@ function characterStructValid(charStruct){
}
function calculateTraitWarnings ( $scope , burningData ) {
// Make lookup maps of traits using lower-case trait names
var allTakenTraitNames = { } ;
for ( var key in $scope . purchasedTraits ) {
@ -2686,7 +2659,7 @@ function calculateTraitWarnings($scope, burningData){
var result = areLifepathRequirementsSatisfied ( $scope , rexpr ) ;
for ( var k = 0 ; k < result [ 1 ] . length ; k ++ ) {
var trait = result [ 1 ] [ k ] ;
if ( ! ( trait in allTakenTraitNames ) ) {
traitWarnings . push ( "You must take the '" + trait + "' trait to satisfy the '" + selectedLifepath . name + "' lifepath requirements." ) ;
}
@ -2704,12 +2677,12 @@ function applyBonusesFromTraits($scope) {
for ( var key in $scope . purchasedTraits ) {
var displayTrait = $scope . purchasedTraits [ key ] ;
traitBonuses . addTrait ( key , displayTrait ) ;
}
}
for ( var key in $scope . requiredTraits ) {
var displayTrait = $scope . requiredTraits [ key ] ;
traitBonuses . addTrait ( key , displayTrait ) ;
}
}
for ( var key in $scope . commonTraits ) {
var displayTrait = $scope . commonTraits [ key ] ;
@ -2725,13 +2698,13 @@ function applyBonusesFromTraits($scope) {
var displaySkill = $scope . lifepathSkills [ key ] ;
displaySkill . bonus = traitBonuses . getAddBonusesForSkill ( key ) ;
displaySkill . roundUp = traitBonuses . getRoundUpBonusForSkill ( displaySkill ) ;
}
}
for ( var key in $scope . generalSkills ) {
var displaySkill = $scope . generalSkills [ key ] ;
displaySkill . bonus = traitBonuses . getAddBonusesForSkill ( key ) ;
displaySkill . roundUp = traitBonuses . getRoundUpBonusForSkill ( displaySkill ) ;
}
}
//** Attributes
@ -2750,7 +2723,7 @@ function applyBonusesFromTraits($scope) {
}
/ *
Compute which traits the user can add as special traits . This value depends on character stock so
Compute which traits the user can add as special traits . This value depends on character stock so
this function should be called when stock changes .
* /
function calculateSpecialTraitsForDisplay ( $scope , burningData ) {
@ -2760,7 +2733,7 @@ function calculateSpecialTraitsForDisplay($scope, burningData){
var trait = burningData . traits [ traitName ] ;
if ( 'restrict' in trait ) {
if ( trait . restrict . indexOf ( validStockToRestrictionStock ( $scope . stock ) ) >= 0 &&
if ( trait . restrict . indexOf ( validStockToRestrictionStock ( burningData . stocks , $scope . stock ) ) >= 0 &&
( trait . restrict . indexOf ( "special" ) >= 0 || trait . restrict . indexOf ( "character" ) >= 0 ) ) {
list . push ( new DisplayTrait ( traitName , burningData . traits ) ) ;
}
@ -2808,48 +2781,16 @@ function calculateUnspentResourcePoints($scope){
$scope . unspentResourcePoints = unspentResourcePoints ;
}
function isValidStock ( stock ) {
return stock == "man" || stock == "elf" || stock == "orc" || stock == "dwarf" || stock == "roden" || stock == "wolf" || stock == "troll" ;
}
function restrictionStockToValidStock ( stock ) {
if ( stock == "mannish" )
return "man" ;
else if ( stock == "elven" )
return "elf" ;
else if ( stock == "orcish" )
return "orc" ;
else if ( stock == "dwarven" )
return "dwarf" ;
else if ( stock == "wolfish" )
return "wolf" ;
else if ( stock == "roden" )
return "roden" ;
else if ( stock == "trollish" )
return "troll" ;
function restrictionStockToValidStock ( stocks , stockAdjective ) {
return Object . values ( stocks ) . findLast ( s => s . adjective == stockAdjective ) . key ;
}
function validStockToRestrictionStock ( stock ) {
if ( stock == "man" )
return "mannish" ;
else if ( stock == "elf" )
return "elven" ;
else if ( stock == "orc" )
return "orcish" ;
else if ( stock == "dwarf" )
return "dwarven" ;
else if ( stock == "roden" )
return "roden" ;
else if ( stock == "wolf" )
return "wolfish" ;
else if ( stock == "troll" )
return "trollish" ;
function validStockToRestrictionStock ( stocks , stockName ) {
return stocks [ stockName ] . adjective ;
}
function attributeModifyingQuestions ( $scope , attribute )
{
{
var result = [ ] ;
var ageMod = function ( age ) {
@ -2919,8 +2860,8 @@ function attributeModifyingQuestions($scope, attribute)
{ question : "+1 Greed if the character is over 200 years old." , computed : true , compute : ageMod ( 200 ) } ,
{ question : "+1 Greed if the character is over 400 years old." , computed : true , compute : ageMod ( 400 ) } ,
{ question : "Each romantic relationship is -1 Greed. Each hateful relationship is +1 Greed. A hateful immediate family member is +2 Greed." , computed : true , compute : relMod }
) ;
}
) ;
}
else if ( attribute == "Health" )
{
var stockMod = function ( ) {
@ -2944,7 +2885,7 @@ function attributeModifyingQuestions($scope, attribute)
// "herald":1, "bannerman":1, "scout":1, "sergeant":1, "veteran":1, "cavalryman":1, "captain":1, "military order":1}
var steelyLps = { "conscript" : 1 , "squire" : 1 , "knight" : 1 , "bandit" : 1 , "pirate" : 1 , "military order" : 1 , "sword singer" : 1 } ;
var steelySettings = { "professional soldier subsetting" : 1 , "black legion subsetting" : 1 , "dwarven host subsetting" : 1 , "protector subsetting" : 1 } ;
var steel = 0 ;
for ( var i = 0 ; i < $scope . selectedLifepaths . length ; i ++ ) {
if ( $scope . selectedLifepaths [ i ] . name . toLowerCase ( ) in steelyLps || $scope . selectedLifepaths [ i ] . setting . toLowerCase ( ) in steelySettings ) {
@ -3051,23 +2992,23 @@ function attributeModifyingQuestions($scope, attribute)
var lpMod1 = function ( ) {
var lps = { "lancer" : 1 , "lieutenant" : 1 , "captain" : 1 } ;
var lps2 = { "lord protector" : 1 , "soother" : 1 } ;
var grief1 = 0 ;
var grief2 = 0 ;
for ( var i = 0 ; i < $scope . selectedLifepaths . length ; i ++ ) {
if ( $scope . selectedLifepaths [ i ] . name . toLowerCase ( ) in lps )
{
grief1 = 1 ;
if ( grief2 > 0 )
if ( grief2 > 0 )
break ;
}
if ( $scope . selectedLifepaths [ i ] . name . toLowerCase ( ) in lps2 )
{
grief2 = 1 ;
if ( grief1 > 0 )
if ( grief1 > 0 )
break ;
}
}
}
return grief1 + grief2 ;
}
@ -3084,11 +3025,11 @@ function attributeModifyingQuestions($scope, attribute)
var lpMod2 = function ( ) {
var lps = { "loremaster" : 1 , "adjutant" : 1 , "althing" : 1 } ;
for ( var i = 0 ; i < $scope . selectedLifepaths . length ; i ++ ) {
if ( $scope . selectedLifepaths [ i ] . name . toLowerCase ( ) in lps )
return 1 ;
}
}
return 0 ;
}
@ -3128,7 +3069,7 @@ function attributeModifyingQuestions($scope, attribute)
var percMod = function ( ) {
return ( $scope . statsByName [ 'Perception' ] . exp ( ) > 5 ? 1 : 0 ) ;
}
result . push (
{ question : "+1 Grief if the character has taken any Protector lifepath." , computed : true , compute : protectMod } ,
{ question : "+1 Grief if the character has been a Lancer, Lieutenant or Captain; Additional +1 if the character has been a Lord Protector or Soother" , computed : true , compute : lpMod1 } ,
@ -3235,7 +3176,7 @@ function attributeModifyingQuestions($scope, attribute)
var brutalMod = function ( ) {
var count = 0 ;
for ( var i = 0 ; i < $scope . selectedLifepaths . length ; i ++ ) {
if ( $scope . selectedLifepaths [ i ] . brutalLifeTraitName ) {
if ( $scope . selectedLifepaths [ i ] . brutalLifeTraitName ) {
count ++ ;
}
}
@ -3354,7 +3295,7 @@ function convertAttributeModifierQuestionResultsForSave($scope){
// Save only the non-computed questions that were answered.
var result = { } ;
for ( key in $scope . attributeModifierQuestionResults ) {
var list = [ ] ;
@ -3384,7 +3325,7 @@ function convertAttributeModifierQuestionResultsForCharsheet($scope){
var attribute = attributeNames [ j ] ;
var fullQuestions = attributeModifyingQuestions ( $scope , attribute )
if ( ! fullQuestions ) {
// Not an attribute with questions
continue ;
@ -3423,7 +3364,7 @@ function loadAttributeModifierQuestionResultsFromSave($scope, questions)
{
var result = { } ;
// For each attribute for which questions were saved, generate the
// For each attribute for which questions were saved, generate the
// full set of questions, then add in the answers from the save.
// The reason we do this rather than save all questions and answers
// is 1) to save space, and 2) because we can't save the compute function
@ -3452,7 +3393,7 @@ function loadAttributeModifierQuestionResultsFromSave($scope, questions)
/ * *
A number of skills are not defined because they are a specific instance of a general skill ; for example
ancient history is a type of history , and has the same roots . This function returns the parent skill for
ancient history is a type of history , and has the same roots . This function returns the parent skill for
a specific skill .
* /
function getGeneralSkillNameFor ( skillName ) {
@ -3510,7 +3451,7 @@ var computeStatAverage = function(statsByName, statNames, roundUp){
if ( getShade ( stats [ i ] ) == 'G' && ! allGray ) {
sum += 2 ;
}
sum += stats [ i ] . exp ( ) ;
}
@ -3557,11 +3498,11 @@ function calculateGearSelectionLists($scope, burningData) {
$scope . gearListForSelect = [ ] ;
for ( var i = 0 ; i < 3 ; i ++ )
$scope . currentSelectListGear . push ( { } ) ;
$scope . gearListForSelect [ 0 ] = calculateHierarchyListForSelect ( $scope , burningData , 'gear' ) ;
if ( $scope . gearListForSelect [ 0 ] . length > 0 )
$scope . currentSelectListGear [ 0 ] = $scope . gearListForSelect [ 0 ] [ 0 ] ;
$scope . calculateHierarchyListForSelectN ( $scope . gearListForSelect , $scope . currentSelectListGear , 1 ) ;
}
@ -3570,11 +3511,11 @@ function calculatePropertySelectionLists($scope, burningData) {
$scope . propertyListForSelect = [ ] ;
for ( var i = 0 ; i < 3 ; i ++ )
$scope . currentSelectListProperty . push ( { } ) ;
$scope . propertyListForSelect [ 0 ] = calculateHierarchyListForSelect ( $scope , burningData , 'property' ) ;
if ( $scope . propertyListForSelect [ 0 ] . length > 0 )
$scope . currentSelectListProperty [ 0 ] = $scope . propertyListForSelect [ 0 ] [ 0 ] ;
$scope . calculateHierarchyListForSelectN ( $scope . propertyListForSelect , $scope . currentSelectListProperty , 1 ) ;
}