diff --git a/.gitignore b/.gitignore index 80e6644..baf9643 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,5 @@ -Distribution Distribution/** +Build/** Source/**/*.js -Source/**/*.md -Source/**/*.txt node_modules/ npm-debug.log diff --git a/Gruntfile.js b/Gruntfile.js index 12d86c1..ffd5032 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -4,53 +4,82 @@ module.exports = function (grunt) { "meta": { "paths": { "source": "Source", + "build": "Build", "dist": "Distribution" } }, "tslint": { - "options": { - "configuration": grunt.file.readJSON("tslint.json") - }, - "files": { - "src": ["<%= meta.paths.source %>/<%= pkg.name %>.ts"] - } - }, - "typescript": { - "base": { - "src": "<%= meta.paths.source %>/<%= pkg.name %>.ts", - "dest": "<%= meta.paths.source %>/<%= pkg.name %>.js" - } - }, - "clean": ["<%= meta.paths.dist %>"], - "copy": { "default": { + "options": { + "configuration": grunt.file.readJSON("tslint.json") + }, + "files": { + "src": ["<%= meta.paths.source %>/*.ts"] + } + } + }, + "clean": { + "prebuild": [ + "<%= meta.paths.dist %>", + "<%= meta.paths.build %>" + ], + "postbuild": [ + "<%= meta.paths.dist %>/<%= pkg.name %>.js", + "<%= meta.paths.build %>" + ] + }, + "copy": { + "prebuild": { "files": [{ - "src": "<%= meta.paths.source %>/<%= pkg.name %>.js", - "dest": "<%= meta.paths.dist %>/<%= pkg.name %>-<%= pkg.version %>.js" + "src": "<%= meta.paths.source %>/*.ts", + "dest": "<%= meta.paths.build %>/", + "expand": true, + "flatten": true }, { "src": "<%= meta.paths.source %>/<%= pkg.name %>.ts", - "dest": "<%= meta.paths.dist %>/<%= pkg.name %>-<%= pkg.version %>.ts" - }, { - "src": "<%= meta.paths.source %>/<%= pkg.name %>.d.ts", - "dest": "<%= meta.paths.dist %>/<%= pkg.name %>-<%= pkg.version %>.d.ts" + "dest": "<%= meta.paths.build %>/", + "expand": true, + "flatten": true, + "rename": function (dest, src) { + return dest + "/<%= pkg.name %>-<%= pkg.version %>.ts"; + } }, { "src": "<%= meta.paths.source %>/References/*.ts", + "dest": "<%= meta.paths.build %>", + "expand": true, + "flatten": true + }, { + "src": "<%= meta.paths.source %>/References/*.?s", "dest": "<%= meta.paths.dist %>/", "expand": true, "flatten": true }, { "src": "README.md", "dest": "<%= meta.paths.dist %>/" - }, { - "src": "README.md", - "dest": "<%= meta.paths.source %>/" }, { "src": "LICENSE.txt", "dest": "<%= meta.paths.dist %>/" - }, { - "src": "LICENSE.txt", - "dest": "<%= meta.paths.source %>/" }] + }, + "distribution": { + "files": [{ + "src": "<%= meta.paths.source %>/<%= pkg.name %>.js", + "dest": "<%= meta.paths.dist %>/<%= pkg.name %>-<%= pkg.version %>.js" + }] + } + }, + "preprocess": { + "default": { + "src": "<%= meta.paths.build %>/<%= pkg.name %>.ts", + "dest": "<%= meta.paths.dist %>/<%= pkg.name %>-<%= pkg.version %>.ts" + } + }, + "typescript": { + "source": { + "src": "<%= meta.paths.source %>/*.ts" + }, + "distribution": { + "src": "<%= meta.paths.dist %>/<%= pkg.name %>-<%= pkg.version %>.ts" } }, "uglify": { @@ -58,31 +87,27 @@ module.exports = function (grunt) { "compress": true, "sourceMap": true }, - "dist": { + "default": { "files": { - "<%= meta.paths.dist %>/<%= pkg.name %>-<%= pkg.version %>.min.js": ["<%= meta.paths.source %>/<%= pkg.name %>.js"], + "<%= meta.paths.dist %>/<%= pkg.name %>-<%= pkg.version %>.min.js": [ + "<%= meta.paths.dist %>/<%= pkg.name %>-<%= pkg.version %>.js" + ] } } }, - "preprocess": { - "dist": { - "src": "<%= meta.paths.dist %>/<%= pkg.name %>-<%= pkg.version %>.ts", - "dest": "<%= meta.paths.dist %>/<%= pkg.name %>-<%= pkg.version %>.ts" - } - }, "mocha_phantomjs": { - "all": ["Tests/*.html"] + "default": ["Tests/*.html"] } }); + grunt.loadNpmTasks("grunt-tslint"); grunt.loadNpmTasks("grunt-contrib-clean"); grunt.loadNpmTasks("grunt-contrib-copy"); + grunt.loadNpmTasks("grunt-preprocess"); + grunt.loadNpmTasks("grunt-typescript"); grunt.loadNpmTasks("grunt-contrib-uglify"); grunt.loadNpmTasks("grunt-mocha-phantomjs"); - grunt.loadNpmTasks("grunt-preprocess"); - grunt.loadNpmTasks("grunt-tslint"); - grunt.loadNpmTasks("grunt-typescript"); grunt.registerTask("default", [ - "tslint", "typescript", "clean", "copy", "uglify", "preprocess", "mocha_phantomjs" + "tslint", "clean", "copy:prebuild", "preprocess", "typescript:source", "copy:distribution", "typescript:distribution", "clean:postbuild", "uglify", "mocha_phantomjs" ]); }; \ No newline at end of file diff --git a/Source/MenuGraphr.d.ts b/Source/MenuGraphr.d.ts index a557a13..2485e07 100644 --- a/Source/MenuGraphr.d.ts +++ b/Source/MenuGraphr.d.ts @@ -1,14 +1,13 @@ declare module MenuGraphr { export interface IGameStartr extends EightBittr.IEightBittr { GroupHolder: GroupHoldr.IGroupHoldr; - ItemsHolder: ItemsHoldr.IItemsHoldr; MapScreener: MapScreenr.IMapScreenr; ObjectMaker: ObjectMakr.IObjectMakr; TimeHandler: TimeHandlr.ITimeHandlr; addThing(thing: IThing | string | any[], left?: number, top?: number): IThing; killNormal(thing: IThing): void; - setHeight(thing: IThing, height: number); - setWidth(thing: IThing, width: number); + setHeight(thing: IThing, height: number): void; + setWidth(thing: IThing, width: number): void; } export interface IThing extends EightBittr.IThing { @@ -23,8 +22,10 @@ declare module MenuGraphr { export interface IMenu extends IThing, IMenuSchema { children: IThing[]; + height: number; progress?: IMenuProgress; textX?: number; + width: number; } export interface IMenuProgress { @@ -33,21 +34,44 @@ declare module MenuGraphr { working?: boolean; } - export interface IListMenu extends IMenu { + export interface IListMenu extends IListMenuSchema, IMenu { arrow: IThing; arrowXOffset?: number; arrowYOffset?: number; - grid: any[][]; + grid: IGridCell[][]; gridColumns: number; gridRows: number; + height: number; options: any[]; optionChildren: any; progress: IListMenuProgress; - scrollingAmount?: number; - scrollingAmountReal?: number; - scrollingItems?: number; + + /** + * How many rows the menu has visually scrolled. + */ + scrollingVisualOffset?: number; + + /** + * Whether the list should be a single column, rather than auto-flow. + */ + singleColumnList: boolean; + selectedIndex: number[]; textColumnWidth: number; + width: number; + } + + export interface IGridCell { + column: IGridCell[]; + columnNumber: number; + index: number; + rowNumber: number; + // These two will likely need to be confirmed... + schema: (string | IMenuWordCommand)[]; + text: (string | IMenuWordCommand)[]; + title: string; + x: number; + y: number; } export interface IListMenuOptions { @@ -74,6 +98,7 @@ declare module MenuGraphr { deleteOnFinish?: boolean; finishAutomatically?: boolean; finishAutomaticSpeed?: number; + height?: number; ignoreA?: boolean; ignoreB?: boolean; ignoreProgressB?: boolean; @@ -101,12 +126,18 @@ declare module MenuGraphr { textWidthMultiplier?: number; textXOffset?: number; textYOffset?: number; + width?: number; } export interface IMenuSchema extends IMenuBase { position?: IMenuSchemaPosition; } + export interface IListMenuSchema extends IMenuSchema { + scrollingItems?: number; + scrollingItemsComputed?: boolean | number; + } + export interface IMenuSchemaSize { width?: number; height?: number; @@ -127,8 +158,9 @@ declare module MenuGraphr { } export interface IMenuChildSchema extends IMenuSchema { + name?: string; type: string; - words?: (string | IMenuWordCommand)[]; + words?: MenuDialogRaw; } export interface IMenuChildMenuSchema extends IMenuChildSchema { @@ -143,7 +175,7 @@ declare module MenuGraphr { } export interface IMenuThingSchema extends IMenuChildSchema { - args: any; + args?: any; position?: IMenuSchemaPosition; size?: IMenuSchemaSize; thing: string; @@ -154,7 +186,7 @@ declare module MenuGraphr { word?: string; } - export type MenuDialogRaw = string | (string | string[] | (string | string[])[] | IMenuWordCommand)[] + export type MenuDialogRaw = string | (string | string[] | (string | string[])[] | IMenuWordFiltered)[] export interface IMenuWordCommand extends IMenuWordFiltered { applyUnitsize?: boolean; @@ -163,7 +195,7 @@ declare module MenuGraphr { value: any; } - export interface IMenuWordPadLeftCommand extends IMenuWordCommand { + export interface IMenuWordPadLeftCommand extends IMenuWordFiltered { alignRight?: boolean; } @@ -182,6 +214,14 @@ declare module MenuGraphr { paddingY: number; } + export interface IReplacements { + [i: string]: string[] | IReplacerFunction; + } + + export interface IReplacerFunction { + (GameStarter: IGameStartr): string[]; + } + export interface IMenuGraphrSettings { GameStarter: IGameStartr; schemas?: { @@ -190,14 +230,8 @@ declare module MenuGraphr { aliases?: { [i: string]: string; }; - replacements?: { - [i: string]: string; - }; + replacements?: IReplacements; replacerKey?: string; - replaceFromItemsHolder?: boolean; - replacementStatistics?: { - [i: string]: boolean; - }; } export interface IMenuGraphr { @@ -205,9 +239,9 @@ declare module MenuGraphr { getMenu(name: string): IMenu; getExistingMenu(name: string): IMenu; getAliases(): { [i: string]: string }; - getReplacements(): { [i: string]: string }; + getReplacements(): IReplacements; createMenu(name: string, attributes?: IMenuSchema): IMenu; - createChild(name: string, schema: IMenuChildSchema): void; + createMenuChild(name: string, schema: IMenuChildSchema): void; createMenuWord(name: string, schema: IMenuWordSchema): void; createMenuThing(name: string, schema: IMenuThingSchema): IThing; hideMenu(name: string): void; @@ -223,13 +257,6 @@ declare module MenuGraphr { skipAdd?: boolean): void; addMenuDialog(name: string, dialogRaw: MenuDialogRaw, onCompletion?: () => any): void; addMenuText(name: string, words: (string[] | IMenuWordCommand)[], onCompletion?: (...args: any[]) => void): void; - addMenuWords( - name: string, - words: (string[] | IMenuWordCommand)[], - i: number, - x: number, - y: number, - onCompletion?: (...args: any[]) => void): IThing[]; continueMenu(name: string): void; addMenuList(name: string, settings: IListMenuOptions): void; activateMenuList(name: string): void; diff --git a/Source/MenuGraphr.ts b/Source/MenuGraphr.ts index 60c1b66..24dbb94 100644 --- a/Source/MenuGraphr.ts +++ b/Source/MenuGraphr.ts @@ -35,21 +35,13 @@ module MenuGraphr { }; private aliases: { - [i: string]: string + [i: string]: string; }; - private replacements: { - [i: string]: string - }; + private replacements: IReplacements; private replacerKey: string; - private replaceFromItemsHolder: boolean; - - private replacementStatistics: { - [i: string]: boolean - }; - /** * */ @@ -61,9 +53,6 @@ module MenuGraphr { this.replacements = settings.replacements || {}; this.replacerKey = settings.replacerKey || "%%%%%%%"; - this.replaceFromItemsHolder = settings.replaceFromItemsHolder; - this.replacementStatistics = settings.replacementStatistics; - this.menus = {}; } @@ -106,7 +95,7 @@ module MenuGraphr { /** * */ - getReplacements(): { [i: string]: string } { + getReplacements(): IReplacements { return this.replacements; } @@ -145,7 +134,7 @@ module MenuGraphr { menu.textAreaWidth = (menu.width - menu.textXOffset * 2) * this.GameStarter.unitsize; if (menu.childrenSchemas) { - menu.childrenSchemas.forEach(this.createChild.bind(this, name)); + menu.childrenSchemas.forEach(this.createMenuChild.bind(this, name)); } if (container.children) { @@ -160,7 +149,7 @@ module MenuGraphr { /** * */ - createChild(name: string, schema: IMenuChildSchema): void { + createMenuChild(name: string, schema: IMenuChildSchema): void { switch (schema.type) { case "menu": this.createMenu( @@ -433,165 +422,6 @@ module MenuGraphr { } } - /** - * - * - * @remarks This is the real force behind addMenuDialog and addMenuText. - */ - addMenuWords( - name: string, - words: (string[] | IMenuWordCommand)[], - i: number, - x: number, - y: number, - onCompletion?: (...args: any[]) => void): IThing[] { - var menu: IMenu = this.getExistingMenu(name), - textProperties: any = this.GameStarter.ObjectMaker.getPropertiesOf("Text"), - command: IMenuWordFiltered, - word: string[], - things: IThing[] = [], - textWidth: number, - textPaddingX: number, - textPaddingY: number, - textSpeed: number, - textWidthMultiplier: number, - character: IText, - j: number; - - // Command objects must be parsed here in case they modify the x/y position - if ((words[i]).command) { - command = words[i]; - word = this.parseWordCommand(command, menu); - - if ((command).command === "position") { - x += (command).x || 0; - y += (command).y || 0; - } - } else { - word = words[i]; - } - - textSpeed = menu.textSpeed; - textWidth = (menu.textWidth || textProperties.width) * this.GameStarter.unitsize; - textPaddingX = (menu.textPaddingX || textProperties.paddingX) * this.GameStarter.unitsize; - textPaddingY = (menu.textPaddingY || textProperties.paddingY) * this.GameStarter.unitsize; - textWidthMultiplier = menu.textWidthMultiplier || 1; - - // For each character in the word, schedule it appearing in the menu - for (j = 0; j < word.length; j += 1) { - // For non-whitespace characters, add them and move to the right - if (/\S/.test(word[j])) { - character = this.addMenuCharacter(name, word[j], x, y, j * textSpeed); - x += textWidthMultiplier * (character.width * this.GameStarter.unitsize + textPaddingX); - continue; - } - - // Endlines skip a line; general whitespace moves to the right - // (" " spaces at the start do not move to the right) - if (word[j] === "\n") { - x = menu.textX; - y += textPaddingY; - } else if (word[j] !== " " || x !== menu.textX) { - x += textWidth * textWidthMultiplier; - } - } - - // Only create a new progress object if one doesn't exist (slight performance boost) - if (!menu.progress) { - menu.progress = {}; - } - - // If this is the last word in the the line (words), mark progress as done - if (i === words.length - 1) { - menu.progress.complete = true; - menu.progress.onCompletion = onCompletion; - - if (menu.finishAutomatically) { - this.GameStarter.TimeHandler.addEvent( - onCompletion, - (word.length + (menu.finishAutomaticSpeed || 1)) * textSpeed); - } - - this.GameStarter.TimeHandler.addEvent( - function (): void { - menu.progress.working = false; - }, - (j + 1) * textSpeed); - - return things; - } - - // If the next word would pass the edge of the menu, move down a line - if (x + this.computeFutureWordLength(words[i + 1], textWidth, textPaddingX) >= menu.right - menu.textXOffset) { - x = menu.textX; - y += textPaddingY; - } - - // Mark the menu's progress as working and incomplete - menu.progress.working = true; - menu.progress.complete = false; - menu.progress.onCompletion = onCompletion; - (menu).progress.words = words; - (menu).progress.i = i + 1; - (menu).progress.x = x; - (menu).progress.y = y - textPaddingY; - - // If the bottom of the menu has been reached, pause the progress - if (y >= menu.bottom - (menu.textYOffset - 1) * this.GameStarter.unitsize) { - this.GameStarter.TimeHandler.addEvent( - function (): void { - menu.progress.working = false; - }, - (j + 1) * textSpeed); - - return things; - } - - if (textSpeed) { - this.GameStarter.TimeHandler.addEvent( - this.addMenuWords.bind(this), - (j + 1) * textSpeed, - name, - words, - i + 1, - x, - y, - onCompletion); - } else { - this.addMenuWords(name, words, i + 1, x, y, onCompletion); - } - - return things; - } - - /** - * - */ - addMenuCharacter(name: string, character: string, x: number, y: number, delay?: number): IText { - var menu: IMenu = this.getExistingMenu(name), - textProperties: any = this.GameStarter.ObjectMaker.getPropertiesOf("Text"), - textPaddingY: number = (menu.textPaddingY || textProperties.paddingY) * this.GameStarter.unitsize, - title: string = "Char" + this.getCharacterEquivalent(character), - thing: IText = this.GameStarter.ObjectMaker.make(title, { - "textPaddingY": textPaddingY - }); - - menu.children.push(thing); - - if (delay) { - this.GameStarter.TimeHandler.addEvent( - this.GameStarter.addThing.bind(this.GameStarter), - delay, - thing, - x, - y); - } else { - this.GameStarter.addThing(thing, x, y); - } - - return thing; - } - /** * */ @@ -666,7 +496,7 @@ module MenuGraphr { schema: any, title: string, character: IThing, - column: IThing[], + column: IGridCell[], x: number, i: number, j: number, @@ -764,7 +594,7 @@ module MenuGraphr { y += textPaddingY; - if (y > menu.bottom - textHeight + 1) { + if (!menu.singleColumnList && y > menu.bottom - textHeight + 1) { y = top; left += menu.textColumnWidth * this.GameStarter.unitsize; column = []; @@ -825,9 +655,12 @@ module MenuGraphr { } } + if (menu.scrollingItemsComputed) { + menu.scrollingItems = this.computeMenuScrollingItems(menu); + } + if (menu.scrollingItems) { - menu.scrollingAmount = 0; - menu.scrollingAmountReal = 0; + menu.scrollingVisualOffset = 0; for (i = menu.scrollingItems; i < menu.gridRows; i += 1) { optionChild = optionChildren[i]; @@ -917,8 +750,6 @@ module MenuGraphr { return; } - // y = Math.min(menu.grid[x].length - 1, y); - menu.selectedIndex[0] = x; menu.selectedIndex[1] = y; option = this.getMenuSelectedOption(name); @@ -948,24 +779,22 @@ module MenuGraphr { */ adjustVerticalScrollingListThings(name: string, dy: number, textPaddingY: number): void { var menu: IListMenu = this.getExistingMenu(name), - scrollingOld: number = menu.scrollingAmount, + scrollingOld: number = menu.selectedIndex[1] - dy, offset: number = -dy * textPaddingY, option: any, optionChild: any, i: number, j: number; - menu.scrollingAmount += dy; - if (dy > 0) { - if (scrollingOld < menu.scrollingItems - 2) { + if (scrollingOld - menu.scrollingVisualOffset < menu.scrollingItems - 1) { return; } - } else if (menu.scrollingAmount < menu.scrollingItems - 2) { + } else if (scrollingOld - menu.scrollingVisualOffset > 0) { return; } - menu.scrollingAmountReal += dy; + menu.scrollingVisualOffset += dy; for (i = 0; i < menu.optionChildren.length; i += 1) { option = menu.options[i]; @@ -976,8 +805,8 @@ module MenuGraphr { for (j = 0; j < optionChild.things.length; j += 1) { this.GameStarter.shiftVert(optionChild.things[j], offset); if ( - i < menu.scrollingAmountReal - || i >= menu.scrollingItems + menu.scrollingAmountReal + i < menu.scrollingVisualOffset + || i >= menu.scrollingItems + menu.scrollingVisualOffset ) { optionChild.things[j].hidden = true; } else { @@ -1191,6 +1020,186 @@ module MenuGraphr { /* Utilities */ + /** + * + * + * @remarks This is the real force behind addMenuDialog and addMenuText. + */ + private addMenuWords( + name: string, + words: (string[] | IMenuWordCommand)[], + i: number, + x: number, + y: number, + onCompletion?: (...args: any[]) => void): IThing[] { + var menu: IMenu = this.getExistingMenu(name), + textProperties: any = this.GameStarter.ObjectMaker.getPropertiesOf("Text"), + command: IMenuWordFiltered, + word: string[], + things: IThing[] = [], + textWidth: number, + textPaddingX: number, + textPaddingY: number, + textSpeed: number, + textWidthMultiplier: number, + character: IText, + j: number; + + // Command objects must be parsed here in case they modify the x/y position + if ((words[i]).command) { + command = words[i]; + word = this.parseWordCommand(command, menu); + + if ((command).command === "position") { + x += (command).x || 0; + y += (command).y || 0; + } + } else { + word = words[i]; + } + + textSpeed = menu.textSpeed; + textWidth = (menu.textWidth || textProperties.width) * this.GameStarter.unitsize; + textPaddingX = (menu.textPaddingX || textProperties.paddingX) * this.GameStarter.unitsize; + textPaddingY = (menu.textPaddingY || textProperties.paddingY) * this.GameStarter.unitsize; + textWidthMultiplier = menu.textWidthMultiplier || 1; + + // For each character in the word, schedule it appearing in the menu + for (j = 0; j < word.length; j += 1) { + // For non-whitespace characters, add them and move to the right + if (/\S/.test(word[j])) { + character = this.addMenuCharacter(name, word[j], x, y, j * textSpeed); + x += textWidthMultiplier * (character.width * this.GameStarter.unitsize + textPaddingX); + continue; + } + + // Endlines skip a line; general whitespace moves to the right + // (" " spaces at the start do not move to the right) + if (word[j] === "\n") { + x = menu.textX; + y += textPaddingY; + } else if (word[j] !== " " || x !== menu.textX) { + x += textWidth * textWidthMultiplier; + } + } + + // Only create a new progress object if one doesn't exist (slight performance boost) + if (!menu.progress) { + menu.progress = {}; + } + + // If this is the last word in the the line (words), mark progress as done + if (i === words.length - 1) { + menu.progress.complete = true; + menu.progress.onCompletion = onCompletion; + + if (menu.finishAutomatically) { + this.GameStarter.TimeHandler.addEvent( + onCompletion, + (word.length + (menu.finishAutomaticSpeed || 1)) * textSpeed); + } + + this.GameStarter.TimeHandler.addEvent( + function (): void { + menu.progress.working = false; + }, + (j + 1) * textSpeed); + + return things; + } + + // If the next word would pass the edge of the menu, move down a line + if (x + this.computeFutureWordLength(words[i + 1], textWidth, textPaddingX) >= menu.right - menu.textXOffset) { + x = menu.textX; + y += textPaddingY; + } + + // Mark the menu's progress as working and incomplete + menu.progress.working = true; + menu.progress.complete = false; + menu.progress.onCompletion = onCompletion; + (menu).progress.words = words; + (menu).progress.i = i + 1; + (menu).progress.x = x; + (menu).progress.y = y - textPaddingY; + + // If the bottom of the menu has been reached, pause the progress + if (y >= menu.bottom - (menu.textYOffset - 1) * this.GameStarter.unitsize) { + this.GameStarter.TimeHandler.addEvent( + function (): void { + menu.progress.working = false; + }, + (j + 1) * textSpeed); + + return things; + } + + if (textSpeed) { + this.GameStarter.TimeHandler.addEvent( + this.addMenuWords.bind(this), + (j + 1) * textSpeed, + name, + words, + i + 1, + x, + y, + onCompletion); + } else { + this.addMenuWords(name, words, i + 1, x, y, onCompletion); + } + + return things; + } + + /** + * + */ + private addMenuCharacter(name: string, character: string, x: number, y: number, delay?: number): IText { + var menu: IMenu = this.getExistingMenu(name), + textProperties: any = this.GameStarter.ObjectMaker.getPropertiesOf("Text"), + textPaddingY: number = (menu.textPaddingY || textProperties.paddingY) * this.GameStarter.unitsize, + title: string = "Char" + this.getCharacterEquivalent(character), + thing: IText = this.GameStarter.ObjectMaker.make(title, { + "textPaddingY": textPaddingY + }); + + menu.children.push(thing); + + if (delay) { + this.GameStarter.TimeHandler.addEvent( + this.GameStarter.addThing.bind(this.GameStarter), + delay, + thing, + x, + y); + } else { + this.GameStarter.addThing(thing, x, y); + } + + return thing; + } + + /** + * + * + * @remarks This could be made into a binary search... + * @remarks This equation is rought, and could be re-checked... + */ + private computeMenuScrollingItems(menu: IListMenu): number { + var bottom: number = menu.bottom + - (menu.textPaddingY * this.GameStarter.unitsize || 0) + - (menu.textYOffset * this.GameStarter.unitsize || 0), + i: number; + + for (i = 0; i < menu.gridRows; i += 1) { + if (menu.grid[0][i].y >= bottom) { + return i; + } + } + + return Infinity; + } + /** * */ @@ -1225,7 +1234,7 @@ module MenuGraphr { } var output: (string[] | IMenuWordCommand)[][] = [], - component: string | string[] | (string | string[])[] | IMenuWordCommand, + component: any, i: number; for (i = 0; i < dialogRaw.length; i += 1) { @@ -1302,9 +1311,14 @@ module MenuGraphr { if (start !== -1 && end !== -1) { inside = this.getReplacement(word.substring(start + "%%%%%%%".length, end)); + if (inside.constructor === Number) { + inside = inside.toString().split(""); + } else if (inside.constructor === String) { + inside = (inside).split(""); + } output.push(...word.substring(0, start).split("")); - output.push(...(inside.constructor === String ? (inside).split("") : (inside))); + output.push(...(inside)); output.push(...this.filterWord(word.substring(end + "%%%%%%%".length))); return output; @@ -1459,29 +1473,14 @@ module MenuGraphr { * */ private getReplacement(key: string): string[] { - var replacement: string = this.replacements[key], - value: string | string[]; + var replacement: string[] | IReplacerFunction = this.replacements[key]; if (typeof replacement === "undefined") { return [""]; - } - - // if (this.replacementStatistics && this.replacementStatistics[value]) { - // return this.replacements[value](this.GameStarter); - // } - - if (this.replaceFromItemsHolder) { - if (this.GameStarter.ItemsHolder.hasKey(replacement)) { - value = this.GameStarter.ItemsHolder.getItem(replacement); - } - } - - if (!value) { - return replacement.split(""); - } else if (value.constructor === String) { - return (value).split(""); + } else if (typeof replacement === "function") { + return (replacement).call(this, this.GameStarter); } else { - return value; + return replacement; } } diff --git a/package.json b/package.json index e7d31c3..8490cc3 100644 --- a/package.json +++ b/package.json @@ -22,11 +22,11 @@ "grunt-contrib-copy": "~0.8.X", "grunt-contrib-uglify": "~0.8.X", "grunt-mocha-phantomjs": "~2.X", - "grunt-tslint": "~2.4.X", - "grunt-typescript": "~0.7.X", + "grunt-tslint": "~3.0.X", + "grunt-typescript": "~0.8.X", "mocha": "~2.2.X", "grunt-preprocess": "~4.1.X", - "tslint": "~2.4.X", - "typescript": "~1.6.X" + "tslint": "~3.2.X", + "typescript": "~1.7.X" } } \ No newline at end of file