├── .gitignore ├── fonts ├── glyphicons-halflings-regular.eot ├── glyphicons-halflings-regular.ttf ├── glyphicons-halflings-regular.woff └── glyphicons-halflings-regular.woff2 ├── css ├── themes │ └── bootswatch │ │ └── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 ├── github.min.css ├── tablesort.css ├── loading-bar.min.css └── style.css ├── partials ├── item │ ├── sql-script.html │ ├── modals │ │ ├── bag-family.html │ │ ├── class.html │ │ └── races.html │ ├── search.html │ ├── enchantment.html │ ├── item-loot.html │ ├── milling-loot.html │ ├── disenchant-loot.html │ └── prospecting-loot.html ├── quest │ ├── sql-script.html │ ├── search.html │ ├── modals │ │ ├── special-flags.html │ │ ├── classes.html │ │ ├── flags.html │ │ └── required-races.html │ ├── gameobject-enders.html │ ├── creature-enders.html │ ├── gameobject-starters.html │ ├── creature-starters.html │ └── objectives.html ├── creature │ ├── sql-script.html │ ├── modals │ │ ├── inhabit-type.html │ │ ├── spawn-mask.html │ │ ├── loot-mode.html │ │ ├── dynamicflags.html │ │ ├── flags-extra.html │ │ ├── unit-flags2.html │ │ └── npcflag.html │ ├── search.html │ ├── template-addon.html │ ├── quest-items.html │ ├── equip-template.html │ ├── on-kill-reputation.html │ ├── spawns-addon.html │ ├── trainer.html │ ├── vendor.html │ ├── creature-loot.html │ ├── skinning-loot.html │ └── pickpocket-loot.html ├── character │ ├── sql-script.html │ ├── search.html │ └── character.html ├── gameobject │ ├── sql-script.html │ ├── search.html │ ├── quest-items.html │ ├── modals │ │ └── flags.html │ └── loot.html ├── sai │ ├── sql-script.html │ ├── modals │ │ └── flags.html │ ├── search.html │ └── search-by-entity.html ├── modals │ ├── sql-script-modal.html │ ├── value.html │ ├── search.html │ └── unusued-guid-search.html ├── character.html ├── sai.html ├── gameobject.html ├── item.html ├── quest.html ├── info.html └── creature.html ├── js ├── lib │ ├── jdf-ngThemeSwitcher.js │ ├── ngStorage.min.js │ ├── loading-bar.min.js │ └── angular-highlightjs.min.js └── app │ ├── sai │ └── search-by-entity.js │ ├── quest │ ├── starters-enders.js │ └── objectives.js │ ├── item │ └── enchantment.js │ ├── info.js │ ├── gameobject │ └── quest-items.js │ ├── routes.js │ ├── creature │ └── quest-items.js │ ├── trainer.js │ ├── loot.js │ ├── switcher.js │ ├── vendor.js │ └── character.js ├── config.js.dist └── README.md /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /config.js 3 | -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Helias/Keira2/HEAD/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Helias/Keira2/HEAD/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Helias/Keira2/HEAD/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Helias/Keira2/HEAD/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /css/themes/bootswatch/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Helias/Keira2/HEAD/css/themes/bootswatch/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /css/themes/bootswatch/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Helias/Keira2/HEAD/css/themes/bootswatch/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /css/themes/bootswatch/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Helias/Keira2/HEAD/css/themes/bootswatch/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /css/themes/bootswatch/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/Helias/Keira2/HEAD/css/themes/bootswatch/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /partials/item/sql-script.html: -------------------------------------------------------------------------------- 1 |
2 |

Item UPDATE SQL Script

3 | 4 |
5 | -------------------------------------------------------------------------------- /partials/quest/sql-script.html: -------------------------------------------------------------------------------- 1 |
2 |

Quest UPDATE SQL Script

3 | 4 |
5 | -------------------------------------------------------------------------------- /partials/creature/sql-script.html: -------------------------------------------------------------------------------- 1 |
2 |

Creature UPDATE SQL Script

3 | 4 |
5 | -------------------------------------------------------------------------------- /partials/character/sql-script.html: -------------------------------------------------------------------------------- 1 |
2 |

Character UPDATE SQL Script

3 | 4 |
5 | -------------------------------------------------------------------------------- /partials/gameobject/sql-script.html: -------------------------------------------------------------------------------- 1 |
2 |

GameObject UPDATE SQL Script

3 | 4 |
5 | -------------------------------------------------------------------------------- /partials/sai/sql-script.html: -------------------------------------------------------------------------------- 1 |
2 |

SmartAI SQL Script

3 | 4 |
5 | -------------------------------------------------------------------------------- /partials/modals/sql-script-modal.html: -------------------------------------------------------------------------------- 1 | 4 | 7 | 10 | -------------------------------------------------------------------------------- /js/lib/jdf-ngThemeSwitcher.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * jdf-ngThemeSwitcher v0.1.0 3 | * http://jdforsythe.github.io/jdf-ngThemeSwitcher 4 | * Copyright (c) 2014 Jeremy Forsythe 5 | * License: MIT 6 | */ 7 | (function() { 8 | function ThemeSwitcherDirective() { 9 | return { 10 | restrict: 'E', 11 | scope: { 12 | urls: '=' 13 | }, 14 | template: '' 15 | }; 16 | } 17 | 18 | angular.module('jdf.ngThemeSwitcher', []) 19 | .directive('themeSwitcher', ThemeSwitcherDirective); 20 | })(); 21 | -------------------------------------------------------------------------------- /partials/character.html: -------------------------------------------------------------------------------- 1 | {{ selectionText }} 2 | 3 | 4 |
5 |
6 | 7 |
8 |
9 | 10 |
11 |
12 |
13 | -------------------------------------------------------------------------------- /partials/sai.html: -------------------------------------------------------------------------------- 1 | {{ selectionText }} 2 | 3 | 4 |
5 |
6 | 7 |
8 |
9 | 10 |
11 |
12 | 13 |
14 |
15 |
16 | -------------------------------------------------------------------------------- /partials/modals/value.html: -------------------------------------------------------------------------------- 1 | 4 | 18 | 22 | -------------------------------------------------------------------------------- /partials/item/modals/bag-family.html: -------------------------------------------------------------------------------- 1 | 4 | 18 | 22 | -------------------------------------------------------------------------------- /partials/creature/modals/inhabit-type.html: -------------------------------------------------------------------------------- 1 | 4 | 24 | 28 | -------------------------------------------------------------------------------- /config.js.dist: -------------------------------------------------------------------------------- 1 | /*jslint browser: true, white: true, plusplus: true*/ 2 | /*global angular, console, alert*/ 3 | 4 | (function () { 5 | 'use strict'; 6 | var app = angular.module('keira2'); 7 | 8 | /* Edit with path of TC-JSON-API */ 9 | app.defaultAPI = "../TC-JSON-API/public/index.php/"; 10 | 11 | /* Edit with default version of Keira2 12 | * Values: 13 | * - "3.3.5" 14 | * - "6.x" 15 | */ 16 | app.defaultVersion = "3.3.5"; 17 | 18 | 19 | /* [OPTIONAL] Multiple API instances 20 | * 21 | * If you have one separated instance TC-JSON-API for each game version 22 | * you can specify them by un-commenting and setting properly the following variables 23 | * 24 | * WARNING: un-comment the lines below *ONLY* if you are going to set *BOTH OF THEM* properly 25 | * if you just want to use Keira2 for one game version only, do *NOT* touch the lines below 26 | * 27 | */ 28 | 29 | app.apiInstances = {}; 30 | //app.apiInstances['3.3.5'] = "../TC-JSON-API/public/index.php/"; 31 | //app.apiInstances['6.x'] = "../TC-JSON-API-6/public/index.php/"; 32 | 33 | }()); 34 | -------------------------------------------------------------------------------- /partials/creature/modals/spawn-mask.html: -------------------------------------------------------------------------------- 1 | 4 | 28 | 32 | -------------------------------------------------------------------------------- /partials/gameobject.html: -------------------------------------------------------------------------------- 1 | {{ selectionText }} 2 | 3 | 4 |
5 |
6 | 7 |
8 |
9 | 10 |
11 |
12 | 13 |
14 |
15 | 16 |
17 |
18 | 19 |
20 |
21 |
22 | -------------------------------------------------------------------------------- /partials/creature/modals/loot-mode.html: -------------------------------------------------------------------------------- 1 | 4 | 30 | 34 | -------------------------------------------------------------------------------- /partials/item/search.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | 6 | 7 |
8 |
9 | 10 | 11 |
12 |
13 | 14 |
15 |
16 | 17 |
18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 |
EntryName
{{ item.entry }}{{ item.name }}
31 | -------------------------------------------------------------------------------- /css/github.min.css: -------------------------------------------------------------------------------- 1 | .hljs{display:block;overflow-x:auto;padding:0.5em;color:#333;background:#f8f8f8;-webkit-text-size-adjust:none}.hljs-comment,.diff .hljs-header{color:#998;font-style:italic}.hljs-keyword,.css .rule .hljs-keyword,.hljs-winutils,.nginx .hljs-title,.hljs-subst,.hljs-request,.hljs-status{color:#333;font-weight:bold}.hljs-number,.hljs-hexcolor,.ruby .hljs-constant{color:#008080}.hljs-string,.hljs-tag .hljs-value,.hljs-doctag,.tex .hljs-formula{color:#d14}.hljs-title,.hljs-id,.scss .hljs-preprocessor{color:#900;font-weight:bold}.hljs-list .hljs-keyword,.hljs-subst{font-weight:normal}.hljs-class .hljs-title,.hljs-type,.vhdl .hljs-literal,.tex .hljs-command{color:#458;font-weight:bold}.hljs-tag,.hljs-tag .hljs-title,.hljs-rule .hljs-property,.django .hljs-tag .hljs-keyword{color:#000080;font-weight:normal}.hljs-attribute,.hljs-variable,.lisp .hljs-body,.hljs-name{color:#008080}.hljs-regexp{color:#009926}.hljs-symbol,.ruby .hljs-symbol .hljs-string,.lisp .hljs-keyword,.clojure .hljs-keyword,.scheme .hljs-keyword,.tex .hljs-special,.hljs-prompt{color:#990073}.hljs-built_in{color:#0086b3}.hljs-preprocessor,.hljs-pragma,.hljs-pi,.hljs-doctype,.hljs-shebang,.hljs-cdata{color:#999;font-weight:bold}.hljs-deletion{background:#fdd}.hljs-addition{background:#dfd}.diff .hljs-change{background:#0086b3}.hljs-chunk{color:#aaa} 2 | -------------------------------------------------------------------------------- /partials/gameobject/search.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | 6 | 7 |
8 |
9 | 10 | 11 |
12 |
13 | 14 |
15 |
16 |
17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 |
EntryName
{{ gameobject.entry }}{{ gameobject.name }}
30 | -------------------------------------------------------------------------------- /css/tablesort.css: -------------------------------------------------------------------------------- 1 | th.tablesort-sortable { 2 | -webkit-user-select: none; 3 | -khtml-user-select: none; 4 | -moz-user-select: none; 5 | -o-user-select: none; 6 | user-select: none; 7 | cursor: pointer; 8 | } 9 | 10 | table .tablesort-sortable:after{ 11 | content:""; 12 | float:right; 13 | margin-top:7px; 14 | visibility:hidden; 15 | border-left:4px solid transparent; 16 | border-right:4px solid transparent; 17 | 18 | border-top:none; 19 | border-bottom:4px solid #000; 20 | } 21 | 22 | table .tablesort-desc:after{ 23 | border-top:4px solid #000; 24 | border-bottom:none; 25 | } 26 | 27 | table .tablesort-asc,table .tablesort-desc{ 28 | background-color:rgba(141, 192, 219, 0.25); 29 | } 30 | 31 | table .tablesort-sortable:hover:after, table .tablesort-asc:after, table .tablesort-desc:after { 32 | visibility:visible; 33 | } 34 | 35 | /* 36 | * Styling for the table row shown in empty tables 37 | */ 38 | 39 | /* The row is always added as the first row in a table 40 | Hide it by default */ 41 | .showIfLast { 42 | display: none; 43 | } 44 | 45 | /* Only show it if it is also the last row of the table. */ 46 | .showIfLast:last-child { 47 | display: table-row; 48 | } 49 | 50 | .showIfLast td { 51 | text-align: center; 52 | } 53 | 54 | .showIfLast td:after { 55 | content: "No data"; 56 | } 57 | -------------------------------------------------------------------------------- /partials/quest/search.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | 6 | 7 |
8 |
9 | 10 | 11 |
12 |
13 | 14 |
15 |
16 |
17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 |
IDLogTitleQuestDescription
{{ quest.ID }}{{ quest.LogTitle }}{{ quest.QuestDescription | limitTo: 100 }}
32 | -------------------------------------------------------------------------------- /partials/character/search.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | 6 | 7 |
8 |
9 | 10 | 11 |
12 |
13 | 14 |
15 |
16 | 17 |
18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 |
guidnameaccount
{{ character.guid }}{{ character.name }}{{ character.account }}
33 | -------------------------------------------------------------------------------- /partials/quest/modals/special-flags.html: -------------------------------------------------------------------------------- 1 | 4 | 34 | 38 | -------------------------------------------------------------------------------- /partials/item.html: -------------------------------------------------------------------------------- 1 | {{ selectionText }} 2 | 3 | 4 |
5 |
6 | 7 |
8 |
9 | 10 |
11 |
12 | 13 |
14 |
15 | 16 |
17 |
18 | 19 |
20 |
21 | 22 |
23 |
24 | 25 |
26 |
27 |
28 | -------------------------------------------------------------------------------- /partials/modals/search.html: -------------------------------------------------------------------------------- 1 | 4 | 36 | 40 | -------------------------------------------------------------------------------- /js/app/sai/search-by-entity.js: -------------------------------------------------------------------------------- 1 | /*jslint browser: true, eqeq: true, white: true, plusplus: true */ 2 | /*global angular, console, alert*/ 3 | 4 | (function () { 5 | 'use strict'; 6 | 7 | var app = angular.module('keira2'); 8 | 9 | app.controller("SearchByEntitySAIController", function ($scope, $rootScope, $stateParams, $http) { 10 | 11 | /* Default selectedSourceType */ 12 | $scope.selectedSourceType = 0; 13 | 14 | /* [Function] searchCreatures*/ 15 | $scope.searchCreatures = function (creatureEntry, creatureName, creatureSubname) { 16 | 17 | if ( creatureEntry && (!creatureName && !creatureSubname) && (creatureEntry.length < 2) ) { 18 | alert("Please insert an Entry of at least 2 characters"); 19 | return; 20 | } 21 | if ( creatureName && (!creatureEntry && !creatureSubname) && (creatureName.length < 3) ) { 22 | alert("Please insert a Name of at least 3 characters"); 23 | return; 24 | } 25 | if ( creatureSubname && (!creatureEntry && !creatureName) && (creatureSubname.length < 3) ) { 26 | alert("Please insert a Subname of at least 3 characters"); 27 | return; 28 | } 29 | 30 | $http.get( app.api + "search/creature/", { 31 | params: { 32 | id: creatureEntry, 33 | name: creatureName, 34 | subname: creatureSubname 35 | } 36 | }).success(function (data, status, header, config) { 37 | $scope.creatures = $rootScope.fixNumericValues(data); 38 | }) 39 | .error(function (data, status, header, config) { 40 | console.log("[ERROR] CREATURE SEARCH $http.get request failed"); 41 | }); 42 | 43 | }; 44 | 45 | }); 46 | 47 | }()); 48 | -------------------------------------------------------------------------------- /partials/creature/search.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | 6 | 7 |
8 |
9 | 10 | 11 |
12 |
13 | 14 | 15 |
16 |
17 | 18 |
19 |
20 |
21 |
22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 |
EntryNameSubname
{{ creature.entry }}{{ creature.name }}{{ creature.subname }}
36 | -------------------------------------------------------------------------------- /partials/modals/unusued-guid-search.html: -------------------------------------------------------------------------------- 1 | 4 | 38 | 42 | -------------------------------------------------------------------------------- /js/app/quest/starters-enders.js: -------------------------------------------------------------------------------- 1 | /*jslint browser: true, eqeq: true, white: true, plusplus: true */ 2 | /*global angular, console, alert*/ 3 | 4 | (function () { 5 | 'use strict'; 6 | 7 | var app = angular.module('keira2'); 8 | 9 | app.controller("StartersEndersController", function ($scope, $rootScope, $stateParams) { 10 | 11 | /* At start we have no row selected */ 12 | $scope.selectedRow = -1; 13 | 14 | /* The item currently selected by the user (bound to the view) */ 15 | $scope.selected = { 16 | id : 0, 17 | quest : parseInt($stateParams.id, 10) 18 | }; 19 | 20 | /* Type check */ 21 | $scope.parseValues = function() { 22 | 23 | $scope.selected.id = parseInt($scope.selected.id, 10); 24 | }; 25 | 26 | /* Select a row from collection */ 27 | $scope.selectRow = function(rows, index) { 28 | $scope.selectedRow = index; 29 | $scope.selected = angular.copy(rows[index]); 30 | }; 31 | 32 | /* Delete selected row from collection */ 33 | $scope.deleteSelectedRowFrom = function(rows) { 34 | if (!$rootScope.isEntrySelected()) { return; } 35 | 36 | rows.splice($scope.selectedRow, 1); 37 | }; 38 | 39 | /* Add selected row to collection */ 40 | $scope.addRowTo = function(rows, primaryKey2) { 41 | if (!$rootScope.isEntrySelected()) { return; } 42 | var i; 43 | $scope.parseValues(); 44 | 45 | // check primaryKey2 uniqueness 46 | for (i = 0; i < rows.length; i++) { 47 | if (rows[i][primaryKey2] == $scope.selected[primaryKey2]) { 48 | alert("Duplicate row with `" + primaryKey2 + "` = " + $scope.selected[primaryKey2]); 49 | return; 50 | } 51 | } 52 | 53 | rows.splice(0, 0, angular.copy($scope.selected)); 54 | }; 55 | 56 | }); 57 | 58 | }()); 59 | -------------------------------------------------------------------------------- /partials/creature/modals/dynamicflags.html: -------------------------------------------------------------------------------- 1 | 4 | 44 | 48 | -------------------------------------------------------------------------------- /js/app/item/enchantment.js: -------------------------------------------------------------------------------- 1 | /*jslint browser: true, eqeq: true, white: true, plusplus: true */ 2 | /*global angular, console, alert*/ 3 | 4 | (function () { 5 | 'use strict'; 6 | 7 | var app = angular.module('keira2'); 8 | 9 | app.controller("EnchantmentController", function ($scope, $rootScope, $stateParams) { 10 | 11 | /* At start we have no row selected */ 12 | $scope.selectedRow = -1; 13 | 14 | /* The item currently selected by the user (bound to the view) */ 15 | $scope.selected = { 16 | entry : parseInt($stateParams.id, 10), 17 | ench : 0, 18 | chance : 0.0 19 | }; 20 | 21 | /* Type check */ 22 | $scope.parseValues = function() { 23 | $scope.selected.ench = parseInt($scope.selected.ench, 10); 24 | $scope.selected.chance = parseFloat($scope.selected.chance, 10); 25 | }; 26 | 27 | /* Select a row from collection */ 28 | $scope.selectRow = function(rows, index) { 29 | $scope.selectedRow = index; 30 | $scope.selected = angular.copy(rows[index]); 31 | }; 32 | 33 | /* Delete selected row from collection */ 34 | $scope.deleteSelectedRowFrom = function(rows) { 35 | if (!$rootScope.isEntrySelected()) { return; } 36 | 37 | rows.splice($scope.selectedRow, 1); 38 | }; 39 | 40 | /* Add selected row to collection */ 41 | $scope.addRowTo = function(rows, primaryKey2) { 42 | if (!$rootScope.isEntrySelected()) { return; } 43 | var i; 44 | $scope.parseValues(); 45 | 46 | // check primaryKey2 uniqueness 47 | for (i = 0; i < rows.length; i++) { 48 | if (rows[i][primaryKey2] == $scope.selected[primaryKey2]) { 49 | alert("Duplicate row with `" + primaryKey2 + "` = " + $scope.selected[primaryKey2]); 50 | return; 51 | } 52 | } 53 | 54 | rows.splice(0, 0, angular.copy($scope.selected)); 55 | }; 56 | 57 | }); 58 | 59 | }()); 60 | -------------------------------------------------------------------------------- /partials/quest.html: -------------------------------------------------------------------------------- 1 | {{ selectionText }} 2 | 3 | 4 |
5 |
6 | 7 |
8 |
9 | 10 |
11 |
12 | 13 |
14 |
15 | 16 |
17 |
18 | 19 |
20 |
21 | 22 |
23 |
24 | 25 |
26 |
27 | 28 |
29 |
30 | 31 |
32 |
33 |
34 | -------------------------------------------------------------------------------- /partials/quest/gameobject-enders.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 | id 6 | 7 |
8 |
9 |
10 |
11 |
12 | 13 | 14 |
15 |
16 |
17 | 18 |
19 |
20 |
21 | 22 |
23 |
24 |
25 |
26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
id
{{ creature.id }}
37 |
38 |
39 | -------------------------------------------------------------------------------- /partials/quest/creature-enders.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 | id 6 | 7 |
8 |
9 |
10 |
11 |
12 | 13 | 14 |
15 |
16 |
17 | 18 |
19 |
20 |
21 | 22 |
23 |
24 |
25 |
26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
id
{{creature.id}}
37 |
38 |
39 | -------------------------------------------------------------------------------- /partials/quest/gameobject-starters.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 | id 6 | 7 |
8 |
9 |
10 |
11 |
12 | 13 | 14 |
15 |
16 |
17 | 18 |
19 |
20 |
21 | 22 |
23 |
24 |
25 |
26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
id
{{ creature.id }}
37 |
38 |
39 | -------------------------------------------------------------------------------- /partials/quest/creature-starters.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 | id 6 | 7 |
8 |
9 |
10 |
11 |
12 | 13 | 14 |
15 |
16 |
17 | 18 |
19 |
20 |
21 | 22 |
23 |
24 |
25 |
26 |
27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 |
id
{{creature.id}}
37 |
38 |
39 | -------------------------------------------------------------------------------- /partials/sai/modals/flags.html: -------------------------------------------------------------------------------- 1 | 4 | 46 | 50 | -------------------------------------------------------------------------------- /partials/sai/search.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | 6 | 12 |
13 |
14 | 15 | 16 |
17 |
18 | 19 | 20 |
21 |
22 | 23 |
24 |
25 | 28 |
29 |
30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 |
SourceTypeEntryOrGuid
{{ script.source_type }}{{ script.entryorguid }}
42 | -------------------------------------------------------------------------------- /css/loading-bar.min.css: -------------------------------------------------------------------------------- 1 | #loading-bar,#loading-bar-spinner{pointer-events:none;-webkit-pointer-events:none;-webkit-transition:350ms linear all;-moz-transition:350ms linear all;-o-transition:350ms linear all;transition:350ms linear all}#loading-bar-spinner.ng-enter,#loading-bar-spinner.ng-leave.ng-leave-active,#loading-bar.ng-enter,#loading-bar.ng-leave.ng-leave-active{opacity:0}#loading-bar-spinner.ng-enter.ng-enter-active,#loading-bar-spinner.ng-leave,#loading-bar.ng-enter.ng-enter-active,#loading-bar.ng-leave{opacity:1}#loading-bar .bar{-webkit-transition:width 350ms;-moz-transition:width 350ms;-o-transition:width 350ms;transition:width 350ms;background:#29d;position:fixed;z-index:10002;top:0;left:0;width:100%;height:2px;border-bottom-right-radius:1px;border-top-right-radius:1px}#loading-bar .peg{position:absolute;width:70px;right:0;top:0;height:2px;opacity:.45;-moz-box-shadow:#29d 1px 0 6px 1px;-ms-box-shadow:#29d 1px 0 6px 1px;-webkit-box-shadow:#29d 1px 0 6px 1px;box-shadow:#29d 1px 0 6px 1px;-moz-border-radius:100%;-webkit-border-radius:100%;border-radius:100%}#loading-bar-spinner{display:block;position:fixed;z-index:10002;top:10px;left:10px}#loading-bar-spinner .spinner-icon{width:14px;height:14px;border:2px solid transparent;border-top-color:#29d;border-left-color:#29d;border-radius:50%;-webkit-animation:loading-bar-spinner 400ms linear infinite;-moz-animation:loading-bar-spinner 400ms linear infinite;-ms-animation:loading-bar-spinner 400ms linear infinite;-o-animation:loading-bar-spinner 400ms linear infinite;animation:loading-bar-spinner 400ms linear infinite}@-webkit-keyframes loading-bar-spinner{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@-moz-keyframes loading-bar-spinner{0%{-moz-transform:rotate(0);transform:rotate(0)}100%{-moz-transform:rotate(360deg);transform:rotate(360deg)}}@-o-keyframes loading-bar-spinner{0%{-o-transform:rotate(0);transform:rotate(0)}100%{-o-transform:rotate(360deg);transform:rotate(360deg)}}@-ms-keyframes loading-bar-spinner{0%{-ms-transform:rotate(0);transform:rotate(0)}100%{-ms-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes loading-bar-spinner{0%{transform:rotate(0)}100%{transform:rotate(360deg)}} 2 | -------------------------------------------------------------------------------- /partials/item/modals/class.html: -------------------------------------------------------------------------------- 1 | 4 | 54 | 58 | -------------------------------------------------------------------------------- /partials/quest/modals/classes.html: -------------------------------------------------------------------------------- 1 | 4 | 54 | 58 | -------------------------------------------------------------------------------- /partials/item/enchantment.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 | ench 6 | 7 |
8 |
9 | chance 10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 |
19 |
20 |
21 | 22 |
23 |
24 |
25 | 26 |
27 |
28 |
29 |
30 |
31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 |
enchchance
{{ creature.ench }}{{ creature.chance }}
43 |
44 |
45 | -------------------------------------------------------------------------------- /js/lib/ngStorage.min.js: -------------------------------------------------------------------------------- 1 | /*! ngstorage 0.3.10 | Copyright (c) 2015 Gias Kay Lee | MIT License */!function(a,b){"use strict";"function"==typeof define&&define.amd?define(["angular"],b):a.hasOwnProperty("angular")?b(a.angular):"object"==typeof exports&&(module.exports=b(require("angular")))}(this,function(a){"use strict";function b(a,b){var c;try{c=a[b]}catch(d){c=!1}if(c&&"localStorage"===b){var e="__"+Math.round(1e7*Math.random());try{localStorage.setItem(e,e),localStorage.removeItem(e)}catch(d){c=!1}}return c}function c(c){var d=b(window,c);return function(){var e="ngStorage-";this.setKeyPrefix=function(a){if("string"!=typeof a)throw new TypeError("[ngStorage] - "+c+"Provider.setKeyPrefix() expects a String.");e=a};var f=a.toJson,g=a.fromJson;this.setSerializer=function(a){if("function"!=typeof a)throw new TypeError("[ngStorage] - "+c+"Provider.setSerializer expects a function.");f=a},this.setDeserializer=function(a){if("function"!=typeof a)throw new TypeError("[ngStorage] - "+c+"Provider.setDeserializer expects a function.");g=a},this.supported=function(){return!!d},this.get=function(a){return d&&g(d.getItem(e+a))},this.set=function(a,b){return d&&d.setItem(e+a,f(b))},this.$get=["$rootScope","$window","$log","$timeout","$document",function(d,h,i,j,k){var l,m,n=e.length,o=b(h,c),p=o||(i.warn("This browser does not support Web Storage!"),{setItem:a.noop,getItem:a.noop,removeItem:a.noop}),q={$default:function(b){for(var c in b)a.isDefined(q[c])||(q[c]=a.copy(b[c]));return q.$sync(),q},$reset:function(a){for(var b in q)"$"===b[0]||delete q[b]&&p.removeItem(e+b);return q.$default(a)},$sync:function(){for(var a,b=0,c=p.length;c>b;b++)(a=p.key(b))&&e===a.slice(0,n)&&(q[a.slice(n)]=g(p.getItem(a)))},$apply:function(){var b;if(m=null,!a.equals(q,l)){b=a.copy(l),a.forEach(q,function(c,d){a.isDefined(c)&&"$"!==d[0]&&(p.setItem(e+d,f(c)),delete b[d])});for(var c in b)p.removeItem(e+c);l=a.copy(q)}},$supported:function(){return!!o}};return q.$sync(),l=a.copy(q),d.$watch(function(){m||(m=j(q.$apply,100,!1))}),h.addEventListener&&h.addEventListener("storage",function(b){if(b.key){var c=k[0];c.hasFocus&&c.hasFocus()||e!==b.key.slice(0,n)||(b.newValue?q[b.key.slice(n)]=g(b.newValue):delete q[b.key.slice(n)],l=a.copy(q),d.$apply())}}),h.addEventListener&&h.addEventListener("beforeunload",function(){q.$apply()}),q}]}}return a=a&&a.module?a:window.angular,a.module("ngStorage",[]).provider("$localStorage",c("localStorage")).provider("$sessionStorage",c("sessionStorage"))}); 2 | -------------------------------------------------------------------------------- /partials/creature/template-addon.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | entry 5 |
6 | 7 |
8 |
9 |
10 |
11 |
12 | path_id 13 |
14 | 15 |
16 |
17 |
18 | mount 19 |
20 | 21 |
22 |
23 |
24 | bytes1 25 |
26 | 27 |
28 |
29 |
30 | bytes2 31 |
32 | 33 |
34 |
35 |
36 | emote 37 |
38 | 39 |
40 | 41 |
42 |
43 |
44 |
45 | auras 46 |
47 | 48 |
49 |
50 |
51 |
52 |
53 |
54 | 55 |
56 |
57 | 58 |
59 |
60 | -------------------------------------------------------------------------------- /partials/creature/quest-items.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 | Idx 6 | 7 |
8 |
9 | ItemId 10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 | 19 |
20 |
21 |
22 | 23 |
24 |
25 |
26 | 27 |
28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
IdxItemId
{{ creature.Idx }}{{creature.ItemId}}
44 |
45 |
46 | -------------------------------------------------------------------------------- /partials/gameobject/quest-items.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 | Idx 6 | 7 |
8 |
9 | ItemId 10 | 11 |
12 |
13 |
14 |
15 |
16 | 17 | 18 | 19 |
20 |
21 |
22 | 23 |
24 |
25 |
26 | 27 |
28 |
29 |
30 |
31 |
32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 |
IdxItemId
{{ gameobject.Idx }}{{gameobject.ItemId}}
44 |
45 |
46 | -------------------------------------------------------------------------------- /js/app/info.js: -------------------------------------------------------------------------------- 1 | /*jslint browser: true, white: true, plusplus: true, es5: true, eqeq: true*/ 2 | /*global angular, console, alert, squel*/ 3 | 4 | (function () { 5 | 'use strict'; 6 | 7 | var app = angular.module('keira2'); 8 | 9 | app.controller("InfoController", function ($scope, $http) { 10 | 11 | // Eventual error message 12 | $scope.errorText = ""; 13 | 14 | // Keira version 15 | $scope.keiraVersion = "DEV"; 16 | $scope.keiraTag = "v" + $scope.keiraVersion; 17 | 18 | // API min required version 19 | $scope.apiRequiredVersion = 0.6; 20 | 21 | // API version 22 | $http.get(app.api + "api") 23 | .success(function (data, status, header, config) { 24 | $scope.apiVersion = data.api_version; 25 | $scope.apiBranch = data.api_branch; 26 | 27 | if (parseFloat($scope.apiVersion, 10) < parseFloat($scope.apiRequiredVersion, 10)) { 28 | $scope.errorText = "ERROR: Your TrinityCore JSON API version is " + $scope.apiVersion + ", but Keira2 requires version " + $scope.apiRequiredVersion + ". Please update your API."; 29 | } 30 | }) 31 | .error(function (data, status, header, config) { 32 | $scope.errorText = "ERROR: API not found, please edit your config.js file and set the path of your TrinityCore JSON API istance."; 33 | console.log("[ERROR] /api/ $http.get request failed"); 34 | }); 35 | 36 | // Database world version 37 | $http.get(app.api + "version") 38 | .success(function (data, status, header, config) { 39 | $scope.databaseVersion = data[0].db_version; 40 | $scope.coreVersion = data[0].core_version; 41 | $scope.coreRevision = data[0].core_revision; 42 | }) 43 | .error(function (data, status, header, config) { 44 | console.log("[ERROR] /version/ $http.get request failed"); 45 | }); 46 | 47 | // Check for newer versions 48 | $scope.updateAvaialable = false; 49 | 50 | if ($scope.keiraVersion != "DEV") { 51 | $http.get( "https://api.github.com/repos/Helias/Keira2/releases" ) 52 | .success(function (data, status, header, config) { 53 | 54 | var latestReleaseTag = data[0].tag_name; 55 | 56 | if ($scope.keiraTag != latestReleaseTag) { 57 | $scope.updateAvaialable = true; 58 | } 59 | 60 | }) 61 | .error(function (data, status, header, config) { 62 | console.log("[ERROR] https://api.github.com/repos/Helias/Keira2/releases $http.get request failed"); 63 | }); 64 | } 65 | 66 | }); 67 | 68 | }()); 69 | -------------------------------------------------------------------------------- /js/app/gameobject/quest-items.js: -------------------------------------------------------------------------------- 1 | /*jslint browser: true, eqeq: true, white: true, plusplus: true */ 2 | /*global angular, console, alert*/ 3 | 4 | (function () { 5 | 'use strict'; 6 | 7 | var app = angular.module('keira2'); 8 | 9 | app.controller("GameObjectQuestItemsController", function ($scope, $rootScope, $stateParams) { 10 | 11 | /* At start we have no row selected */ 12 | $scope.selectedRow = -1; 13 | 14 | /* The item currently selected by the user (bound to the view) */ 15 | $scope.selected = { 16 | GameObject : parseInt($stateParams.id, 10), 17 | Idx : 0, 18 | ItemId : 0 19 | }; 20 | 21 | /* Type check */ 22 | $scope.parseValues = function() { 23 | $scope.selected.Idx = parseInt($scope.selected.Idx, 10); 24 | $scope.selected.ItemId = parseInt($scope.selected.ItemId, 10); 25 | }; 26 | 27 | /* Select a row from collection */ 28 | $scope.selectRow = function(rows, index) { 29 | $scope.selectedRow = index; 30 | $scope.selected = angular.copy(rows[index]); 31 | }; 32 | 33 | /* Delete selected row from collection */ 34 | $scope.deleteSelectedRowFrom = function(rows) { 35 | if (!$rootScope.isEntrySelected()) { return; } 36 | 37 | rows.splice($scope.selectedRow, 1); 38 | }; 39 | 40 | /* Edit selected row */ 41 | $scope.editSelectedRowOf = function(rows, primaryKey2) { 42 | if (!$scope.isEntrySelected()) { return; } 43 | var i; 44 | $scope.parseValues(); 45 | 46 | // check primaryKey2 uniqueness 47 | for (i = 0; i < rows.length; i++) { 48 | if ( (rows[i][primaryKey2] == $scope.selected[primaryKey2]) && (i !== $scope.selectedRow) ) { 49 | alert("Duplicate row with `" + primaryKey2 + "` = " + $scope.selected[primaryKey2]); 50 | return; 51 | } 52 | } 53 | 54 | rows.splice($scope.selectedRow, 1, angular.copy($scope.selected)); 55 | }; 56 | 57 | /* Add selected row to collection */ 58 | $scope.addRowTo = function(rows, primaryKey2) { 59 | if (!$rootScope.isEntrySelected()) { return; } 60 | var i; 61 | $scope.parseValues(); 62 | 63 | // check primaryKey2 uniqueness 64 | for (i = 0; i < rows.length; i++) { 65 | if (rows[i][primaryKey2] == $scope.selected[primaryKey2]) { 66 | alert("Duplicate row with `" + primaryKey2 + "` = " + $scope.selected[primaryKey2]); 67 | return; 68 | } 69 | } 70 | 71 | rows.splice(0, 0, angular.copy($scope.selected)); 72 | }; 73 | 74 | }); 75 | 76 | }()); 77 | -------------------------------------------------------------------------------- /js/app/routes.js: -------------------------------------------------------------------------------- 1 | /*jslint browser: true, white: true, plusplus: true*/ 2 | /*global angular, console, alert*/ 3 | 4 | (function () { 5 | 'use strict'; 6 | 7 | var app = angular.module('keira2'); 8 | 9 | app.config(function ($stateProvider, $urlRouterProvider, hljsServiceProvider) { 10 | 11 | /* routing */ 12 | 13 | // default route 14 | $urlRouterProvider.otherwise("/"); 15 | 16 | $stateProvider 17 | .state('info', { 18 | url: '/', 19 | controller: 'InfoController', 20 | templateUrl: 'partials/info.html' 21 | }) 22 | .state('quest', { 23 | url: '/quest', 24 | controller: 'QuestController', 25 | templateUrl: 'partials/quest.html' 26 | }) 27 | .state('questSelected', { 28 | url: '/quest/:id', 29 | controller: 'QuestController', 30 | templateUrl: 'partials/quest.html' 31 | }) 32 | .state('creature', { 33 | url: '/creature', 34 | controller: 'CreatureController', 35 | templateUrl: 'partials/creature.html' 36 | }) 37 | .state('creatureSelected', { 38 | url: '/creature/:id', 39 | controller: 'CreatureController', 40 | templateUrl: 'partials/creature.html' 41 | }) 42 | .state('gameobject', { 43 | url: '/gameobject', 44 | controller: 'GameobjectController', 45 | templateUrl: 'partials/gameobject.html' 46 | }) 47 | .state('gameobjectSelected', { 48 | url: '/gameobject/:id', 49 | controller: 'GameobjectController', 50 | templateUrl: 'partials/gameobject.html' 51 | }) 52 | .state('item', { 53 | url: '/item', 54 | controller: 'ItemController', 55 | templateUrl: 'partials/item.html' 56 | }) 57 | .state('itemSelected', { 58 | url: '/item/:id', 59 | controller: 'ItemController', 60 | templateUrl: 'partials/item.html' 61 | }) 62 | .state('character', { 63 | url: '/character', 64 | controller: 'CharacterController', 65 | templateUrl: 'partials/character.html' 66 | }) 67 | .state('characterSelected', { 68 | url: '/character/:id', 69 | controller: 'CharacterController', 70 | templateUrl: 'partials/character.html' 71 | }) 72 | .state('sai', { 73 | url: '/sai', 74 | controller: 'SmartAIController', 75 | templateUrl: 'partials/sai.html' 76 | }) 77 | .state('saiSelected', { 78 | url: '/sai/:sourceType/:entryOrGuid', 79 | controller: 'SmartAIController', 80 | templateUrl: 'partials/sai.html' 81 | }); 82 | 83 | }); 84 | 85 | }()); 86 | -------------------------------------------------------------------------------- /js/app/creature/quest-items.js: -------------------------------------------------------------------------------- 1 | /*jslint browser: true, eqeq: true, white: true, plusplus: true */ 2 | /*global angular, console, alert*/ 3 | 4 | (function () { 5 | 'use strict'; 6 | 7 | var app = angular.module('keira2'); 8 | 9 | app.controller("CreatureQuestItemsController", function ($scope, $rootScope, $stateParams) { 10 | 11 | /* At start we have no row selected */ 12 | $scope.selectedRow = -1; 13 | 14 | /* The item currently selected by the user (bound to the view) */ 15 | $scope.selected = { 16 | CreatureEntry : parseInt($stateParams.id, 10), 17 | Idx : 0, 18 | ItemId : 0 19 | }; 20 | 21 | /* Type check */ 22 | $scope.parseValues = function() { 23 | $scope.selected.Idx = parseInt($scope.selected.Idx, 10); 24 | $scope.selected.ItemId = parseInt($scope.selected.ItemId, 10); 25 | }; 26 | 27 | /* Select a row from collection */ 28 | $scope.selectRow = function(rows, index) { 29 | $scope.selectedRow = index; 30 | $scope.selected = angular.copy(rows[index]); 31 | }; 32 | 33 | /* Delete selected row from collection */ 34 | $scope.deleteSelectedRowFrom = function(rows) { 35 | if (!$rootScope.isEntrySelected()) { return; } 36 | 37 | rows.splice($scope.selectedRow, 1); 38 | }; 39 | 40 | /* Edit selected row */ 41 | $scope.editSelectedRowOf = function(rows, primaryKey2) { 42 | if (!$scope.isEntrySelected()) { return; } 43 | var i; 44 | $scope.parseValues(); 45 | 46 | // check primaryKey2 uniqueness 47 | for (i = 0; i < rows.length; i++) { 48 | if ( (rows[i][primaryKey2] == $scope.selected[primaryKey2]) && (i !== $scope.selectedRow) ) { 49 | alert("Duplicate row with `" + primaryKey2 + "` = " + $scope.selected[primaryKey2]); 50 | return; 51 | } 52 | } 53 | 54 | rows.splice($scope.selectedRow, 1, angular.copy($scope.selected)); 55 | }; 56 | 57 | /* Add selected row to collection */ 58 | $scope.addRowTo = function(rows, primaryKey2) { 59 | if (!$rootScope.isEntrySelected()) { return; } 60 | var i; 61 | $scope.parseValues(); 62 | 63 | // check primaryKey2 uniqueness 64 | for (i = 0; i < rows.length; i++) { 65 | if (rows[i][primaryKey2] == $scope.selected[primaryKey2]) { 66 | alert("Duplicate row with `" + primaryKey2 + "` = " + $scope.selected[primaryKey2]); 67 | return; 68 | } 69 | } 70 | 71 | rows.splice(0, 0, angular.copy($scope.selected)); 72 | }; 73 | 74 | }); 75 | 76 | }()); 77 | -------------------------------------------------------------------------------- /partials/info.html: -------------------------------------------------------------------------------- 1 |

A newer version of Keira2 has been released, please download and install the latest version.

2 |

{{ errorText }}

3 | 4 |

Informations

5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 |
Keira version: {{ keiraVersion }}
API version: {{ apiVersion }}
DB version: {{ databaseVersion }}
19 |
20 |

About Keira2

21 | 22 |

Created by Helias and ShinDarth

23 |

Released under the GNU AGPL license

24 |
25 |

 Remember to share your fixes with the community  

26 |


27 |   Give us a star if you like this software!

28 |
29 |
30 |

  Please report any bug here

31 |
32 |
33 |

You can donate if you want to support us

34 |
35 | 36 | 37 | 38 | 39 |
40 | -------------------------------------------------------------------------------- /partials/gameobject/modals/flags.html: -------------------------------------------------------------------------------- 1 | 4 | 54 | 58 | -------------------------------------------------------------------------------- /partials/creature/equip-template.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | CreatureID 5 |
6 | 7 |
8 |
9 |
10 | ID 11 |
12 | 13 |
14 |
15 |
16 | ItemID1 17 |
18 | 19 |
20 | 21 |
22 |
23 |
24 |
25 | ItemID2 26 |
27 | 28 |
29 | 30 |
31 |
32 |
33 |
34 | ItemID3 35 |
36 | 37 |
38 | 39 |
40 |
41 |
42 |
43 | VerifiedBuild 44 |
45 | 46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 | 54 |
55 |
56 | 57 |
58 |
59 | -------------------------------------------------------------------------------- /partials/creature.html: -------------------------------------------------------------------------------- 1 | {{ selectionText }} 2 | 3 | 4 |
5 |
6 | 7 |
8 |
9 | 10 |
11 |
12 | 13 |
14 |
15 | 16 |
17 |
18 | 19 |
20 |
21 | 22 |
23 |
24 | 25 |
26 |
27 | 28 |
29 |
30 | 31 |
32 |
33 | 34 |
35 |
36 | 37 |
38 |
39 | 40 |
41 |
42 | 43 |
44 |
45 |
46 | -------------------------------------------------------------------------------- /css/style.css: -------------------------------------------------------------------------------- 1 | /* Remove responsive from container */ 2 | .container { 3 | width: 1170px !important; 4 | max-width: none !important; 5 | } 6 | 7 | .input-xs { 8 | padding: 2px 5px !important; 9 | font-size: 12px; 10 | line-height: 1.5; 11 | border-radius: 3px !important; 12 | } 13 | 14 | input.input-xs, 15 | select.input-xs, 16 | button.input-xs { 17 | height: 22px; 18 | } 19 | 20 | .pointer { cursor: pointer; } 21 | 22 | .tr-selected { 23 | background-color: rgba(44,105,158, 0.4) !important; 24 | } 25 | 26 | .doc-link { 27 | margin-top: 8px; 28 | margin-bottom: 2px; 29 | } 30 | 31 | .lh { 32 | display: block; 33 | margin: 4px 0px 0px 0px; 34 | } 35 | 36 | .hr { 37 | margin-bottom: 4px; 38 | } 39 | 40 | .selection-text { 41 | margin-bottom: 4px; 42 | } 43 | 44 | .nav-tabs { 45 | margin-top: 8px; 46 | } 47 | 48 | .input-margin input { 49 | margin-top: 5px; 50 | } 51 | 52 | .tooltip-inner { 53 | max-width: 300px !important; 54 | width: 300px !important; 55 | } 56 | 57 | .borders { 58 | padding: 10px 20px 10px 20px; 59 | margin-bottom: 5px; 60 | margin-top: 5px; 61 | border: 1px solid rgba(0,0,0,0.2); 62 | } 63 | 64 | /* Info CSS */ 65 | 66 | .info-table { 67 | max-width: 400px; 68 | margin: auto; 69 | } 70 | 71 | .info-table tr td:first-child { 72 | text-align: right; 73 | } 74 | 75 | .info-table tr td:last-child { 76 | text-align: left; 77 | } 78 | 79 | /* Modal CSS */ 80 | 81 | .modal-lg { 82 | width: 1170px; 83 | } 84 | 85 | .modal-title { 86 | text-transform: capitalize; 87 | } 88 | 89 | .modal-body * { 90 | padding-left: 10px; 91 | } 92 | 93 | .modal-body tr, .modal-body label { 94 | cursor: pointer; 95 | } 96 | 97 | .modal-body input[type='checkbox'] { 98 | max-height: 16px; 99 | } 100 | 101 | .modal-overflow { 102 | height: 400px; 103 | overflow: auto; 104 | } 105 | 106 | /* SAI CSS */ 107 | 108 | .sai-editor-head > div { 109 | border-left: 1px solid grey; 110 | border-top: 1px solid grey; 111 | min-height: 256px; 112 | } 113 | 114 | .sai-editor-head > div:last-child { 115 | border-right: 1px solid grey; 116 | } 117 | 118 | .sai-options-container { 119 | min-height: 30px; 120 | padding-top: 8px; 121 | } 122 | 123 | .sai-option { 124 | margin-left: 8px; 125 | } 126 | 127 | .sai-table { 128 | transition: 1s linear; 129 | overflow-x: auto; 130 | width: 1170px; 131 | display: inline-block; 132 | } 133 | 134 | .sai-table-large { 135 | transition: 1s linear; 136 | width: 98vw; 137 | } 138 | 139 | .sai-table-box { 140 | left: 0px; 141 | position: absolute; 142 | width: 100vw; 143 | } 144 | -------------------------------------------------------------------------------- /js/app/trainer.js: -------------------------------------------------------------------------------- 1 | /*jslint browser: true, eqeq: true, white: true, plusplus: true */ 2 | /*global angular, console, alert*/ 3 | 4 | (function () { 5 | 'use strict'; 6 | 7 | var app = angular.module('keira2'); 8 | 9 | app.controller("TrainerController", function ($scope, $rootScope, $stateParams) { 10 | 11 | /* At start we have no row selected */ 12 | $scope.selectedRow = -1; 13 | 14 | /* The item currently selected by the user (bound to the view) */ 15 | $scope.selected = { 16 | ID : parseInt($stateParams.id, 10), 17 | SpellID : 0, 18 | MoneyCost : 0, 19 | ReqSkillLine : 0, 20 | ReqSkillRank : 0, 21 | ReqLevel : 0 22 | }; 23 | 24 | /* Type check */ 25 | $scope.parseValues = function() { 26 | 27 | $scope.selected.SpellID = parseInt($scope.selected.SpellID, 10); 28 | $scope.selected.MoneyCost = parseInt($scope.selected.MoneyCost, 10); 29 | $scope.selected.ReqSkillLine = parseInt($scope.selected.ReqSkillLine, 10); 30 | $scope.selected.ReqSkillRank = parseInt($scope.selected.ReqSkillRank, 10); 31 | $scope.selected.ReqLevel = parseInt($scope.selected.ReqLevel, 10); 32 | }; 33 | 34 | /* Select a row from collection */ 35 | $scope.selectRow = function(rows, index) { 36 | $scope.selectedRow = index; 37 | $scope.selected = angular.copy(rows[index]); 38 | }; 39 | 40 | /* Edit selected row */ 41 | $scope.editSelectedRowOf = function(rows, primaryKey2) { 42 | if (!$scope.isEntrySelected()) { return; } 43 | var i; 44 | $scope.parseValues(); 45 | 46 | // check primaryKey2 uniqueness 47 | for (i = 0; i < rows.length; i++) { 48 | if ( (rows[i][primaryKey2] == $scope.selected[primaryKey2]) && (i !== $scope.selectedRow) ) { 49 | alert("Duplicate row with `" + primaryKey2 + "` = " + $scope.selected[primaryKey2]); 50 | return; 51 | } 52 | } 53 | 54 | rows.splice($scope.selectedRow, 1, angular.copy($scope.selected)); 55 | }; 56 | 57 | /* Delete selected row from collection */ 58 | $scope.deleteSelectedRowFrom = function(rows) { 59 | if (!$rootScope.isEntrySelected()) { return; } 60 | 61 | rows.splice($scope.selectedRow, 1); 62 | }; 63 | 64 | /* Add selected row to collection */ 65 | $scope.addRowTo = function(rows, primaryKey2) { 66 | if (!$rootScope.isEntrySelected()) { return; } 67 | var i; 68 | $scope.parseValues(); 69 | 70 | // check primaryKey2 uniqueness 71 | for (i = 0; i < rows.length; i++) { 72 | if (rows[i][primaryKey2] == $scope.selected[primaryKey2]) { 73 | alert("Duplicate row with `" + primaryKey2 + "` = " + $scope.selected[primaryKey2]); 74 | return; 75 | } 76 | } 77 | 78 | rows.splice(0, 0, angular.copy($scope.selected)); 79 | }; 80 | 81 | }); 82 | 83 | }()); 84 | -------------------------------------------------------------------------------- /partials/character/character.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |
7 | account 8 |
9 | 10 |
11 |
12 |
13 | name 14 |
15 | 16 |
17 |
18 |
19 | race 20 |
21 | 22 |
23 | 24 |
25 |
26 |
27 |
28 | class 29 |
30 | 31 |
32 | 33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 | gender 42 |
43 | 44 |
45 |
46 |
47 | level 48 |
49 | 50 |
51 |
52 |
53 | xp 54 |
55 | 56 |
57 |
58 |
59 | money 60 |
61 | 62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 | 71 |
72 |
73 | 74 |
75 |
76 | -------------------------------------------------------------------------------- /js/app/loot.js: -------------------------------------------------------------------------------- 1 | /*jslint browser: true, eqeq: true, white: true, plusplus: true */ 2 | /*global angular, console, alert*/ 3 | 4 | (function () { 5 | 'use strict'; 6 | 7 | var app = angular.module('keira2'); 8 | 9 | app.controller("LootController", function ($scope, $rootScope, $stateParams) { 10 | 11 | /* At start we have no row selected */ 12 | $scope.selectedRow = -1; 13 | 14 | /* The item currently selected by the user (bound to the view) */ 15 | $scope.selected = { 16 | Entry : parseInt($stateParams.id, 10), 17 | Item : 0, 18 | Reference : 0, 19 | Chance : 100, 20 | QuestRequired : 0, 21 | LootMode : 1, 22 | GroupId : 0, 23 | MinCount : 1, 24 | MaxCount : 1, 25 | Comment : '' 26 | }; 27 | 28 | /* Type check */ 29 | $scope.parseValues = function() { 30 | 31 | $scope.selected.Item = parseInt($scope.selected.Item, 10); 32 | $scope.selected.Reference = parseInt($scope.selected.Reference, 10); 33 | $scope.selected.Chance = parseFloat($scope.selected.Chance, 10); 34 | $scope.selected.QuestRequired = parseInt($scope.selected.QuestRequired, 10); 35 | $scope.selected.LootMode = parseInt($scope.selected.LootMode, 10); 36 | $scope.selected.GroupId = parseInt($scope.selected.GroupId, 10); 37 | $scope.selected.MinCount = parseInt($scope.selected.MinCount, 10); 38 | $scope.selected.MaxCount = parseInt($scope.selected.MaxCount, 10); 39 | }; 40 | 41 | /* Select a row from collection */ 42 | $scope.selectRow = function(rows, index) { 43 | $scope.selectedRow = index; 44 | $scope.selected = angular.copy(rows[index]); 45 | }; 46 | 47 | /* Edit selected row */ 48 | $scope.editSelectedRowOf = function(rows, primaryKey2) { 49 | if (!$scope.isEntrySelected()) { return; } 50 | var i; 51 | $scope.parseValues(); 52 | 53 | // check primaryKey2 uniqueness 54 | for (i = 0; i < rows.length; i++) { 55 | if ( (rows[i][primaryKey2] == $scope.selected[primaryKey2]) && (i !== $scope.selectedRow) ) { 56 | alert("Duplicate row with `" + primaryKey2 + "` = " + $scope.selected[primaryKey2]); 57 | return; 58 | } 59 | } 60 | 61 | rows.splice($scope.selectedRow, 1, angular.copy($scope.selected)); 62 | }; 63 | 64 | /* Delete selected row from collection */ 65 | $scope.deleteSelectedRowFrom = function(rows) { 66 | if (!$rootScope.isEntrySelected()) { return; } 67 | 68 | rows.splice($scope.selectedRow, 1); 69 | }; 70 | 71 | /* Add selected row to collection */ 72 | $scope.addRowTo = function(rows, primaryKey2) { 73 | if (!$rootScope.isEntrySelected()) { return; } 74 | var i; 75 | $scope.parseValues(); 76 | 77 | // check primaryKey2 uniqueness 78 | for (i = 0; i < rows.length; i++) { 79 | if (rows[i][primaryKey2] == $scope.selected[primaryKey2]) { 80 | alert("Duplicate row with `" + primaryKey2 + "` = " + $scope.selected[primaryKey2]); 81 | return; 82 | } 83 | } 84 | 85 | rows.splice(0, 0, angular.copy($scope.selected)); 86 | }; 87 | 88 | }); 89 | 90 | }()); 91 | -------------------------------------------------------------------------------- /js/app/switcher.js: -------------------------------------------------------------------------------- 1 | /*jslint browser: true, white: true, plusplus: true*/ 2 | /*global angular, console, alert*/ 3 | 4 | (function () { 5 | 'use strict'; 6 | 7 | var app = angular.module('keira2'); 8 | 9 | app.controller("SwitcherController", function ($scope, $http, $localStorage, $location, $rootScope, $state) { 10 | 11 | /* Versions */ 12 | $scope.versions = [ 13 | { name: "3.3.5" }, 14 | { name: "6.x" } 15 | ]; 16 | 17 | /* Themes */ 18 | $scope.themes = [ 19 | { name: "Default", url: "css/bootstrap.min.css"}, 20 | { name: "Amelia", url: "css/themes/bootswatch/3.3.0/amelia.css"}, 21 | { name: "Cerulean", url: "css/themes/bootswatch/3.3.6/cerulean.css"}, 22 | { name: "Cosmo", url: "css/themes/bootswatch/3.3.6/cosmo.css"}, 23 | { name: "Cyborg", url: "css/themes/bootswatch/3.3.6/cyborg.css"}, 24 | { name: "Darkly", url: "css/themes/bootswatch/3.3.6/darkly.css"}, 25 | { name: "Flatly", url: "css/themes/bootswatch/3.3.6/flatly.css"}, 26 | { name: "Journal", url: "css/themes/bootswatch/3.3.6/journal.css"}, 27 | { name: "Lumen", url: "css/themes/bootswatch/3.3.6/lumen.css"}, 28 | { name: "Paper", url: "css/themes/bootswatch/3.3.6/paper.css"}, 29 | { name: "Readable", url: "css/themes/bootswatch/3.3.6/readable.css"}, 30 | { name: "Sandstone", url: "css/themes/bootswatch/3.3.6/sandstone.css"}, 31 | { name: "Simplex", url: "css/themes/bootswatch/3.3.6/simplex.css"}, 32 | { name: "Slate", url: "css/themes/bootswatch/3.3.6/slate.css"}, 33 | { name: "Spacelab", url: "css/themes/bootswatch/3.3.6/spacelab.css"}, 34 | { name: "Superhero", url: "css/themes/bootswatch/3.3.6/superhero.css"}, 35 | { name: "United", url: "css/themes/bootswatch/3.3.6/united.css"}, 36 | { name: "Yeti", url: "css/themes/bootswatch/3.3.6/yeti.css"} 37 | ]; 38 | 39 | // initialize localStorage with default theme 40 | $rootScope.$storage = $localStorage.$default({ 41 | theme: { 42 | name: $scope.themes[0].name, 43 | url: $scope.themes[0].urls 44 | }, 45 | version: { 46 | name: $scope.versions[0].name 47 | } 48 | }); 49 | 50 | // the theme switching method 51 | $scope.setTheme = function(theme) { 52 | // don't do anything if the theme is the same 53 | if (theme.name !== $scope.theme.name) { 54 | // set the model so the directive updates 55 | $scope.theme = theme; 56 | // save the new theme to localStorage 57 | $scope.$storage.theme = theme; 58 | } 59 | }; 60 | 61 | // the version switching method 62 | $scope.setVersion = function(version) { 63 | // set the model so the directive updates 64 | $scope.version = version; 65 | // save the new version to localStorage 66 | $scope.$storage.version = version; 67 | 68 | if (app.apiInstances[version.name]) { 69 | $localStorage.api = app.api = app.apiInstances[version.name]; 70 | $state.reload(); 71 | } 72 | console.log("[INFO] API path changed: " + app.api); 73 | }; 74 | 75 | // initialize theme and version - pull from localStorage (which gets the default if none is set) 76 | $scope.theme = $scope.$storage.theme; 77 | $rootScope.version = $scope.$storage.version; 78 | }); 79 | 80 | }()); 81 | -------------------------------------------------------------------------------- /js/lib/loading-bar.min.js: -------------------------------------------------------------------------------- 1 | /*! 2 | * angular-loading-bar v0.8.0 3 | * https://chieffancypants.github.io/angular-loading-bar 4 | * Copyright (c) 2015 Wes Cruver 5 | * License: MIT 6 | */ 7 | !function(){"use strict";angular.module("angular-loading-bar",["cfp.loadingBarInterceptor"]),angular.module("chieffancypants.loadingBar",["cfp.loadingBarInterceptor"]),angular.module("cfp.loadingBarInterceptor",["cfp.loadingBar"]).config(["$httpProvider",function(a){var b=["$q","$cacheFactory","$timeout","$rootScope","$log","cfpLoadingBar",function(b,c,d,e,f,g){function h(){d.cancel(j),g.complete(),l=0,k=0}function i(b){var d,e=c.get("$http"),f=a.defaults;!b.cache&&!f.cache||b.cache===!1||"GET"!==b.method&&"JSONP"!==b.method||(d=angular.isObject(b.cache)?b.cache:angular.isObject(f.cache)?f.cache:e);var g=void 0!==d?void 0!==d.get(b.url):!1;return void 0!==b.cached&&g!==b.cached?b.cached:(b.cached=g,g)}var j,k=0,l=0,m=g.latencyThreshold;return{request:function(a){return a.ignoreLoadingBar||i(a)||(e.$broadcast("cfpLoadingBar:loading",{url:a.url}),0===k&&(j=d(function(){g.start()},m)),k++,g.set(l/k)),a},response:function(a){return a&&a.config?(a.config.ignoreLoadingBar||i(a.config)||(l++,e.$broadcast("cfpLoadingBar:loaded",{url:a.config.url,result:a}),l>=k?h():g.set(l/k)),a):(f.error("Broken interceptor detected: Config object not supplied in response:\n https://github.com/chieffancypants/angular-loading-bar/pull/50"),a)},responseError:function(a){return a&&a.config?(a.config.ignoreLoadingBar||i(a.config)||(l++,e.$broadcast("cfpLoadingBar:loaded",{url:a.config.url,result:a}),l>=k?h():g.set(l/k)),b.reject(a)):(f.error("Broken interceptor detected: Config object not supplied in rejection:\n https://github.com/chieffancypants/angular-loading-bar/pull/50"),b.reject(a))}}}];a.interceptors.push(b)}]),angular.module("cfp.loadingBar",[]).provider("cfpLoadingBar",function(){this.autoIncrement=!0,this.includeSpinner=!0,this.includeBar=!0,this.latencyThreshold=100,this.startSize=.02,this.parentSelector="body",this.spinnerTemplate='
',this.loadingBarTemplate='
',this.$get=["$injector","$document","$timeout","$rootScope",function(a,b,c,d){function e(){k||(k=a.get("$animate"));var e=b.find(n).eq(0);c.cancel(m),r||(d.$broadcast("cfpLoadingBar:started"),r=!0,v&&k.enter(o,e,angular.element(e[0].lastChild)),u&&k.enter(q,e,angular.element(e[0].lastChild)),f(w))}function f(a){if(r){var b=100*a+"%";p.css("width",b),s=a,t&&(c.cancel(l),l=c(function(){g()},250))}}function g(){if(!(h()>=1)){var a=0,b=h();a=b>=0&&.25>b?(3*Math.random()+3)/100:b>=.25&&.65>b?3*Math.random()/100:b>=.65&&.9>b?2*Math.random()/100:b>=.9&&.99>b?.005:0;var c=h()+a;f(c)}}function h(){return s}function i(){s=0,r=!1}function j(){k||(k=a.get("$animate")),d.$broadcast("cfpLoadingBar:completed"),f(1),c.cancel(m),m=c(function(){var a=k.leave(o,i);a&&a.then&&a.then(i),k.leave(q)},500)}var k,l,m,n=this.parentSelector,o=angular.element(this.loadingBarTemplate),p=o.find("div").eq(0),q=angular.element(this.spinnerTemplate),r=!1,s=0,t=this.autoIncrement,u=this.includeSpinner,v=this.includeBar,w=this.startSize;return{start:e,set:f,status:h,inc:g,complete:j,autoIncrement:this.autoIncrement,includeSpinner:this.includeSpinner,latencyThreshold:this.latencyThreshold,parentSelector:this.parentSelector,startSize:this.startSize}}]})}(); 8 | -------------------------------------------------------------------------------- /js/app/quest/objectives.js: -------------------------------------------------------------------------------- 1 | /*jslint browser: true, eqeq: true, white: true, plusplus: true */ 2 | /*global angular, console, alert*/ 3 | 4 | (function () { 5 | 'use strict'; 6 | 7 | var app = angular.module('keira2'); 8 | 9 | app.controller("QuestObjectivesController", function ($scope, $rootScope, $stateParams) { 10 | 11 | /* At start we have no row selected */ 12 | $scope.selectedRow = -1; 13 | 14 | /* The item currently selected by the user (bound to the view) */ 15 | $scope.selected = { 16 | ID : 0, 17 | QuestID : parseInt($stateParams.id, 10), 18 | Type : 0, 19 | StorageIndex : 0, 20 | ObjectID : 0, 21 | Amount : 0, 22 | Flags : 0, 23 | UnkFloat : 0, 24 | Description : '', 25 | VerifiedBuild : 0 26 | }; 27 | console.log($scope.selected); 28 | 29 | /* Type check */ 30 | $scope.parseValues = function() { 31 | 32 | $scope.selected.ID = parseInt($scope.selected.ID, 10); 33 | $scope.selected.Type = parseInt($scope.selected.Type, 10); 34 | $scope.selected.StorageIndex = parseInt($scope.selected.StorageIndex, 10); 35 | $scope.selected.ObjectID = parseInt($scope.selected.ObjectID, 10); 36 | $scope.selected.Amount = parseInt($scope.selected.Amount, 10); 37 | $scope.selected.Flags = parseInt($scope.selected.Flags, 10); 38 | $scope.selected.UnkFloat = parseInt($scope.selected.UnkFloat, 10); 39 | $scope.selected.VerifiedBuild = parseInt($scope.selected.VerifiedBuild, 10); 40 | }; 41 | 42 | /* Select a row from collection */ 43 | $scope.selectRow = function(rows, index) { 44 | $scope.selectedRow = index; 45 | $scope.selected = angular.copy(rows[index]); 46 | console.log($scope.selected); 47 | }; 48 | 49 | /* Edit selected row */ 50 | $scope.editSelectedRowOf = function(rows, primaryKey2) { 51 | if (!$scope.isEntrySelected()) { return; } 52 | var i; 53 | $scope.parseValues(); 54 | 55 | // check primaryKey2 uniqueness 56 | for (i = 0; i < rows.length; i++) { 57 | if ( (rows[i][primaryKey2] == $scope.selected[primaryKey2]) && (i !== $scope.selectedRow) ) { 58 | alert("Duplicate row with `" + primaryKey2 + "` = " + $scope.selected[primaryKey2]); 59 | return; 60 | } 61 | } 62 | 63 | rows.splice($scope.selectedRow, 1, angular.copy($scope.selected)); 64 | }; 65 | 66 | /* Delete selected row from collection */ 67 | $scope.deleteSelectedRowFrom = function(rows) { 68 | if (!$rootScope.isEntrySelected()) { return; } 69 | 70 | rows.splice($scope.selectedRow, 1); 71 | }; 72 | 73 | /* Add selected row to collection */ 74 | $scope.addRowTo = function(rows, primaryKey2) { 75 | if (!$rootScope.isEntrySelected()) { return; } 76 | var i; 77 | $scope.parseValues(); 78 | 79 | // check primaryKey2 uniqueness 80 | for (i = 0; i < rows.length; i++) { 81 | if (rows[i][primaryKey2] == $scope.selected[primaryKey2]) { 82 | alert("Duplicate row with `" + primaryKey2 + "` = " + $scope.selected[primaryKey2]); 83 | return; 84 | } 85 | } 86 | 87 | rows.splice(0, 0, angular.copy($scope.selected)); 88 | }; 89 | 90 | }); 91 | 92 | }()); 93 | -------------------------------------------------------------------------------- /js/app/vendor.js: -------------------------------------------------------------------------------- 1 | /*jslint browser: true, eqeq: true, white: true, plusplus: true */ 2 | /*global angular, console, alert*/ 3 | 4 | (function () { 5 | 'use strict'; 6 | 7 | var app = angular.module('keira2'); 8 | 9 | app.controller("VendorController", function ($scope, $rootScope, $stateParams) { 10 | 11 | /* At start we have no row selected */ 12 | $scope.selectedRow = -1; 13 | 14 | /* The item currently selected by the user (bound to the view) */ 15 | $scope.selected = { 16 | entry : parseInt($stateParams.id, 10), 17 | slot : 0, 18 | item : 0, 19 | maxcount : 0, 20 | incrtime : 0, 21 | ExtendedCost : 0, 22 | VerifiedBuild : 0 23 | }; 24 | 25 | if ($rootScope.$storage.version.name == "6.x") { 26 | $scope.selected.type = 0; 27 | $scope.selected.PlayerConditionID = 0; 28 | $scope.selected.IgnoreFiltering = 0; 29 | } 30 | 31 | /* Type check */ 32 | $scope.parseValues = function() { 33 | 34 | $scope.selected.slot = parseInt($scope.selected.slot, 10); 35 | $scope.selected.item = parseInt($scope.selected.item, 10); 36 | $scope.selected.maxcount = parseInt($scope.selected.maxcount, 10); 37 | $scope.selected.incrtime = parseInt($scope.selected.incrtime, 10); 38 | $scope.selected.ExtendedCost = parseInt($scope.selected.ExtendedCost, 10); 39 | $scope.selected.VerifiedBuild = parseInt($scope.selected.VerifiedBuild, 10); 40 | 41 | if ($rootScope.$storage.version.name == "6.x") { 42 | $scope.selected.type = parseInt($scope.selected.type, 10); 43 | $scope.selected.PlayerConditionID = parseInt($scope.selected.PlayerConditionID, 10); 44 | $scope.selected.IgnoreFiltering = parseInt($scope.selected.IgnoreFiltering, 10); 45 | } 46 | }; 47 | 48 | /* Select a row from collection */ 49 | $scope.selectRow = function(rows, index) { 50 | $scope.selectedRow = index; 51 | $scope.selected = angular.copy(rows[index]); 52 | }; 53 | 54 | /* Edit selected row */ 55 | $scope.editSelectedRowOf = function(rows, primaryKey2) { 56 | if (!$scope.isEntrySelected()) { return; } 57 | var i; 58 | $scope.parseValues(); 59 | 60 | // check primaryKey2 uniqueness 61 | for (i = 0; i < rows.length; i++) { 62 | if ( (rows[i][primaryKey2] == $scope.selected[primaryKey2]) && (i !== $scope.selectedRow) ) { 63 | alert("Duplicate row with `" + primaryKey2 + "` = " + $scope.selected[primaryKey2]); 64 | return; 65 | } 66 | } 67 | 68 | rows.splice($scope.selectedRow, 1, angular.copy($scope.selected)); 69 | }; 70 | 71 | /* Delete selected row from collection */ 72 | $scope.deleteSelectedRowFrom = function(rows) { 73 | if (!$rootScope.isEntrySelected()) { return; } 74 | 75 | rows.splice($scope.selectedRow, 1); 76 | }; 77 | 78 | /* Add selected row to collection */ 79 | $scope.addRowTo = function(rows, primaryKey2) { 80 | if (!$rootScope.isEntrySelected()) { return; } 81 | var i; 82 | $scope.parseValues(); 83 | 84 | // check primaryKey2 uniqueness 85 | for (i = 0; i < rows.length; i++) { 86 | if (rows[i][primaryKey2] == $scope.selected[primaryKey2]) { 87 | alert("Duplicate row with `" + primaryKey2 + "` = " + $scope.selected[primaryKey2]); 88 | return; 89 | } 90 | } 91 | 92 | rows.splice(0, 0, angular.copy($scope.selected)); 93 | }; 94 | 95 | }); 96 | 97 | }()); 98 | -------------------------------------------------------------------------------- /partials/creature/on-kill-reputation.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 | creature_id (entry) 5 |
6 | 7 |
8 |
9 |
10 |
11 |
12 | RewOnKillRepFaction1 13 |
14 | 15 |
16 | 17 |
18 |
19 |
20 |
21 | RewOnKillRepValue1 22 |
23 | 24 |
25 |
26 |
27 | MaxStanding1 28 |
29 | 30 |
31 |
32 |
33 | IsTeamAward1 34 |
35 | 36 |
37 |
38 |
39 |
40 |
41 | RewOnKillRepFaction2 42 |
43 | 44 |
45 | 46 |
47 |
48 |
49 |
50 | RewOnKillRepValue2 51 |
52 | 53 |
54 |
55 |
56 | MaxStanding2 57 |
58 | 59 |
60 |
61 |
62 | IsTeamAward2 63 |
64 | 65 |
66 |
67 |
68 |
69 |
70 | TeamDependent 71 |
72 | 73 |
74 |
75 |
76 |
77 |
78 | 79 |
80 |
81 | 82 |
83 |
84 | -------------------------------------------------------------------------------- /partials/creature/spawns-addon.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |
7 | guid 8 | 9 |
10 |
11 | path_id 12 | 13 |
14 |
15 | mount 16 | 17 |
18 |
19 | bytes1 20 |
21 | 22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 | bytes2 30 | 31 |
32 |
33 | emote 34 |
35 | 36 |
37 | 38 |
39 |
40 |
41 |
42 | auras 43 | 44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 | 53 | 54 | 55 |
56 |
57 |
58 | 59 |
60 |
61 |
62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 |
guidpath_idmountbytes1bytes2emoteauras
{{ spawn.guid }}{{ spawn.path_id }}{{ spawn.mount }}{{ spawn.bytes1 }}{{ spawn.bytes2 }}{{ spawn.emote }}{{ spawn.auras }}
84 | -------------------------------------------------------------------------------- /partials/creature/trainer.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |
7 | SpellID 8 |
9 | 10 |
11 | 12 |
13 |
14 |
15 |
16 | MoneyCost 17 | 18 |
19 |
20 | ReqSkillLine 21 |
22 | 23 |
24 | 25 |
26 |
27 |
28 |
29 | ReqSkillRank 30 |
31 | 32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 | ReqLevel 40 | 41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 | 50 | 51 | 52 |
53 |
54 |
55 | 56 |
57 |
58 |
59 | 60 |
61 |
62 |
63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 |
SpellIDMoneyCostReqSkillLineReqSkillRankReqLevel
{{ trainer.SpellID }}{{ trainer.MoneyCost }}{{ trainer.ReqSkillLine }}{{ trainer.ReqSkillRank }}{{ trainer.ReqLevel }}
81 | -------------------------------------------------------------------------------- /partials/quest/modals/flags.html: -------------------------------------------------------------------------------- 1 | 4 | 92 | 96 | -------------------------------------------------------------------------------- /js/app/character.js: -------------------------------------------------------------------------------- 1 | 2 | /*jslint browser: true, white: true, plusplus: true */ 3 | /*global angular, console, alert*/ 4 | 5 | (function () { 6 | 'use strict'; 7 | 8 | var app = angular.module('keira2'); 9 | 10 | app.controller("CharacterController", function ($rootScope, $scope, $http, $stateParams, $uibModal) { 11 | 12 | /* All Character tabs, disabled by default. 13 | * Only one tab can be active at a time */ 14 | $scope.characterTabs = { 15 | search : false, 16 | character : false 17 | }; 18 | 19 | /* Init arrays */ 20 | // no object arrays at the moment 21 | 22 | /* Check if a character is selected */ 23 | if ($stateParams.id) { 24 | 25 | /* We have a character selected and default active tab is characterTemplate */ 26 | $scope.isCharacterSelected = true; 27 | $scope.characterTabs.character = true; 28 | 29 | /* Following lines retrieve all character data 30 | * current_* mantains the database state 31 | * new_* mantains the editor state 32 | * we will use those two objects to generate the SQL queries 33 | */ 34 | 35 | /* Retrieve all characters data */ 36 | $http.get( app.api + "characters/" + $stateParams.id, { 37 | params: { no_extra_fields : 1 } 38 | }) 39 | .success(function (data, status, header, config) { 40 | $scope.current_characters = $rootScope.fixNumericValues(data[0]); 41 | $scope.new_characters = angular.copy($scope.current_characters); 42 | $scope.selectionText = $scope.current_characters.name + " (" + $scope.current_characters.guid +") "; 43 | }) 44 | .error(function (data, status, header, config) { 45 | console.log("[ERROR] characters/" + $stateParams.id + " $http.get request failed"); 46 | }); 47 | 48 | } else { 49 | /* We have no character selected and default active tab is search */ 50 | $scope.isCharacterSelected = false; 51 | $scope.characterTabs.search = true; 52 | $scope.selectionText = "No Character selected. Please use Search to select one."; 53 | } 54 | 55 | /* [Function] Search */ 56 | $scope.search = function (characterGuid, characterName) { 57 | 58 | if ( characterName && !characterGuid && (characterName.length < 2) ) { 59 | alert("Please insert a Name of at least 2 characters"); 60 | return; 61 | } 62 | 63 | $http.get( app.api + "search/character/", { 64 | params: { 65 | guid: characterGuid, 66 | name: characterName 67 | } 68 | }).success(function (data, status, header, config) { 69 | $scope.characters = $rootScope.fixNumericValues(data); 70 | }) 71 | .error(function (data, status, header, config) { 72 | console.log("[ERROR] character SEARCH $http.get request failed"); 73 | }); 74 | 75 | }; 76 | 77 | /* [Function] Generate SQL Script for Character */ 78 | $scope.generateCharacterScript = function() { 79 | 80 | if (!$scope.isCharacterSelected) { 81 | $scope.characterScript = "-- No Character selected"; 82 | return; 83 | } 84 | 85 | $scope.characterScript = ""; 86 | 87 | var whereCondition = "guid = " + $scope.current_characters.guid; 88 | 89 | // characters 90 | $scope.characterScript += app.getUpdateQuery("characters", whereCondition, $scope.current_characters, $scope.new_characters); 91 | }; 92 | 93 | /* [Function] disactive all tabs */ 94 | $scope.disactiveAllTabs = function() { 95 | angular.forEach($scope.characterTabs, function(value, key) { 96 | value = false; 97 | }); 98 | }; 99 | 100 | /* [Function] open SQL Script tab */ 101 | $scope.openScriptTab = function() { 102 | $scope.disactiveAllTabs(); 103 | $scope.generateCharacterScript(); 104 | $scope.characterTabs.script = true; 105 | }; 106 | 107 | }); 108 | 109 | }()); 110 | -------------------------------------------------------------------------------- /partials/item/modals/races.html: -------------------------------------------------------------------------------- 1 | 4 | 96 | 100 | -------------------------------------------------------------------------------- /partials/creature/modals/flags-extra.html: -------------------------------------------------------------------------------- 1 | 4 | 100 | 104 | -------------------------------------------------------------------------------- /js/lib/angular-highlightjs.min.js: -------------------------------------------------------------------------------- 1 | /*! angular-highlightjs 2 | version: 0.5.1 3 | build date: 2015-11-08 4 | author: Chih-Hsuan Fan 5 | https://github.com/pc035860/angular-highlightjs.git */ 6 | !function(a,b){"object"==typeof exports||"object"==typeof module&&module.exports?module.exports=b(require("angular"),require("highlight.js")):"function"==typeof define&&define.amd?define(["angular","hljs"],b):a.returnExports=b(a.angular,a.hljs)}(this,function(a,b){function c(b){var c=!0;return a.forEach(["source","include"],function(a){b[a]&&(c=!1)}),c}var d=a.module("hljs",[]);d.provider("hljsService",function(){var c={};return{setOptions:function(b){a.extend(c,b)},getOptions:function(){return a.copy(c)},$get:function(){return(b.configure||a.noop)(c),b}}}),d.factory("hljsCache",["$cacheFactory",function(a){return a("hljsCache")}]),d.controller("HljsCtrl",["hljsCache","hljsService","$interpolate","$window","$log",function(b,c,d,e,f){function g(a,b,c){var d;return function(){var f=this,g=arguments,h=function(){d=null,c||a.apply(f,g)},i=c&&!d;e.clearTimeout(d),d=e.setTimeout(h,b),i&&a.apply(f,g)}}function h(a,b){var c=b?"\\\\$&":"\\$&";return a.replace(/[-[\]{}()*+?.,\\^$|#\s]/g,c)}function i(a){for(var b,c=[],d=new RegExp(r,"g"),e="",f=0;null!==(b=d.exec(a));)e+=a.substring(f,b.index)+s,f=b.index+b[0].length,c.push(b[0]);return e+=a.substr(f),{code:e,tokens:c}}function j(a,b){for(var c,d=new RegExp(s,"g"),e="",f=0;null!==(c=d.exec(a));)e+=a.substring(f,c.index)+b.shift(),f=c.index+c[0].length;return e+=a.substr(f)}var k=this,l=null,m=null,n=null,o=!1,p=null,q=null,r=h(d.startSymbol())+"((.|\\s)+?)"+h(d.endSymbol()),s="∫";k.init=function(a){l=a},k.setInterpolateScope=function(a){o=a,n&&k.highlight(n)},k.setLanguage=function(a){m=a,n&&k.highlight(n)},k.highlightCallback=function(a){q=a},k._highlight=function(e){if(l){var f,g,h;if(n=e,o&&(h=i(e),e=h.code),m?(g=k._cacheKey(m,!!o,e),f=b.get(g),f||(f=c.highlight(m,c.fixMarkup(e),!0),b.put(g,f))):(g=k._cacheKey(!!o,e),f=b.get(g),f||(f=c.highlightAuto(c.fixMarkup(e)),b.put(g,f))),e=f.value,o){(p||a.noop)(),h&&(e=j(e,h.tokens));var r=d(e);p=o.$watch(r,function(a,b){a!==b&&l.html(a)}),l.html(r(o))}else l.html(e);l.addClass(f.language),null!==q&&a.isFunction(q)&&q()}},k.highlight=g(k._highlight,17),k.clear=function(){l&&(n=null,l.text(""))},k.release=function(){l=null,o=null,(p||a.noop)(),p=null},k._cacheKey=function(){var a=Array.prototype.slice.call(arguments),b="!angular-highlightjs!";return a.join(b)}}]);var e,f,g,h,i;return e=["$parse",function(b){return{restrict:"EA",controller:"HljsCtrl",compile:function(d,e,f){var g=d[0].innerHTML.replace(/^(\r\n|\r|\n)/m,""),h=d[0].textContent.replace(/^(\r\n|\r|\n)/m,"");return d.html('
'),function(d,e,f,i){var j;if(a.isDefined(f.escape)?j=b(f.escape):a.isDefined(f.noEscape)&&(j=b("false")),i.init(e.find("code")),f.onhighlight&&i.highlightCallback(function(){d.$eval(f.onhighlight)}),(g||h)&&c(f)){var k;k=j&&!j(d)?h:g,i.highlight(k)}d.$on("$destroy",function(){i.release()})}}}}],g=function(b){return function(){return{require:"?hljs",restrict:"A",link:function(c,d,e,f){f&&e.$observe(b,function(b){a.isDefined(b)&&f.setLanguage(b)})}}}},f=function(a){return function(){return{require:"?hljs",restrict:"A",link:function(b,c,d,e){e&&b.$watch(d[a],function(a,c){(a||a!==c)&&e.setInterpolateScope(a?b:null)})}}}},h=function(a){return function(){return{require:"?hljs",restrict:"A",link:function(b,c,d,e){e&&b.$watch(d[a],function(a,b){a?e.highlight(a):e.clear()})}}}},i=function(b){return["$http","$templateCache","$q",function(c,d,e){return{require:"?hljs",restrict:"A",compile:function(f,g,h){var i=g[b];return function(b,f,g,h){var j=0;h&&b.$watch(i,function(b){var f=++j;if(b&&a.isString(b)){var g,i;g=d.get(b),g||(i=e.defer(),c.get(b,{cache:d,transformResponse:function(a,b){return a}}).success(function(a){f===j&&i.resolve(a)}).error(function(){f===j&&h.clear(),i.resolve()}),g=i.promise),e.when(g).then(function(b){b&&(a.isArray(b)?b=b[1]:a.isObject(b)&&(b=b.data),b=b.replace(/^(\r\n|\r|\n)/m,""),h.highlight(b))})}else h.clear()})}}}}]},function(b){b.directive("hljs",e),a.forEach(["interpolate","hljsInterpolate","compile","hljsCompile"],function(a){b.directive(a,f(a))}),a.forEach(["language","hljsLanguage"],function(a){b.directive(a,g(a))}),a.forEach(["source","hljsSource"],function(a){b.directive(a,h(a))}),a.forEach(["include","hljsInclude"],function(a){b.directive(a,i(a))})}(d),"hljs"}); 7 | -------------------------------------------------------------------------------- /partials/creature/modals/unit-flags2.html: -------------------------------------------------------------------------------- 1 | 4 | 100 | 104 | -------------------------------------------------------------------------------- /partials/quest/objectives.html: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 |
5 |
6 | 7 |
8 | ID 9 | 10 |
11 |
12 | Type 13 | 14 |
15 |
16 | StorageIndex 17 | 18 |
19 |
20 | ObjectID 21 | 22 |
23 |
24 | Amount 25 | 26 |
27 |
28 | Flags 29 | 30 |
31 |
32 | UnkFloat 33 | 34 |
35 |
36 | Description 37 | 38 |
39 |
40 | VerifiedBuild 41 | 42 |
43 | 44 |
45 |
46 |
47 |
48 | 49 | 50 | 51 |
52 |
53 |
54 | 55 |
56 |
57 |
58 | 59 |
60 |
61 |
62 |
63 |
64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 |
IDTypeStorageIndexObjectIDAmountFlagsUnkFloatDescriptionVerifiedBuild
{{ objective.ID }}{{ objective.Type }}{{ objective.StorageIndex }}{{ objective.ObjectID }}{{ objective.Amount }}{{ objective.Flags }}{{ objective.UnkFloat }}{{ objective.Description }}{{ objective.VerifiedBuild }}
90 |
91 |
92 | 93 |
94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | > [!IMPORTANT] 2 | > Keira2 is no longer being mantained and has been archived by the Keira's authors as for: 16th of June, 2019. 3 | > 4 | > Keira development has moved from [TrinityCore](https://github.com/TrinityCore/TrinityCore) ([Keira2](https://github.com/Helias/Keira2)) to [AzerothCore](https://github.com/azerothcore/azerothcore-wotlk) ([Keira3](https://github.com/azerothcore/Keira3)) 5 | 6 | ------------------ 7 | 8 | ## Keira2 the TrinityCore Database Web-Editor 9 | 10 | This software is a Database Editor web application for the [TrinityCore MMORPG framework](https://github.com/TrinityCore/TrinityCore) built with [AngularJS](https://angularjs.org/) and using the [TrinityCore JSON RESTful API](https://github.com/ShinDarth/TC-JSON-API/) to retrieve database data. 11 | 12 | Keira2 allows the user to **edit the database via GUI** and **generates automatically the SQL code** for him/her. It is inspired by the old **Quice/Truice** database editor, originally developed by **indomit**, and by the [Discover-'s SAI Editor](https://github.com/Discover-/SAI-Editor). 13 | 14 | Using Keira2, you can edit **SmartAI**, **Quests**, **Creatures**, **Spawns**, **Loots**, **GameObjects**, **Items**, **Characters**, etc... 15 | 16 | Also you can change the GUI style choosing a different **graphic theme** using the theme-switcher button. There are several themes, light and dark ones. 17 | 18 | ![Keira2](http://shinworld.altervista.org/images/keira2/Keira2.png "Keira2") 19 | 20 | ## Live demo 21 | 22 | A live demo is available [here](https://keira2.altervista.org/Keira2-dev/). You can use it for production but be aware that its database may not be updated to the latest version. (Current Version: [TDB](https://github.com/TrinityCore/TrinityCore/issues/14421) 335.59) 23 | 24 | Also you can **help us** by testing the development version **without installing it**, simply using our [development live demo](http://keira2.altervista.org/Keira2-dev/). Remember to **clear your browser cache** before testing it and [report any bug or suggestion](https://github.com/Helias/Keira2/issues/new). 25 | 26 | ## Installation 27 | 28 | Keira2 fetches data from an istance of the [TrinityCore JSON API](https://github.com/ShinDarth/TC-JSON-API/), it can be installed either on the same machine or on an external one. 29 | 30 | You can install an istance of the TrinityCore JSON API using [this guide](https://github.com/ShinDarth/TC-JSON-API/blob/master/INSTALL.md). 31 | 32 | Once you have installed the API, download the [latest release of Keira2](https://github.com/Helias/Keira2/releases) and extract the Keira2 folder and place is inside your web server directory (e.g. /var/www/). 33 | 34 | Then open the Keira2 folder and copy the file config.js.dist to config.js, open it and set it properly with the path of the API: 35 | 36 | `app.api = "../TC-JSON-API/public/index.php/";` 37 | 38 | replace "../TC-JSON-API/public/index.php/" with the path of your API istance. 39 | 40 | If you have the TrinityCore JSON API on an external machine, you should set it like: 41 | 42 | `app.api = "http://www.your.external.server.org/path/to/TC-JSON-API/public/index.php/";` 43 | 44 | 45 | ### Contribute 46 | 47 | - You can help us even without installing your own Keira2 instance by testing our [development live demo](http://keira2.altervista.org/Keira2-dev/). 48 | - Report any bug or suggestion by [opening a new issue](https://github.com/Helias/Keira2/issues/new). 49 | - Check our [documentation](https://github.com/Helias/Keira2/wiki) to understand how the source is structured. 50 | 51 | or you can donate to support us 52 | 53 | [![Donate](https://www.paypal.com/en_GB/i/btn/btn_donateCC_LG.gif "Donate")](https://www.paypal.me/Stefano303) 54 | 55 | ### License 56 | 57 | Keira2 is open-sourced software licensed under the [GNU AGPL license](https://github.com/Helias/Keira2/blob/master/LICENSE). 58 | 59 | ### Screenshots 60 | 61 | ![Keira2](http://shinworld.altervista.org/images/keira2/Keira2-2.png "Keira2") 62 | ![Keira2](http://shinworld.altervista.org/images/keira2/Keira2-3.png "Keira2") 63 | ![Keira2](http://shinworld.altervista.org/images/keira2/Keira2-4.png "Keira2") 64 | ![Keira2](http://shinworld.altervista.org/images/keira2/Keira2-5.png "Keira2") 65 | ![Keira2](http://shinworld.altervista.org/images/keira2/Keira2-themes.png "Keira2") 66 | ![Keira2](http://shinworld.altervista.org/images/keira2/Keira2-themes2.png "Keira2") 67 | ![Keira2](http://shinworld.altervista.org/images/keira2/Keira2-themes3.png "Keira2") 68 | -------------------------------------------------------------------------------- /partials/quest/modals/required-races.html: -------------------------------------------------------------------------------- 1 | 4 | 104 | 108 | -------------------------------------------------------------------------------- /partials/sai/search-by-entity.html: -------------------------------------------------------------------------------- 1 |
2 |
3 |
4 |
5 | 6 | 12 |
13 |
14 |
15 |
16 |
17 |

Search for Creatures

18 |
19 |
20 |
21 | 22 | 23 |
24 |
25 | 26 | 27 |
28 |
29 | 30 | 31 |
32 |
33 | 34 |
35 |
36 |
37 |
38 |

Select the target of the new SmartAI script:

39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 |
EntryNameSubname
{{ creature.entry }}{{ creature.name }}{{ creature.subname }}
53 |
54 | 55 |
56 |

Search for Gameobjects

57 |
58 |
59 |
60 | 61 | 62 |
63 |
64 | 65 | 66 |
67 |
68 | 69 |
70 |
71 |
72 |
73 |

Select the target of the new SmartAI script:

74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 |
EntryName
{{ gameobject.entry }}{{ gameobject.name }}
86 | 87 |
88 | 89 |
90 |
91 |
92 | 93 | 94 |
95 |
96 | 97 |
98 |
99 |
100 | 101 |
102 |
103 |
104 | 105 | 106 |
107 |
108 | 109 |
110 |
111 |
112 | -------------------------------------------------------------------------------- /partials/creature/vendor.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |
7 | item 8 |
9 | 10 |
11 | 12 |
13 |
14 |
15 |
16 | slot 17 | 18 |
19 |
20 | maxcount 21 | 22 |
23 |
24 | incrtime 25 |
26 | 27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 | ExtendedCost 35 |
36 | 37 |
38 | 39 |
40 |
41 |
42 |
43 |
44 | type 45 | 46 |
47 |
48 | PlayerConditionID 49 | 50 |
51 |
52 | IgnoreFiltering 53 | 54 |
55 |
56 |
57 | VerifiedBuild 58 | 59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 | 68 | 69 | 70 |
71 |
72 |
73 | 74 |
75 |
76 |
77 | 78 |
79 |
80 |
81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 |
itemslotmaxcountincrtimeExtendedCosttypePlayerConditionIDIgnoreFilteringVerifiedBuild
{{vendor.item}}{{ vendor.slot }}{{ vendor.maxcount }}{{ vendor.incrtime }}{{ vendor.ExtendedCost }}{{ vendor.type }}{{ vendor.PlayerConditionID }}{{ vendor.IgnoreFiltering }}{{ vendor.VerifiedBuild }}
107 | -------------------------------------------------------------------------------- /partials/item/item-loot.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |
7 | Item 8 |
9 | 10 |
11 | 12 |
13 |
14 |
15 |
16 | Reference 17 | 18 |
19 |
20 | Chance 21 | 22 |
23 |
24 |
25 |
26 |
27 |
28 | QuestRequired 29 | 30 |
31 |
32 | LootMode 33 |
34 | 35 |
36 | 37 |
38 |
39 |
40 |
41 | GroupId 42 | 43 |
44 |
45 |
46 |
47 |
48 |
49 | MinCount 50 | 51 |
52 |
53 | MaxCount 54 | 55 |
56 |
57 | Comment 58 | 59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | 67 | 68 | 69 |
70 |
71 |
72 | 73 |
74 |
75 |
76 | 77 |
78 |
79 |
80 |
81 |
82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
ItemReferenceChanceQuestRequiredLootModeGroupIdMinCountMaxCountComment
{{ loot.Reference == 0 ? loot.Item : "" }}{{ loot.Reference != 0 ? loot.Item : "" }}{{ loot.Reference }}{{ loot.Chance }}{{ loot.QuestRequired }}{{ loot.LootMode }}{{ loot.GroupId }}{{ loot.MinCount }}{{ loot.MaxCount }}{{ loot.Comment }}
108 |
109 |
110 | -------------------------------------------------------------------------------- /partials/item/milling-loot.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |
7 | Item 8 |
9 | 10 |
11 | 12 |
13 |
14 |
15 |
16 | Reference 17 | 18 |
19 |
20 | Chance 21 | 22 |
23 |
24 |
25 |
26 |
27 |
28 | QuestRequired 29 | 30 |
31 |
32 | LootMode 33 |
34 | 35 |
36 | 37 |
38 |
39 |
40 |
41 | GroupId 42 | 43 |
44 |
45 |
46 |
47 |
48 |
49 | MinCount 50 | 51 |
52 |
53 | MaxCount 54 | 55 |
56 |
57 | Comment 58 | 59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | 67 | 68 | 69 |
70 |
71 |
72 | 73 |
74 |
75 |
76 | 77 |
78 |
79 |
80 |
81 |
82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
ItemReferenceChanceQuestRequiredLootModeGroupIdMinCountMaxCountComment
{{ loot.Reference == 0 ? loot.Item : "" }}{{ loot.Reference != 0 ? loot.Item : "" }}{{ loot.Reference }}{{ loot.Chance }}{{ loot.QuestRequired }}{{ loot.LootMode }}{{ loot.GroupId }}{{ loot.MinCount }}{{ loot.MaxCount }}{{ loot.Comment }}
108 |
109 |
110 | -------------------------------------------------------------------------------- /partials/creature/creature-loot.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |
7 | Item 8 |
9 | 10 |
11 | 12 |
13 |
14 |
15 |
16 | Reference 17 | 18 |
19 |
20 | Chance 21 | 22 |
23 |
24 |
25 |
26 |
27 |
28 | QuestRequired 29 | 30 |
31 |
32 | LootMode 33 |
34 | 35 |
36 | 37 |
38 |
39 |
40 |
41 | GroupId 42 | 43 |
44 |
45 |
46 |
47 |
48 |
49 | MinCount 50 | 51 |
52 |
53 | MaxCount 54 | 55 |
56 |
57 | Comment 58 | 59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | 67 | 68 | 69 |
70 |
71 |
72 | 73 |
74 |
75 |
76 | 77 |
78 |
79 |
80 |
81 |
82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
ItemReferenceChanceQuestRequiredLootModeGroupIdMinCountMaxCountComment
{{ loot.Reference == 0 ? loot.Item : "" }}{{ loot.Reference != 0 ? loot.Item : "" }}{{ loot.Reference }}{{ loot.Chance }}{{ loot.QuestRequired }}{{ loot.LootMode }}{{ loot.GroupId }}{{ loot.MinCount }}{{ loot.MaxCount }}{{ loot.Comment }}
108 |
109 |
110 | -------------------------------------------------------------------------------- /partials/creature/skinning-loot.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |
7 | Item 8 |
9 | 10 |
11 | 12 |
13 |
14 |
15 |
16 | Reference 17 | 18 |
19 |
20 | Chance 21 | 22 |
23 |
24 |
25 |
26 |
27 |
28 | QuestRequired 29 | 30 |
31 |
32 | LootMode 33 |
34 | 35 |
36 | 37 |
38 |
39 |
40 |
41 | GroupId 42 | 43 |
44 |
45 |
46 |
47 |
48 |
49 | MinCount 50 | 51 |
52 |
53 | MaxCount 54 | 55 |
56 |
57 | Comment 58 | 59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | 67 | 68 | 69 |
70 |
71 |
72 | 73 |
74 |
75 |
76 | 77 |
78 |
79 |
80 |
81 |
82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
ItemReferenceChanceQuestRequiredLootModeGroupIdMinCountMaxCountComment
{{ loot.Reference == 0 ? loot.Item : "" }}{{ loot.Reference != 0 ? loot.Item : "" }}{{ loot.Reference }}{{ loot.Chance }}{{ loot.QuestRequired }}{{ loot.LootMode }}{{ loot.GroupId }}{{ loot.MinCount }}{{ loot.MaxCount }}{{ loot.Comment }}
108 |
109 |
110 | -------------------------------------------------------------------------------- /partials/gameobject/loot.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |
7 | Item 8 |
9 | 10 |
11 | 12 |
13 |
14 |
15 |
16 | Reference 17 | 18 |
19 |
20 | Chance 21 | 22 |
23 |
24 |
25 |
26 |
27 |
28 | QuestRequired 29 | 30 |
31 |
32 | LootMode 33 |
34 | 35 |
36 | 37 |
38 |
39 |
40 |
41 | GroupId 42 | 43 |
44 |
45 |
46 |
47 |
48 |
49 | MinCount 50 | 51 |
52 |
53 | MaxCount 54 | 55 |
56 |
57 | Comment 58 | 59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | 67 | 68 | 69 |
70 |
71 |
72 | 73 |
74 |
75 |
76 | 77 |
78 |
79 |
80 |
81 |
82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
ItemReferenceChanceQuestRequiredLootModeGroupIdMinCountMaxCountComment
{{ loot.Reference == 0 ? loot.Item : "" }}{{ loot.Reference != 0 ? loot.Item : "" }}{{ loot.Reference }}{{ loot.Chance }}{{ loot.QuestRequired }}{{ loot.LootMode }}{{ loot.GroupId }}{{ loot.MinCount }}{{ loot.MaxCount }}{{ loot.Comment }}
108 |
109 |
110 | -------------------------------------------------------------------------------- /partials/item/disenchant-loot.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |
7 | Item 8 |
9 | 10 |
11 | 12 |
13 |
14 |
15 |
16 | Reference 17 | 18 |
19 |
20 | Chance 21 | 22 |
23 |
24 |
25 |
26 |
27 |
28 | QuestRequired 29 | 30 |
31 |
32 | LootMode 33 |
34 | 35 |
36 | 37 |
38 |
39 |
40 |
41 | GroupId 42 | 43 |
44 |
45 |
46 |
47 |
48 |
49 | MinCount 50 | 51 |
52 |
53 | MaxCount 54 | 55 |
56 |
57 | Comment 58 | 59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | 67 | 68 | 69 |
70 |
71 |
72 | 73 |
74 |
75 |
76 | 77 |
78 |
79 |
80 |
81 |
82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
ItemReferenceChanceQuestRequiredLootModeGroupIdMinCountMaxCountComment
{{ loot.Reference == 0 ? loot.Item : "" }}{{ loot.Reference != 0 ? loot.Item : "" }}{{ loot.Reference }}{{ loot.Chance }}{{ loot.QuestRequired }}{{ loot.LootMode }}{{ loot.GroupId }}{{ loot.MinCount }}{{ loot.MaxCount }}{{ loot.Comment }}
108 |
109 |
110 | -------------------------------------------------------------------------------- /partials/item/prospecting-loot.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |
7 | Item 8 |
9 | 10 |
11 | 12 |
13 |
14 |
15 |
16 | Reference 17 | 18 |
19 |
20 | Chance 21 | 22 |
23 |
24 |
25 |
26 |
27 |
28 | QuestRequired 29 | 30 |
31 |
32 | LootMode 33 |
34 | 35 |
36 | 37 |
38 |
39 |
40 |
41 | GroupId 42 | 43 |
44 |
45 |
46 |
47 |
48 |
49 | MinCount 50 | 51 |
52 |
53 | MaxCount 54 | 55 |
56 |
57 | Comment 58 | 59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | 67 | 68 | 69 |
70 |
71 |
72 | 73 |
74 |
75 |
76 | 77 |
78 |
79 |
80 |
81 |
82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
ItemReferenceChanceQuestRequiredLootModeGroupIdMinCountMaxCountComment
{{ loot.Reference == 0 ? loot.Item : "" }}{{ loot.Reference != 0 ? loot.Item : "" }}{{ loot.Reference }}{{ loot.Chance }}{{ loot.QuestRequired }}{{ loot.LootMode }}{{ loot.GroupId }}{{ loot.MinCount }}{{ loot.MaxCount }}{{ loot.Comment }}
108 |
109 |
110 | -------------------------------------------------------------------------------- /partials/creature/modals/npcflag.html: -------------------------------------------------------------------------------- 1 | 4 | 124 | 128 | -------------------------------------------------------------------------------- /partials/creature/pickpocket-loot.html: -------------------------------------------------------------------------------- 1 | 2 |
3 |
4 |
5 |
6 |
7 | Item 8 |
9 | 10 |
11 | 12 |
13 |
14 |
15 |
16 | Reference 17 | 18 |
19 |
20 | Chance 21 | 22 |
23 |
24 |
25 |
26 |
27 |
28 | QuestRequired 29 | 30 |
31 |
32 | LootMode 33 |
34 | 35 |
36 | 37 |
38 |
39 |
40 |
41 | GroupId 42 | 43 |
44 |
45 |
46 |
47 |
48 |
49 | MinCount 50 | 51 |
52 |
53 | MaxCount 54 | 55 |
56 |
57 | Comment 58 | 59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 | 67 | 68 | 69 |
70 |
71 |
72 | 73 |
74 |
75 |
76 | 77 |
78 |
79 |
80 |
81 |
82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 |
ItemReferenceChanceQuestRequiredLootModeGroupIdMinCountMaxCountComment
{{ loot.Reference == 0 ? loot.Item : "" }}{{ loot.Reference != 0 ? loot.Item : "" }}{{ loot.Reference }}{{ loot.Chance }}{{ loot.QuestRequired }}{{ loot.LootMode }}{{ loot.GroupId }}{{ loot.MinCount }}{{ loot.MaxCount }}{{ loot.Comment }}
108 |
109 |
110 | --------------------------------------------------------------------------------