Stephan Fuchs пре 3 месеци
родитељ
комит
b8f2a823ed

+ 2 - 2
npcs_convert.py

@@ -8,14 +8,14 @@ import sys
 def file_convert(filename):
 def file_convert(filename):
 	global tw_sources_path, tw_destination_path
 	global tw_sources_path, tw_destination_path
 	source_filepath= os.path.join(tw_sources_path,filename)+'.tw'
 	source_filepath= os.path.join(tw_sources_path,filename)+'.tw'
-	destination_filepath= os.path.join(tw_destination_path,filename)+'compiled.js'
+	destination_filepath= os.path.join(tw_destination_path,filename)+'compiled.ts'
 	with open(source_filepath, 'r') as file:
 	with open(source_filepath, 'r') as file:
 		lines = [line.rstrip() for line in file]
 		lines = [line.rstrip() for line in file]
 
 
 	npccounter = 0
 	npccounter = 0
 
 
 	with open(destination_filepath, 'w') as file:
 	with open(destination_filepath, 'w') as file:
-		file.write("setup.npcs ??= {};\n")
+		file.write("""/// <reference path="../../../npcs/_system/NPC.ts" />\n\n""")
 		identifier = 'none'
 		identifier = 'none'
 		npc_id = ''
 		npc_id = ''
 		npc_subobjects = {}
 		npc_subobjects = {}

+ 53 - 1
sugarcube/src/interfaces.d.ts

@@ -12,6 +12,7 @@ declare module "twine-sugarcube" {
 		Mood: { new(): Mood };
 		Mood: { new(): Mood };
 		Moodlet: { new(): Moodlet };
 		Moodlet: { new(): Moodlet };
 		MoodletGroup: { new(): MoodletGroup };
 		MoodletGroup: { new(): MoodletGroup };
+		NPC:{ new(): NPC };
 		OutfitItem: { new(): OutfitItem };
 		OutfitItem: { new(): OutfitItem };
 		Pain: { new(): Pain };
 		Pain: { new(): Pain };
 		PlayerCharacter: { new(): PlayerCharacter };
 		PlayerCharacter: { new(): PlayerCharacter };
@@ -38,6 +39,9 @@ declare module "twine-sugarcube" {
 		locations: { [key: string]: LocationDefinition; };
 		locations: { [key: string]: LocationDefinition; };
 		moodlets: { [key: string]: Moodlet; };
 		moodlets: { [key: string]: Moodlet; };
 		moodletGroups: { [key: string]: MoodletGroup; };
 		moodletGroups: { [key: string]: MoodletGroup; };
+		npcs:{ [key: string]: NPCDefinition; };
+		npcDefaults:{ [key: string]: NPCDefaultDefinition; };
+		npcPreferences:{ [key: string]: NPCPreferenceDefinition; };
 		outfits: { [key: string]: OutfitDefinition; };
 		outfits: { [key: string]: OutfitDefinition; };
 		outfitsDefaults: {[key: string]: {[key: string]: any; } };
 		outfitsDefaults: {[key: string]: {[key: string]: any; } };
 		outfitItemImagePath: {[key: string]: string | {[key: string]: any; } };
 		outfitItemImagePath: {[key: string]: string | {[key: string]: any; } };
@@ -98,7 +102,7 @@ declare module "twine-sugarcube" {
 		inventory: Inventory;
 		inventory: Inventory;
 		jobs: any;
 		jobs: any;
 		location: GameLocation;
 		location: GameLocation;
-		npcs:any;
+		npcs:NPCsDict;
 		pc: PlayerCharacter;
 		pc: PlayerCharacter;
 		q: QuestsDict;
 		q: QuestsDict;
 		settings:any;
 		settings:any;
@@ -159,6 +163,7 @@ declare global {
 
 
 	export interface Window{
 	export interface Window{
 		rand(x:number,y:number): number;
 		rand(x:number,y:number): number;
+		NPCsDict: { new(): NPCsDict };
 		Wardrobe: { new(): Wardrobe };
 		Wardrobe: { new(): Wardrobe };
 	}
 	}
 
 
@@ -454,6 +459,53 @@ declare global {
 		openTimes?:TimespanIdentifier;
 		openTimes?:TimespanIdentifier;
 	}
 	}
 
 
+	export interface NPCDefinition{
+		passage?:string;
+		image?:string;
+
+		rel?:number;
+
+		dna?:string;
+
+		firstname?:string;
+		nickname?:string;
+		lastname?:string;
+		usedname?:string;
+
+		dob?:number;
+		gender: EGender;
+
+		haircol?:number;
+		height?:number;
+
+		notes?:string;
+
+		thdick?:string;
+		dick?:number;
+		bust?:number;
+		spermpot?:number;
+
+		sexskill?:number;
+
+		rep?:number;
+
+		intel?:number;
+
+		hotcat_rating?:number;
+
+		preference?:{[key:string]:number|number[]};
+
+		defaults?:string[];
+	}
+
+	export interface NPCDefaultDefinition{
+
+	}
+
+	export interface NPCPreferenceDefinition{
+		
+	}
+
 	export type OutfitDefinition = OutfitDefinitionBodysuit | OutfitDefinitionBra | OutfitDefinitionClothes | OutfitDefinitionCoat | OutfitDefinitionPanties | OutfitDefinitionPurse | OutfitDefinitionShoes | OutfitDefinitionSwimwear;
 	export type OutfitDefinition = OutfitDefinitionBodysuit | OutfitDefinitionBra | OutfitDefinitionClothes | OutfitDefinitionCoat | OutfitDefinitionPanties | OutfitDefinitionPurse | OutfitDefinitionShoes | OutfitDefinitionSwimwear;
 
 
 	export interface OutfitDefinitionRaw{
 	export interface OutfitDefinitionRaw{

+ 9 - 9
sugarcube/src/npcs/_npcstatic/compiled/npcstatic1compiled.js → sugarcube/src/npcs/_npcstatic/compiled/npcstatic1compiled.ts

@@ -1,4 +1,6 @@
-setup.npcs ??= {};
+/// <reference path="../../../npcs/_system/NPC.ts" />
+
+
 setup.npcs["A1"] = {
 setup.npcs["A1"] = {
 	dna:'1594378993 1607632682 1428796224 1448474566 1775134737 1909315069 1882255348',
 	dna:'1594378993 1607632682 1428796224 1448474566 1775134737 1909315069 1882255348',
 	firstname:'Dmitriy',
 	firstname:'Dmitriy',
@@ -218,7 +220,7 @@ setup.npcs["A9"] = {
 	thdick:'thick',
 	thdick:'thick',
 	dick:18,
 	dick:18,
 	rep:270,
 	rep:270,
-	sexskill:'Incorrect Initialization: rand(0,2)',
+	sexskill:1,
 	intel:31,
 	intel:31,
 	hotcat_rating:5,
 	hotcat_rating:5,
 	preference:{
 	preference:{
@@ -245,7 +247,7 @@ setup.npcs["A10"] = {
 	thdick:'thick',
 	thdick:'thick',
 	dick:17,
 	dick:17,
 	rep:230,
 	rep:230,
-	sexskill:'Incorrect Initialization: rand(0,2)',
+	sexskill:1,
 	intel:48,
 	intel:48,
 	hotcat_rating:6,
 	hotcat_rating:6,
 	preference:{
 	preference:{
@@ -276,7 +278,7 @@ setup.npcs["A11"] = {
 	thdick:'massive',
 	thdick:'massive',
 	dick:15,
 	dick:15,
 	rep:180,
 	rep:180,
-	sexskill:'Incorrect Initialization: rand(0,2)',
+	sexskill:1,
 	intel:33,
 	intel:33,
 	hotcat_rating:4,
 	hotcat_rating:4,
 	preference:{
 	preference:{
@@ -674,7 +676,6 @@ setup.npcs["A25"] = {
 	intel:54,
 	intel:54,
 	hotcat_rating:6,
 	hotcat_rating:6,
 	rep:390,
 	rep:390,
-	rep:40,
 	passage:'npc_Sonia',
 	passage:'npc_Sonia',
 	preference:{
 	preference:{
 		bimbo:1,
 		bimbo:1,
@@ -966,10 +967,9 @@ setup.npcs["A37"] = {
 	firstname:'Margaret',
 	firstname:'Margaret',
 	nickname:'Margo',
 	nickname:'Margo',
 	usedname:'A girl met outside of the Boutique',
 	usedname:'A girl met outside of the Boutique',
-	notes:19940810,
-	dob:'Incorrect Initialization: rand(10,30)',
+	dob:19940810,
 	gender:1,
 	gender:1,
-	sexskill:'Incorrect Initialization: rand(1,2)',
+	sexskill:2,
 	bust:19,
 	bust:19,
 }
 }
 setup.npcs["A38"] = {
 setup.npcs["A38"] = {
@@ -990,7 +990,7 @@ setup.npcs["A39"] = {
 	gender:0,
 	gender:0,
 	thdick:'thicker than average',
 	thdick:'thicker than average',
 	dick:15,
 	dick:15,
-	sexskill:'Incorrect Initialization: rand(0,1)',
+	sexskill:1,
 }
 }
 setup.npcs["A40"] = {
 setup.npcs["A40"] = {
 	dna:'1378982990 1311934118 1904514436 1282506111 1725049043 1341280625 1250233099',
 	dna:'1378982990 1311934118 1904514436 1282506111 1725049043 1341280625 1250233099',

+ 10 - 12
sugarcube/src/npcs/_npcstatic/compiled/npcstatic2compiled.js → sugarcube/src/npcs/_npcstatic/compiled/npcstatic2compiled.ts

@@ -1,4 +1,4 @@
-setup.npcs ??= {};
+/// <reference path="../../../npcs/_system/NPC.ts" />
 setup.npcs["A50"] = {
 setup.npcs["A50"] = {
 	dna:'1435367511 1891990398 1521901210 1459906326 1825460937 1413691134 1744017772',
 	dna:'1435367511 1891990398 1521901210 1459906326 1825460937 1413691134 1744017772',
 	firstname:'Stas',
 	firstname:'Stas',
@@ -190,7 +190,7 @@ setup.npcs["A60"] = {
 	dob:19990805,
 	dob:19990805,
 	gender:1,
 	gender:1,
 	bust:9,
 	bust:9,
-	pic:'images/characters/gadukino/mira/mira.jpg',
+	image:'images/characters/gadukino/mira/mira.jpg',
 	hotcat_rating:5,
 	hotcat_rating:5,
 }
 }
 setup.npcs["A61"] = {
 setup.npcs["A61"] = {
@@ -229,7 +229,7 @@ setup.npcs["A63"] = {
 	gender:0,
 	gender:0,
 	thdick:'thick',
 	thdick:'thick',
 	dick:18,
 	dick:18,
-	pic:'images/locations/gadukino/village/mitka.jpg',
+	image:'images/locations/gadukino/village/mitka.jpg',
 	hotcat_rating:6,
 	hotcat_rating:6,
 }
 }
 setup.npcs["A64"] = {
 setup.npcs["A64"] = {
@@ -241,7 +241,7 @@ setup.npcs["A64"] = {
 	gender:0,
 	gender:0,
 	thdick:'thick',
 	thdick:'thick',
 	dick:18,
 	dick:18,
-	pic:'images/locations/gadukino/village/mirafather.jpg',
+	image:'images/locations/gadukino/village/mirafather.jpg',
 	hotcat_rating:5,
 	hotcat_rating:5,
 }
 }
 setup.npcs["A65"] = {
 setup.npcs["A65"] = {
@@ -256,8 +256,8 @@ setup.npcs["A65"] = {
 	dick:20,
 	dick:20,
 	hotcat_rating:6,
 	hotcat_rating:6,
 }
 }
-setup.npcs["A66"] = {
-}
+/*setup.npcs["A66"] = {
+}*/
 setup.npcs["A67"] = {
 setup.npcs["A67"] = {
 	dna:'1770994710 1045056456 1630291439 1823144512 2022969490 1003713468 1769557695',
 	dna:'1770994710 1045056456 1630291439 1823144512 2022969490 1003713468 1769557695',
 	firstname:'Big C',
 	firstname:'Big C',
@@ -287,7 +287,7 @@ setup.npcs["A69"] = {
 	thdick:'well proportioned',
 	thdick:'well proportioned',
 	dick:18,
 	dick:18,
 	sexskill:2,
 	sexskill:2,
-	discoenable:1,
+	/*discoenable:1,*/
 	hotcat_rating:6,
 	hotcat_rating:6,
 	preference:{
 	preference:{
 		bimbo:- 1,
 		bimbo:- 1,
@@ -388,11 +388,11 @@ setup.npcs["A75"] = {
 	gender:0,
 	gender:0,
 	thdick:'massive',
 	thdick:'massive',
 	dick:20,
 	dick:20,
-	QW:0,
+	/*QW:0,*/
 	rel:0,
 	rel:0,
-	love:0,
+	/*love:0,
 	occupation:'',
 	occupation:'',
-	outfit:0,
+	outfit:0,*/
 }
 }
 setup.npcs["A76"] = {
 setup.npcs["A76"] = {
 	dna:'1008510370 1518299135 1584717411 1093601930 1547392081 1332335506 1589745960',
 	dna:'1008510370 1518299135 1584717411 1093601930 1547392081 1332335506 1589745960',
@@ -513,7 +513,6 @@ setup.npcs["A84"] = {
 }
 }
 setup.npcs["A85"] = {
 setup.npcs["A85"] = {
 	dna:'1938942779 2106314839 1289521515 1217866816 2023591880 1519928587 1939169723',
 	dna:'1938942779 2106314839 1289521515 1217866816 2023591880 1519928587 1939169723',
-	firstname:0,
 	nickname:'Kas',
 	nickname:'Kas',
 	notes:'A black handyman from the office.',
 	notes:'A black handyman from the office.',
 	gender:0,
 	gender:0,
@@ -531,7 +530,6 @@ setup.npcs["A86"] = {
 setup.npcs["A87"] = {
 setup.npcs["A87"] = {
 	dna:'1847378236 1162293273 1556619643 1329175895 1349109199 1613614049 1534225588',
 	dna:'1847378236 1162293273 1556619643 1329175895 1349109199 1613614049 1534225588',
 	firstname:'Boris',
 	firstname:'Boris',
-	nickname:0,
 	lastname:'Ivanovich',
 	lastname:'Ivanovich',
 	notes:'Cleaning Job Boss',
 	notes:'Cleaning Job Boss',
 	gender:0,
 	gender:0,

+ 4 - 4
sugarcube/src/npcs/_npcstatic/compiled/npcstatic3compiled.js → sugarcube/src/npcs/_npcstatic/compiled/npcstatic3compiled.ts

@@ -1,6 +1,6 @@
-setup.npcs ??= {};
-setup.npcs["A100"] = {
-}
+/// <reference path="../../../npcs/_system/NPC.ts" />
+/*setup.npcs["A100"] = {
+}*/
 setup.npcs["A101"] = {
 setup.npcs["A101"] = {
 	dna:'1316262053 1139860599 1054558181 1564591207 1897612229 1770085065 1904973185',
 	dna:'1316262053 1139860599 1054558181 1564591207 1897612229 1770085065 1904973185',
 	firstname:'Andrew',
 	firstname:'Andrew',
@@ -96,7 +96,7 @@ setup.npcs["A111"] = {
 	dob:19970410,
 	dob:19970410,
 	gender:1,
 	gender:1,
 	bust:14,
 	bust:14,
-	pic:'images/characters/city/isolde/izolda.jpg',
+	image:'images/characters/city/isolde/izolda.jpg',
 }
 }
 setup.npcs["A112"] = {
 setup.npcs["A112"] = {
 	dna:'1357552191 1808035750 1644370082 1970842460 1776176573 1211917555 1776040163',
 	dna:'1357552191 1808035750 1644370082 1970842460 1776176573 1211917555 1776040163',

+ 2 - 2
sugarcube/src/npcs/_npcstatic/compiled/npcstatic4compiled.js → sugarcube/src/npcs/_npcstatic/compiled/npcstatic4compiled.ts

@@ -1,4 +1,4 @@
-setup.npcs ??= {};
+/// <reference path="../../../npcs/_system/NPC.ts" />
 setup.npcs["A150"] = {
 setup.npcs["A150"] = {
 	dna:'1912077115 1054317172 1216715520 1272636005 1666248718 2044828734 1577551516',
 	dna:'1912077115 1054317172 1216715520 1272636005 1666248718 2044828734 1577551516',
 	firstname:'Erast',
 	firstname:'Erast',
@@ -729,7 +729,7 @@ setup.npcs["A196"] = {
 	usedname:'Porn actor Ignat Vedenin',
 	usedname:'Porn actor Ignat Vedenin',
 	notes:'Ignat signed up for both the pussy and the money. He lives near the university and often pretends to be a student so he can hook up with girls and bring them back to his place to film himself having sex with them. He then sells this footage to the studio.',
 	notes:'Ignat signed up for both the pussy and the money. He lives near the university and often pretends to be a student so he can hook up with girls and bring them back to his place to film himself having sex with them. He then sells this footage to the studio.',
 	dob:19980501,
 	dob:19980501,
-	intel:'Incorrect Initialization: rand(40,50)',
+	intel:45,
 	gender:0,
 	gender:0,
 	thdick:'thick',
 	thdick:'thick',
 	dick:17,
 	dick:17,

+ 3 - 3
sugarcube/src/npcs/_npcstatic/compiled/npcstatic5compiled.js → sugarcube/src/npcs/_npcstatic/compiled/npcstatic5compiled.ts

@@ -1,4 +1,4 @@
-setup.npcs ??= {};
+/// <reference path="../../../npcs/_system/NPC.ts" />
 setup.npcs["A200"] = {
 setup.npcs["A200"] = {
 	dna:'7894193659 7682081397 7204840012 1999784485 1457862984 1446965385 1706290392',
 	dna:'7894193659 7682081397 7204840012 1999784485 1457862984 1446965385 1706290392',
 	firstname:'Daniil',
 	firstname:'Daniil',
@@ -270,7 +270,7 @@ setup.npcs["A220"] = {
 	nickname:'Vika',
 	nickname:'Vika',
 	lastname:'Kirilova',
 	lastname:'Kirilova',
 	notes:'Vika goes to the local university. She comes from a town in a truly remote part of Russia. Her family is poor. She pays for her studies by working in a brothel in the city center.',
 	notes:'Vika goes to the local university. She comes from a town in a truly remote part of Russia. Her family is poor. She pays for her studies by working in a brothel in the city center.',
-	dob:'Incorrect Initialization: $pcs_dob - 10000',
+	/*dob:'Incorrect Initialization: $pcs_dob - 10000',*/
 	gender:1,
 	gender:1,
 	hotcat_rating:7,
 	hotcat_rating:7,
 	sexskill:2,
 	sexskill:2,
@@ -545,7 +545,7 @@ setup.npcs["A240"] = {
 	gender:1,
 	gender:1,
 	bust:22,
 	bust:22,
 	hotcat_rating:6,
 	hotcat_rating:6,
-	body:'s3',
+	/*body:'s3',*/
 	preference:{
 	preference:{
 		bimbo:0,
 		bimbo:0,
 		punk:0,
 		punk:0,

+ 3 - 5
sugarcube/src/npcs/_npcstatic/compiled/npcstatic6compiled.js → sugarcube/src/npcs/_npcstatic/compiled/npcstatic6compiled.ts

@@ -1,4 +1,4 @@
-setup.npcs ??= {};
+/// <reference path="../../../npcs/_system/NPC.ts" />
 setup.npcs["A250"] = {
 setup.npcs["A250"] = {
 	dna:'0',
 	dna:'0',
 	firstname:'Gora',
 	firstname:'Gora',
@@ -320,12 +320,10 @@ setup.npcs["A263"] = {
 	dob:19950101,
 	dob:19950101,
 	notes:'Ksenya dosent use her last name anyone as she dosent like or trust her father. She is of Chinese decent as her mother was a mail-order bride for her father and after she was born, her mother left him. She is an only child living in Russia with a shop of her own selling the exhibitionist clothing. She has been called a tease with her sheer clothing and flashing habits.',
 	notes:'Ksenya dosent use her last name anyone as she dosent like or trust her father. She is of Chinese decent as her mother was a mail-order bride for her father and after she was born, her mother left him. She is an only child living in Russia with a shop of her own selling the exhibitionist clothing. She has been called a tease with her sheer clothing and flashing habits.',
 	gender:1,
 	gender:1,
-	intel:'Incorrect Initialization: rand(10,30)',
-	drunk:0,
+	intel:20,
 	sexskill:0,
 	sexskill:0,
-	apprnc:0,
 	height:173,
 	height:173,
 	bust:22,
 	bust:22,
 	haircol:0,
 	haircol:0,
-	occupation:'Exhibitionist Store Owner',
+	/*occupation:'Exhibitionist Store Owner',*/
 }
 }

+ 7 - 0
sugarcube/src/npcs/_system/NPC.js → sugarcube/src/npcs/_system/NPC.ts

@@ -1,3 +1,10 @@
+setup.npcs = {};
+
+const enum EGender{
+	MALE = 0,
+	FEMALE = 1
+}
+
 class NPC{
 class NPC{
 
 
 	_npcID;
 	_npcID;

+ 18 - 13
sugarcube/src/npcs/_system/NPCsDict.js → sugarcube/src/npcs/_system/NPCsDict.ts

@@ -1,3 +1,6 @@
+/// <reference path="NPC.ts" />
+
+
 const npcFieldBoundaries = {
 const npcFieldBoundaries = {
     rel:{min:0,max:100}
     rel:{min:0,max:100}
 }
 }
@@ -101,8 +104,8 @@ class NPCsDict{
         return {};
         return {};
     }
     }
 
 
-    inc(npcId,field,v,min=-Infinity,max=Infinity){
-        let d = '';
+    inc(npcId,field,v:string|number,min=-Infinity,max=Infinity){
+        let d:string|number = '';
         if(typeof v === "number")
         if(typeof v === "number")
             d = 0;
             d = 0;
         let current = this.get(npcId,field,d);
         let current = this.get(npcId,field,d);
@@ -165,7 +168,7 @@ class NPCsDict{
 		let now = State.variables.time.now;
 		let now = State.variables.time.now;
 		let memory = {time:now,vars:{}};
 		let memory = {time:now,vars:{}};
         for(let rememberedField of rememberedFields){
         for(let rememberedField of rememberedFields){
-			memory.vars[rememberedField] = getvar(rememberedField);
+			memory.vars[rememberedField] = State.getVar(rememberedField);
         }
         }
 		this.set(npcId,'memory',memory);
 		this.set(npcId,'memory',memory);
 		console.log('NPC memory updated',npcId,memory);
 		console.log('NPC memory updated',npcId,memory);
@@ -178,8 +181,8 @@ class NPCsDict{
 		}
 		}
 	}
 	}
 
 
-	npc(npcId){
-		return new Proxy(new setup.NPC(npcId),setup.NPC.handler);
+	npc(npcId:string){
+		return new Proxy(new NPC(npcId),NPC.handler);
 	}
 	}
 
 
     npcData(npcId){
     npcData(npcId){
@@ -199,7 +202,7 @@ class NPCsDict{
         return data;
         return data;
     }
     }
 
 
-	npcFitsFilter(npcId,filters={}){
+	npcFitsFilter(npcId,filters:{[key:string]:any}={}){
 		outerLoop:for (const [filterKey, filterValue] of Object.entries(filters)) {
 		outerLoop:for (const [filterKey, filterValue] of Object.entries(filters)) {
 			let npcValue = undefined;
 			let npcValue = undefined;
 
 
@@ -226,13 +229,13 @@ class NPCsDict{
 		return true;
 		return true;
 	}
 	}
 
 
-	npcLikesAppearance(npcId){
+	npcLikesAppearance(npcId):boolean{
 		let appearanceDemand = this.get(npcId,'appearanceDemand',[null,null,5]);
 		let appearanceDemand = this.get(npcId,'appearanceDemand',[null,null,5]);
-		let hotcat = $pc.appearance.hotcat;
+		let hotcat = State.variables.pc.appearance;
 
 
-		if(appearanceDemand[0] !== null && hotcat.genetic	< appearanceDemand[0])	return false;
-		if(appearanceDemand[1] !== null && hotcat.lasting	< appearanceDemand[1])	return false;
-		if(appearanceDemand[2] !== null && hotcat.temp		< appearanceDemand[2])	return false;
+		if(appearanceDemand[0] !== null && hotcat.geneticValue	< appearanceDemand[0])	return false;
+		if(appearanceDemand[1] !== null && hotcat.lastingValue	< appearanceDemand[1])	return false;
+		if(appearanceDemand[2] !== null && hotcat.currentValue	< appearanceDemand[2])	return false;
 		
 		
 		let preferenceBalance = this.preferenceBalance(npcId);
 		let preferenceBalance = this.preferenceBalance(npcId);
 		return (preferenceBalance >= 0);
 		return (preferenceBalance >= 0);
@@ -246,7 +249,7 @@ class NPCsDict{
 	 * @param {string} npcId
 	 * @param {string} npcId
 	 * @returns {number}
 	 * @returns {number}
 	 */
 	 */
-	preferenceBalance(npcId){
+	preferenceBalance(npcId):number{
 		let preferenceValues = this.preferencesCompare(npcId);
 		let preferenceValues = this.preferencesCompare(npcId);
 		return Object.values(preferenceValues).reduce((a,x) => a+x, 0);
 		return Object.values(preferenceValues).reduce((a,x) => a+x, 0);
 	}
 	}
@@ -322,6 +325,8 @@ class NPCsDict{
 
 
 			for (const [preferenceId, value] of Object.entries(preferences[positive_negative].currentMatches)) {
 			for (const [preferenceId, value] of Object.entries(preferences[positive_negative].currentMatches)) {
 				// Value is the number that represents how negative or positive the opinion is
 				// Value is the number that represents how negative or positive the opinion is
+				if(typeof value != "number")
+					continue;
 				let opinionMagnitude = Math.abs(value);
 				let opinionMagnitude = Math.abs(value);
 				let opinionIsPositive = Math.sign(value);	//-1: Negative, 1: Positive
 				let opinionIsPositive = Math.sign(value);	//-1: Negative, 1: Positive
 
 
@@ -433,7 +438,7 @@ class NPCsDict{
 	 * @param {*} npcId
 	 * @param {*} npcId
 	 * @returns {{}}
 	 * @returns {{}}
 	 */
 	 */
-	preferencesCompare(npcId){
+	preferencesCompare(npcId):{[key: string]:number}{
 		
 		
         let result = {};
         let result = {};
 		let preferences = this.get(npcId,'preference');
 		let preferences = this.get(npcId,'preference');