diff --git a/client/src/components/cryp.spawn.button.jsx b/client/src/components/construct.spawn.button.jsx similarity index 100% rename from client/src/components/cryp.spawn.button.jsx rename to client/src/components/construct.spawn.button.jsx diff --git a/client/src/components/cryp.spawn.container.js b/client/src/components/construct.spawn.container.js similarity index 100% rename from client/src/components/cryp.spawn.container.js rename to client/src/components/construct.spawn.container.js diff --git a/client/src/components/game.cryp.jsx b/client/src/components/game.construct.jsx similarity index 100% rename from client/src/components/game.cryp.jsx rename to client/src/components/game.construct.jsx diff --git a/client/src/components/instance.cryps.jsx b/client/src/components/instance.constructs.jsx similarity index 100% rename from client/src/components/instance.cryps.jsx rename to client/src/components/instance.constructs.jsx diff --git a/phaser-client/.eslintrc.js b/phaser-client/.eslintrc.js deleted file mode 100755 index 2bb5ed38..00000000 --- a/phaser-client/.eslintrc.js +++ /dev/null @@ -1,1504 +0,0 @@ -module.exports = { - // extends: [ - // 'plugin:react/recommended', - // ], - env: { - browser: true, - node: true - }, - parserOptions: { - ecmaVersion: 6, - sourceType: 'module', - }, - plugins: [ - 'import' - ], - settings: { - // react: { - // pragma: "preact", - // version: "15.0", - // }, - 'import/resolver': { - node: { - extensions: ['.mjs', '.js', '.jsx', '.json'] - } - }, - 'import/extensions': [ - '.js', - '.mjs', - '.jsx', - ], - 'import/core-modules': [], - 'import/ignore': [ - 'node_modules', - '\\.(coffee|scss|css|less|hbs|svg|json)$', - ], - }, - rules: { - // prevents stupid complaints a la - // (req) { - // req.something = x; - // } - 'no-param-reassign': [2, { props: false }], - 'no-multi-spaces': [0], - 'max-len': ['error', 120], - 'import/no-extraneous-dependencies': [0], - 'prefer-arrow-callback': [0], - 'arrow-body-style': [0], - 'no-return-assign': [2, 'except-parens'], - 'no-console': [0], - // i like loops - 'no-plusplus': [0], - 'no-await-in-loop': [0], - 'indent': ['error', 4], - 'keyword-spacing': ['error'], - 'key-spacing': ['error'], - - // for preact - // "react/react-in-jsx-scope": [0], - // "react/jsx-indent": [2, 4], - // "react/jsx-uses-react": 1, - // "react/jsx-uses-vars": 1, - // "react/prefer-stateless-function": 1, - // "react/prop-types": 0, - - // airbnb copypasta - // enforces getter/setter pairs in objects - 'accessor-pairs': 'off', - - // enforces return statements in callbacks of array's methods - // https://eslint.org/docs/rules/array-callback-return - 'array-callback-return': ['error', { allowImplicit: true }], - - // treat var statements as if they were block scoped - 'block-scoped-var': 'error', - - // specify the maximum cyclomatic complexity allowed in a program - complexity: ['off', 11], - - // enforce that class methods use "this" - // https://eslint.org/docs/rules/class-methods-use-this - 'class-methods-use-this': ['error', { - exceptMethods: [], - }], - - // require return statements to either always or never specify values - 'consistent-return': 'error', - - // specify curly brace conventions for all control statements - curly: ['error', 'multi-line'], - - // require default case in switch statements - 'default-case': ['error', { commentPattern: '^no default$' }], - - // encourages use of dot notation whenever possible - 'dot-notation': ['error', { allowKeywords: true }], - - // enforces consistent newlines before or after dots - // https://eslint.org/docs/rules/dot-location - 'dot-location': ['error', 'property'], - - // require the use of === and !== - // https://eslint.org/docs/rules/eqeqeq - eqeqeq: ['error', 'always', { null: 'ignore' }], - - // make sure for-in loops have an if statement - 'guard-for-in': 'error', - - // enforce a maximum number of classes per file - // https://eslint.org/docs/rules/max-classes-per-file - // TODO: semver-major (eslint 5): enable - 'max-classes-per-file': ['off', 1], - - // disallow the use of alert, confirm, and prompt - 'no-alert': 'warn', - - // disallow use of arguments.caller or arguments.callee - 'no-caller': 'error', - - // disallow lexical declarations in case/default clauses - // https://eslint.org/docs/rules/no-case-declarations.html - 'no-case-declarations': 'error', - - // disallow division operators explicitly at beginning of regular expression - // https://eslint.org/docs/rules/no-div-regex - 'no-div-regex': 'off', - - // disallow else after a return in an if - // https://eslint.org/docs/rules/no-else-return - 'no-else-return': ['error', { allowElseIf: false }], - - // disallow empty functions, except for standalone funcs/arrows - // https://eslint.org/docs/rules/no-empty-function - 'no-empty-function': ['error', { - allow: [ - 'arrowFunctions', - 'functions', - 'methods', - ] - }], - - // disallow empty destructuring patterns - // https://eslint.org/docs/rules/no-empty-pattern - 'no-empty-pattern': 'error', - - // disallow comparisons to null without a type-checking operator - 'no-eq-null': 'off', - - // disallow use of eval() - 'no-eval': 'error', - - // disallow adding to native types - 'no-extend-native': 'error', - - // disallow unnecessary function binding - 'no-extra-bind': 'error', - - // disallow Unnecessary Labels - // https://eslint.org/docs/rules/no-extra-label - 'no-extra-label': 'error', - - // disallow fallthrough of case statements - 'no-fallthrough': 'error', - - // disallow the use of leading or trailing decimal points in numeric literals - 'no-floating-decimal': 'error', - - // disallow reassignments of native objects or read-only globals - // https://eslint.org/docs/rules/no-global-assign - 'no-global-assign': ['error', { exceptions: [] }], - // deprecated in favor of no-global-assign - 'no-native-reassign': 'off', - - // disallow implicit type conversions - // https://eslint.org/docs/rules/no-implicit-coercion - 'no-implicit-coercion': ['off', { - boolean: false, - number: true, - string: true, - allow: [], - }], - - // disallow var and named functions in global scope - // https://eslint.org/docs/rules/no-implicit-globals - 'no-implicit-globals': 'off', - - // disallow use of eval()-like methods - 'no-implied-eval': 'error', - - // disallow this keywords outside of classes or class-like objects - 'no-invalid-this': 'off', - - // disallow usage of __iterator__ property - 'no-iterator': 'error', - - // disallow use of labels for anything other then loops and switches - 'no-labels': ['error', { allowLoop: false, allowSwitch: false }], - - // disallow unnecessary nested blocks - 'no-lone-blocks': 'error', - - // disallow creation of functions within loops - 'no-loop-func': 'error', - - // disallow magic numbers - // https://eslint.org/docs/rules/no-magic-numbers - 'no-magic-numbers': ['off', { - ignore: [], - ignoreArrayIndexes: true, - enforceConst: true, - detectObjects: false, - }], - - // disallow use of multiple spaces - 'no-multi-spaces': ['error', { - ignoreEOLComments: false, - }], - - // disallow use of multiline strings - 'no-multi-str': 'error', - - // disallow use of new operator when not part of the assignment or comparison - 'no-new': 'error', - - // disallow use of new operator for Function object - 'no-new-func': 'error', - - // disallows creating new instances of String, Number, and Boolean - 'no-new-wrappers': 'error', - - // disallow use of (old style) octal literals - 'no-octal': 'error', - - // disallow use of octal escape sequences in string literals, such as - // var foo = 'Copyright \251'; - 'no-octal-escape': 'error', - - // disallow reassignment of function parameters - // disallow parameter object manipulation except for specific exclusions - // rule: https://eslint.org/docs/rules/no-param-reassign.html - 'no-param-reassign': ['error', { - props: true, - ignorePropertyModificationsFor: [ - 'acc', // for reduce accumulators - 'accumulator', // for reduce accumulators - 'e', // for e.returnvalue - 'ctx', // for Koa routing - 'req', // for Express requests - 'request', // for Express requests - 'res', // for Express responses - 'response', // for Express responses - '$scope', // for Angular 1 scopes - ] - }], - - // disallow usage of __proto__ property - 'no-proto': 'error', - - // disallow declaring the same variable more then once - 'no-redeclare': 'error', - - // disallow certain object properties - // https://eslint.org/docs/rules/no-restricted-properties - 'no-restricted-properties': ['error', { - object: 'arguments', - property: 'callee', - message: 'arguments.callee is deprecated', - }, { - object: 'global', - property: 'isFinite', - message: 'Please use Number.isFinite instead', - }, { - object: 'self', - property: 'isFinite', - message: 'Please use Number.isFinite instead', - }, { - object: 'window', - property: 'isFinite', - message: 'Please use Number.isFinite instead', - }, { - object: 'global', - property: 'isNaN', - message: 'Please use Number.isNaN instead', - }, { - object: 'self', - property: 'isNaN', - message: 'Please use Number.isNaN instead', - }, { - object: 'window', - property: 'isNaN', - message: 'Please use Number.isNaN instead', - }, { - property: '__defineGetter__', - message: 'Please use Object.defineProperty instead.', - }, { - property: '__defineSetter__', - message: 'Please use Object.defineProperty instead.', - }, { - object: 'Math', - property: 'pow', - message: 'Use the exponentiation operator (**) instead.', - }], - - // disallow use of assignment in return statement - 'no-return-assign': ['error', 'always'], - - // disallow redundant `return await` - 'no-return-await': 'error', - - // disallow use of `javascript:` urls. - 'no-script-url': 'error', - - // disallow self assignment - // https://eslint.org/docs/rules/no-self-assign - // TODO: semver-major: props -> true - 'no-self-assign': ['error', { - props: false, - }], - - // disallow comparisons where both sides are exactly the same - 'no-self-compare': 'error', - - // disallow use of comma operator - 'no-sequences': 'error', - - // restrict what can be thrown as an exception - 'no-throw-literal': 'error', - - // disallow unmodified conditions of loops - // https://eslint.org/docs/rules/no-unmodified-loop-condition - 'no-unmodified-loop-condition': 'off', - - // disallow usage of expressions in statement position - 'no-unused-expressions': ['error', { - allowShortCircuit: false, - allowTernary: false, - allowTaggedTemplates: false, - }], - - // disallow unused labels - // https://eslint.org/docs/rules/no-unused-labels - 'no-unused-labels': 'error', - - // disallow unnecessary .call() and .apply() - 'no-useless-call': 'off', - - // disallow useless string concatenation - // https://eslint.org/docs/rules/no-useless-concat - 'no-useless-concat': 'error', - - // disallow unnecessary string escaping - // https://eslint.org/docs/rules/no-useless-escape - 'no-useless-escape': 'error', - - // disallow redundant return; keywords - // https://eslint.org/docs/rules/no-useless-return - 'no-useless-return': 'error', - - // disallow use of void operator - // https://eslint.org/docs/rules/no-void - 'no-void': 'error', - - // disallow usage of configurable warning terms in comments: e.g. todo - 'no-warning-comments': ['off', { terms: ['todo', 'fixme', 'xxx'], location: 'start' }], - - // disallow use of the with statement - 'no-with': 'error', - - // require using Error objects as Promise rejection reasons - // https://eslint.org/docs/rules/prefer-promise-reject-errors - 'prefer-promise-reject-errors': ['error', { allowEmptyReject: true }], - - // require use of the second argument for parseInt() - radix: 'error', - - // require `await` in `async function` (note: this is a horrible rule that should never be used) - // https://eslint.org/docs/rules/require-await - 'require-await': 'off', - - // Enforce the use of u flag on RegExp - // https://eslint.org/docs/rules/require-unicode-regexp - 'require-unicode-regexp': 'off', - - // requires to declare all vars on top of their containing scope - 'vars-on-top': 'error', - - // require immediate function invocation to be wrapped in parentheses - // https://eslint.org/docs/rules/wrap-iife.html - 'wrap-iife': ['error', 'outside', { functionPrototypeMethods: false }], - - // require or disallow Yoda conditions - yoda: 'error', - - // Enforce “for” loop update clause moving the counter in the right direction - // https://eslint.org/docs/rules/for-direction - 'for-direction': 'error', - - // Enforces that a return statement is present in property getters - // https://eslint.org/docs/rules/getter-return - 'getter-return': ['error', { allowImplicit: true }], - - // disallow using an async function as a Promise executor - // https://eslint.org/docs/rules/no-async-promise-executor - // TODO: enable, semver-major - 'no-async-promise-executor': 'off', - - // Disallow await inside of loops - // https://eslint.org/docs/rules/no-await-in-loop - 'no-await-in-loop': 'error', - - // Disallow comparisons to negative zero - // https://eslint.org/docs/rules/no-compare-neg-zero - 'no-compare-neg-zero': 'error', - - // disallow assignment in conditional expressions - 'no-cond-assign': ['error', 'always'], - - // disallow use of console - 'no-console': 'warn', - - // disallow use of constant expressions in conditions - 'no-constant-condition': 'warn', - - // disallow control characters in regular expressions - 'no-control-regex': 'error', - - // disallow use of debugger - 'no-debugger': 'error', - - // disallow duplicate arguments in functions - 'no-dupe-args': 'error', - - // disallow duplicate keys when creating object literals - 'no-dupe-keys': 'error', - - // disallow a duplicate case label. - 'no-duplicate-case': 'error', - - // disallow empty statements - 'no-empty': 'error', - - // disallow the use of empty character classes in regular expressions - 'no-empty-character-class': 'error', - - // disallow assigning to the exception in a catch block - 'no-ex-assign': 'error', - - // disallow double-negation boolean casts in a boolean context - // https://eslint.org/docs/rules/no-extra-boolean-cast - 'no-extra-boolean-cast': 'error', - - // disallow unnecessary parentheses - // https://eslint.org/docs/rules/no-extra-parens - 'no-extra-parens': ['off', 'all', { - conditionalAssign: true, - nestedBinaryExpressions: false, - returnAssign: false, - ignoreJSX: 'all', // delegate to eslint-plugin-react - enforceForArrowConditionals: false, - }], - - // disallow unnecessary semicolons - 'no-extra-semi': 'error', - - // disallow overwriting functions written as function declarations - 'no-func-assign': 'error', - - // disallow function or variable declarations in nested blocks - 'no-inner-declarations': 'error', - - // disallow invalid regular expression strings in the RegExp constructor - 'no-invalid-regexp': 'error', - - // disallow irregular whitespace outside of strings and comments - 'no-irregular-whitespace': 'error', - - // Disallow characters which are made with multiple code points in character class syntax - // https://eslint.org/docs/rules/no-misleading-character-class - // TODO: enable, semver-major - 'no-misleading-character-class': 'off', - - // disallow the use of object properties of the global object (Math and JSON) as functions - 'no-obj-calls': 'error', - - // disallow use of Object.prototypes builtins directly - // https://eslint.org/docs/rules/no-prototype-builtins - 'no-prototype-builtins': 'error', - - // disallow multiple spaces in a regular expression literal - 'no-regex-spaces': 'error', - - // disallow sparse arrays - 'no-sparse-arrays': 'error', - - // Disallow template literal placeholder syntax in regular strings - // https://eslint.org/docs/rules/no-template-curly-in-string - 'no-template-curly-in-string': 'error', - - // Avoid code that looks like two expressions but is actually one - // https://eslint.org/docs/rules/no-unexpected-multiline - 'no-unexpected-multiline': 'error', - - // disallow unreachable statements after a return, throw, continue, or break statement - 'no-unreachable': 'error', - - // disallow return/throw/break/continue inside finally blocks - // https://eslint.org/docs/rules/no-unsafe-finally - 'no-unsafe-finally': 'error', - - // disallow negating the left operand of relational operators - // https://eslint.org/docs/rules/no-unsafe-negation - 'no-unsafe-negation': 'error', - // disallow negation of the left operand of an in expression - // deprecated in favor of no-unsafe-negation - 'no-negated-in-lhs': 'off', - - // Disallow assignments that can lead to race conditions due to usage of await or yield - // https://eslint.org/docs/rules/require-atomic-updates - // TODO: enable, semver-major - 'require-atomic-updates': 'off', - - // disallow comparisons with the value NaN - 'use-isnan': 'error', - - // ensure JSDoc comments are valid - // https://eslint.org/docs/rules/valid-jsdoc - 'valid-jsdoc': 'off', - - // ensure that the results of typeof are compared against a valid string - // https://eslint.org/docs/rules/valid-typeof - 'valid-typeof': ['error', { requireStringLiterals: true }], - - // enforces no braces where they can be omitted - // https://eslint.org/docs/rules/arrow-body-style - // TODO: enable requireReturnForObjectLiteral? - 'arrow-body-style': ['error', 'as-needed', { - requireReturnForObjectLiteral: false, - }], - - // require parens in arrow function arguments - // https://eslint.org/docs/rules/arrow-parens - 'arrow-parens': ['error', 'as-needed', { - requireForBlockBody: true, - }], - - // require space before/after arrow function's arrow - // https://eslint.org/docs/rules/arrow-spacing - 'arrow-spacing': ['error', { before: true, after: true }], - - // verify super() callings in constructors - 'constructor-super': 'error', - - // enforce the spacing around the * in generator functions - // https://eslint.org/docs/rules/generator-star-spacing - 'generator-star-spacing': ['error', { before: false, after: true }], - - // disallow modifying variables of class declarations - // https://eslint.org/docs/rules/no-class-assign - 'no-class-assign': 'error', - - // disallow arrow functions where they could be confused with comparisons - // https://eslint.org/docs/rules/no-confusing-arrow - 'no-confusing-arrow': ['error', { - allowParens: true, - }], - - // disallow modifying variables that are declared using const - 'no-const-assign': 'error', - - // disallow duplicate class members - // https://eslint.org/docs/rules/no-dupe-class-members - 'no-dupe-class-members': 'error', - - // disallow importing from the same path more than once - // https://eslint.org/docs/rules/no-duplicate-imports - // replaced by https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-duplicates.md - 'no-duplicate-imports': 'off', - - // disallow symbol constructor - // https://eslint.org/docs/rules/no-new-symbol - 'no-new-symbol': 'error', - - // disallow specific imports - // https://eslint.org/docs/rules/no-restricted-imports - 'no-restricted-imports': ['off', { - paths: [], - patterns: [] - }], - - // disallow to use this/super before super() calling in constructors. - // https://eslint.org/docs/rules/no-this-before-super - 'no-this-before-super': 'error', - - // disallow useless computed property keys - // https://eslint.org/docs/rules/no-useless-computed-key - 'no-useless-computed-key': 'error', - - // disallow unnecessary constructor - // https://eslint.org/docs/rules/no-useless-constructor - 'no-useless-constructor': 'error', - - // disallow renaming import, export, and destructured assignments to the same name - // https://eslint.org/docs/rules/no-useless-rename - 'no-useless-rename': ['error', { - ignoreDestructuring: false, - ignoreImport: false, - ignoreExport: false, - }], - - // require let or const instead of var - 'no-var': 'error', - - // require method and property shorthand syntax for object literals - // https://eslint.org/docs/rules/object-shorthand - 'object-shorthand': ['error', 'always', { - ignoreConstructors: false, - avoidQuotes: true, - }], - - // // suggest using arrow functions as callbacks - // 'prefer-arrow-callback': ['error', { - // allowNamedFunctions: false, - // allowUnboundThis: true, - // }], - - // suggest using of const declaration for variables that are never modified after declared - 'prefer-const': ['error', { - destructuring: 'any', - ignoreReadBeforeAssign: true, - }], - - // Prefer destructuring from arrays and objects - // https://eslint.org/docs/rules/prefer-destructuring - 'prefer-destructuring': ['error', { - VariableDeclarator: { - array: false, - object: true, - }, - AssignmentExpression: { - array: true, - object: true, - }, - }, { - enforceForRenamedProperties: false, - }], - - // disallow parseInt() in favor of binary, octal, and hexadecimal literals - // https://eslint.org/docs/rules/prefer-numeric-literals - 'prefer-numeric-literals': 'error', - - // suggest using Reflect methods where applicable - // https://eslint.org/docs/rules/prefer-reflect - 'prefer-reflect': 'off', - - // use rest parameters instead of arguments - // https://eslint.org/docs/rules/prefer-rest-params - 'prefer-rest-params': 'error', - - // suggest using the spread operator instead of .apply() - // https://eslint.org/docs/rules/prefer-spread - 'prefer-spread': 'error', - - // suggest using template literals instead of string concatenation - // https://eslint.org/docs/rules/prefer-template - 'prefer-template': 'error', - - // disallow generator functions that do not have yield - // https://eslint.org/docs/rules/require-yield - 'require-yield': 'error', - - // enforce spacing between object rest-spread - // https://eslint.org/docs/rules/rest-spread-spacing - 'rest-spread-spacing': ['error', 'never'], - - // import sorting - // https://eslint.org/docs/rules/sort-imports - 'sort-imports': ['off', { - ignoreCase: false, - ignoreMemberSort: false, - memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'], - }], - - // require a Symbol description - // https://eslint.org/docs/rules/symbol-description - 'symbol-description': 'error', - - // enforce usage of spacing in template strings - // https://eslint.org/docs/rules/template-curly-spacing - 'template-curly-spacing': 'error', - - // enforce spacing around the * in yield* expressions - // https://eslint.org/docs/rules/yield-star-spacing - 'yield-star-spacing': ['error', 'after'], - - // VARIABLES // - // enforce or disallow variable initializations at definition - 'init-declarations': 'off', - - // disallow the catch clause parameter name being the same as a variable in the outer scope - 'no-catch-shadow': 'off', - - // disallow deletion of variables - 'no-delete-var': 'error', - - // disallow labels that share a name with a variable - // https://eslint.org/docs/rules/no-label-var - 'no-label-var': 'error', - - // disallow specific globals - 'no-restricted-globals': ['error', 'isFinite', 'isNaN'], - - // disallow declaration of variables already declared in the outer scope - 'no-shadow': 'error', - - // disallow shadowing of names such as arguments - 'no-shadow-restricted-names': 'error', - - // disallow use of undeclared variables unless mentioned in a /*global */ block - 'no-undef': 'error', - - // disallow use of undefined when initializing variables - 'no-undef-init': 'error', - - // disallow use of undefined variable - // https://eslint.org/docs/rules/no-undefined - // TODO: enable? - 'no-undefined': 'off', - - // disallow declaration of variables that are not used in the code - 'no-unused-vars': ['error', { vars: 'all', args: 'after-used', ignoreRestSiblings: true }], - - // disallow use of variables before they are defined - 'no-use-before-define': ['error', { functions: true, classes: true, variables: true }], - - // STYLE // - - // enforce line breaks after opening and before closing array brackets - // https://eslint.org/docs/rules/array-bracket-newline - // TODO: enable? semver-major - 'array-bracket-newline': ['off', 'consistent'], // object option alternative: { multiline: true, minItems: 3 } - - // enforce line breaks between array elements - // https://eslint.org/docs/rules/array-element-newline - // TODO: enable? semver-major - 'array-element-newline': ['off', { multiline: true, minItems: 3 }], - - // enforce spacing inside array brackets - 'array-bracket-spacing': ['error', 'never'], - - // enforce spacing inside single-line blocks - // https://eslint.org/docs/rules/block-spacing - 'block-spacing': ['error', 'always'], - - // enforce one true brace style - 'brace-style': ['error', '1tbs', { allowSingleLine: true }], - - // require camel case names - // TODO: semver-major (eslint 5): add ignoreDestructuring: false option - camelcase: ['error', { properties: 'never' }], - - // enforce or disallow capitalization of the first letter of a comment - // https://eslint.org/docs/rules/capitalized-comments - 'capitalized-comments': ['off', 'never', { - line: { - ignorePattern: '.*', - ignoreInlineComments: true, - ignoreConsecutiveComments: true, - }, - block: { - ignorePattern: '.*', - ignoreInlineComments: true, - ignoreConsecutiveComments: true, - }, - }], - - // require trailing commas in multiline object literals - 'comma-dangle': ['error', { - arrays: 'always-multiline', - objects: 'always-multiline', - imports: 'always-multiline', - exports: 'always-multiline', - // functions: 'always-multiline', - }], - - // enforce spacing before and after comma - 'comma-spacing': ['error', { before: false, after: true }], - - // enforce one true comma style - 'comma-style': ['error', 'last', { - exceptions: { - ArrayExpression: false, - ArrayPattern: false, - ArrowFunctionExpression: false, - CallExpression: false, - FunctionDeclaration: false, - FunctionExpression: false, - ImportDeclaration: false, - ObjectExpression: false, - ObjectPattern: false, - VariableDeclaration: false, - NewExpression: false, - } - }], - - // disallow padding inside computed properties - 'computed-property-spacing': ['error', 'never'], - - // enforces consistent naming when capturing the current execution context - 'consistent-this': 'off', - - // enforce newline at the end of file, with no multiple empty lines - 'eol-last': ['error', 'always'], - - // enforce spacing between functions and their invocations - // https://eslint.org/docs/rules/func-call-spacing - 'func-call-spacing': ['error', 'never'], - - // requires function names to match the name of the variable or property to which they are - // assigned - // https://eslint.org/docs/rules/func-name-matching - // TODO: semver-major (eslint 5): add considerPropertyDescriptor: true - 'func-name-matching': ['off', 'always', { - includeCommonJSModuleExports: false - }], - - // require function expressions to have a name - // https://eslint.org/docs/rules/func-names - 'func-names': 'warn', - - // enforces use of function declarations or expressions - // https://eslint.org/docs/rules/func-style - // TODO: enable - 'func-style': ['off', 'expression'], - - // enforce consistent line breaks inside function parentheses - // https://eslint.org/docs/rules/function-paren-newline - 'function-paren-newline': ['error', 'consistent'], - - // Blacklist certain identifiers to prevent them being used - // https://eslint.org/docs/rules/id-blacklist - 'id-blacklist': 'off', - - // this option enforces minimum and maximum identifier lengths - // (variable names, property names etc.) - 'id-length': 'off', - - // require identifiers to match the provided regular expression - 'id-match': 'off', - - // Enforce the location of arrow function bodies with implicit returns - // https://eslint.org/docs/rules/implicit-arrow-linebreak - 'implicit-arrow-linebreak': ['error', 'beside'], - - // this option sets a specific tab width for your code - // https://eslint.org/docs/rules/indent - indent: ['error', 4, { - SwitchCase: 1, - VariableDeclarator: 1, - outerIIFEBody: 1, - // MemberExpression: null, - FunctionDeclaration: { - parameters: 1, - body: 1 - }, - FunctionExpression: { - parameters: 1, - body: 1 - }, - CallExpression: { - arguments: 1 - }, - ArrayExpression: 1, - ObjectExpression: 1, - ImportDeclaration: 1, - flatTernaryExpressions: false, - // list derived from https://github.com/benjamn/ast-types/blob/HEAD/def/jsx.js - ignoredNodes: ['JSXElement', 'JSXElement > *', 'JSXAttribute', 'JSXIdentifier', 'JSXNamespacedName', 'JSXMemberExpression', 'JSXSpreadAttribute', 'JSXExpressionContainer', 'JSXOpeningElement', 'JSXClosingElement', 'JSXText', 'JSXEmptyExpression', 'JSXSpreadChild'], - ignoreComments: false - }], - - // specify whether double or single quotes should be used in JSX attributes - // https://eslint.org/docs/rules/jsx-quotes - 'jsx-quotes': ['off', 'prefer-double'], - - // enforces spacing between keys and values in object literal properties - 'key-spacing': ['error', { beforeColon: false, afterColon: true }], - - // require a space before & after certain keywords - 'keyword-spacing': ['error', { - before: true, - after: true, - overrides: { - return: { after: true }, - throw: { after: true }, - case: { after: true } - } - }], - - // enforce position of line comments - // https://eslint.org/docs/rules/line-comment-position - // TODO: enable? - 'line-comment-position': ['off', { - position: 'above', - ignorePattern: '', - applyDefaultPatterns: true, - }], - - // disallow mixed 'LF' and 'CRLF' as linebreaks - // https://eslint.org/docs/rules/linebreak-style - 'linebreak-style': ['error', 'unix'], - - // require or disallow an empty line between class members - // https://eslint.org/docs/rules/lines-between-class-members - 'lines-between-class-members': ['error', 'always', { exceptAfterSingleLine: false }], - - // enforces empty lines around comments - 'lines-around-comment': 'off', - - // require or disallow newlines around directives - // https://eslint.org/docs/rules/lines-around-directive - 'lines-around-directive': ['error', { - before: 'always', - after: 'always', - }], - - // specify the maximum depth that blocks can be nested - 'max-depth': ['off', 4], - - // specify the maximum length of a line in your program - // https://eslint.org/docs/rules/max-len - 'max-len': ['error', 120, 2, { - ignoreUrls: true, - ignoreComments: false, - ignoreRegExpLiterals: true, - ignoreStrings: true, - ignoreTemplateLiterals: true, - }], - - // specify the max number of lines in a file - // https://eslint.org/docs/rules/max-lines - 'max-lines': ['off', { - max: 300, - skipBlankLines: true, - skipComments: true - }], - - // enforce a maximum function length - // https://eslint.org/docs/rules/max-lines-per-function - 'max-lines-per-function': ['off', { - max: 50, - skipBlankLines: true, - skipComments: true, - IIFEs: true, - }], - - // specify the maximum depth callbacks can be nested - 'max-nested-callbacks': 'off', - - // limits the number of parameters that can be used in the function declaration. - 'max-params': ['off', 3], - - // specify the maximum number of statement allowed in a function - 'max-statements': ['off', 10], - - // restrict the number of statements per line - // https://eslint.org/docs/rules/max-statements-per-line - 'max-statements-per-line': ['off', { max: 1 }], - - // enforce a particular style for multiline comments - // https://eslint.org/docs/rules/multiline-comment-style - 'multiline-comment-style': ['off', 'starred-block'], - - // require multiline ternary - // https://eslint.org/docs/rules/multiline-ternary - // TODO: enable? - 'multiline-ternary': ['off', 'never'], - - // require a capital letter for constructors - 'new-cap': ['error', { - newIsCap: true, - newIsCapExceptions: [], - capIsNew: false, - capIsNewExceptions: ['Immutable.Map', 'Immutable.Set', 'Immutable.List'], - }], - - // disallow the omission of parentheses when invoking a constructor with no arguments - // https://eslint.org/docs/rules/new-parens - 'new-parens': 'error', - - // allow/disallow an empty newline after var statement - 'newline-after-var': 'off', - - // https://eslint.org/docs/rules/newline-before-return - 'newline-before-return': 'off', - - // enforces new line after each method call in the chain to make it - // more readable and easy to maintain - // https://eslint.org/docs/rules/newline-per-chained-call - 'newline-per-chained-call': ['error', { ignoreChainWithDepth: 4 }], - - // disallow use of the Array constructor - 'no-array-constructor': 'error', - - // disallow use of bitwise operators - // https://eslint.org/docs/rules/no-bitwise - 'no-bitwise': 'error', - - // disallow use of the continue statement - // https://eslint.org/docs/rules/no-continue - 'no-continue': 'error', - - // disallow comments inline after code - 'no-inline-comments': 'off', - - // disallow if as the only statement in an else block - // https://eslint.org/docs/rules/no-lonely-if - 'no-lonely-if': 'error', - - // disallow un-paren'd mixes of different operators - // https://eslint.org/docs/rules/no-mixed-operators - 'no-mixed-operators': ['error', { - // the list of arthmetic groups disallows mixing `%` and `**` - // with other arithmetic operators. - groups: [ - ['%', '**'], - ['%', '+'], - ['%', '-'], - ['%', '*'], - ['%', '/'], - ['**', '+'], - ['**', '-'], - ['**', '*'], - ['**', '/'], - ['&', '|', '^', '~', '<<', '>>', '>>>'], - ['==', '!=', '===', '!==', '>', '>=', '<', '<='], - ['&&', '||'], - ['in', 'instanceof'] - ], - allowSamePrecedence: false - }], - - // disallow mixed spaces and tabs for indentation - 'no-mixed-spaces-and-tabs': 'error', - - // disallow use of chained assignment expressions - // https://eslint.org/docs/rules/no-multi-assign - 'no-multi-assign': ['error'], - - // disallow multiple empty lines and only one newline at the end - 'no-multiple-empty-lines': ['error', { max: 2, maxEOF: 0 }], - - // disallow negated conditions - // https://eslint.org/docs/rules/no-negated-condition - 'no-negated-condition': 'off', - - // disallow nested ternary expressions - 'no-nested-ternary': 'error', - - // disallow use of the Object constructor - 'no-new-object': 'error', - - // disallow use of unary operators, ++ and -- - // https://eslint.org/docs/rules/no-plusplus - 'no-plusplus': 'error', - - // disallow certain syntax forms - // https://eslint.org/docs/rules/no-restricted-syntax - 'no-restricted-syntax': [ - 'error', - { - selector: 'ForInStatement', - message: 'for..in loops iterate over the entire prototype chain, which is virtually never what you want. Use Object.{keys,values,entries}, and iterate over the resulting array.', - }, - { - selector: 'ForOfStatement', - message: 'iterators/generators require regenerator-runtime, which is too heavyweight for this guide to allow them. Separately, loops should be avoided in favor of array iterations.', - }, - { - selector: 'LabeledStatement', - message: 'Labels are a form of GOTO; using them makes code confusing and hard to maintain and understand.', - }, - { - selector: 'WithStatement', - message: '`with` is disallowed in strict mode because it makes code impossible to predict and optimize.', - }, - ], - - // disallow space between function identifier and application - 'no-spaced-func': 'error', - - // disallow tab characters entirely - 'no-tabs': 'error', - - // disallow the use of ternary operators - 'no-ternary': 'off', - - // disallow trailing whitespace at the end of lines - 'no-trailing-spaces': ['error', { - skipBlankLines: false, - ignoreComments: false, - }], - - // disallow dangling underscores in identifiers - // https://eslint.org/docs/rules/no-underscore-dangle - 'no-underscore-dangle': ['error', { - allow: [], - allowAfterThis: false, - allowAfterSuper: false, - enforceInMethodNames: true, - }], - - // disallow the use of Boolean literals in conditional expressions - // also, prefer `a || b` over `a ? a : b` - // https://eslint.org/docs/rules/no-unneeded-ternary - 'no-unneeded-ternary': ['error', { defaultAssignment: false }], - - // disallow whitespace before properties - // https://eslint.org/docs/rules/no-whitespace-before-property - 'no-whitespace-before-property': 'error', - - // enforce the location of single-line statements - // https://eslint.org/docs/rules/nonblock-statement-body-position - 'nonblock-statement-body-position': ['error', 'beside', { overrides: {} }], - - // require padding inside curly braces - 'object-curly-spacing': ['error', 'always'], - - // enforce line breaks between braces - // https://eslint.org/docs/rules/object-curly-newline - 'object-curly-newline': ['error', { - ObjectExpression: { minProperties: 4, multiline: true, consistent: true }, - ObjectPattern: { minProperties: 4, multiline: true, consistent: true }, - ImportDeclaration: { minProperties: 4, multiline: true, consistent: true }, - ExportDeclaration: { minProperties: 4, multiline: true, consistent: true }, - }], - - // enforce "same line" or "multiple line" on object properties. - // https://eslint.org/docs/rules/object-property-newline - 'object-property-newline': ['error', { - allowAllPropertiesOnSameLine: true, - }], - - // allow just one var statement per function - 'one-var': ['error', 'never'], - - // require a newline around variable declaration - // https://eslint.org/docs/rules/one-var-declaration-per-line - 'one-var-declaration-per-line': ['error', 'always'], - - // require assignment operator shorthand where possible or prohibit it entirely - // https://eslint.org/docs/rules/operator-assignment - 'operator-assignment': ['error', 'always'], - - // Requires operator at the beginning of the line in multiline statements - // https://eslint.org/docs/rules/operator-linebreak - 'operator-linebreak': ['error', 'before', { overrides: { '=': 'none' } }], - - // disallow padding within blocks - 'padded-blocks': ['error', { blocks: 'never', classes: 'never', switches: 'never' }], - - // Require or disallow padding lines between statements - // https://eslint.org/docs/rules/padding-line-between-statements - 'padding-line-between-statements': 'off', - - // Prefer use of an object spread over Object.assign - // https://eslint.org/docs/rules/prefer-object-spread - // TODO: semver-major (eslint 5): enable - 'prefer-object-spread': 'off', - - // require quotes around object literal property names - // https://eslint.org/docs/rules/quote-props.html - 'quote-props': ['error', 'as-needed', { keywords: false, unnecessary: true, numbers: false }], - - // specify whether double or single quotes should be used - quotes: ['error', 'single', { avoidEscape: true }], - - // do not require jsdoc - // https://eslint.org/docs/rules/require-jsdoc - 'require-jsdoc': 'off', - - // require or disallow use of semicolons instead of ASI - semi: ['error', 'always'], - - // enforce spacing before and after semicolons - 'semi-spacing': ['error', { before: false, after: true }], - - // Enforce location of semicolons - // https://eslint.org/docs/rules/semi-style - 'semi-style': ['error', 'last'], - - // requires object keys to be sorted - 'sort-keys': ['off', 'asc', { caseSensitive: false, natural: true }], - - // sort variables within the same declaration block - 'sort-vars': 'off', - - // require or disallow space before blocks - 'space-before-blocks': 'error', - - // require or disallow space before function opening parenthesis - // https://eslint.org/docs/rules/space-before-function-paren - 'space-before-function-paren': ['error', { - anonymous: 'always', - named: 'never', - asyncArrow: 'always' - }], - - // require or disallow spaces inside parentheses - 'space-in-parens': ['error', 'never'], - - // require spaces around operators - 'space-infix-ops': 'error', - - // Require or disallow spaces before/after unary operators - // https://eslint.org/docs/rules/space-unary-ops - 'space-unary-ops': ['error', { - words: true, - nonwords: false, - overrides: { - }, - }], - - // require or disallow a space immediately following the // or /* in a comment - // https://eslint.org/docs/rules/spaced-comment - 'spaced-comment': ['error', 'always', { - line: { - exceptions: ['-', '+'], - markers: ['=', '!'], // space here to support sprockets directives - }, - block: { - exceptions: ['-', '+'], - markers: ['=', '!'], // space here to support sprockets directives - balanced: true, - } - }], - - // Enforce spacing around colons of switch statements - // https://eslint.org/docs/rules/switch-colon-spacing - 'switch-colon-spacing': ['error', { after: true, before: false }], - - // Require or disallow spacing between template tags and their literals - // https://eslint.org/docs/rules/template-tag-spacing - 'template-tag-spacing': ['error', 'never'], - - // require or disallow the Unicode Byte Order Mark - // https://eslint.org/docs/rules/unicode-bom - 'unicode-bom': ['error', 'never'], - - // require regex literals to be wrapped in parentheses - 'wrap-regex': 'off', - - // NODE // - // enforce return after a callback - 'callback-return': 'off', - - // require all requires be top-level - // https://eslint.org/docs/rules/global-require - 'global-require': 'error', - - // enforces error handling in callbacks (node environment) - 'handle-callback-err': 'off', - - // disallow use of the Buffer() constructor - // https://eslint.org/docs/rules/no-buffer-constructor - 'no-buffer-constructor': 'error', - - // disallow mixing regular variable and require declarations - 'no-mixed-requires': ['off', false], - - // disallow use of new operator with the require function - 'no-new-require': 'error', - - // disallow string concatenation with __dirname and __filename - // https://eslint.org/docs/rules/no-path-concat - 'no-path-concat': 'error', - - // disallow use of process.env - 'no-process-env': 'off', - - // disallow process.exit() - 'no-process-exit': 'off', - - // restrict usage of specified node modules - 'no-restricted-modules': 'off', - - // disallow use of synchronous methods (off by default) - 'no-sync': 'off', - - // IMPORT // - // Static analysis: - - // ensure imports point to files/modules that can be resolved - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-unresolved.md - 'import/no-unresolved': ['error', { commonjs: true, caseSensitive: true }], - - // ensure named imports coupled with named exports - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/named.md#when-not-to-use-it - 'import/named': 'error', - - // ensure default import coupled with default export - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/default.md#when-not-to-use-it - 'import/default': 'off', - - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/namespace.md - 'import/namespace': 'off', - - // Helpful warnings: - - // disallow invalid exports, e.g. multiple defaults - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/export.md - 'import/export': 'error', - - // do not allow a default import name to match a named export - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-named-as-default.md - 'import/no-named-as-default': 'error', - - // warn on accessing default export property names that are also named exports - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-named-as-default-member.md - 'import/no-named-as-default-member': 'error', - - // disallow use of jsdoc-marked-deprecated imports - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-deprecated.md - 'import/no-deprecated': 'off', - - // Forbid the use of extraneous packages - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-extraneous-dependencies.md - // paths are treated both as absolute paths, and relative to process.cwd() - 'import/no-extraneous-dependencies': ['error', { - devDependencies: [ - 'test/**', // tape, common npm pattern - 'tests/**', // also common npm pattern - 'spec/**', // mocha, rspec-like pattern - '**/__tests__/**', // jest pattern - '**/__mocks__/**', // jest pattern - 'test.{js,jsx}', // repos with a single test file - 'test-*.{js,jsx}', // repos with multiple top-level test files - '**/*{.,_}{test,spec}.{js,jsx}', // tests where the extension or filename suffix denotes that it is a test - '**/jest.config.js', // jest config - '**/vue.config.js', // vue-cli config - '**/webpack.config.js', // webpack config - '**/webpack.config.*.js', // webpack config - '**/rollup.config.js', // rollup config - '**/rollup.config.*.js', // rollup config - '**/gulpfile.js', // gulp config - '**/gulpfile.*.js', // gulp config - '**/Gruntfile{,.js}', // grunt config - '**/protractor.conf.js', // protractor config - '**/protractor.conf.*.js', // protractor config - ], - optionalDependencies: false, - }], - - // Forbid mutable exports - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-mutable-exports.md - 'import/no-mutable-exports': 'error', - - // Module systems: - - // disallow require() - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-commonjs.md - 'import/no-commonjs': 'off', - - // disallow AMD require/define - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-amd.md - 'import/no-amd': 'error', - - // No Node.js builtin modules - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-nodejs-modules.md - // TODO: enable? - 'import/no-nodejs-modules': 'off', - - // Style guide: - - // disallow non-import statements appearing before import statements - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/first.md - 'import/first': 'error', - - // disallow non-import statements appearing before import statements - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/imports-first.md - // deprecated: use `import/first` - 'import/imports-first': 'off', - - // disallow duplicate imports - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-duplicates.md - 'import/no-duplicates': 'error', - - // disallow namespace imports - // TODO: enable? - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-namespace.md - 'import/no-namespace': 'off', - - // Ensure consistent use of file extension within the import path - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/extensions.md - 'import/extensions': ['error', 'ignorePackages', { - js: 'never', - mjs: 'never', - jsx: 'never', - }], - - // ensure absolute imports are above relative imports and that unassigned imports are ignored - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/order.md - // TODO: enforce a stricter convention in module import order? - 'import/order': ['error', { groups: [['builtin', 'external', 'internal']] }], - - // Require a newline after the last import/require in a group - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/newline-after-import.md - 'import/newline-after-import': 'error', - - // Require modules with a single export to use a default export - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/prefer-default-export.md - 'import/prefer-default-export': 'error', - - // Restrict which files can be imported in a given folder - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-restricted-paths.md - 'import/no-restricted-paths': 'off', - - // Forbid modules to have too many dependencies - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/max-dependencies.md - 'import/max-dependencies': ['off', { max: 10 }], - - // Forbid import of modules using absolute paths - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-absolute-path.md - 'import/no-absolute-path': 'error', - - // Forbid require() calls with expressions - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-dynamic-require.md - 'import/no-dynamic-require': 'error', - - // prevent importing the submodules of other modules - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-internal-modules.md - 'import/no-internal-modules': ['off', { - allow: [], - }], - - // Warn if a module could be mistakenly parsed as a script by a consumer - // leveraging Unambiguous JavaScript Grammar - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/unambiguous.md - // this should not be enabled until this proposal has at least been *presented* to TC39. - // At the moment, it's not a thing. - 'import/unambiguous': 'off', - - // Forbid Webpack loader syntax in imports - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-webpack-loader-syntax.md - 'import/no-webpack-loader-syntax': 'error', - - // Prevent unassigned imports - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-unassigned-import.md - // importing for side effects is perfectly acceptable, if you need side effects. - 'import/no-unassigned-import': 'off', - - // Prevent importing the default as if it were named - // https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-named-default.md - 'import/no-named-default': 'error', - - // Reports if a module's default export is unnamed - // https://github.com/benmosher/eslint-plugin-import/blob/d9b712ac7fd1fddc391f7b234827925c160d956f/docs/rules/no-anonymous-default-export.md - 'import/no-anonymous-default-export': ['off', { - allowArray: false, - allowArrowFunction: false, - allowAnonymousClass: false, - allowAnonymousFunction: false, - allowLiteral: false, - allowObject: false, - }], - - // This rule enforces that all exports are declared at the bottom of the file. - // https://github.com/benmosher/eslint-plugin-import/blob/98acd6afd04dcb6920b81330114e146dc8532ea4/docs/rules/exports-last.md - // TODO: enable? - 'import/exports-last': 'off', - - // Reports when named exports are not grouped together in a single export declaration - // or when multiple assignments to CommonJS module.exports or exports object are present - // in a single file. - // https://github.com/benmosher/eslint-plugin-import/blob/44a038c06487964394b1e15b64f3bd34e5d40cde/docs/rules/group-exports.md - 'import/group-exports': 'off', - - // forbid default exports. this is a terrible rule, do not use it. - // https://github.com/benmosher/eslint-plugin-import/blob/44a038c06487964394b1e15b64f3bd34e5d40cde/docs/rules/no-default-export.md - 'import/no-default-export': 'off', - - // Forbid a module from importing itself - // https://github.com/benmosher/eslint-plugin-import/blob/44a038c06487964394b1e15b64f3bd34e5d40cde/docs/rules/no-self-import.md - 'import/no-self-import': 'error', - - // Forbid cyclical dependencies between modules - // https://github.com/benmosher/eslint-plugin-import/blob/d81f48a2506182738409805f5272eff4d77c9348/docs/rules/no-cycle.md - 'import/no-cycle': ['error', { maxDepth: Infinity }], - - // Ensures that there are no useless path segments - // https://github.com/benmosher/eslint-plugin-import/blob/ebafcbf59ec9f653b2ac2a0156ca3bcba0a7cf57/docs/rules/no-useless-path-segments.md - 'import/no-useless-path-segments': 'error', - - // dynamic imports require a leading comment with a webpackChunkName - // https://github.com/benmosher/eslint-plugin-import/blob/ebafcbf59ec9f653b2ac2a0156ca3bcba0a7cf57/docs/rules/dynamic-import-chunkname.md - 'import/dynamic-import-chunkname': ['off', { - importFunctions: [], - webpackChunknameFormat: '[0-9a-zA-Z-_/.]+', - }], - - // Use this rule to prevent imports to folders in relative parent paths. - // https://github.com/benmosher/eslint-plugin-import/blob/c34f14f67f077acd5a61b3da9c0b0de298d20059/docs/rules/no-relative-parent-imports.md - 'import/no-relative-parent-imports': 'off', - - }, -}; \ No newline at end of file diff --git a/phaser-client/.gitignore b/phaser-client/.gitignore deleted file mode 100644 index 2106e507..00000000 --- a/phaser-client/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -package-lock.json -node_modules/ -dist/ -.cache/ -assets/molecules diff --git a/phaser-client/assets/alakazam-f.png b/phaser-client/assets/alakazam-f.png deleted file mode 100644 index f792d270..00000000 Binary files a/phaser-client/assets/alakazam-f.png and /dev/null differ diff --git a/phaser-client/assets/alphabet.jpg b/phaser-client/assets/alphabet.jpg deleted file mode 100644 index 99347201..00000000 Binary files a/phaser-client/assets/alphabet.jpg and /dev/null differ diff --git a/phaser-client/assets/aztec.atlas.json b/phaser-client/assets/aztec.atlas.json deleted file mode 100644 index 873289aa..00000000 --- a/phaser-client/assets/aztec.atlas.json +++ /dev/null @@ -1,444 +0,0 @@ -{ - "textures": [ - { - "format": "RGBA8888", - "size": { - "w": 1024, - "h": 1024 - }, - "scale": 1, - "frames":[ - { - "filename":"sprite0", - "frame":{ - "x":655, - "y":100, - "w":110, - "h":97 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":110, - "h":97 - }, - "sourceSize":{ - "w":110, - "h":97 - } - }, - { - "filename":"sprite1", - "frame":{ - "x":180, - "y":105, - "w":140, - "h":88 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":140, - "h":88 - }, - "sourceSize":{ - "w":140, - "h":88 - } - }, - { - "filename":"sprite2", - "frame":{ - "x":20, - "y":106, - "w":140, - "h":86 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":140, - "h":86 - }, - "sourceSize":{ - "w":140, - "h":86 - } - }, - { - "filename":"sprite3", - "frame":{ - "x":475, - "y":106, - "w":150, - "h":86 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":150, - "h":86 - }, - "sourceSize":{ - "w":150, - "h":86 - } - }, - { - "filename":"sprite4", - "frame":{ - "x":330, - "y":112, - "w":140, - "h":74 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":140, - "h":74 - }, - "sourceSize":{ - "w":140, - "h":74 - } - }, - { - "filename":"sprite5", - "frame":{ - "x":198, - "y":274, - "w":104, - "h":110 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":104, - "h":110 - }, - "sourceSize":{ - "w":104, - "h":110 - } - }, - { - "filename":"sprite6", - "frame":{ - "x":342, - "y":279, - "w":116, - "h":100 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":116, - "h":100 - }, - "sourceSize":{ - "w":116, - "h":100 - } - }, - { - "filename":"sprite7", - "frame":{ - "x":480, - "y":283, - "w":140, - "h":92 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":140, - "h":92 - }, - "sourceSize":{ - "w":140, - "h":92 - } - }, - { - "filename":"sprite8", - "frame":{ - "x":24, - "y":284, - "w":132, - "h":90 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":132, - "h":90 - }, - "sourceSize":{ - "w":132, - "h":90 - } - }, - { - "filename":"sprite9", - "frame":{ - "x":645, - "y":287, - "w":130, - "h":84 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":130, - "h":84 - }, - "sourceSize":{ - "w":130, - "h":84 - } - }, - { - "filename":"sprite10", - "frame":{ - "x":514, - "y":434, - "w":74, - "h":110 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":74, - "h":110 - }, - "sourceSize":{ - "w":74, - "h":110 - } - }, - { - "filename":"sprite11", - "frame":{ - "x":222, - "y":439, - "w":56, - "h":100 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":56, - "h":100 - }, - "sourceSize":{ - "w":56, - "h":100 - } - }, - { - "filename":"sprite12", - "frame":{ - "x":667, - "y":439, - "w":86, - "h":100 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":86, - "h":100 - }, - "sourceSize":{ - "w":86, - "h":100 - } - }, - { - "filename":"sprite13", - "frame":{ - "x":20, - "y":451, - "w":140, - "h":74 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":140, - "h":74 - }, - "sourceSize":{ - "w":140, - "h":74 - } - }, - { - "filename":"sprite14", - "frame":{ - "x":335, - "y":453, - "w":130, - "h":72 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":130, - "h":72 - }, - "sourceSize":{ - "w":130, - "h":72 - } - }, - { - "filename":"sprite15", - "frame":{ - "x":493, - "y":619, - "w":114, - "h":100 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":114, - "h":100 - }, - "sourceSize":{ - "w":114, - "h":100 - } - }, - { - "filename":"sprite16", - "frame":{ - "x":180, - "y":626, - "w":140, - "h":86 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":140, - "h":86 - }, - "sourceSize":{ - "w":140, - "h":86 - } - }, - { - "filename":"sprite17", - "frame":{ - "x":640, - "y":632, - "w":140, - "h":94 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":140, - "h":94 - }, - "sourceSize":{ - "w":140, - "h":94 - } - }, - { - "filename":"sprite18", - "frame":{ - "x":329, - "y":635, - "w":141, - "h":88 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":141, - "h":88 - }, - "sourceSize":{ - "w":141, - "h":88 - } - }, - { - "filename":"sprite19", - "frame":{ - "x":25, - "y":641, - "w":130, - "h":76 - }, - "rotated":false, - "trimmed":false, - "spriteSourceSize":{ - "x":0, - "y":0, - "w":130, - "h":76 - }, - "sourceSize":{ - "w":130, - "h":76 - } - } - ], - "meta":{ - "app":"https://www.leshylabs.com/apps/sstool/", - "version":"Leshy SpriteSheet Tool v0.8.4", - "image":"spritesheet.png", - "size":{ - "w":800, - "h":800 - }, - "scale":1 - } - } - ] -} \ No newline at end of file diff --git a/phaser-client/assets/aztec.clean.png b/phaser-client/assets/aztec.clean.png deleted file mode 100644 index 931bb520..00000000 Binary files a/phaser-client/assets/aztec.clean.png and /dev/null differ diff --git a/phaser-client/assets/aztec.jpg b/phaser-client/assets/aztec.jpg deleted file mode 100644 index e9700f56..00000000 Binary files a/phaser-client/assets/aztec.jpg and /dev/null differ diff --git a/phaser-client/assets/c1.svg b/phaser-client/assets/c1.svg deleted file mode 100644 index 42347312..00000000 --- a/phaser-client/assets/c1.svg +++ /dev/null @@ -1,18 +0,0 @@ - - - - - - diff --git a/phaser-client/assets/c2.svg b/phaser-client/assets/c2.svg deleted file mode 100644 index d816a009..00000000 --- a/phaser-client/assets/c2.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - diff --git a/phaser-client/assets/c3.svg b/phaser-client/assets/c3.svg deleted file mode 100644 index 0092ae89..00000000 --- a/phaser-client/assets/c3.svg +++ /dev/null @@ -1,20 +0,0 @@ - - - - - - diff --git a/phaser-client/assets/fonts/noway-regular-webfont.eot b/phaser-client/assets/fonts/noway-regular-webfont.eot deleted file mode 100755 index 90f74294..00000000 Binary files a/phaser-client/assets/fonts/noway-regular-webfont.eot and /dev/null differ diff --git a/phaser-client/assets/fonts/noway-regular-webfont.svg b/phaser-client/assets/fonts/noway-regular-webfont.svg deleted file mode 100755 index 38a28df0..00000000 --- a/phaser-client/assets/fonts/noway-regular-webfont.svg +++ /dev/null @@ -1,2657 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/phaser-client/assets/fonts/noway-regular-webfont.ttf b/phaser-client/assets/fonts/noway-regular-webfont.ttf deleted file mode 100755 index c9f82f9a..00000000 Binary files a/phaser-client/assets/fonts/noway-regular-webfont.ttf and /dev/null differ diff --git a/phaser-client/assets/fonts/noway-regular-webfont.woff b/phaser-client/assets/fonts/noway-regular-webfont.woff deleted file mode 100755 index 909dde86..00000000 Binary files a/phaser-client/assets/fonts/noway-regular-webfont.woff and /dev/null differ diff --git a/phaser-client/assets/fonts/noway-regular-webfont.woff2 b/phaser-client/assets/fonts/noway-regular-webfont.woff2 deleted file mode 100755 index aeb654cc..00000000 Binary files a/phaser-client/assets/fonts/noway-regular-webfont.woff2 and /dev/null differ diff --git a/phaser-client/assets/glyphs.jpg b/phaser-client/assets/glyphs.jpg deleted file mode 100644 index 7dd065be..00000000 Binary files a/phaser-client/assets/glyphs.jpg and /dev/null differ diff --git a/phaser-client/assets/magmar.png b/phaser-client/assets/magmar.png deleted file mode 100644 index c59cad7a..00000000 Binary files a/phaser-client/assets/magmar.png and /dev/null differ diff --git a/phaser-client/cryps.css b/phaser-client/cryps.css deleted file mode 100644 index b0020329..00000000 --- a/phaser-client/cryps.css +++ /dev/null @@ -1,24 +0,0 @@ -/*@font-face { - font-family: 'nowayregular'; - src: url('./assets/fonts/noway-regular-webfont.eot'); - src: url('./assets/fonts/noway-regular-webfont.eot?#iefix') format('embedded-opentype'), - url('./assets/fonts/noway-regular-webfont.woff2') format('woff2'), - url('./assets/fonts/noway-regular-webfont.woff') format('woff'), - url('./assets/fonts/noway-regular-webfont.ttf') format('truetype'), - url('./assets/fonts/noway-regular-webfont.svg#nowayregular') format('svg'); - font-weight: normal; - font-style: normal; -} -*/ -body { - background-color: #181818; -} - -canvas{ - display:block; - margin: 0; - position: absolute; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); -} \ No newline at end of file diff --git a/phaser-client/index.html b/phaser-client/index.html deleted file mode 100644 index 79fb6fc6..00000000 --- a/phaser-client/index.html +++ /dev/null @@ -1,16 +0,0 @@ - - - - constructs.gg - mnml pvp atbs - - - - - - - - - - - - \ No newline at end of file diff --git a/phaser-client/index.js b/phaser-client/index.js deleted file mode 100644 index ff86aee9..00000000 --- a/phaser-client/index.js +++ /dev/null @@ -1,4 +0,0 @@ -require('./constructs.css'); - -// kick it off -require('./src/main'); diff --git a/phaser-client/lib/fizzy-noise.js b/phaser-client/lib/fizzy-noise.js deleted file mode 100644 index 20b6510f..00000000 --- a/phaser-client/lib/fizzy-noise.js +++ /dev/null @@ -1,189 +0,0 @@ -// http://mrl.nyu.edu/~perlin/noise/ - -const ImprovedNoise = function () { - const p = [151, 160, 137, 91, 90, 15, 131, 13, 201, 95, 96, 53, 194, 233, 7, 225, 140, 36, 103, 30, 69, 142, 8, 99, 37, 240, 21, 10, - 23, 190, 6, 148, 247, 120, 234, 75, 0, 26, 197, 62, 94, 252, 219, 203, 117, 35, 11, 32, 57, 177, 33, 88, 237, 149, 56, 87, - 174, 20, 125, 136, 171, 168, 68, 175, 74, 165, 71, 134, 139, 48, 27, 166, 77, 146, 158, 231, 83, 111, 229, 122, 60, 211, - 133, 230, 220, 105, 92, 41, 55, 46, 245, 40, 244, 102, 143, 54, 65, 25, 63, 161, 1, 216, 80, 73, 209, 76, 132, 187, 208, - 89, 18, 169, 200, 196, 135, 130, 116, 188, 159, 86, 164, 100, 109, 198, 173, 186, 3, 64, 52, 217, 226, 250, 124, 123, 5, - 202, 38, 147, 118, 126, 255, 82, 85, 212, 207, 206, 59, 227, 47, 16, 58, 17, 182, 189, 28, 42, 223, 183, 170, 213, 119, - 248, 152, 2, 44, 154, 163, 70, 221, 153, 101, 155, 167, 43, 172, 9, 129, 22, 39, 253, 19, 98, 108, 110, 79, 113, 224, 232, - 178, 185, 112, 104, 218, 246, 97, 228, 251, 34, 242, 193, 238, 210, 144, 12, 191, 179, 162, 241, 81, 51, 145, 235, 249, - 14, 239, 107, 49, 192, 214, 31, 181, 199, 106, 157, 184, 84, 204, 176, 115, 121, 50, 45, 127, 4, 150, 254, 138, 236, 205, - 93, 222, 114, 67, 29, 24, 72, 243, 141, 128, 195, 78, 66, 215, 61, 156, 180]; - - for (let i = 0; i < 256; i++) { - p[256 + i] = p[i]; - } - - function fade(t) { - return t * t * t * (t * (t * 6 - 15) + 10); - } - - function lerp(t, a, b) { - return a + t * (b - a); - } - - function grad(hash, x, y, z) { - const h = hash & 15; - const u = h < 8 ? x : y; const - v = h < 4 ? y : h == 12 || h == 14 ? x : z; - return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); - } - - return { - - noise(x, y, z) { - const floorX = Math.floor(x); const floorY = Math.floor(y); const - floorZ = Math.floor(z); - - const X = floorX & 255; const Y = floorY & 255; const - Z = floorZ & 255; - - x -= floorX; - y -= floorY; - z -= floorZ; - - const xMinus1 = x - 1; const yMinus1 = y - 1; const - zMinus1 = z - 1; - - const u = fade(x); const v = fade(y); const - w = fade(z); - - const A = p[X] + Y; const AA = p[A] + Z; const AB = p[A + 1] + Z; const B = p[X + 1] + Y; const BA = p[B] + Z; const - BB = p[B + 1] + Z; - - return lerp(w, lerp(v, lerp(u, grad(p[AA], x, y, z), - grad(p[BA], xMinus1, y, z)), - lerp(u, grad(p[AB], x, yMinus1, z), - grad(p[BB], xMinus1, yMinus1, z))), - lerp(v, lerp(u, grad(p[AA + 1], x, y, zMinus1), - grad(p[BA + 1], xMinus1, y, z - 1)), - lerp(u, grad(p[AB + 1], x, yMinus1, zMinus1), - grad(p[BB + 1], xMinus1, yMinus1, zMinus1)))); - }, - }; -}; - -const currentRandom = Math.random; - -// Pseudo-random generator -function Marsaglia(i1, i2) { - // from http://www.math.uni-bielefeld.de/~sillke/ALGORITHMS/random/marsaglia-c - let z = i1 || 362436069; let - w = i2 || 521288629; - const nextInt = function () { - z = (36969 * (z & 65535) + (z >>> 16)) & 0xFFFFFFFF; - w = (18000 * (w & 65535) + (w >>> 16)) & 0xFFFFFFFF; - return (((z & 0xFFFF) << 16) | (w & 0xFFFF)) & 0xFFFFFFFF; - }; - - this.nextDouble = function () { - const i = nextInt() / 4294967296; - return i < 0 ? 1 + i : i; - }; - this.nextInt = nextInt; -} -Marsaglia.createRandomized = function () { - const now = new Date(); - return new Marsaglia((now / 60000) & 0xFFFFFFFF, now & 0xFFFFFFFF); -}; - -// Noise functions and helpers -function PerlinNoise(seed) { - const rnd = seed !== undefined ? new Marsaglia(seed) : Marsaglia.createRandomized(); - let i; let - j; - // http://www.noisemachine.com/talk1/17b.html - // http://mrl.nyu.edu/~perlin/noise/ - // generate permutation - const p = new Array(512); - for (i = 0; i < 256; ++i) { p[i] = i; } - for (i = 0; i < 256; ++i) { const t = p[j = rnd.nextInt() & 0xFF]; p[j] = p[i]; p[i] = t; } - // copy to avoid taking mod in p[0]; - for (i = 0; i < 256; ++i) { p[i + 256] = p[i]; } - - function grad3d(i, x, y, z) { - const h = i & 15; // convert into 12 gradient directions - const u = h < 8 ? x : y; - - - const v = h < 4 ? y : h === 12 || h === 14 ? x : z; - return ((h & 1) === 0 ? u : -u) + ((h & 2) === 0 ? v : -v); - } - - function grad2d(i, x, y) { - const v = (i & 1) === 0 ? x : y; - return (i & 2) === 0 ? -v : v; - } - - function grad1d(i, x) { - return (i & 1) === 0 ? -x : x; - } - - function lerp(t, a, b) { return a + t * (b - a); } - - this.noise3d = function (x, y, z) { - const X = Math.floor(x) & 255; const Y = Math.floor(y) & 255; const - Z = Math.floor(z) & 255; - x -= Math.floor(x); y -= Math.floor(y); z -= Math.floor(z); - const fx = (3 - 2 * x) * x * x; const fy = (3 - 2 * y) * y * y; const - fz = (3 - 2 * z) * z * z; - const p0 = p[X] + Y; const p00 = p[p0] + Z; const p01 = p[p0 + 1] + Z; const p1 = p[X + 1] + Y; const p10 = p[p1] + Z; const - p11 = p[p1 + 1] + Z; - return lerp(fz, - lerp(fy, lerp(fx, grad3d(p[p00], x, y, z), grad3d(p[p10], x - 1, y, z)), - lerp(fx, grad3d(p[p01], x, y - 1, z), grad3d(p[p11], x - 1, y - 1, z))), - lerp(fy, lerp(fx, grad3d(p[p00 + 1], x, y, z - 1), grad3d(p[p10 + 1], x - 1, y, z - 1)), - lerp(fx, grad3d(p[p01 + 1], x, y - 1, z - 1), grad3d(p[p11 + 1], x - 1, y - 1, z - 1)))); - }; - - this.noise2d = function (x, y) { - const X = Math.floor(x) & 255; const - Y = Math.floor(y) & 255; - x -= Math.floor(x); y -= Math.floor(y); - const fx = (3 - 2 * x) * x * x; const - fy = (3 - 2 * y) * y * y; - const p0 = p[X] + Y; const - p1 = p[X + 1] + Y; - return lerp(fy, - lerp(fx, grad2d(p[p0], x, y), grad2d(p[p1], x - 1, y)), - lerp(fx, grad2d(p[p0 + 1], x, y - 1), grad2d(p[p1 + 1], x - 1, y - 1))); - }; - - this.noise1d = function (x) { - const X = Math.floor(x) & 255; - x -= Math.floor(x); - const fx = (3 - 2 * x) * x * x; - return lerp(fx, grad1d(p[X], x), grad1d(p[X + 1], x - 1)); - }; -} - -// these are lifted from Processing.js -// processing defaults -const noiseProfile = { - generator: undefined, octaves: 4, fallout: 0.5, seed: undefined, -}; - -module.exports = function noise(x, y, z) { - if (noiseProfile.generator === undefined) { - // caching - noiseProfile.generator = new PerlinNoise(noiseProfile.seed); - } - const generator = noiseProfile.generator; - let effect = 1; let k = 1; let - sum = 0; - for (let i = 0; i < noiseProfile.octaves; ++i) { - effect *= noiseProfile.fallout; - switch (arguments.length) { - case 1: - sum += effect * (1 + generator.noise1d(k * x)) / 2; break; - case 2: - sum += effect * (1 + generator.noise2d(k * x, k * y)) / 2; break; - case 3: - sum += effect * (1 + generator.noise3d(k * x, k * y, k * z)) / 2; break; - } - k *= 2; - } - return sum; -}; diff --git a/phaser-client/lib/fizzy-text.js b/phaser-client/lib/fizzy-text.js deleted file mode 100644 index bee34d8e..00000000 --- a/phaser-client/lib/fizzy-text.js +++ /dev/null @@ -1,220 +0,0 @@ -const noise = require('./fizzy-noise'); - -function fizzyText(message) { - const that = this; - - // These are the variables that we manipulate with gui-dat. - // Notice they're all defined with "this". That makes them public. - // Otherwise, gui-dat can't see them. - - this.growthSpeed = 0.8; // how fast do particles change size? - this.minSize = 1; - this.maxSize = 4; // how big can they get? - this.noiseStrength = 10; // how turbulent is the flow? - this.speed = 0.4; // how fast do particles move? - this.displayOutline = false; // should we draw the message as a stroke? - this.framesRendered = 0; - - // ////////////////////////////////////////////////////////////// - - const _this = this; - - const width = 550; - const height = 200; - const textAscent = 101; - const textOffsetLeft = 80; - const noiseScale = 300; - const frameTime = 30; - - const colors = ['#000000', '#1A1A1A', '#163C50', '#205A79', '#2A78A2']; - - // This is the context we use to get a bitmap of text using - // the getImageData function. - const r = document.createElement('canvas'); - const s = r.getContext('2d'); - - // This is the context we actually use to draw. - const c = document.createElement('canvas'); - const g = c.getContext('2d'); - - r.setAttribute('width', width); - c.setAttribute('width', width); - r.setAttribute('height', height); - c.setAttribute('height', height); - - // Add our demo to the HTML - document.getElementById('fizzytext').appendChild(c); - - // Stores bitmap image - let pixels = []; - - // Stores a list of particles - const particles = []; - - // Set g.font to the same font as the bitmap canvas, incase we - // want to draw some outlines. - s.font = g.font = '800 82px monospace, monospace'; - - // Instantiate some particles - for (let i = 0; i < 1000; i++) { - particles.push(new Particle(Math.random() * width, Math.random() * height)); - } - - // This function creates a bitmap of pixels based on your message - // It's called every time we change the message property. - const createBitmap = function (msg) { - s.fillStyle = '#fff'; - s.fillRect(0, 0, width, height); - - s.fillStyle = '#222'; - s.fillText(msg, textOffsetLeft, textAscent); - - // Pull reference - const imageData = s.getImageData(0, 0, width, height); - pixels = imageData.data; - }; - - // Called once per frame, updates the animation. - const render = function () { - that.framesRendered++; - - g.clearRect(0, 0, width, height); - - if (_this.displayOutline) { - g.globalCompositeOperation = 'source-over'; - g.strokeStyle = '#000'; - g.lineWidth = 0.5; - g.strokeText(message, textOffsetLeft, textAscent); - } - - g.globalCompositeOperation = 'darker'; - - for (let i = 0; i < particles.length; i++) { - g.fillStyle = colors[i % colors.length]; - particles[i].render(); - } - }; - - // Returns x, y coordinates for a given index in the pixel array. - const getPosition = function (i) { - return { - x: (i - (width * 4) * Math.floor(i / (width * 4))) / 4, - y: Math.floor(i / (width * 4)), - }; - }; - - // Returns a color for a given pixel in the pixel array. - const getColor = function (x, y) { - const base = (Math.floor(y) * width + Math.floor(x)) * 4; - const c = { - r: pixels[base + 0], - g: pixels[base + 1], - b: pixels[base + 2], - a: pixels[base + 3], - }; - - return `rgb(${c.r},${c.g},${c.b})`; - }; - - this.message = message; - createBitmap(message); - - var loop = function () { - requestAnimationFrame(loop); - render(); - }; - - // This calls the render function every 30 milliseconds. - loop(); - - // This class is responsible for drawing and moving those little - // colored dots. - function Particle(x, y, c) { - // Position - this.x = x; - this.y = y; - - // Size of particle - this.r = 1; - - // This velocity is used by the explode function. - this.vx = 0; - this.vy = 0; - - this.constrain = function constrainFn(v, o1, o2) { - if (v < o1) v = o1; - else if (v > o2) v = o2; - return v; - }; - - // Called every frame - this.render = function renderFrame() { - // What color is the pixel we're sitting on top of? - const c = getColor(this.x, this.y); - - // Where should we move? - const angle = noise(this.x / noiseScale, this.y / noiseScale) * _this.noiseStrength; - // var angle = -Math.PI/2; - - // Are we within the boundaries of the image? - const onScreen = this.x > 0 && this.x < width && this.y > 0 && this.y < height; - - const isBlack = c !== 'rgb(255,255,255)' && onScreen; - - // If we're on top of a black pixel, grow. - // If not, shrink. - if (isBlack) { - this.r += _this.growthSpeed; - } else { - this.r -= _this.growthSpeed; - } - - // This velocity is used by the explode function. - this.vx *= 0.5; - this.vy *= 0.5; - - // Change our position based on the flow field and our - // explode velocity. - this.x += Math.cos(angle) * _this.speed + this.vx; - this.y += -Math.sin(angle) * _this.speed + this.vy; - - if (this.r > _this.maxSize) { - this.r = _this.maxSize; - } else if (this.r < 0) { - this.r = 0; - this.x = Math.random() * width; - this.y = Math.random() * height; - return false; - } - - // this.r = 3; - // debugger - // console.log(DAT.GUI.constrain(this.r, 0, _this.maxSize)); - // this.r = this.constrain(this.r, _this.minSize, _this.maxSize); - - // If we're tiny, keep moving around until we find a black - // pixel. - if (this.r <= 0) { - this.x = Math.random() * width; - this.y = Math.random() * height; - return false; // Don't draw! - } - - // If we're off the screen, go over to other side - if (this.x < 0) this.x = width; - if (this.x > width) this.x = 0; - if (this.y < 0) this.y = height; - if (this.y > height) this.y = 0; - - // Draw the circle. - g.beginPath(); - // g.arc(this.x, this.y, this.r, 0, Math.PI * 2, false); - g.rect(this.x, this.y, this.r, this.r); - g.fill(); - - return true; - }; - } -} - -module.exports = fizzyText; diff --git a/phaser-client/package.json b/phaser-client/package.json deleted file mode 100644 index b62d7ce2..00000000 --- a/phaser-client/package.json +++ /dev/null @@ -1,33 +0,0 @@ -{ - "name": "constructs-client", - "version": "1.0.0", - "description": "", - "main": "index.js", - "scripts": { - "start": "parcel index.html --port 40080 --no-hmr --no-source-maps", - "build": "rm -rf dist && parcel build --no-source-maps index.html", - "lint": "eslint --fix src/", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "UNLICENSED", - "dependencies": { - "async": "^2.6.1", - "borc": "^2.0.3", - "docco": "^0.7.0", - "izitoast": "^1.4.0", - "jdenticon": "^2.1.0", - "key": "^0.1.11", - "keymaster": "^1.6.2", - "lodash": "^4.17.11", - "parcel": "^1.11.0", - "phaser": "^3.16.1", - "redux": "^4.0.0" - }, - "devDependencies": { - "eslint": "^5.6.0", - "eslint-config-airbnb-base": "^13.1.0", - "eslint-plugin-import": "^2.14.0", - "jest": "^18.0.0" - } -} diff --git a/phaser-client/src/events.js b/phaser-client/src/events.js deleted file mode 100644 index bfc600d0..00000000 --- a/phaser-client/src/events.js +++ /dev/null @@ -1,219 +0,0 @@ -const toast = require('izitoast'); - -function registerEvents(registry, events, tutorial) { - function setConstructs(constructs) { - registry.set('constructs', constructs); - tutorial('homepage'); - } - - function setConstructList(constructs) { - registry.set('constructList', constructs); - } - - - function setWs(ws) { - registry.set('ws', ws); - } - - function setGame(game) { - if (game.phase === 'Skill') tutorial('skillPhase'); - if (game.phase === 'Target') tutorial('targetPhase'); - if (game.resolved.length) tutorial('resolutionPhase'); - if (game.phase === 'Finish') tutorial('finishPhase'); - return registry.set('game', game); - } - - function setAccount(account) { - registry.set('account', account); - registry.set('home', true); - events.emit('ACCOUNT', account); - } - - function setActiveSkill(skill) { - registry.set('activeSkill', skill); - } - - function setMenu() { - registry.set('menu', true); - } - - function setVbox(items) { - registry.set('vbox', items); - } - - function setScores(scores) { - registry.set('scores', scores); - } - - function setPlayerList(list) { - registry.set('playerList', list); - registry.set('homeInstances', true); - } - - function setPlayer(player) { - registry.set('player', player); - if (!registry.get('inMenu')) { - setMenu(); - } - } - - function setZone(zone) { - registry.set('zone', zone); - } - - function setGameList(gameList) { - registry.set('gameList', gameList); - } - - function setConstructStatusUpdate(id, skill, target) { - registry.set('constructStatusUpdate', { id, skill, target }); - } - - events.on('SET_PLAYER', setPlayer); - - events.on('SEND_SKILL', function skillActive(gameId, constructId, targetConstructId, skill) { - const ws = registry.get('ws'); - ws.sendGameSkill(gameId, constructId, targetConstructId, skill); - setConstructStatusUpdate(constructId, skill, targetConstructId); - }); - - events.on('CONSTRUCT_ACTIVE', function constructActiveCb(construct) { - const constructs = registry.get('constructs'); - for (let i = 0; i < constructs.length; i += 1) { - if (constructs[i].id === construct.id) constructs[i].active = !constructs[i].active; - } - return setConstructs(constructs); - }); - - const errMessages = { - select_constructs: 'Select your constructs before battle using the numbered buttons next to the construct avatar', - complete_nodes: 'You need to complete the previously connected nodes first', - max_skills: 'Your construct can only learn a maximum of 4 skills', - - }; - - function errorPrompt(type) { - const message = errMessages[type]; - const OK_BUTTON = ''; - toast.info({ - theme: 'dark', - color: 'black', - timeout: false, - drag: false, - position: 'center', - maxWidth: window.innerWidth / 2, - close: false, - buttons: [ - [OK_BUTTON, (instance, thisToast) => instance.hide({ transitionOut: 'fadeOut' }, thisToast)], - ], - message, - }); - } - - function loginPrompt() { - const USER_INPUT = ''; - const PASSWORD_INPUT = ''; - const LOGIN_BUTTON = ''; - const REGISTER_BUTTON = ''; - const DEMO_BUTTON = ''; - - const ws = registry.get('ws'); - - function submitLogin(instance, thisToast, button, e, inputs) { - const USERNAME = inputs[0].value; - const PASSWORD = inputs[1].value; - ws.sendAccountLogin(USERNAME, PASSWORD); - } - - function submitRegister(instance, thisToast, button, e, inputs) { - const USERNAME = inputs[0].value; - const PASSWORD = inputs[1].value; - ws.sendAccountCreate(USERNAME, PASSWORD); - } - - function submitDemo() { - ws.sendAccountDemo(); - } - - const existing = document.querySelector('#login'); // Selector of your toast - if (existing) toast.hide({}, existing, 'reconnect'); - - toast.question({ - id: 'login', - theme: 'dark', - color: 'black', - timeout: false, - // overlay: true, - drag: false, - close: false, - title: 'LOGIN', - position: 'center', - inputs: [ - [USER_INPUT, 'change', () => true, true], // true to focus - [PASSWORD_INPUT, 'change', () => true], - ], - buttons: [ - [LOGIN_BUTTON, submitLogin], // true to focus - [REGISTER_BUTTON, submitRegister], // true to focus - [DEMO_BUTTON, submitDemo], // true to focus - ], - }); - - events.once('ACCOUNT', function closeLoginCb() { - const prompt = document.querySelector('#login'); // Selector of your toast - if (prompt) toast.hide({ transitionOut: 'fadeOut' }, prompt, 'event'); - }); - } - - events.on('CONSTRUCT_SPAWN', function spawnPrompt() { - const NAME_INPUT = ''; - const SPAWN_BUTTON = ''; - - const ws = registry.get('ws'); - - function submitSpawn(instance, thisToast, button, e, inputs) { - const NAME = inputs[0].value; - ws.sendConstructSpawn(NAME); - instance.hide({ transitionOut: 'fadeOut' }, thisToast, 'button'); - } - - toast.question({ - theme: 'dark', - color: 'black', - timeout: false, - // overlay: true, - drag: false, - close: true, - title: 'SPAWN CONSTRUCT', - position: 'center', - inputs: [ - [NAME_INPUT, 'change', null, true], // true to focus - ], - buttons: [ - [SPAWN_BUTTON, submitSpawn], // true to focus - ], - }); - }); - - tutorial('welcome'); - - return { - errorPrompt, - loginPrompt, - setAccount, - setActiveSkill, - setConstructs, - setConstructList, - setGame, - setMenu, - setPlayer, - setPlayerList, - setVbox, - setWs, - setGameList, - setZone, - setScores, - }; -} - -module.exports = registerEvents; diff --git a/phaser-client/src/main.js b/phaser-client/src/main.js deleted file mode 100644 index ef2fbede..00000000 --- a/phaser-client/src/main.js +++ /dev/null @@ -1,17 +0,0 @@ -const renderConstructs = require('./scenes/constructs'); - -const createSocket = require('./socket'); -const registerEvents = require('./events'); -const createTutorial = require('./tutorial'); - -document.fonts.load('10pt "Jura"').then(() => { - const game = renderConstructs(); - const tutorial = createTutorial(); - const events = registerEvents(game.registry, game.events, tutorial); - const ws = createSocket(events); - - // events.setWs(ws); - // events.setGameList([]); - - ws.connect(); -}); diff --git a/phaser-client/src/scenes/avatar.js b/phaser-client/src/scenes/avatar.js deleted file mode 100644 index 0ca54da0..00000000 --- a/phaser-client/src/scenes/avatar.js +++ /dev/null @@ -1,13 +0,0 @@ -const genAvatar = (name) => { - let hash = 0; - if (name.length === 0) return hash; - // Probs don't need to hash using the whole string - for (let i = 0; i < name.length; i += 1) { - const chr = name.charCodeAt(i); - hash = ((hash << 5) - hash) + chr; - hash = hash & 10000; // We have avatars named 0-19 - } - return `sprite${hash}`; -}; - -module.exports = genAvatar; diff --git a/phaser-client/src/scenes/background.js b/phaser-client/src/scenes/background.js deleted file mode 100644 index 7baaadd7..00000000 --- a/phaser-client/src/scenes/background.js +++ /dev/null @@ -1,166 +0,0 @@ -const Phaser = require('phaser'); - -const CHART = ` -#ifdef GL_ES -precision mediump float; -#endif - -#extension GL_OES_standard_derivatives : enable - -uniform float time; -uniform vec2 mouse; -uniform vec2 resolution; - -float rand(float n){return fract(sin(n) * 43758.5453123 * time * 0.00001);} - -float noise(float p){ - float fl = floor(p); - float fc = fract(p); - // return mix(rand(fl), rand(fl + 1.0), p); - return mix(rand(fl), rand(fl + 1.0), p); -} - -float getLine(vec2 p, float y){ - float margin = 0.; - - vec2 pos = p; - float a = time * 100. + y * 31.; - vec2 lineCenter = vec2(0.5, y); - - pos -= lineCenter; - pos *- mat2(cos(a), -sin(a), sin(a), cos(a)); - pos += lineCenter; - - - float marginb = 0.005; - float b = 0.004; - float t = y + (noise((pos.x + y) * 100.) - 0.5) * 0.02; - float f = (smoothstep(t - b, t, pos.y) - smoothstep(t, t + b, pos.y)); - f *= smoothstep(margin - marginb, margin, pos.x) - smoothstep(1. - margin, 1. - margin + marginb, pos.x); - f *= 0.8; - - float light = 0.5 + 0.5 * sin(time * .2); - vec2 point = vec2(margin + light * (1. - margin * 2.), t); - f += .008 / distance(pos, point); - return f; -} - -void main( void ) { - vec2 p = gl_FragCoord.xy / resolution.xy; - float f = 0.; - - for(int i = 0; i < 10; i++){ - f += getLine(p, 0.1 + (0.8) / 10. * float(i)); - } - - vec3 color = vec3(0., .4, .6) * f; - gl_FragColor = vec4(color, 1.); -}`; - -const STARS = ` -//--- hatsuyuki --- -// by Catzpaw 2016 -#ifdef GL_ES -precision mediump float; -#endif - -#extension GL_OES_standard_derivatives : enable - -uniform float time; -uniform vec2 resolution; - float hash(float x){ - return fract(sin(x*133.3)*12.13); - } - void main(void){ - vec2 uv=(gl_FragCoord.xy*2.-resolution.xy)/min(resolution.x,resolution.y); - vec3 c=vec3(.2,.2,.2); - float a=4.4; - float si=sin(a),co=cos(a); - uv*=mat2(co,-si,si,co); - uv*=length(uv+vec2(0,1.9))*.5+1.; - float v=1.-sin(hash(floor(uv.x*200.))*2.); - float b=clamp(abs(sin(5.*time*v+uv.y*(5./(2.+v))))-.95,0.,1.)*20.; - c*=v*b; - gl_FragColor = vec4(c,2); -} -`; - -const PLASMA = ` -precision mediump float; - -uniform sampler2D uMainSampler; -uniform vec2 resolution; -uniform float time; - -varying vec2 outTexCoord; -varying vec4 outTint; - -#define MAX_ITER 4 - -void main( void ) -{ - vec2 v_texCoord = gl_FragCoord.xy / resolution; - - vec2 p = v_texCoord * 8.0 - vec2(20.0); - vec2 i = p; - float c = 1.0; - float inten = .05; - - for (int n = 0; n < MAX_ITER; n++) - { - float t = time * (1.0 - (3.0 / float(n+1))); - - i = p + vec2(cos(t - i.x) + sin(t + i.y), - sin(t - i.y) + cos(t + i.x)); - - c += 1.0/length(vec2(p.x / (sin(i.x+t)/inten), - p.y / (cos(i.y+t)/inten))); - } - - c /= float(MAX_ITER); - c = 1.5 - sqrt(c); - - vec4 texColor = vec4(0.01, 0.01, 0.01, 1.0); - - texColor.rgb *= (1.0 / (1.0 - (c + 0.05))); - - gl_FragColor = texColor; -} -`; - -const CustomPipeline = new Phaser.Class({ - Extends: Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline, - initialize: function CustomPipeline (game) { - Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline.call(this, { - game, - renderer: game.renderer, - fragShader: STARS, - }); - }, -}); - - -class Background extends Phaser.Scene { - constructor() { - super({ key: 'Background', active: true }); - this.bgTime = 10.0; - } - - create() { - const game = this.game; - this.customPipeline = game.renderer.addPipeline('Custom', new CustomPipeline(game)); - this.customPipeline.setFloat2('resolution', 1600, 1000); - - const sprite = this.add.sprite(800, 500); - sprite.setPipeline('Custom'); - sprite.displayWidth = 1600 * window.devicePixelRatio; - sprite.displayHeight = 1000 * window.devicePixelRatio; - } - - update() { - this.customPipeline.setFloat1('time', this.bgTime); - this.bgTime += 0.005; - } -} - -module.exports = Background; diff --git a/phaser-client/src/scenes/combat.animations.js b/phaser-client/src/scenes/combat.animations.js deleted file mode 100644 index 7a1ef934..00000000 --- a/phaser-client/src/scenes/combat.animations.js +++ /dev/null @@ -1,250 +0,0 @@ -const Phaser = require('phaser'); -const { POSITIONS: { COMBAT }, DELAYS } = require('./constants'); - -const randomColour = () => { - const colours = ['green', 'blue', 'red', 'white', 'yellow']; - return colours[Math.floor(Math.random() * 5)]; -}; - -const animationParams = (sourceAlly) => { - const spawnLocation = sourceAlly ? COMBAT.width() * 0.35 : COMBAT.width() * 0.65; - const speed = sourceAlly ? 250 : -250; - const img = randomColour(); - const angleMin = sourceAlly ? 320 : 180; - const angleMax = sourceAlly ? 360 : 220; - return { spawnLocation, speed, img, angleMin, angleMax }; -}; - -const randomAttack = () => { - const animations = ['wall', 'spit', 'gravBlast', 'gravBomb', 'chargeBall']; - return animations[Math.floor(Math.random() * 5)]; -}; - -class CombatSkills extends Phaser.GameObjects.Group { - constructor(scene) { - super(scene); - this.scene = scene; - } - - getSkill(type, sourceAlly, targetAlly, castLocation) { - const genericHeal = ['Heal', 'Triage', 'TriageTick', 'DecayTick']; - const genericBlock = ['Block', 'Parry', 'Evasion', 'Shield']; - - if (genericHeal.includes(type)) { - this.genericHeal(targetAlly, castLocation); - } else if (genericBlock.includes(type)) { - this.genericBlock(sourceAlly); - } else { - this[randomAttack()](sourceAlly); - } - } - - genericHeal(sourceAlly, castLocation) { - // const { sourceX, sourceY } = getConstructPosition(sourcePos, 0); - const lifespan = DELAYS.ANIMATION_DURATION; - const colour = randomColour(); - const particles = this.scene.add.particles(colour); - const x = sourceAlly ? COMBAT.width() * 0.3 : COMBAT.width() * 0.7; - - const emitter2 = particles.createEmitter({ - x: castLocation.x, - y: castLocation.y, - moveToX: x, - moveToY: COMBAT.height() * 0.2, - speed: 500, - lifespan: lifespan / 3, - scale: { start: 0.5, end: 1 }, - quantity: 3, - _frequency: 20, - blendMode: 'ADD', - emitZone: { source: new Phaser.Geom.Rectangle(-200, -100, 400, 200) }, - }); - - const emitter = particles.createEmitter({ - x, - y: COMBAT.height() * 0.2, - angle: { min: 250, max: 290 }, - speed: 250, - gravityY: 1000, - quantity: 4, - scale: { start: 0.1, end: 1 }, - blendMode: 'ADD', - lifespan, - active: false, - }); - - - this.add(particles); - this.scene.time.delayedCall(lifespan / 3, () => { emitter2.stop(); }, [], this); - this.scene.time.delayedCall(lifespan / 3, () => { emitter.active = true; }, [], this); - - this.scene.time.delayedCall(lifespan, () => { emitter.stop(); }, [], this); - } - - genericBlock(sourceAlly) { - const lifespan = DELAYS.ANIMATION_DURATION; - const colour = randomColour(); - const x = sourceAlly ? COMBAT.width() * 0.3 : COMBAT.width() * 0.7; - const emitter1 = this.scene.add.particles(colour).createEmitter({ - x, - y: COMBAT.height() * 0.4, - scale: { start: 0.75, end: 0.25 }, - blendMode: 'ADD', - emitZone: { - source: new Phaser.Geom.Rectangle(-100, -100, 200, 200), - type: 'edge', - quantity: 24, - yoyo: true, - }, - }); - const emitter2 = this.scene.add.particles(colour).createEmitter({ - x, - y: COMBAT.height() * 0.4, - blendMode: 'SCREEN', - scale: { start: 0.2, end: 0 }, - speed: { min: -100, max: 100 }, - quantity: 50, - active: false, - emitZone: { - source: new Phaser.Geom.Rectangle(-100, -100, 200, 200), - type: 'edge', - quantity: 50, - }, - }); - this.scene.time.delayedCall(lifespan / 2, () => { emitter1.stop(); }, [], this); - this.scene.time.delayedCall(lifespan / 2, () => { emitter2.active = true; }, [], this); - this.scene.time.delayedCall(lifespan, () => { emitter2.stop(); }, [], this); - } - - wall(sourceAlly) { - const lifespan = DELAYS.ANIMATION_DURATION; - const { spawnLocation, speed, img } = animationParams(sourceAlly); - const particles = this.scene.add.particles(img); - const emitter = particles.createEmitter({ - x: spawnLocation, - y: { min: COMBAT.height() * 0.2, max: COMBAT.height() * 0.5 }, - speedX: { min: speed, max: speed * 2 }, - scale: { start: 0.4, end: 0 }, - quantity: 4, - blendMode: 'ADD', - lifespan, - }); - this.add(particles); - this.scene.time.delayedCall(1000, () => { emitter.stop(); }, [], this.scene); - } - - spit(sourceAlly) { - const lifespan = DELAYS.ANIMATION_DURATION; - const { spawnLocation, speed, img, angleMin, angleMax } = animationParams(sourceAlly); - const particles = this.scene.add.particles(img); - const emitter = particles.createEmitter({ - x: spawnLocation, - y: COMBAT.height() * 0.35, - angle: { min: angleMin, max: angleMax }, - speed: speed * 2, - scale: { start: 0.4, end: 1 }, - gravityY: 250, - quantity: 4, - blendMode: 'ADD', - lifespan, - }); - this.add(particles); - this.scene.time.delayedCall(lifespan, () => { emitter.stop(); }, [], this); - } - - gravBomb(sourceAlly) { - const lifespan = DELAYS.ANIMATION_DURATION; - - const { spawnLocation, img } = animationParams(!sourceAlly); - const particles = this.scene.add.particles(img); - const well = particles.createGravityWell({ - x: spawnLocation, - y: COMBAT.height() * 0.25, - power: 4, - gravity: 500, - }); - this.emitter = particles.createEmitter({ - x: spawnLocation, - y: COMBAT.height() * 0.25, - speed: 1000, - scale: { start: 0.7, end: 1 }, - blendMode: 'ADD', - lifespan, - }); - this.add(particles); - this.scene.time.delayedCall(lifespan, () => { this.emitter.stop(); well.active = false; }, [], this.scene); - } - - gravBlast(sourceAlly) { - const lifespan = DELAYS.ANIMATION_DURATION; - const WELL_END = lifespan / 2; - - const img = randomColour(); - const spawnLocation = sourceAlly ? COMBAT.width() * 0.35 : COMBAT.width() * 0.65; - const isEnemyLocation = sourceAlly ? COMBAT.width() * 0.7 : COMBAT.width() * 0.3; - const particles = this.scene.add.particles(img); - const bounds = sourceAlly - ? { x: COMBAT.width() * 0.3, y: COMBAT.height() * 0.2, w: COMBAT.width() * 0.5, h: COMBAT.height() * 0.2 } - : { x: 0.2 * COMBAT.width(), y: COMBAT.height() * 0.2, w: COMBAT.width() * 0.5, h: COMBAT.height() * 0.2 }; - const well = particles.createGravityWell({ - x: spawnLocation, - y: COMBAT.height() * 0.35, - power: 4, - gravity: 500, - }); - const emitter = particles.createEmitter({ - x: spawnLocation, - y: COMBAT.height() * 0.35, - speed: 1000, - scale: { start: 0.7, end: 1 }, - blendMode: 'ADD', - bounds, - lifespan, - }); - this.add(particles); - this.scene.time.delayedCall(WELL_END, () => { emitter.stop(); well.x = isEnemyLocation; }, [], this.scene); - this.scene.time.delayedCall(lifespan, () => { well.active = false; }, [], this.scene); - } - - chargeBall(sourceAlly) { - const lifespan = DELAYS.ANIMATION_DURATION; - const CHARGE_LIFESPAN = lifespan / 3; - - const { img, spawnLocation } = animationParams(sourceAlly); - const targetLocation = sourceAlly ? 0.7 * COMBAT.width() : 0.25 * COMBAT.width(); - const particles = this.scene.add.particles(img); - const emitter = particles.createEmitter({ - x: 0, - y: 0, - moveToX: spawnLocation, - moveToY: COMBAT.height() * 0.1, - scale: 0.75, - quantity: 4, - _frequency: 20, - blendMode: 'ADD', - emitZone: { source: new Phaser.Geom.Rectangle(0, 0, COMBAT.width(), COMBAT.height()) }, - lifespan: CHARGE_LIFESPAN, - }); - const emitter2 = particles.createEmitter({ - radial: false, - x: { min: spawnLocation, max: targetLocation, steps: 90 }, - y: { min: COMBAT.height() * 0.1, max: COMBAT.height() * 0.4, steps: 90 }, - quantity: 4, - gravityY: 0, - scale: { start: 2, end: 0.1, ease: 'Power3' }, - blendMode: 'ADD', - active: false, - lifespan: CHARGE_LIFESPAN, - }); - this.add(particles); - this.scene.time.delayedCall(CHARGE_LIFESPAN, () => { emitter.stop(); }, [], this.scene); - this.scene.time.delayedCall(CHARGE_LIFESPAN * 2, () => { emitter2.active = true; }, [], this.scene); - this.scene.time.delayedCall(lifespan, () => { emitter2.stop(); }, [], this.scene); - } - - cleanup() { - this.children.entries.forEach(obj => obj.destroy()); - } -} - -module.exports = CombatSkills; diff --git a/phaser-client/src/scenes/combat.cryps.js b/phaser-client/src/scenes/combat.cryps.js deleted file mode 100644 index 6616a5b4..00000000 --- a/phaser-client/src/scenes/combat.cryps.js +++ /dev/null @@ -1,239 +0,0 @@ -const Phaser = require('phaser'); -const genAvatar = require('./avatar'); -const StatBar = require('./elements/combat.statbar'); - -const { DELAYS, TEXT, POSITIONS: { COMBAT } } = require('./constants'); - -const CONSTRUCT_MARGIN = COMBAT.constructMargin(); -const TEXT_MARGIN = COMBAT.textMargin(); - -const constructAvatarText = (team, iter) => { - const nameX = COMBAT.width() * team; - const nameY = COMBAT.y() + CONSTRUCT_MARGIN * iter + COMBAT.height() * 0.07; - const statusX = COMBAT.width() * team; - const statusY = COMBAT.y() + TEXT_MARGIN * 6 + CONSTRUCT_MARGIN * iter + COMBAT.height() * 0.07; - return { statusX, statusY, nameX, nameY }; -}; - -const constructEffects = (team, iter) => { - const constructEffectsX = team ? COMBAT.width() - COMBAT.width() / 6.5 : COMBAT.width() / 6.5; - const constructEffectsY = TEXT_MARGIN * 2 + CONSTRUCT_MARGIN * iter; - return { constructEffectsX, constructEffectsY }; -}; - -const constructPosition = (team, iter) => { - const constructAvatarX = team ? COMBAT.width() - COMBAT.width() / 6 : COMBAT.width() / 6; - const constructAvatarY = TEXT_MARGIN * 5 + CONSTRUCT_MARGIN * iter; - return { constructAvatarX, constructAvatarY }; -}; - - -class Effects extends Phaser.GameObjects.Group { - constructor(scene, team, iter) { - super(scene); - this.scene = scene; - const { constructEffectsX, constructEffectsY } = constructEffects(team, iter); - this.x = constructEffectsX; this.y = constructEffectsY; - this.effectCount = 0; - } - - addEffect(effect) { - const y = this.y + this.effectCount * TEXT_MARGIN; - const text = `${effect.effect} for ${effect.duration} turn`; - const e = this.scene.add.text(this.x, y, text, TEXT.NORMAL); - e.effect = effect.effect; - this.add(e); - this.effectCount += 1; - } - - removeEffect(effect) { - this.children.entries.forEach((e) => { - if (e.effect === effect) e.destroy(); - }); - } - - update(effects) { - this.effectCount = 0; - this.children.entries.forEach(e => e.destroy()); - effects.forEach((effect) => { - this.addEffect(effect); - }); - return true; - } -} - -class ConstructImage extends Phaser.GameObjects.Image { - constructor(scene, team, iter, construct) { - // Get coords - const { constructAvatarX, constructAvatarY } = constructPosition(team, iter); - const { statusX, statusY, nameX, nameY } = constructAvatarText(team, iter); - - // Construct display - // const avatar = team ? 'magmar' : 'alk'; - super(scene, constructAvatarX, constructAvatarY, 'aztec', genAvatar(construct.name)); - this.setScale(0.5); - - if (!team) this.flipX = true; - - // Save position and construct details - this.scene = scene; - this.iter = iter; - this.team = team; - this.construct = construct; - this.state = 'deselect'; - // Add construct name - scene.add.text(nameX, nameY, construct.name, TEXT.NORMAL).setOrigin(team, 0); - // Add construct stat bars - this.health = scene.add.existing(new StatBar(scene, this, 'HP')); - this.red_shield = scene.add.existing(new StatBar(scene, this, 'Red Shield')); - this.blue_shield = scene.add.existing(new StatBar(scene, this, 'Blue Shield')); - // this.evasion = scene.add.existing(new StatBar(scene, this, 'Evasion')); - - this.effects = scene.add.existing(new Effects(scene, team, iter)); - this.statusText = scene.add.text(statusX, statusY, '', TEXT.NORMAL); - } - - select() { - this.setTint('0x00bb00'); - this.state = 'select'; - } - - setKo() { - this.state = 'ko'; - this.setTint('0x9d9ea0'); - } - - deselect() { - if (this.state !== 'ko') { - this.clearTint(); - this.state = 'deselect'; - } - } - - clearStatus() { - this.statusText.text = ''; - } - - reduceDefense(amount, type) { - if (type === 'PhysDmg') { - this.red_shield.takeDamage(amount); - } else if (type === 'BlueDmg') { - this.blue_shield.takeDamage(amount); - } - } - - takeDamage(props) { - const { amount, mitigation, category } = props; - if (mitigation) this.reduceDefense(mitigation, category); - this.setTint(0xff0000); - this.health.takeDamage(amount); - this.scene.time.delayedCall(DELAYS.DAMAGE_TICK, () => { - if (this.state !== 'ko') this.clearTint(); - }); - } - - takeHealing(amount) { - this.setTint(0x00bb00); - this.health.takeDamage(amount * -1); - this.scene.time.delayedCall(DELAYS.DAMAGE_TICK, () => { - if (this.state !== 'ko') this.clearTint(); - }); - } -} - -class CombatConstructs extends Phaser.Scene { - constructor() { - super({ key: 'CombatConstructs' }); - } - - create(game) { - this.constructs = this.add.group(); - this.phase = game.phase; - this.account = this.registry.get('account'); - this.drawConstructs(game); - this.registry.events.on('changedata', this.updateData, this); - this.registry.set('constructStatusUpdate', false); - this.teams = game.teams.length; - } - - updateData(parent, key, data) { - if (key === 'game' && data) { - if (data.teams.length !== this.teams) this.scene.restart(data); - const isAnimating = this.phase === 'animating'; - this.game = data; - if (isAnimating) return false; - } - - if (key === 'gamePhase' && data) { - const shouldUpdate = data !== this.phase; - this.phase = data; - if (shouldUpdate) { - this.constructs.children.entries.forEach(c => c.clearStatus()); - this.drawConstructs(this.game); - } - } - - if (key === 'constructStatusUpdate' && data) { - this.updateConstructStatus(data); - } - - return true; - } - - drawConstructs(game) { - const renderConstruct = (construct, iter, team) => { - // Add Image Avatar Class - const constructObj = new ConstructImage(this, team, iter, construct); - this.add.existing(constructObj); - this.constructs.add(constructObj); - return constructObj; - }; - - const renderTeam = (construct, iter, team) => { - const constructObj = this.constructs.children.entries - .find(c => c.construct.id === construct.id) - || renderConstruct(construct, iter, team); - constructObj.health.val = construct.hp.value; - constructObj.red_shield.val = construct.red_shield.value; - constructObj.blue_shield.val = construct.red_shield.value; - - constructObj.health.drawStatBar(); - constructObj.red_shield.drawStatBar(); - constructObj.blue_shield.drawStatBar(); - constructObj.effects.update(construct.effects); - }; - - const allyTeam = game.teams.find(t => t.id === this.account.id); - // in future there will be more than one - const [enemyTeam] = game.teams.filter(t => t.id !== this.account.id); - - allyTeam.constructs.forEach((construct, i) => renderTeam(construct, i, 0)); - if (!enemyTeam) return false; - enemyTeam.constructs.forEach((construct, i) => renderTeam(construct, i, 1)); - return true; - } - - selectConstruct(constructId) { - this.constructs.children.entries.forEach(c => c.deselect()); - if (constructId) this.constructs.children.entries.find(c => c.construct.id === constructId).select(); - } - - updateConstructStatus(status) { - const sourceConstruct = this.constructs.children.entries - .find(c => c.construct.id === status.id); - - const targetConstruct = this.constructs.children.entries - .find(c => c.construct.id === status.target); - - if (this.phase === 'Skill') { - sourceConstruct.statusText.text = `${status.skill} on ${targetConstruct.construct.name}`; - } - } - - cleanUp() { - this.registry.events.off('changedata', this.updateData); - this.scene.remove(); - } -} - -module.exports = CombatConstructs; diff --git a/phaser-client/src/scenes/combat.hitbox.js b/phaser-client/src/scenes/combat.hitbox.js deleted file mode 100644 index 868fe5ce..00000000 --- a/phaser-client/src/scenes/combat.hitbox.js +++ /dev/null @@ -1,89 +0,0 @@ -const Phaser = require('phaser'); -const { POSITIONS: { COMBAT } } = require('./constants'); - -const CONSTRUCT_MARGIN = COMBAT.constructMargin(); -const BOX_HEIGHT = CONSTRUCT_MARGIN * 0.8; -const BOX_WIDTH = COMBAT.width() * 0.2; - - -class ConstructHitBox extends Phaser.GameObjects.Rectangle { - constructor(scene, iter, team, cback) { - const y = COMBAT.y() + COMBAT.height() * 0.05 + CONSTRUCT_MARGIN * iter; - super(scene, (COMBAT.width() - BOX_WIDTH) * team, y, BOX_WIDTH, BOX_HEIGHT, 0x222222); - this.setOrigin(0); - this.clickHandler = () => cback(); - } - - select() { - this.setFillStyle(0x003300); - } - - deselect() { - this.setFillStyle(0x222222); - } -} - -class CombatHitBox extends Phaser.Scene { - constructor() { - super({ key: 'CombatHitBox' }); - } - - create(phase) { - this.phase = phase; - this.registry.events.off('changedata', this.updateData); - this.registry.events.on('changedata', this.updateData, this); - if (phase === 'animating') return true; - this.selectHitBox(phase); - return true; - } - - updateData(parent, key, data) { - if (key === 'game' && data) { - // In the case that we hit skill phase but teams change we restart - if (data.teams.length !== this.teams) this.scene.restart(data.phase); - } - if (key === 'gamePhase' && data) { - const shouldUpdate = data !== this.phase; - if (shouldUpdate) this.scene.restart(data); - return false; - } - return true; - } - - selectHitBox(phase) { - const game = this.registry.get('game'); - this.teams = game.teams.length; - if (phase === 'Skill') return this.skillHitBox(game); - return false; - } - - skillHitBox(game) { - const account = this.registry.get('account'); - const group = this.scene.get('CombatConstructs').constructs; - const skillScene = this.scene.get('CombatSkills'); - game.teams.forEach((t) => { - t.constructs.forEach((c) => { - const cback = () => { - const { activeSkill } = skillScene; - if (activeSkill) { - this.scene.get('CombatSkills').clearConstructActive(activeSkill.construct.id); - activeSkill.activate(); - skillScene.activeSkill = null; - this.game.events.emit('SEND_SKILL', game.id, activeSkill.construct.id, c.id, activeSkill.skill.skill); - } - }; - const constructSpawn = group.children.entries.find(s => s.construct.id === c.id); - const team = c.account === account.id ? 0 : 1; - if (constructSpawn) this.add.existing(new ConstructHitBox(this, constructSpawn.iter, team, cback)); - }); - }); - this.scene.moveBelow('Combat'); - } - - cleanUp() { - this.registry.events.off('changedata', this.updateData); - this.scene.remove(); - } -} - -module.exports = CombatHitBox; diff --git a/phaser-client/src/scenes/combat.js b/phaser-client/src/scenes/combat.js deleted file mode 100644 index 1c520c60..00000000 --- a/phaser-client/src/scenes/combat.js +++ /dev/null @@ -1,138 +0,0 @@ -const Phaser = require('phaser'); -const { throttle } = require('lodash'); - -const { TEXT, POSITIONS: { COMBAT } } = require('./constants'); -const CombatLog = require('./combat.log'); -const CombatConstructs = require('./combat.constructs'); -const CombatSkills = require('./combat.skills'); -const CombatHitBox = require('./combat.hitbox'); - -const renderResolutions = require('./combat.render.resolutions'); - - -class Combat extends Phaser.Scene { - constructor() { - super({ key: 'Combat' }); - } - - preload() { - this.load.image('proj', 'https://labs.phaser.io/assets/sprites/bullet.png'); - this.load.image('blue', 'https://labs.phaser.io/assets/particles/blue.png'); - this.load.image('green', 'https://labs.phaser.io/assets/particles/green.png'); - this.load.image('red', 'https://labs.phaser.io/assets/particles/red.png'); - this.load.image('white', 'https://labs.phaser.io/assets/particles/white.png'); - this.load.image('yellow', 'https://labs.phaser.io/assets/particles/yellow.png'); - } - - create() { - console.log('creating game'); - this.registry.events.off('changedata', this.updateData); - this.registry.events.on('changedata', this.updateData, this); - this.addLeaveGame(); - - this.registry.set('gamePhase', false); - this.registry.set('inGame', true); - this.registry.set('gameAnimating', false); - this.account = this.registry.get('account'); - this.fetchGame = throttle(() => { - const game = this.registry.get('game'); - if (game) { - const ws = this.registry.get('ws'); - return ws.sendGameState(game.id); - } - return false; - }, 500); - - return true; - } - - startGame(game) { - this.scene.manager.add('CombatConstructs', CombatConstructs, true, game); - this.scene.manager.add('CombatLog', CombatLog, true, game); - this.renderedResolves = game.resolved.length; // In case you rejoin mid way - this.scene.manager.add('CombatSkills', CombatSkills, true, game.phase); - this.scene.manager.add('CombatHitBox', CombatHitBox, true, game.phase); - this.registry.set('gamePhase', game.phase); - this.phase = game.phase; - return true; - } - - update() { - this.fetchGame(); - return true; - } - - updateData(parent, key, data) { - if (key === 'game') { - if (!data) return false; - const startGame = this.registry.get('gamePhase') === false; - if (startGame) { this.startGame(data); return true; } - this.checkAnimation(data); - // Game over? - // if (data.phase === 'Finish') { - // this.time.delayedCall(10000, () => { - // this.endGame(); - // }); - // } - } - return true; - } - - checkAnimation(game) { - // Check constructs are loaded and whether game is animating - const cantAnimate = this.registry.get('gamePhase') === 'animating'; - if (cantAnimate) return false; - if (game.resolved.length !== this.renderedResolves) { - const newResolutions = game.resolved.slice(this.renderedResolves); - renderResolutions(this, game, newResolutions); - this.renderedResolves = game.resolved.length; - return true; - } - if (this.phase !== game.phase) { - this.phase = game.phase; - this.registry.set('gamePhase', game.phase); - } - if (this.registry.get('gameLog') !== game.log.length) { - this.registry.set('gameLog', game.log.length); - } - return true; - } - - addLeaveGame() { - const leaveGame = () => this.cleanUp(); - this.input.keyboard.on('keydown_BACKSPACE', leaveGame, 0, this); - const LEAVE_HEIGHT = COMBAT.height() / 6; - const LEAVE_WIDTH = COMBAT.width() / 5; - const LEAVE_X = COMBAT.width() * 0.8; - const LEAVE_Y = COMBAT.height() * 0.9; - - const menu = this.add - .rectangle(LEAVE_X, LEAVE_Y, LEAVE_WIDTH, LEAVE_HEIGHT, 0x440000) - .setInteractive() - .setOrigin(0) - .on('pointerdown', leaveGame); - - this.add - .text(menu.getCenter().x, menu.getCenter().y, 'Menu', TEXT.HEADER) - .setOrigin(0.5, 0.5); - } - - cleanUp() { - this.registry.events.off('changedata', this.updateData, this); - this.registry.events.off('setdata', this.updateData, this); - - this.registry.set('inGame', null); - this.registry.set('menu', true); - this.registry.set('game', null); - - const ACTIVE_SCENES = ['CombatLog', 'CombatConstructs', 'CombatSkills', 'CombatHitBox']; - ACTIVE_SCENES.forEach((sKey) => { - if (this.scene.get(sKey)) this.scene.get(sKey).cleanUp(); - }); - this.scene.remove(); - - return true; - } -} - -module.exports = Combat; diff --git a/phaser-client/src/scenes/combat.log.js b/phaser-client/src/scenes/combat.log.js deleted file mode 100644 index 7b353ef4..00000000 --- a/phaser-client/src/scenes/combat.log.js +++ /dev/null @@ -1,50 +0,0 @@ -const Phaser = require('phaser'); -const { POSITIONS: { COMBAT }, TEXT } = require('./constants'); - -class CombatLog extends Phaser.Scene { - constructor() { - super({ key: 'CombatLog' }); - } - - create(game) { - this.registry.events.on('changedata', this.updateData, this); - this.cameras.main.setViewport(COMBAT.LOG.x(), COMBAT.LOG.y(), COMBAT.LOG.width(), COMBAT.LOG.height()); - this.log = this.add.text(0, 0, '', TEXT.NORMAL); - this.logIndex = game.log.length; - this.logData = game.log; - this.log.setWordWrapWidth(COMBAT.LOG.width()); - this.log.setText(Array.from(game.log).reverse()); - } - - updateData(parent, key, data) { - const UPDATE_KEYS = ['game', 'gameLog']; - if (UPDATE_KEYS.includes(key) && data) { - if (key === 'game') { - this.logData = data.log; - } - if (key === 'gameLog') { - this.logIndex = data; - } - this.updateLog(); - } - return true; - } - - updateLog() { - // shallow copy because reverse mutates - if (this.logData.length > this.logIndex + 1 - && Array.from(this.logData)[this.logIndex].slice(-2) === 'KO') { - this.logIndex += 1; - this.registry.set('gameLog', this.logIndex); - } - // } - this.log.setText(Array.from(this.logData).slice(0, this.logIndex).reverse()); - } - - cleanUp() { - this.registry.events.off('changedata', this.updateData); - this.scene.remove(); - } -} - -module.exports = CombatLog; diff --git a/phaser-client/src/scenes/combat.render.resolutions.js b/phaser-client/src/scenes/combat.render.resolutions.js deleted file mode 100644 index 77ceed62..00000000 --- a/phaser-client/src/scenes/combat.render.resolutions.js +++ /dev/null @@ -1,135 +0,0 @@ -const { eachSeries } = require('async'); - -const CombatAnimations = require('./combat.animations'); -const { - DELAYS: { ANIMATION_DURATION, MOVE_CREEP, DAMAGE_TICK }, - POSITIONS: { COMBAT }, -} = require('./constants'); - -function findResolutionConstructs(scene, group, resolution, game) { - const sourceSpawn = group.children.entries.find(c => c.construct.id === resolution.source.id); - -/* const sourceConstruct = game.teams.find(t => t.constructs.find(c => c.id === resolution.source_construct_id)) - .constructs.find(c => c.id === resolution.source_construct_id); - - const targetConstruct = game.teams.find(t => t.constructs.find(c => c.id === resolution.target_construct_id)) - .constructs.find(c => c.id === resolution.target_construct_id); -*/ - const targetSpawn = group.children.entries.find(c => c.construct.id === resolution.target.id); - - return { sourceSpawn, targetSpawn }; -} - -function calculateTweenParams(sourceSpawn, targetSpawn, account, skill) { - const tweenParams = (targets, centreSpot) => { - const enemy = targets.construct.account !== account.id; - let x = centreSpot ? COMBAT.width() * 0.3 : targets.x; - x = (enemy && centreSpot) ? x + COMBAT.width() * 0.4 : x; - const y = centreSpot ? COMBAT.height() * 13.25 / 35 : targets.y; - const ease = 'Power1'; - const duration = MOVE_CREEP; - return { - targets, x, y, ease, duration, - }; - }; - let moveSourceBattle = false; - let moveSourceOrig = false; - const targetOnlySkill = ['DecayTick']; - if (!(targetOnlySkill.includes(skill))) { - if (sourceSpawn.construct.account !== targetSpawn.construct.account) { - moveSourceBattle = tweenParams(sourceSpawn, true); - moveSourceOrig = tweenParams(sourceSpawn, false); - } - } - - const moveTargetBattle = tweenParams(targetSpawn, true); - const moveTargetOrig = tweenParams(targetSpawn, false); - - return { - moveSourceBattle, moveSourceOrig, moveTargetBattle, moveTargetOrig, - }; -} - -function animatePhase(scene, game, resolution, cb) { - // return early for disabled skills - if (resolution.length === 0) return cb(); - if (resolution.event[0] === 'Disable' - || resolution.event[0] === 'TargetKo' - || resolution.event === 'Ko') return cb(); - - const group = scene.scene.get('CombatConstructs').constructs; - const animations = new CombatAnimations(scene); - const account = scene.registry.get('account'); - - // Find constructs, targets - const { sourceSpawn, targetSpawn } = findResolutionConstructs(scene, group, resolution, game); - const { - moveSourceBattle, moveSourceOrig, moveTargetBattle, moveTargetOrig, - } = calculateTweenParams(sourceSpawn, targetSpawn, account, resolution.event[1].skill); - - const castParams = () => { - const x = (sourceSpawn === targetSpawn) ? moveTargetBattle.x : sourceSpawn.x; - const y = (sourceSpawn === targetSpawn) ? moveTargetBattle.y : sourceSpawn.y; - return { x, y }; - }; - const castLocation = castParams(); - - // Move constructs into position - if (moveSourceBattle) scene.tweens.add(moveSourceBattle); - scene.tweens.add(moveTargetBattle); - - return scene.time.delayedCall(MOVE_CREEP, () => { - const sourceAlly = sourceSpawn.construct.account === account.id; - const targetAlly = targetSpawn.construct.account === account.id; - // animate animation - animations.getSkill(resolution.event[1].skill, sourceAlly, targetAlly, castLocation); - // Target construct takes damage - scene.time.delayedCall(ANIMATION_DURATION, () => { - console.log(resolution); - if (resolution.event[0] === 'Damage') { - targetSpawn.takeDamage(resolution.event[1]); - scene.registry.set('gameLog', scene.registry.get('gameLog') + 1); - } - if (resolution.event[0] === 'Healing') { - targetSpawn.takeHealing(resolution.event[1]); - scene.registry.set('gameLog', scene.registry.get('gameLog') + 1); - } - if (resolution.event[0] === 'Effect') { - targetSpawn.effects.addEffect(resolution.event[1]); - console.log('target has new effect', resolution.event[1].effect); - } - - if (resolution.event[0] === 'Removal') { - targetSpawn.effects.removeEffect(resolution.event[1].effect); - console.log('target effect removed', resolution.event[1].effect); - } - if (moveSourceOrig) scene.tweens.add(moveSourceOrig); - scene.tweens.add(moveTargetOrig); - - // all done - scene.time.delayedCall(MOVE_CREEP, () => { - animations.destroy(true); - return cb(); - }); - }); - }); -} - -function renderResolutions(scene, game, resolutions) { - scene.registry.set('gamePhase', 'animating'); - scene.registry.set('gameLog', scene.registry.get('gameLog') + 1); - - eachSeries( - resolutions, - (resolution, cb) => animatePhase(scene, game, resolution, cb), - (err) => { - if (err) return console.error(err); - scene.registry.set('gamePhase', 'Skill'); - return true; - } - ); - - return true; -} - -module.exports = renderResolutions; diff --git a/phaser-client/src/scenes/combat.skills.js b/phaser-client/src/scenes/combat.skills.js deleted file mode 100644 index 7b0ac765..00000000 --- a/phaser-client/src/scenes/combat.skills.js +++ /dev/null @@ -1,235 +0,0 @@ -const Phaser = require('phaser'); - -const { TEXT, POSITIONS: { COMBAT } } = require('./constants'); - -const CONSTRUCT_KEY_MAP = ['keydown_ONE', 'keydown_TWO', 'keydown_THREE']; -const SKILL_KEY_MAP = ['keydown_Q', 'keydown_W', 'keydown_E', 'keydown_R']; -const TARGET_KEY_MAP = ['keydown_SEVEN', 'keydown_EIGHT', 'keydown_NINE', 'keydown_ZERO']; - -const CONSTRUCT_MARGIN = COMBAT.constructMargin(); -const TEXT_MARGIN = COMBAT.textMargin(); -const SKILL_WIDTH = COMBAT.width() / 10; -const SKILL_HEIGHT = COMBAT.height() / 30; - -const skillPosition = (constructIter, skillIter) => { - const skillTextX = COMBAT.width() / 3.8; - const skillTextY = (TEXT_MARGIN * skillIter) * 1.5 + CONSTRUCT_MARGIN * constructIter + COMBAT.y() + COMBAT.height() * 0.07; - return [skillTextX, skillTextY]; -}; - -const skillCheckHitBox = (scenePlugin, pointer) => { - const { list } = scenePlugin.get('CombatHitBox').children; - for (let i = 0; i < list.length; i += 1) { - if (Phaser.Geom.Rectangle.ContainsPoint(list[i].getBounds(), - pointer.position)) return list[i]; - } - // If we didn't find a hitbox deselect them all - for (let i = 0; i < list.length; i += 1) list[i].deselect(); - return false; -}; - -class ConstructSkill extends Phaser.GameObjects.Container { - constructor(scene, x, y, skill, construct) { - // Avatar will be a property of construct - super(scene, x, y); - const CD_TEXT = skill.cd ? `(${skill.cd}T)` : ''; - const SKILL_TEXT = `${skill.skill} ${CD_TEXT}`; - this.origX = x; this.origY = y; - - this.skillBox = scene.add.rectangle(0, 0, SKILL_WIDTH, SKILL_HEIGHT, 0x222222); - this.skillText = scene.add.text(0, 0, SKILL_TEXT, TEXT.NORMAL).setOrigin(0.5, 0.5); - this.add(this.skillBox); - this.add(this.skillText); - - this.state = 'deselect'; - this.construct = construct; - this.skill = skill; - this.scene = scene; - - this.setSize(SKILL_WIDTH, SKILL_HEIGHT); - this.setInteractive(); - } - - clickHandler() { - if (this.scene.phase === 'Skill') this.scene.activeSkill = this; - this.select(); - } - - select() { - this.scene.children.list.forEach((skill) => { - if (skill.state === 'select') skill.deselect(); - }); - this.skillBox.setFillStyle(0x004bfe); - this.state = 'select'; - } - - activate() { - this.scene.children.list.forEach((skill) => { - if (skill.state === 'select') skill.deselect(); - }); - this.skillBox.setFillStyle(0xff0000); - this.state = 'activate'; - } - - deselect() { - this.skillBox.setFillStyle(0x222222); - this.state = 'deselect'; - } -} - -class CombatSkills extends Phaser.Scene { - constructor() { - super({ key: 'CombatSkills' }); - } - - create(phase) { - this.phase = phase; - this.registry.events.off('changedata', this.updateData); - this.registry.events.on('changedata', this.updateData, this); - this.account = this.registry.get('account'); - - this.input.on('dragstart', (pointer, box) => { - box.clickHandler(); - }); - this.input.on('drag', (pointer, box, dragX, dragY) => { - const hitBox = skillCheckHitBox(this.scene, pointer); - if (hitBox) hitBox.select(); - box.setPosition(dragX, dragY); - }); - this.input.on('dragend', (pointer, box) => { - box.deselect(); - const hitBox = skillCheckHitBox(this.scene, pointer); - if (hitBox) { - hitBox.clickHandler(); - } - box.setPosition(box.origX, box.origY); - }); - - if (phase === 'animating') return true; - // can't set this.game cause of phaser class named the same - const game = this.registry.get('game'); - this.renderSkills(game, phase); - - return true; - } - - updateData(parent, key, data) { - if (key === 'gamePhase' && data) { - const shouldUpdate = data !== this.phase; - if (shouldUpdate) { - this.scene.get('CombatConstructs').selectConstruct(null); - return this.scene.restart(data); - } - return false; - } - return true; - } - - renderSkills(game, phase) { - if (phase === 'Skill') return this.renderSkillPhase(game); - return false; - } - - renderSkillPhase(game) { - const { account } = this; - const { keyboard } = this.input; - const { events } = this.game; - - const addSkill = (i, j, skill, construct) => { - const skillTextPos = skillPosition(i, j); - const skillObj = new ConstructSkill(this, skillTextPos[0], skillTextPos[1], skill, construct); - if (skill.cd) { - skillObj.skillBox.setFillStyle(0x9d9ea0); - } else { - this.input.setDraggable(skillObj); - } - this.add.existing(skillObj); - return skillObj; - }; - - const team = game.teams.find(t => t.id === account.id); - const enemyTeam = game.teams.find(t => t.id !== account.id); - - team.constructs.forEach((construct) => { - // return early if KOd - if (construct.hp.value === 0) return true; - - // find the construct position - const { iter } = this.scene.get('CombatConstructs').constructs.children.entries.find(c => c.construct.id === construct.id); - - // draw the skills - const skillButtons = construct.skills.map((skill, j) => addSkill(iter, j, skill, construct)); - - const bindConstructKeys = () => this.mapSkillKeys(skillButtons, game.id, construct.id, team.id, enemyTeam.id, iter); - - // reset everything - keyboard.on('keydown_ESC', bindConstructKeys, this); - events.on('SEND_SKILL', bindConstructKeys, this); - bindConstructKeys(); - - return true; - }); - - return true; - } - - // FIXME - // needs to send constructId not team - mapSkillKeys(skillButtons, gameId, constructId, alliesId, enemyId, i) { - const { keyboard } = this.input; - - keyboard.removeListener(CONSTRUCT_KEY_MAP[i]); - - keyboard.on(CONSTRUCT_KEY_MAP[i], () => { - SKILL_KEY_MAP.forEach(k => keyboard.removeListener(k)); - - this.scene.get('CombatConstructs').selectConstruct(constructId); - - skillButtons.forEach((button, j) => { - keyboard.on(SKILL_KEY_MAP[j], () => { - this.activeSkill = button; - button.select(); - - // clear existing keys - CONSTRUCT_KEY_MAP.forEach(k => keyboard.removeListener(k)); - TARGET_KEY_MAP.forEach(k => keyboard.removeListener(k)); - - CONSTRUCT_KEY_MAP.forEach(k => keyboard.on(k, () => { - this.clearConstructActive(constructId); - button.activate(); - this.activeSkill = null; - this.game.events.emit('SEND_SKILL', gameId, constructId, alliesId, button.skill.skill); - })); - - TARGET_KEY_MAP.forEach(k => keyboard.on(k, () => { - this.clearConstructActive(constructId); - button.activate(); - this.activeSkill = null; - this.game.events.emit('SEND_SKILL', gameId, constructId, enemyId, button.skill.skill); - })); - }, this); - }); - }, this); - - return true; - } - - clearConstructActive(constructId) { - this.scene.scene.children.list.forEach((s) => { - if (s.construct.id === constructId && s.state === 'activate') s.deselect(); - }); - } - - clearKeys() { - TARGET_KEY_MAP.forEach(tKey => this.input.keyboard.removeListener(tKey)); - CONSTRUCT_KEY_MAP.forEach(tKey => this.input.keyboard.removeListener(tKey)); - SKILL_KEY_MAP.forEach(tKey => this.input.keyboard.removeListener(tKey)); - } - - cleanUp() { - this.registry.events.off('changedata', this.updateData); - this.scene.remove(); - } -} - -module.exports = CombatSkills; diff --git a/phaser-client/src/scenes/constants.js b/phaser-client/src/scenes/constants.js deleted file mode 100644 index ffe0b475..00000000 --- a/phaser-client/src/scenes/constants.js +++ /dev/null @@ -1,388 +0,0 @@ -// POSITIONING FNS -// floors prevent subpixel rendering which looks trash - -const CANVAS_WIDTH = () => Math.floor(window.innerHeight * 1.6); -const CANVAS_HEIGHT = () => Math.floor(window.innerHeight); - -const headerWidth = () => CANVAS_WIDTH(); -const headerHeight = () => Math.floor(CANVAS_HEIGHT() * 0.05); - -const menuConstructListWidth = () => Math.floor(CANVAS_WIDTH() * 0.3); -const menuConstructListHeight = () => Math.floor(CANVAS_HEIGHT() - headerHeight()); -const menuConstructListX = () => Math.floor(CANVAS_WIDTH() * 0.3); -const menuConstructListY = () => headerHeight(); - -const itemListWidth = () => Math.floor(CANVAS_WIDTH() * 0.5); -const itemListHeight = () => Math.floor(CANVAS_HEIGHT() * 0.95); -const itemListX = () => 0; -const itemListY = () => headerHeight(); -const itemBlockWidth = () => Math.floor(itemListWidth() * 0.12); -const itemBlockHeight = () => Math.floor(itemListHeight() * 0.04); - -const menuNavigationWidth = () => Math.floor(CANVAS_WIDTH() * 0.5); -const menuNavigationHeight = () => Math.floor(CANVAS_HEIGHT() * 0.3); -const menuNavigationX = () => Math.floor(CANVAS_WIDTH() * 0.5); -const menuNavigationY = () => Math.floor(CANVAS_HEIGHT() * 0.7); - -const menuMainWidth = () => Math.floor(CANVAS_WIDTH() * 0.4); -const menuMainHeight = () => Math.floor(CANVAS_HEIGHT() * 0.5); -const menuMainX = () => Math.floor(CANVAS_WIDTH() * 0.65); -const menuMainY = () => headerHeight(); - -const homeMainWidth = () => Math.floor(CANVAS_WIDTH() * 0.6); -const homeMainHeight = () => Math.floor(CANVAS_HEIGHT() * 0.5); -const homeMainX = () => Math.floor(CANVAS_WIDTH() * 0.4); -const homeMainY = () => headerHeight(); - -const combatWidth = () => CANVAS_WIDTH(); -const combatHeight = () => CANVAS_HEIGHT() - headerHeight(); -const combatY = () => headerHeight(); -const combatX = () => 0; -const combatConstructMargin = () => Math.floor((CANVAS_HEIGHT() - headerHeight()) / 4.5); -const combatTextMargin = () => Math.floor((CANVAS_HEIGHT() - headerHeight()) / 35); - -const statsWidth = () => Math.floor(CANVAS_WIDTH() - menuConstructListWidth()); -const statsHeight = () => CANVAS_HEIGHT() - headerHeight(); -const statsY = () => headerHeight(); -const statsX = () => menuConstructListWidth(); -const statsKnownX = () => Math.floor(statsX() + statsWidth() / 4); -const statsLearnableX = () => Math.floor(statsX() + statsWidth() / 2); -const statsTextMargin = () => 24; -const statsLearnableMargin = () => 12; - -const logWidth = () => Math.floor(combatWidth() * 0.5); -const logHeight = () => Math.floor(combatHeight() * 0.3); -const logY = () => Math.floor(headerHeight() + (combatHeight() * 0.7)); -const logX = () => Math.floor(combatWidth() * 0.2); - - -module.exports = { - TEXT: { - NORMAL: { fontFamily: 'Jura', fontSize: 18, color: '#ffffff' }, - LEARNABLE: { fontFamily: 'Jura', fontSize: 18, color: '#ffffff' }, - HEADER: { fontFamily: 'Jura', fontSize: 24, color: '#ffffff', fontStyle: 'bold' }, - HOVER: { fontFamily: 'Jura', fontSize: 16, color: '#ffffff', backgroundColor: '#222222' }, - }, - - POSITIONS: { - HEADER: { - width: headerWidth, - height: headerHeight, - }, - - CONSTRUCT_LIST: { - x: menuConstructListX, - y: menuConstructListY, - width: menuConstructListWidth, - height: menuConstructListHeight, - }, - - MENU_MAIN: { - x: menuMainX, - y: menuMainY, - width: menuMainWidth, - height: menuMainHeight, - - }, - - HOME_MAIN: { - x: homeMainX, - y: homeMainY, - width: homeMainWidth, - height: homeMainHeight, - - }, - - - NAVIGATION: { - x: menuNavigationX, - y: menuNavigationY, - width: menuNavigationWidth, - height: menuNavigationHeight, - }, - - ITEM_LIST: { - x: itemListX, - y: itemListY, - width: itemListWidth, - height: itemListHeight, - itemWidth: itemBlockWidth, - itemHeight: itemBlockHeight, - - }, - - STATS: { - x: statsX, - y: statsY, - width: statsWidth, - height: statsHeight, - knownX: statsKnownX, - learnableX: statsLearnableX, - textMargin: statsTextMargin, - learnableMargin: statsLearnableMargin, - }, - - COMBAT: { - x: combatX, - y: combatY, - width: combatWidth, - height: combatHeight, - constructMargin: combatConstructMargin, - textMargin: combatTextMargin, - - - LOG: { - x: logX, - y: logY, - width: logWidth, - height: logHeight, - }, - }, - }, - - COLOURS: { - BLUE: 0x004bfe, - CYAN: 0x27e7c0, - PURPLE: 0x61008c, - YELLOW: 0xfdfe02, - ORANGE: 0xff9215, - PINK: 0xe766b6, - GRAY: 0x9d9ea0, - LBLUE: 0x87c6f2, - GREEN: 0x166c4f, - BROWN: 0x583108, - BLACK: 0x000000, - RED: 0xff0000, - WHITE: 0xffffff, - - SELECT: 0x003300, - }, - - DELAYS: { - MOVE_CREEP: 500, - DAMAGE_TICK: 500, - ANIMATION_DURATION: 1000, - // wall: [500], - // spit: [300, 500], - // gravBomb: [300, 500], - // gravBlast: [300, 500], - // chargeBall: [300, 500], - }, - - ITEMS: { - SKILLS: { - Amplify: { - description: 'increase the magic damage dealt by a construct', - colours: '1 Green 1 Blue', - }, - - Attack: { - description: 'a fast attack with red damage', - upgrades: 'combine with 2 red / blue / green - red + blue attack not implemented', - }, - - Banish: { - description: 'target construct is prevented from casting any skills and taking any damage', - colours: '1 Red 1 Green', - - }, - - Blast: { - description: 'blast the target with magic damage', - colours: '2 Blue', - }, - - Block: { - description: 'decreases incoming red damage for 1T', - upgrades: 'combine with 2 red / blue / green', - }, - - Buff: { - description: 'increase target construct speed', - upgrades: 'combine with 2 red / blue / green', - }, - - Clutch: { - description: '??????', - colours: '1 Red 1 Green', - }, - - Corrupt: { - description: 'Inflicts a dot to attacker while active', - colours: '2 Blue', - }, - - Curse: { - description: 'target construct takes increased magic damage', - colours: '2 Blue', - }, - - Debuff: { - description: 'reduce target construct speed', - upgrades: 'combine with 2 red / blue / green', - }, - - Decay: { - description: 'afflict a construct with a blue damage based damage over time debuff', - colours: '1 Green 1 Blue', - }, - - Empower: { - description: 'increase the red damage dealt by a construct', - colours: '2 Red', - }, - - Haste: { - description: 'magical skill that increases speed of target construct', - colours: '1 Red 1 Blue', - }, - - Heal: { - description: 'heal a construct with blue damage', - colours: '2 Green', - }, - - Hex: { - description: 'magical bsed skill that prevents target construct from using any skills', - colours: '1 Red 1 Blue', - }, - - Hostility: { - description: 'magical bsed skill that prevents target construct from using any skills', - colours: '2 Blue', - }, - - Invert: { - description: 'reverse ???', - colours: '1 Red 1 Blue', - }, - - Parry: { - description: 'prevents all red damage for 1T', - colours: '2 Red', - }, - - Purge: { - description: 'remove magical buffs from target construct', - colours: '2 Green', - }, - - Purify: { - description: 'remove magical debuffs from target construct', - colours: '1 Red 1 Green', - }, - - Recharge: { - description: 'restore something', - colours: '1 Red 1 Blue', - }, - - Reflect: { - description: 'reflect damage back to attacker', - colours: '2 Green', - }, - - Riposte: { - description: '???', - }, - - Ruin: { - description: 'Stun the entire enemy team', - colours: '2 Blue', - }, - - Shield: { - description: 'grants immunity to magical skills to target construct', - colours: '1 Green 1 Blue', - }, - - Silence: { - description: 'prevent target construct from casting magical skills', - colours: '1 Green 1 Blue', - }, - - Siphon: { - description: 'siphon hp from target construct with a blue damage based debuff', - colours: '1 Green 1 Blue', - }, - - Slay: { - description: '????', - }, - - Slow: { - description: 'magical skill that reduces speed of target construct', - colours: '1 Red 1 Green', - }, - - Snare: { - description: 'prevents red skills from being used for 2T', - colours: '2 Red', - }, - - Strangle: { - description: 'Stun the enemy and inflict physical damage over 3T', - colours: '2 Red', - }, - - Strike: { - description: 'Fast attacking red skill', - colours: '2 Red', - }, - - Stun: { - description: 'red skill hat prevents target construct from using any skills', - upgrades: 'combine with 2 red / blue / green', - - }, - - Taunt: { - description: 'Enemy skills will prioritise constructs with this skill active', - colours: '1 Red 1 Green', - }, - - Throw: { - description: 'stuns and makes the target take increased red damage', - colours: '2 Green', - }, - - Triage: { - description: 'grants a blue damage based healing over time buff', - colours: '2 Green', - }, - }, - - SPECS: { - Damage: { - description: 'Increase red / green / blue power stats construct', - upgrades: 'combine with 2 red / blue / green', - - }, - - Hp: { - description: 'Increases health of construct', - upgrades: 'combine with 2 red / blue / green', - - }, - - Speed: { - description: 'Increases speed of construct', - upgrades: 'combine with 2 red / blue / green', - }, - }, - - COLOURS: { - Red: { - description: 'Used to create offensive type combos - fast and chaotic', - }, - - Green: { - description: 'Used to create defensive / healing type combos', - }, - - Blue: { - description: 'Used to create offensive type combos - slow and reliable', - }, - }, - }, -}; diff --git a/phaser-client/src/scenes/cryps.js b/phaser-client/src/scenes/cryps.js deleted file mode 100644 index c1fd95e9..00000000 --- a/phaser-client/src/scenes/cryps.js +++ /dev/null @@ -1,77 +0,0 @@ -const Phaser = require('phaser'); - -const Header = require('./header'); -const Home = require('./home'); -const Menu = require('./menu'); -const Combat = require('./combat'); - -// const Background = require('./background'); - -function renderConstructs() { - const config = { - type: Phaser.CANVAS, - // backgroundColor: '#181818', - resolution: window.devicePixelRatio, - scale: { - mode: Phaser.Scale.FIT, - width: Math.floor(window.innerHeight * 1.6), - height: Math.floor(window.innerHeight), - max: { - width: Math.floor(window.innerHeight * 1.6), - height: Math.floor(window.innerHeight), - }, - - }, - antialias: true, - physics: { - default: 'arcade', - arcade: { - debug: false, - gravity: { y: 0 }, - }, - }, - scene: [ - // Background, - Header, - ], - }; - - const game = new Phaser.Game(config); - - - function changeData(parent, key, data) { - // Don't load other scenes if you're not logged in - if (!game.registry.get('account')) return false; - - if (key === 'home') { - if (data) return game.scene.add('Home', Home, true); - } - - if (key === 'menu') { - if (!data || game.registry.get('inMenu')) return false; - if (data) return game.scene.add('Menu', Menu, true); - } - - if (key === 'game') { - if (!data || game.registry.get('inGame')) return false; - return game.scene.add('Combat', Combat, true); - } - - return true; - } - - game.registry.events.on('changedata', changeData); - game.registry.events.on('setdata', changeData); - - window.addEventListener('mouseup', () => game.registry.set('pan', false)); - window.addEventListener('mousedown', () => game.registry.set('pan', true)); - window.addEventListener('resize', () => { - game.scale.displaySize.maxWidth = window.innerHeight * 1.6; - game.scale.displaySize.maxHeight = window.innerHeight; - }); - - - return game; -} - -module.exports = renderConstructs; diff --git a/phaser-client/src/scenes/elements/box.js b/phaser-client/src/scenes/elements/box.js deleted file mode 100644 index b95e6287..00000000 --- a/phaser-client/src/scenes/elements/box.js +++ /dev/null @@ -1,132 +0,0 @@ -const Phaser = require('phaser'); -const { TEXT } = require('.././constants'); - -const BOX = ` -#ifdef GL_ES -precision mediump float; -#endif - -#extension GL_OES_standard_derivatives : enable - -#ifdef GL_ES -precision mediump float; -#endif - -#extension GL_OES_standard_derivatives : enable - -uniform float time; -uniform vec2 resolution; -uniform vec2 dimensions; -uniform vec2 offset; -uniform vec3 colour; -uniform sampler2D uMainSampler; - - -varying vec2 outTexCoord; -varying vec4 outTint; - -float sdBox( in vec2 p, in vec2 b ) -{ - vec2 d = abs(p)-b; - return length(max(d,vec2(0))) + min(max(d.x,d.y),0.0); -} - -void main() -{ - - vec2 p = (gl_FragCoord.xy / resolution.xy); - p.x -= offset.x / resolution.x + dimensions.x / (2.0 * resolution.x); - p.y -= -1.0 * offset.y / resolution.y + ((resolution.y - dimensions.y) / (2.0 * resolution.y)) + 0.5; - vec2 dim = 0.5 * dimensions / resolution.xy; - float d = sdBox(p, dim); - float tb = abs(sin(time)) + 0.9; - - vec3 col = tb * colour - sign(d) * vec3(0.1); - col *= 0.0 + exp(-100.0 * abs(d)); - col += colour * 0.8; - vec4 texel = texture2D(uMainSampler, outTexCoord); - texel *= vec4(outTint.rgb * outTint.a, outTint.a); - - gl_FragColor = vec4(col, 1.0); -} -`; - - -class CustomPipeline extends Phaser.Renderer.WebGL.Pipelines.TextureTintPipeline { - constructor(game) { - super({ game, renderer: game.renderer, fragShader: BOX }); - } -} - -function rgbToHex(rgb) { - const getHex = (c) => { - const hex = Math.floor(c * 255).toString(16); - return hex.length === 1 ? `0${hex}` : hex; - }; - return `0x${getHex(rgb[0])}${getHex(rgb[1])}${getHex(rgb[2])}`; -} - - -class BoxEffect extends Phaser.GameObjects.Graphics { - constructor(scene, x, y, width, height, colour, tag) { - super(scene); - this.tag = tag; - this.customPipeline = scene.game.renderer.addPipeline(tag, new CustomPipeline(scene.game)); - this.customPipeline.setFloat2('resolution', 1600, 1000); - this.customPipeline.setFloat2('offset', x, y); - this.customPipeline.setFloat2('dimensions', width, height); - this.customPipeline.setFloat3('colour', colour[0], colour[1], colour[2]); - this.bgTime = 10.0; - - const radius = height / 2; - this.fillStyle(rgbToHex(colour), 1.0); - this.fillRect(x + radius, y, width - radius * 2, height); - this.fillCircle(x + radius, y + radius, radius); - this.fillCircle(x + width - radius, y + radius, radius); - - - this.on('destroy', () => { - scene.game.renderer.removePipeline(tag); - }); - } - - activate() { - this.setPipeline(this.tag); - } - - deactivate() { - this.resetPipeline(); - } - - update() { - this.bgTime += 0.05; - this.customPipeline.setFloat1('time', this.bgTime); - } -} - -class Button extends Phaser.GameObjects.Group { - constructor(scene, props) { - const { - x, y, width, height, colour, glTag, bText, callback, - } = props; - - super(scene, { classType: BoxEffect, runChildUpdate: true }); - - const leaveGame = scene.add - .rectangle(x, y, width, height, 0xaaaaaa, 0xffffff) - .setInteractive() - .setOrigin(0); - - const effect = scene.add.existing(new BoxEffect(scene, x, y, width, height, colour, glTag)); - this.add(effect); - - leaveGame - .on('pointerdown', callback) - .on('pointerover', () => effect.activate()) - .on('pointerout', () => effect.deactivate()); - - this.buttonText = scene.add.text(leaveGame.getCenter().x, leaveGame.getCenter().y, bText, TEXT.HEADER).setOrigin(0.5, 0.5); - } -} - -module.exports = Button; diff --git a/phaser-client/src/scenes/elements/combat.statbar.js b/phaser-client/src/scenes/elements/combat.statbar.js deleted file mode 100644 index c85d10a1..00000000 --- a/phaser-client/src/scenes/elements/combat.statbar.js +++ /dev/null @@ -1,86 +0,0 @@ -const Phaser = require('phaser'); -const { TEXT, POSITIONS: { COMBAT }, COLOURS } = require('.././constants'); - -const CONSTRUCT_MARGIN = COMBAT.constructMargin(); -const TEXT_MARGIN = COMBAT.textMargin(); - -const statBarDimensions = (team, iter, margin) => { - const statBarWidth = COMBAT.width() * 0.07; - const statBarHeight = TEXT_MARGIN / 1.5; - const statBarX = (COMBAT.width() - statBarWidth) * team; - const statBarY = COMBAT.y() + TEXT_MARGIN * (margin + 1) + CONSTRUCT_MARGIN * iter + COMBAT.height() * 0.07; - return { statBarX, statBarY, statBarWidth, statBarHeight }; -}; - -const statTextCoord = (team, iter, margin) => { - const statTextX = team ? COMBAT.width() - COMBAT.width() * 0.075 : COMBAT.width() * 0.075; - const statTextY = COMBAT.y() + TEXT_MARGIN * (margin + 1) + CONSTRUCT_MARGIN * iter + COMBAT.height() * 0.07; - return { statTextX, statTextY }; -}; - - -class StatBar extends Phaser.GameObjects.Graphics { - constructor(scene, construct, type) { - super(scene); - this.constructObj = construct; - this.type = type; - - if (type === 'HP') { - this.val = this.constructObj.construct.hp.value; - this.max = this.constructObj.construct.hp.max; - this.margin = 0; - } else if (type === 'Red Shield') { - this.val = this.constructObj.construct.red_shield.value; - this.max = this.constructObj.construct.red_shield.max; - this.margin = 1; - } else if (type === 'Blue Shield') { - this.val = this.constructObj.construct.blue_shield.value; - this.max = this.constructObj.construct.blue_shield.max; - this.margin = 2; - } else if (type === 'Evasion') { - this.val = this.constructObj.construct.evasion.value; - this.max = this.constructObj.construct.evasion.max; - this.margin = 3; - } - const { statTextX, statTextY } = statTextCoord(construct.team, construct.iter, this.margin); - this.statText = scene.add.text(statTextX, statTextY, '', TEXT.NORMAL).setOrigin(construct.team, 0); - this.drawStatBar(); - } - - drawStatBar() { - this.clear(); - const { - statBarX, statBarY, statBarWidth, statBarHeight, - } = statBarDimensions(this.constructObj.team, this.constructObj.iter, this.margin); - this.statText.text = `${this.val.toString()} / ${this.max.toString()} ${this.type}`; - // Draw Black Border - this.fillStyle(COLOURS.BLACK); - this.fillRect(statBarX, statBarY, statBarWidth, statBarHeight); - // White fill - this.fillStyle(COLOURS.WHITE); - this.fillRect(statBarX + 2, statBarY + 2, statBarWidth - 4, statBarHeight - 4); - // Fill the health bar - const statPercentage = this.val / this.max; - if (statPercentage < 0.3) { - this.fillStyle(COLOURS.RED); - } else if (statPercentage < 0.65) { - this.fillStyle(COLOURS.YELLOW); - } else { - this.fillStyle(0x00ff00); // str8 up green - } - const statWidth = statBarWidth * statPercentage; - this.fillRect(statBarX + 2, statBarY + 2, statWidth, statBarHeight - 4); - } - - takeDamage(value) { - if (value > 0) { - this.val = (value >= this.val) ? 0 : this.val -= value; - } else { - this.val = (this.val - value > this.max) ? this.max : this.val -= value; - } - if (this.val === 0 && this.type === 'HP') this.constructObj.setKo(); - this.drawStatBar(); - } -} - -module.exports = StatBar; diff --git a/phaser-client/src/scenes/elements/item.js b/phaser-client/src/scenes/elements/item.js deleted file mode 100644 index 07e820b3..00000000 --- a/phaser-client/src/scenes/elements/item.js +++ /dev/null @@ -1,56 +0,0 @@ -const Phaser = require('phaser'); - -const { - TEXT, - COLOURS, -} = require('../constants'); - -function FindColour(item) { - // Future add skills and use a constants lookup file ?? - switch (item) { - case 'Green': return 0x396E26; - case 'Red': return 0x622433; - case 'Blue': return 0x223158; - // case 'Green': return 0x043003; - // case 'Red': return 0x5C0202; - // case 'Blue': return 0x040345; - - default: return 0x222222; - } -} - -class Item extends Phaser.GameObjects.Container { - constructor(scene, item, index, x, y, width, height) { - super(scene, x, y); - - this.scene = scene; - this.item = item; - this.index = index; - this.origX = x; - this.origY = y; - this.width = width; - this.height = height; - - this.colour = FindColour(item); - this.box = scene.add - .rectangle(0, 0, width, height, this.colour); - - this.text = scene.add - // .text(0, 0, `${action} x${count}`, TEXT.NORMAL) - .text(0, 0, `${item}`, TEXT.NORMAL) - .setOrigin(0.5, 0.5); - - this.add(this.box); - this.add(this.text); - - this.setSize(width, height); - this.setInteractive(); - } - - changeOrigin(x, y) { - this.origX = x + this.width / 2; - this.origY = y + this.height / 2; - } -} - -module.exports = Item; diff --git a/phaser-client/src/scenes/elements/outline.rotate.js b/phaser-client/src/scenes/elements/outline.rotate.js deleted file mode 100644 index 041611ee..00000000 --- a/phaser-client/src/scenes/elements/outline.rotate.js +++ /dev/null @@ -1,73 +0,0 @@ -const Phaser = require('phaser'); - -class LineBox extends Phaser.GameObjects.Graphics { - constructor(scene, x, y, width, height, colour, speed) { - super(scene); - this.colour = colour; - this.x0 = x; this.x1 = x + width; - this.y0 = y; this.y1 = y + height; - const margin = Math.abs(Math.floor((this.x1 - this.x0) / 4)); - this.lineCoord = [this.x0 + margin, this.x1 - margin, this.y0, this.y0, 0]; - this.speed = speed; - } - - update() { - this.clear(); - - let vertX = this.x1; - let horizY = this.y0; - const genLine = () => { - switch (this.lineCoord[4]) { - case 0: - if (this.lineCoord[1] < this.x1) return [1, 1, 0, 0, 0]; - return [0, 0, 0, 0, 1]; - case 1: - if (this.lineCoord[0] < this.x1) return [1, 0, 0, 1, 1]; - return [0, 0, 0, 0, 2]; - case 2: - if (this.lineCoord[3] < this.y1) return [0, 0, 1, 1, 2]; - return [0, 0, 0, 0, 3]; - case 3: - horizY = this.y1; - if (this.lineCoord[2] < this.y1) return [-1, 0, 1, 0, 3]; - return [0, 0, 0, 0, 4]; - case 4: - horizY = this.y1; - if (this.lineCoord[0] > this.x0) return [-1, -1, 0, 0, 4]; - return [0, 0, 0, 0, 5]; - case 5: - horizY = this.y1; - vertX = this.x0; - if (this.lineCoord[1] > this.x0) return [0, -1, -1, 0, 5]; - return [0, 0, 0, 0, 6]; - case 6: - vertX = this.x0; - if (this.lineCoord[2] >= this.y0) return [0, 0, -1, -1, 6]; - return [0, 0, 0, 0, 7]; - case 7: - vertX = this.x0; - if (this.lineCoord[3] >= this.y0) return [0, 1, 0, -1, 7]; - return [0, 0, 0, 0, 0]; - default: return false; - } - }; - for (let i = 0; i < this.speed; i += 1) { - const delta = genLine(); - this.lineCoord = this.lineCoord.map((x, j) => { - if (j < 4) return (x + delta[j]); - return delta[j]; - }); - } - this.lineStyle(5, this.colour, 1); - this.lineBetween(this.lineCoord[0], horizY, this.lineCoord[1], horizY); - this.lineBetween(vertX, this.lineCoord[2], vertX, this.lineCoord[3]); - } -} - -class LineGroup extends Phaser.GameObjects.Group { - constructor(scene) { - super(scene, { classType: LineBox, runChildUpdate: true }); - } -} - -module.exports = { LineGroup, LineBox } \ No newline at end of file diff --git a/phaser-client/src/scenes/game.list.js b/phaser-client/src/scenes/game.list.js deleted file mode 100644 index d436770b..00000000 --- a/phaser-client/src/scenes/game.list.js +++ /dev/null @@ -1,53 +0,0 @@ -const Phaser = require('phaser'); -const { TEXT, POSITIONS: { MENU_MAIN } } = require('./constants'); - -const X = MENU_MAIN.x(); -const Y = MENU_MAIN.y(); -const WIDTH = MENU_MAIN.width(); -const HEIGHT = MENU_MAIN.height(); -const ROW_SIZE = 50; -const LOBBY_WIDTH = WIDTH / 2; - -class GameList extends Phaser.Scene { - constructor() { - super({ key: 'GameList' }); - } - - create(gameList) { - this.cameras.main.setViewport(X, Y, WIDTH, HEIGHT); - const ws = this.registry.get('ws'); - - this.add.text(WIDTH / 3, 0, 'PVP open games', TEXT.HEADER); - const gameRow = (game, i) => { - const GAME_X = WIDTH / 6; - const GAME_Y = 1.3 * ROW_SIZE * (i + 1); - - const gameBox = this.add - .rectangle(GAME_X, GAME_Y, LOBBY_WIDTH, ROW_SIZE, 0x222222) - .setInteractive() - .setOrigin(0); - - const TITLE = `${game.teams[0].constructs.map(c => c.name).join(', ')} - ${game.team_size}v${game.team_size}`; - - this.add - .text(gameBox.getCenter().x, gameBox.getCenter().y, TITLE, TEXT.NORMAL) - .setOrigin(0.5, 0.5); - - gameBox.on('pointerdown', () => { - const constructs = this.registry.get('constructs'); - const team = constructs.filter(c => c.active).map(c => c.id); - ws.sendGameJoin(game.id, team); - }); - }; - - gameList.forEach(gameRow); - - return true; - } - - cleanUp() { - this.scene.remove(); - } -} - -module.exports = GameList; diff --git a/phaser-client/src/scenes/header.js b/phaser-client/src/scenes/header.js deleted file mode 100644 index c6c31c05..00000000 --- a/phaser-client/src/scenes/header.js +++ /dev/null @@ -1,27 +0,0 @@ -const Phaser = require('phaser'); -const fs = require('fs'); - -const { TEXT } = require('./constants'); - -const aztecAtlas = require('../../assets/aztec.atlas.json'); - - -class Header extends Phaser.Scene { - constructor() { - super({ key: 'Header', active: true }); - } - - preload() { - const aztecImg = new Image(); - aztecImg.src = `data:image/png;base64,${new Buffer.from(fs.readFileSync('./assets/aztec.clean.png')).toString('base64')}`; - aztecImg.onload = () => { - this.textures.addAtlas('aztec', aztecImg, aztecAtlas); - }; - } - - create() { - this.add.text(0, 0, 'constructs.gg', TEXT.HEADER); - } -} - -module.exports = Header; diff --git a/phaser-client/src/scenes/home.cryps.js b/phaser-client/src/scenes/home.cryps.js deleted file mode 100644 index c0620d11..00000000 --- a/phaser-client/src/scenes/home.cryps.js +++ /dev/null @@ -1,142 +0,0 @@ -const Phaser = require('phaser'); -const { remove } = require('lodash'); - -const { TEXT, COLOURS, POSITIONS: { CONSTRUCT_LIST } } = require('./constants'); -const genAvatar = require('./avatar'); -const { LineGroup, LineBox } = require('./elements/outline.rotate'); - -const ROW_HEIGHT = CONSTRUCT_LIST.height() * 0.1; -const ROW_WIDTH = CONSTRUCT_LIST.width(); - -const menuY = CONSTRUCT_LIST.height() * 0.8; - -const KEY_MAP = [ - 'keydown-ONE', - 'keydown-TWO', - 'keydown-THREE', -]; - -const NULL_UUID = '00000000-0000-0000-0000-000000000000'; - -class HomeConstructList extends Phaser.Scene { - constructor() { - super({ key: 'HomeConstructs' }); - } - - - updateData(parent, key, data) { - if (key === 'constructList') { - KEY_MAP.forEach(k => this.input.keyboard.removeListener(k)); - this.scene.restart(); - } - } - - create() { - // this.cameras.main.setViewport(CONSTRUCT_LIST.x(), CONSTRUCT_LIST.y(), CONSTRUCT_LIST.width(), CONSTRUCT_LIST.height()); - this.registry.events.on('changedata', this.updateData, this); - this.registry.events.on('setdata', this.updateData, this); - const constructs = this.registry.get('constructList'); - const lineGroup = this.add.existing(new LineGroup(this)); - - if (!constructs) return true; - const ws = this.registry.get('ws'); - this.activeConstructs = []; - // We only display 3 constructs others can be viewed in construct list (soon TM) - for (let i = 0; i < constructs.length; i += 1) { - const construct = constructs[i]; - const BOX_WIDTH = Math.floor(ROW_WIDTH / 5); - const ROW_X = BOX_WIDTH * 2 * (i % 3); - const ROW_Y = CONSTRUCT_LIST.y() + (Math.floor(i / 3)) * ROW_HEIGHT * 1.5; - const ACTIVE_FILL = 0.2; - - const FILL = Object.values(COLOURS)[i]; - // Selection of constructs - - // Construct avatar and interaction box - const cReady = this.add - .rectangle(ROW_X, ROW_Y + ROW_HEIGHT * 0.2, BOX_WIDTH * 2, ROW_HEIGHT, FILL) - .setInteractive() - .setOrigin(0); - cReady.setAlpha(0.2); - cReady.on('pointerdown', () => { - lineGroup.clear(true, true); - if (this.activeConstructs.includes(cReady)) { - remove(this.activeConstructs, n => n === cReady); - cReady.setAlpha(0.2); - } else { - this.activeConstructs.push(cReady); - cReady.setAlpha(0.75); - lineGroup.add(this.add.existing( - new LineBox(this, cReady.x, cReady.y, cReady.width, cReady.height, cReady.fillColor, 3) - )); - } - }); - - cReady.itemSelect = () => { - cReady.setFillStyle(COLOURS.SELECT); - }; - cReady.itemDeselect = () => { - cReady.setFillStyle(FILL, ACTIVE_FILL); - }; - - cReady.construct = construct; - this.add.image( - cReady.getCenter().x, - cReady.getCenter().y, - 'aztec', - genAvatar(construct.name) - ); - this.add.text(ROW_X + BOX_WIDTH, ROW_Y, construct.name, TEXT.HEADER) - .setOrigin(0.5, 0.5); - } - - // Add Spawn Construct Option - const spawn = this.add - .rectangle(ROW_WIDTH * 0.05, menuY, ROW_WIDTH * 0.2, ROW_HEIGHT * 0.5, 0x888888) - .setInteractive() - .setOrigin(0) - .on('pointerdown', () => { - this.game.events.emit('CONSTRUCT_SPAWN'); - }); - this.add - .text(spawn.getCenter().x, spawn.getCenter().y, '+', TEXT.HEADER) - .setOrigin(0.5, 0.5); - - const joinNormal = this.add - .rectangle(ROW_WIDTH * 0.3, menuY, ROW_WIDTH * 0.4, ROW_HEIGHT * 0.5, 0x888888) - .setInteractive() - .setOrigin(0) - .on('pointerdown', () => { - const playerConstructs = []; - this.activeConstructs.forEach(obj => playerConstructs.push(obj.construct.id)); - ws.sendPlayerConstructsSet(NULL_UUID, playerConstructs); - }); - this.add - .text(joinNormal.getCenter().x, joinNormal.getCenter().y, 'Join Normal', TEXT.HEADER) - .setOrigin(0.5, 0.5); - - const joinInstance = this.add - .rectangle(ROW_WIDTH * 0.8, menuY, ROW_WIDTH * 0.4, ROW_HEIGHT * 0.5, 0x888888) - .setInteractive() - .setOrigin(0) - .on('pointerdown', () => { - const playerConstructs = []; - this.activeConstructs.forEach(obj => playerConstructs.push(obj.construct.id)); - ws.sendInstanceJoin(playerConstructs); - }); - this.add - .text(joinInstance.getCenter().x, joinInstance.getCenter().y, 'New Instance', TEXT.HEADER) - .setOrigin(0.5, 0.5); - - return this; - } - - cleanUp() { - KEY_MAP.forEach(k => this.input.keyboard.removeListener(k)); - this.registry.events.off('changedata', this.updateData, this); - this.registry.events.off('setdata', this.updateData, this); - this.scene.remove(); - } -} - -module.exports = HomeConstructList; diff --git a/phaser-client/src/scenes/home.instances.js b/phaser-client/src/scenes/home.instances.js deleted file mode 100644 index db4e6994..00000000 --- a/phaser-client/src/scenes/home.instances.js +++ /dev/null @@ -1,48 +0,0 @@ -const Phaser = require('phaser'); -const { POSITIONS: { HOME_MAIN }, TEXT } = require('./constants'); - -const X = HOME_MAIN.x(); -const Y = HOME_MAIN.y(); -const WIDTH = HOME_MAIN.width(); -const HEIGHT = HOME_MAIN.height(); - -const NULL_UUID = '00000000-0000-0000-0000-000000000000'; - -class HomeRankings extends Phaser.Scene { - constructor() { - super({ key: 'HomeInstances' }); - } - - create() { - this.add.text(X, Y, 'Instances Scene', TEXT.HEADER); - const playerList = this.registry.get('playerList'); - const addInstance = (player, i) => { - const joinNormal = this.add - .rectangle(X, Y + HEIGHT * 0.15 * (i + 1), WIDTH * 0.5, HEIGHT * 0.1, 0x888888) - .setInteractive() - .setOrigin(0) - .on('pointerdown', () => { - if (player.ready) { - this.registry.set('player', player); - this.registry.get('ws').sendInstanceReady(player.instance); - } else { - this.game.events.emit('SET_PLAYER', player); - this.registry.get('ws').sendInstanceScores(player.instance); - } - }); - const name = player.instance === NULL_UUID ? 'Normal Mode' : `${player.instance.substring(0, 5)}`; - const disp = player.ready ? name.concat(' - in progress') : name; - this.add - .text(joinNormal.getCenter().x, joinNormal.getCenter().y, disp, TEXT.NORMAL) - .setOrigin(0.5, 0.5); - }; - - playerList.forEach(addInstance); - } - - cleanUp() { - this.scene.remove(); - } -} - -module.exports = HomeRankings; diff --git a/phaser-client/src/scenes/home.js b/phaser-client/src/scenes/home.js deleted file mode 100644 index fb03e009..00000000 --- a/phaser-client/src/scenes/home.js +++ /dev/null @@ -1,91 +0,0 @@ -const Phaser = require('phaser'); - - -const HomeConstructs = require('./home.constructs'); -const HomeNavigation = require('./home.navigation'); - -const HomeRankings = require('./home.rankings'); -const HomeNews = require('./home.news'); -const HomeShop = require('./home.shop'); -const HomeInstances = require('./home.instances'); - -const FIXED_SCENES = [ - 'HomeConstructs', - 'HomeNavigation', -]; - -const VAR_SCENES = [ - 'HomeRankings', - 'HomeNews', - 'HomeShop', - 'HomeInstances', -]; - -class Home extends Phaser.Scene { - constructor() { - super({ key: 'Home', active: true }); - } - - create() { - this.registry.get('ws').sendAccountInstances(); - - this.registry.events.on('changedata', this.updateData, this); - this.registry.events.on('setdata', this.updateData, this); - this.scene.manager.add('HomeConstructs', HomeConstructs, true); - this.scene.manager.add('HomeNavigation', HomeNavigation, true); - - - return true; - } - - updateData(parent, key, data) { - if (!data) return false; - // Controls which scene shows in the main top right section - switch (key) { - case 'game': return this.cleanUp(); - case 'menu': return this.cleanUp(); - case 'homeInstances': return this.newMainScene('HomeInstances', HomeInstances, data); - case 'homeRankings': return this.newMainScene('HomeRankings', HomeRankings, data); - case 'homeNews': return this.newMainScene('HomeNews', HomeNews, data); - case 'homeShop': return this.newMainScene('HomeShop', HomeShop, data); - - - default: return false; - } - } - - newMainScene(key, scene, data) { - let addScene = true; - // List of scenes which could be occupying the main section of the menu - VAR_SCENES.forEach((sKey) => { - if (this.scene.manager.keys[sKey]) { - if (key === sKey) { - // If there is new data for the current scene restart - this.scene.manager.keys[sKey].scene.restart(data); - addScene = false; - } else { - // Delete the old scene - this.scene.manager.keys[sKey].cleanUp(); - } - } - }); - if (addScene) this.scene.manager.add(key, scene, true, data); - } - - cleanUp() { - this.registry.events.off('changedata', this.updateData, this); - this.registry.events.off('setdata', this.updateData, this); - // Delete scenes which could be showing before switching to battle scene - - const removeScenes = (sKey) => { - if (this.scene.get(sKey)) this.scene.get(sKey).cleanUp(); - }; - FIXED_SCENES.forEach(removeScenes); - VAR_SCENES.forEach(removeScenes); - - - this.scene.remove(); - } -} - -module.exports = Home; diff --git a/phaser-client/src/scenes/home.navigation.js b/phaser-client/src/scenes/home.navigation.js deleted file mode 100644 index 40846df8..00000000 --- a/phaser-client/src/scenes/home.navigation.js +++ /dev/null @@ -1,61 +0,0 @@ -const Phaser = require('phaser'); - -const { TEXT, POSITIONS: { NAVIGATION } } = require('./constants'); - -const X = NAVIGATION.x(); -const Y = NAVIGATION.y(); -const WIDTH = NAVIGATION.width(); -const HEIGHT = NAVIGATION.height(); - -const BTN_WIDTH = Math.floor(WIDTH / 6); -const BTN_HEIGHT = Math.floor(HEIGHT / 3); - -class HomeNavigation extends Phaser.Scene { - constructor() { - super({ key: 'HomeNavigation' }); - } - - create() { -/* const ranks = this.add - .rectangle(X, Y, BTN_WIDTH, BTN_HEIGHT, 0x222222) - .setInteractive() - .setOrigin(0); - this.add - .text(ranks.getCenter().x, ranks.getCenter().y, 'Rankings', TEXT.HEADER) - .setOrigin(0.5, 0.5); - ranks.on('pointerdown', () => this.registry.set('homeRankings', true)); - - const news = this.add - .rectangle(X + BTN_WIDTH * 1.5, Y, BTN_WIDTH, BTN_HEIGHT, 0x222222) - .setInteractive() - .setOrigin(0); - this.add - .text(news.getCenter().x, news.getCenter().y, 'News', TEXT.HEADER) - .setOrigin(0.5, 0.5); - news.on('pointerdown', () => this.registry.set('homeNews', true)); - - const shop = this.add - .rectangle(X + BTN_WIDTH * 3, Y, BTN_WIDTH, BTN_HEIGHT, 0x222222) - .setInteractive() - .setOrigin(0); - this.add - .text(shop.getCenter().x, shop.getCenter().y, 'Shop', TEXT.HEADER) - .setOrigin(0.5, 0.5); - shop.on('pointerdown', () => this.registry.set('homeShop', true)); - - const instances = this.add - .rectangle(X + BTN_WIDTH * 4.5, Y, BTN_WIDTH, BTN_HEIGHT, 0x222222) - .setInteractive() - .setOrigin(0); - this.add - .text(instances.getCenter().x, instances.getCenter().y, 'Instances', TEXT.HEADER) - .setOrigin(0.5, 0.5); - instances.on('pointerdown', () => this.registry.set('homeInstances', true));*/ - } - - cleanUp() { - this.scene.remove(); - } -} - -module.exports = HomeNavigation; diff --git a/phaser-client/src/scenes/home.news.js b/phaser-client/src/scenes/home.news.js deleted file mode 100644 index 9e7937df..00000000 --- a/phaser-client/src/scenes/home.news.js +++ /dev/null @@ -1,24 +0,0 @@ -const Phaser = require('phaser'); -const { POSITIONS: { HOME_MAIN }, TEXT } = require('./constants'); - -const X = HOME_MAIN.x(); -const Y = HOME_MAIN.y(); -const WIDTH = HOME_MAIN.width(); -const HEIGHT = HOME_MAIN.height(); - -class HomeNews extends Phaser.Scene { - constructor() { - super({ key: 'HomeNews' }); - } - - create() { - this.add.text(X, Y, 'News Scene', TEXT.HEADER); - this.add.text(X, Y + HEIGHT * 0.1, 'some other stuff here', TEXT.NORMAL); - } - - cleanUp() { - this.scene.remove(); - } -} - -module.exports = HomeNews; diff --git a/phaser-client/src/scenes/home.rankings.js b/phaser-client/src/scenes/home.rankings.js deleted file mode 100644 index 0d6dc0d1..00000000 --- a/phaser-client/src/scenes/home.rankings.js +++ /dev/null @@ -1,24 +0,0 @@ -const Phaser = require('phaser'); -const { POSITIONS: { HOME_MAIN }, TEXT } = require('./constants'); - -const X = HOME_MAIN.x(); -const Y = HOME_MAIN.y(); -const WIDTH = HOME_MAIN.width(); -const HEIGHT = HOME_MAIN.height(); - -class HomeRankings extends Phaser.Scene { - constructor() { - super({ key: 'HomeRankings' }); - } - - create() { - this.add.text(X, Y, 'Rankings Scene', TEXT.HEADER); - this.add.text(X, Y + HEIGHT * 0.1, 'some stuff here', TEXT.NORMAL); - } - - cleanUp() { - this.scene.remove(); - } -} - -module.exports = HomeRankings; diff --git a/phaser-client/src/scenes/home.shop.js b/phaser-client/src/scenes/home.shop.js deleted file mode 100644 index 24ed0921..00000000 --- a/phaser-client/src/scenes/home.shop.js +++ /dev/null @@ -1,24 +0,0 @@ -const Phaser = require('phaser'); -const { POSITIONS: { HOME_MAIN }, TEXT } = require('./constants'); - -const X = HOME_MAIN.x(); -const Y = HOME_MAIN.y(); -const WIDTH = HOME_MAIN.width(); -const HEIGHT = HOME_MAIN.height(); - -class HomeShop extends Phaser.Scene { - constructor() { - super({ key: 'HomeShop' }); - } - - create() { - this.add.text(X, Y, 'Shop Scene', TEXT.HEADER); - this.add.text(X, Y + HEIGHT * 0.1, 'rulul', TEXT.NORMAL); - } - - cleanUp() { - this.scene.remove(); - } -} - -module.exports = HomeShop; diff --git a/phaser-client/src/scenes/item.info.js b/phaser-client/src/scenes/item.info.js deleted file mode 100644 index 0e116ae3..00000000 --- a/phaser-client/src/scenes/item.info.js +++ /dev/null @@ -1,78 +0,0 @@ -const Phaser = require('phaser'); -const { POSITIONS: { MENU_MAIN }, TEXT, ITEMS: { SKILLS, SPECS, COLOURS } } = require('./constants'); - -const X = MENU_MAIN.x(); -const Y = MENU_MAIN.y(); -const WIDTH = MENU_MAIN.width(); -const HEIGHT = MENU_MAIN.height(); - -const UNEQUIP_Y = Y + Math.floor(HEIGHT * 0.7); -const UNEQUIP_WIDTH = Math.floor(WIDTH * 0.4); -const UNEQUIP_HEIGHT = Math.floor(HEIGHT * 0.15); - -class ItemInfo extends Phaser.Scene { - constructor() { - super({ key: 'ItemInfo' }); - } - - create(props) { - const { item, construct } = props; - if (!item) return false; - - // Default item text - let title = item; - let description = 'Description missing'; - let upgrades = ''; - let colours = ''; - - // Replace item text with constants if it exists - if (SKILLS[item]) { - title = `Skill Item - ${item}`; - ({ description } = SKILLS[item]); - if (SKILLS[item].upgrades) ({ upgrades } = SKILLS[item]); - if (SKILLS[item].colours) ({ colours } = SKILLS[item]); - } else if (SPECS[item]) { - title = `Spec Item - ${item}`; - ({ description } = SPECS[item]); - if (SPECS[item].upgrades) ({ upgrades } = SPECS[item]); - } else if (COLOURS[item]) { - title = `Colour Item - ${item}`; - ({ description } = COLOURS[item]); - if (COLOURS[item].upgrades) ({ upgrades } = COLOURS[item]); - } - - // Add text objects - this.add.text(X, Y, title, TEXT.HEADER); - this.add - .text(X, Y + HEIGHT * 0.1, description, TEXT.NORMAL) - .setWordWrapWidth(WIDTH * 0.75); - this.add - .text(X, Y + HEIGHT * 0.25, upgrades, TEXT.NORMAL) - .setWordWrapWidth(WIDTH * 0.75); - if (colours !== '') { - this.add - .text(X, Y + HEIGHT * 0.35, `Adds ${colours} to construct`, TEXT.NORMAL) - .setWordWrapWidth(WIDTH * 0.75); - } - - if (!construct) return true; - const ws = this.registry.get('ws'); - const { vbox } = this.registry.get('player'); - const unEquip = this.add.rectangle(X, UNEQUIP_Y, UNEQUIP_WIDTH, UNEQUIP_HEIGHT, 0x222222) - .setOrigin(0, 0) - .setInteractive() - .on('pointerdown', () => { - ws.sendVboxUnequip(vbox.instance, construct.id, item); - this.registry.set('constructStats', construct); - }); - this.add.text(unEquip.getCenter().x, unEquip.getCenter().y, 'unequip', TEXT.HEADER) - .setOrigin(0.5, 0.5); - return true; - } - - cleanUp() { - this.scene.remove(); - } -} - -module.exports = ItemInfo; diff --git a/phaser-client/src/scenes/item.list.js b/phaser-client/src/scenes/item.list.js deleted file mode 100644 index 74758520..00000000 --- a/phaser-client/src/scenes/item.list.js +++ /dev/null @@ -1,323 +0,0 @@ -const Phaser = require('phaser'); - -const Item = require('./elements/item'); - -const { - TEXT, - POSITIONS: { ITEM_LIST }, -} = require('./constants'); - -const X = ITEM_LIST.x(); -const Y = ITEM_LIST.y(); -const WIDTH = ITEM_LIST.width(); -const HEIGHT = ITEM_LIST.height(); -const ITEM_WIDTH = ITEM_LIST.itemWidth(); -const ITEM_HEIGHT = ITEM_LIST.itemHeight(); - -const BOX_X = X + ITEM_WIDTH * 0.5; -const BOX_Y = Y + ITEM_HEIGHT + ITEM_HEIGHT * 2; -const BOX_ROWS = 6; -const BOX_COLUMNS = 3; - -const INV_X = X + ITEM_WIDTH * 0.5; -const INV_Y = Y + ITEM_HEIGHT * 12; -const INV_ROWS = 3; -const INV_COLUMNS = 3; - -const COMB_X = X + ITEM_WIDTH * 0.5; -const COMB_Y = Y + ITEM_HEIGHT * 19; -const COMB_ROWS = 1; -const COMB_COLUMNS = 3; - -const drawVbox = (graphics) => { - const boxDrawX = BOX_X - ITEM_WIDTH * 0.05; - const boxDrawY = BOX_Y - ITEM_HEIGHT * 0.05; - graphics.strokeRect(boxDrawX, boxDrawY, ITEM_WIDTH * 1.1 * BOX_COLUMNS, ITEM_HEIGHT * 1.1 * BOX_ROWS); - - for (let i = 0; i < (BOX_COLUMNS - 1); i += 1) { - const x = boxDrawX + (i + 1) * ITEM_WIDTH * 1.1; - graphics.lineBetween(x, boxDrawY, x, boxDrawY + ITEM_HEIGHT * 1.1 * BOX_ROWS); - } - for (let i = 0; i < (BOX_ROWS - 1); i += 1) { - const y = boxDrawY + (i + 1) * ITEM_HEIGHT * 1.1; - graphics.lineBetween(boxDrawX, y, boxDrawX + ITEM_WIDTH * 1.1 * BOX_COLUMNS, y); - } -}; - -const drawInventory = (graphics) => { - const invDrawX = INV_X - ITEM_WIDTH * 0.05; - const invDrawY = INV_Y - ITEM_HEIGHT * 0.05; - graphics.strokeRect(invDrawX, invDrawY, ITEM_WIDTH * 1.1 * INV_COLUMNS, ITEM_HEIGHT * 1.1 * INV_ROWS); - - for (let i = 0; i < (INV_COLUMNS - 1); i += 1) { - const x = invDrawX + (i + 1) * ITEM_WIDTH * 1.1; - graphics.lineBetween(x, invDrawY, x, invDrawY + ITEM_HEIGHT * 1.1 * INV_ROWS); - } - for (let i = 0; i < (INV_ROWS - 1); i += 1) { - const y = invDrawY + (i + 1) * ITEM_HEIGHT * 1.1; - graphics.lineBetween(invDrawX, y, invDrawX + ITEM_WIDTH * 1.1 * INV_COLUMNS, y); - } -}; - -const drawCombiner = (graphics) => { - const combDrawX = COMB_X - ITEM_WIDTH * 0.05; - const combDrawY = COMB_Y - ITEM_HEIGHT * 0.05; - graphics.strokeRect(combDrawX, combDrawY, ITEM_WIDTH * 1.1 * COMB_COLUMNS, ITEM_HEIGHT * 1.1 * COMB_ROWS); - - for (let i = 0; i < (COMB_COLUMNS - 1); i += 1) { - const x = combDrawX + (i + 1) * ITEM_WIDTH * 1.1; - graphics.lineBetween(x, combDrawY, x, combDrawY + ITEM_HEIGHT * 1.1 * COMB_ROWS); - } - for (let i = 0; i <= (COMB_ROWS - 1); i += 1) { - const y = combDrawY + (i + 1) * ITEM_HEIGHT * 1.1; - graphics.lineBetween(combDrawX, y, combDrawX + ITEM_WIDTH * 1.1 * COMB_COLUMNS, y); - } -}; - -class CombinerHitBox extends Phaser.GameObjects.Rectangle { - constructor(scene, x, y, i) { - super(scene, x, y, ITEM_WIDTH, ITEM_HEIGHT, 0x000000); - this.setOrigin(0); - this.x = x; - this.y = y; - this.slot = i; - this.item = false; - this.itemSelect = () => this.setFillStyle(0x222222); - this.itemDeselect = () => this.setFillStyle(0x000000); - } - - allocate(item) { - if (this.item) this.deallocate(); - item.setPosition(this.x + item.width / 2, this.y + item.height / 2); - this.item = item; - } - - deallocate() { - if (this.item) this.item.setPosition(this.item.origX, this.item.origY); - this.item = false; - } -} - -class DeleteHitBox extends Phaser.GameObjects.Rectangle { - constructor(scene, x, y) { - super(scene, x, y, ITEM_WIDTH * 3.4, ITEM_HEIGHT * 1.25, 0x444444); - this.setOrigin(0); - this.itemSelect = () => this.setFillStyle(0xff0000); - this.itemDeselect = () => this.setFillStyle(0x444444); - } -} - - -const itemCheckHitbox = (scene, pointer) => { - const { list } = scene.scene.get('MenuConstructList').children; - const hitboxes = list.filter(c => c.construct) - .concat(scene.children.list.filter(c => c instanceof CombinerHitBox || c instanceof DeleteHitBox)); - - let found; - for (let i = 0; i < hitboxes.length; i += 1) { - if (Phaser.Geom.Rectangle.ContainsPoint(hitboxes[i].getBounds(), pointer.position)) { - found = hitboxes[i]; - } else { - hitboxes[i].itemDeselect(); - } - } - - return found; -}; - -class ItemList extends Phaser.Scene { - constructor() { - super({ key: 'ItemList', active: true }); - } - - updateData(parent, key, data) { - if (key === 'player' || key === 'scores') { - this.registry.events.off('changedata', this.updateData, this); - this.registry.events.off('setdata', this.updateData, this); - this.scene.restart(); - } - } - - create() { - const player = this.registry.get('player'); - const scores = this.registry.get('scores') || []; - if (!player) return false; - const { vbox } = player; - this.registry.events.on('changedata', this.updateData, this); - this.registry.events.on('setdata', this.updateData, this); - if (!vbox.bound) return false; - if (!this.combinerItems || vbox.bound.length < this.registry.get('boundLength')) { - this.combinerItems = [-1, -1, -1]; - } - this.registry.set('boundLength', vbox.bound.length); - const ws = this.registry.get('ws'); - - // Static Elements - const graphics = this.add.graphics(); - graphics.lineStyle(5, 0x808080, 1.0); - drawCombiner(graphics); - drawInventory(graphics); - drawVbox(graphics); - - this.add.text(X + ITEM_WIDTH * 0.5, Y + ITEM_HEIGHT * 0.5, `vBox - ${vbox.bits}b`, TEXT.HEADER); - this.add.text(X + ITEM_WIDTH * 0.5, Y + ITEM_HEIGHT * 11, 'inventory', TEXT.HEADER); - this.add.text(X + ITEM_WIDTH * 0.5, Y + ITEM_HEIGHT * 18, 'iCombinator', TEXT.HEADER); - this.add.text(X + ITEM_WIDTH * 0.5, Y + ITEM_HEIGHT * 23, `Wins: ${player.score.wins}`, TEXT.HEADER); - this.add.text(X + ITEM_WIDTH * 0.5, Y + ITEM_HEIGHT * 24, `Losses: ${player.score.losses}`, TEXT.HEADER); - - const discard = this.add - .rectangle(X + ITEM_WIDTH * 0.4, Y + ITEM_HEIGHT * 1.5, ITEM_WIDTH * 3.4, ITEM_HEIGHT * 1.25, 0x444444) - .setInteractive() - .setOrigin(0) - .on('pointerdown', () => this.registry.get('ws').sendVboxDiscard(vbox.instance)); - this.add.text(discard.getCenter().x, discard.getCenter().y, 'discard - 5b', TEXT.HEADER) - .setOrigin(0.5, 0.5); - - const combine = this.add - .rectangle(X + ITEM_WIDTH * 0.4, Y + ITEM_HEIGHT * 20.25, ITEM_WIDTH * 3.4, ITEM_HEIGHT * 1.25, 0x444444) - .setInteractive() - .setOrigin(0) - .on('pointerdown', () => { - ws.sendVboxCombine(vbox.instance, this.combinerItems); - this.combinerItems = [-1, -1, -1]; - this.children.list.filter(obj => obj instanceof CombinerHitBox).forEach(cBox => cBox.deallocate()); - }); - this.add.text(combine.getCenter().x, combine.getCenter().y, 'combine', TEXT.HEADER) - .setOrigin(0.5, 0.5); - - for (let i = 0; i < 3; i += 1) { - const ITEM_X = ITEM_WIDTH * 1.1 * (i % COMB_COLUMNS) + COMB_X; - const ITEM_Y = ITEM_HEIGHT * 1.1 * Math.floor(i / COMB_COLUMNS) + COMB_Y; - this.add.existing(new CombinerHitBox(this, ITEM_X, ITEM_Y, i)); - } - const del = this.add.existing(new DeleteHitBox(this, X + ITEM_WIDTH * 0.4, Y + ITEM_HEIGHT * 15.5)); - this.add.text(del.getCenter().x, del.getCenter().y, 'drop', TEXT.HEADER) - .setOrigin(0.5, 0.5); - - // Generate Items - vbox.bound.forEach((item, i) => { - const ITEM_X = ITEM_WIDTH * 1.1 * (i % INV_COLUMNS) + INV_X + ITEM_WIDTH * 0.5; - const ITEM_Y = ITEM_HEIGHT * 1.1 * Math.floor(i / INV_COLUMNS) + INV_Y + ITEM_HEIGHT * 0.5; - const clickFn = () => this.registry.set('itemInfo', { item }); - const itemBox = new Item(this, item, i, ITEM_X, ITEM_Y, ITEM_WIDTH, ITEM_HEIGHT); - itemBox.on('pointerdown', clickFn); - - this.input.setDraggable(itemBox); - this.add.existing(itemBox); - }); - - vbox.free.forEach((type, i) => { - type.forEach((item, j) => { - const ITEM_X = ITEM_WIDTH * 1.1 * i + BOX_X + ITEM_WIDTH * 0.5; - const ITEM_Y = ITEM_HEIGHT * 1.1 * j + BOX_Y + ITEM_HEIGHT * 0.5; - const clickFn = () => { - this.registry.set('itemInfo', { item }); - ws.sendVboxAccept(vbox.instance, i, j); - }; - const itemBox = new Item(this, item, i, ITEM_X, ITEM_Y, ITEM_WIDTH, ITEM_HEIGHT); - itemBox.on('pointerdown', clickFn); - this.add.existing(itemBox); - }); - }); - - // Restore previous combiner item slots - this.combinerItems.forEach((index, i) => { - if (index === -1) return false; - const item = this.children.list.filter(obj => obj instanceof Item).find(it => it.index === index); - const hitBox = this.children.list.filter(obj => obj instanceof CombinerHitBox).find(hb => hb.slot === i); - if (item) hitBox.allocate(item); - return true; - }); - - // allocation functions - const allocate = (item, hitBox) => { - hitBox.allocate(item); - this.combinerItems[hitBox.slot] = item.index; - this.registry.set('combinerItems', this.combinerItems); - }; - - const deallocate = (item) => { - const clearIndex = this.combinerItems.indexOf(item.index); - if (clearIndex !== -1) { - this.children.list.filter(obj => obj instanceof CombinerHitBox) - .forEach((cBox) => { - if (cBox.item === item) cBox.deallocate(); - }); - this.combinerItems[clearIndex] = -1; - this.registry.set('combinerItems', this.combinerItems); - } - item.setPosition(item.origX, item.origY); - }; - - const findUnallocated = () => { - for (let i = 0; i <= 2; i += 1) { - if (this.combinerItems[i] === -1) { - return this.children.list.filter(obj => obj instanceof CombinerHitBox).find(hb => hb.slot === i); - } - } return false; - }; - - // this.add.text(ITEM_WIDTH * 11, ITEM_HEIGHT * 1.1, 'Scoreboard', TEXT.HEADER); - // scores.forEach(([name, score], i) => { - // const SCORE_X = ITEM_WIDTH * 11; - // const SCORE_Y = ITEM_HEIGHT * 1.1 * (i + 2); - // this.add.text(SCORE_X, SCORE_Y, `${score.wins} - ${score.losses} | ${name}`, TEXT.NORMAL); - // }); - - // Add Handlers - this.input.on('dragstart', (pointer, item) => { - if (!(item instanceof Item)) return false; - return true; - }); - - this.input.on('drag', (pointer, item, dragX, dragY) => { - if (!(item instanceof Item)) return false; - item.setPosition(dragX, dragY); - const hitBox = itemCheckHitbox(this, pointer); - if (hitBox) hitBox.itemSelect(); - return true; - }); - - this.input.on('dragend', (pointer, item) => { - if (!(item instanceof Item)) return false; - // Check first for hitbox interaction - const hitBox = itemCheckHitbox(this, pointer); - if (hitBox) { - // hitbox can only be the combinerhitbox, deletehitbox or construct avatar - hitBox.itemDeselect(); - if (hitBox instanceof CombinerHitBox) { - if (hitBox.item === item) deallocate(item); - else allocate(item, hitBox); - } else if (hitBox instanceof DeleteHitBox) { - ws.sendVboxReclaim(vbox.instance, item.index); - } else { - ws.sendVboxApply(vbox.instance, hitBox.construct.id, item.index); - deallocate(item); - } return true; - } - // If not interacting with hitbox and didn't move much try to allocate the item - if (Math.hypot(item.x - item.origX, item.y - item.origY) < Math.hypot(item.width, item.height)) { - // Check theres a free combiner slot - const cBox = findUnallocated(); - if (cBox) { - allocate(item, cBox); - return true; - } - } - // If the item hasn't been allocated above reset to natural location - // Check if item needs to be deallocated - // Scene will restart if there is vbox change - deallocate(item); - return true; - }); - return this; - } - - cleanUp() { - this.registry.events.off('changedata', this.updateData, this); - this.registry.events.off('setdata', this.updateData, this); - this.scene.remove(); - } -} - -module.exports = ItemList; diff --git a/phaser-client/src/scenes/menu.cryps.list.js b/phaser-client/src/scenes/menu.cryps.list.js deleted file mode 100644 index d5792e71..00000000 --- a/phaser-client/src/scenes/menu.cryps.list.js +++ /dev/null @@ -1,137 +0,0 @@ -const Phaser = require('phaser'); - -const { TEXT, COLOURS, POSITIONS: { CONSTRUCT_LIST } } = require('./constants'); -const genAvatar = require('./avatar'); -const Item = require('./elements/item'); - -const BOX_WIDTH = Math.floor(CONSTRUCT_LIST.width()); -const BOX_HEIGHT = Math.floor(CONSTRUCT_LIST.height() / 3.34); - -const TEXT_MARGIN = 24; - -const KEY_MAP = [ - 'keydown-ONE', - 'keydown-TWO', - 'keydown-THREE', -]; - -class MenuConstructList extends Phaser.Scene { - constructor() { - super({ key: 'MenuConstructList' }); - } - - create() { - this.registry.events.on('changedata', this.updateData, this); - this.registry.events.on('setdata', this.updateData, this); - const player = this.registry.get('player'); - if (player) this.drawConstructs(player.constructs); - } - - updateData(parent, key, data) { - if (key === 'player') { - this.drawConstructs(data.constructs); - } - } - - drawConstructs(constructs) { - if (!constructs) return true; - if (this.constructGroup) this.constructGroup.destroy(true); - this.constructGroup = this.add.group(); - const addConstruct = (construct, i) => { - const ROW_X = CONSTRUCT_LIST.x(); - const ROW_Y = CONSTRUCT_LIST.y() + BOX_HEIGHT * i * 1.1; - - - const ACTIVE_FILL = 0.2; - - const FILL = Object.values(COLOURS)[i]; - // Selection of constructs - const selectFn = () => { - this.registry.set('constructStats', construct); - }; - - // Construct interaction box for adding items - const constructInteract = this.add - .rectangle(ROW_X, ROW_Y, BOX_WIDTH, BOX_HEIGHT, FILL, ACTIVE_FILL) - .setInteractive() - .setOrigin(0) - .on('pointerdown', selectFn); - constructInteract.itemSelect = () => { - constructInteract.setFillStyle(COLOURS.SELECT); - }; - constructInteract.itemDeselect = () => { - constructInteract.setFillStyle(FILL, ACTIVE_FILL); - }; - constructInteract.construct = construct; - - // Construct Avatar - const { name } = construct; - const constructImage = this.add.image( - constructInteract.getCenter().x - constructInteract.width / 4, - constructInteract.getCenter().y, - 'aztec', - genAvatar(name) - ); - - // Add text info - const yConstructTextAlgin = Math.floor(constructInteract.y + TEXT_MARGIN / 2); - const xConstructNameAlign = Math.floor(constructInteract.x + constructInteract.width * 1 / 10); - const constructInfoText = this.add.text(xConstructNameAlign, yConstructTextAlgin, name, TEXT.HEADER); - const colourText = (c, j) => { - // Placeholder for when gems are implemented - const gemText = this.add.text(constructInteract.x + constructInteract.width * (j + 3) / 6, yConstructTextAlgin, `${c[0]} - ${c[1]}`, TEXT.HEADER); - this.constructGroup.add(gemText); - }; - - const { red, green, blue } = construct.colours; - const CONSTRUCT_COLOURS = [ - ['R', red], - ['G', green], - ['B', blue], - ]; - CONSTRUCT_COLOURS.forEach(colourText); - - this.constructGroup.addMultiple([constructInteract, constructImage, constructInfoText]); - - const constructSkill = (stat, j) => { - const SKILL_WIDTH = Math.floor(BOX_WIDTH / 2); - const SKILL_HEIGHT = Math.floor(BOX_HEIGHT / 8); - const SKILL_X = constructInteract.getCenter().x + constructInteract.width / 4; - const SKILL_Y = constructInteract.y + SKILL_HEIGHT * 1.15 * (j + 1.6); - const itemObj = new Item(this, stat.skill, j, SKILL_X, SKILL_Y, SKILL_WIDTH, SKILL_HEIGHT); - this.add.existing(itemObj); - itemObj.setInteractive(); - const itemInfo = { item: stat.skill, construct }; - itemObj.on('pointerdown', () => this.registry.set('itemInfo', itemInfo)); - this.constructGroup.add(itemObj); - }; - construct.skills.forEach(constructSkill); - - const constructSpec = (spec, j) => { - const SKILL_WIDTH = Math.floor(BOX_WIDTH * 0.15); - const SKILL_HEIGHT = Math.floor(BOX_HEIGHT * 0.2); - const SKILL_X = Math.floor(constructInteract.x + BOX_WIDTH * (0.6 + j) * 0.175); - const SKILL_Y = Math.floor(constructInteract.y + BOX_HEIGHT * 0.875); - const itemObj = new Item(this, spec, j, SKILL_X, SKILL_Y, SKILL_WIDTH, SKILL_HEIGHT); - itemObj.setInteractive(); - const itemInfo = { item: spec, construct }; - itemObj.on('pointerdown', () => this.registry.set('itemInfo', itemInfo)); - this.add.existing(itemObj); - this.constructGroup.add(itemObj); - }; - construct.specs.forEach(constructSpec); - }; - constructs.forEach(addConstruct); - - return true; - } - - cleanUp() { - KEY_MAP.forEach(k => this.input.keyboard.removeListener(k)); - this.registry.events.off('changedata', this.updateData, this); - this.registry.events.off('setdata', this.updateData, this); - this.scene.remove(); - } -} - -module.exports = MenuConstructList; diff --git a/phaser-client/src/scenes/menu.js b/phaser-client/src/scenes/menu.js deleted file mode 100644 index 091335d7..00000000 --- a/phaser-client/src/scenes/menu.js +++ /dev/null @@ -1,97 +0,0 @@ -const Phaser = require('phaser'); - -// Scenes constantly showing -const MenuConstructList = require('./menu.constructs.list'); -const MenuNavigation = require('./menu.navigation'); -const ItemList = require('./item.list'); -// Scenes which change depending on menu context -const Zones = require('./zones'); -const GameList = require('./game.list'); -const StatSheet = require('./statsheet'); -const ItemInfo = require('./item.info'); - -const FIXED_MENU_SCENES = [ - 'MenuConstructList', - 'MenuNavigation', - 'ItemList', -]; - -const MAIN_MENU_SCENES = [ - 'Zones', - 'GameList', - 'StatSheet', - 'ItemInfo', -]; - -class Menu extends Phaser.Scene { - constructor() { - super({ key: 'Menu', active: true }); - } - - create() { - this.registry.events.on('changedata', this.updateData, this); - this.registry.events.on('setdata', this.updateData, this); - - // Request the latest player state when we load the scene - const player = this.registry.get('player'); - this.registry.get('ws').sendPlayerState(player.instance); - // When we load the menu request the latest items - // Item list will restart when the data comes in - this.scene.manager.add('MenuConstructList', MenuConstructList, true); - this.scene.manager.add('MenuNavigation', MenuNavigation, true); - this.scene.manager.add('ItemList', ItemList, true); - this.registry.set('inMenu', true); - - return true; - } - - updateData(parent, key, data) { - if (!data) return false; - // Controls which scene shows in the main top right section - switch (key) { - case 'game': return this.cleanUp(); - case 'home': return this.cleanUp(); - case 'zone': return this.newMainScene('Zones', Zones, data); - case 'gameList': return this.newMainScene('GameList', GameList, data); - case 'constructStats': return this.newMainScene('StatSheet', StatSheet, data); - case 'itemInfo': return this.newMainScene('ItemInfo', ItemInfo, data); - default: return false; - } - } - - newMainScene(key, scene, data) { - let addScene = true; - // List of scenes which could be occupying the main section of the menu - MAIN_MENU_SCENES.forEach((sKey) => { - if (this.scene.manager.keys[sKey]) { - if (key === sKey) { - // If there is new data for the current scene restart - this.scene.manager.keys[sKey].scene.restart(data); - addScene = false; - } else { - // Delete the old scene - this.scene.manager.keys[sKey].cleanUp(); - } - } - }); - if (addScene) this.scene.manager.add(key, scene, true, data); - } - - cleanUp() { - this.registry.events.off('changedata', this.updateData, this); - this.registry.events.off('setdata', this.updateData, this); - // Delete scenes which could be showing before switching to battle scene - const removeScenes = (sKey) => { - if (this.scene.get(sKey)) this.scene.get(sKey).cleanUp(); - }; - FIXED_MENU_SCENES.forEach(removeScenes); - MAIN_MENU_SCENES.forEach(removeScenes); - this.registry.set('inMenu', false); - this.combinerItems = this.registry.set('combinerItems', null); - - - this.scene.remove(); - } -} - -module.exports = Menu; diff --git a/phaser-client/src/scenes/menu.navigation.js b/phaser-client/src/scenes/menu.navigation.js deleted file mode 100644 index b6f72656..00000000 --- a/phaser-client/src/scenes/menu.navigation.js +++ /dev/null @@ -1,50 +0,0 @@ -const Phaser = require('phaser'); - -const { TEXT, POSITIONS: { NAVIGATION } } = require('./constants'); - -const X = NAVIGATION.x(); -const Y = NAVIGATION.y(); -const WIDTH = NAVIGATION.width(); -const HEIGHT = NAVIGATION.height(); - -const BTN_WIDTH = Math.floor(WIDTH / 4); -const BTN_HEIGHT = Math.floor(HEIGHT / 2); - -class MenuNavigation extends Phaser.Scene { - constructor() { - super({ key: 'MenuNavigation' }); - } - - create() { - const ws = this.registry.get('ws'); - const player = this.registry.get('player'); - this.cameras.main.setViewport(X, Y, WIDTH, HEIGHT); - - const ready = this.add - .rectangle(BTN_WIDTH * 3, 0, BTN_WIDTH, BTN_HEIGHT, 0x222222) - .setInteractive() - .setOrigin(0); - this.add - .text(ready.getCenter().x, ready.getCenter().y, 'Ready', TEXT.HEADER) - .setOrigin(0.5, 0.5); - ready.on('pointerdown', () => { - ws.sendInstanceReady(player.instance); - }); - - const menu = this.add - .rectangle(BTN_WIDTH * 3, BTN_HEIGHT, BTN_WIDTH, BTN_HEIGHT, 0x440000) - .setInteractive() - .setOrigin(0) - .on('pointerdown', () => this.registry.set('home', true)); - - this.add - .text(menu.getCenter().x, menu.getCenter().y, 'Menu', TEXT.HEADER) - .setOrigin(0.5, 0.5); - } - - cleanUp() { - this.scene.remove(); - } -} - -module.exports = MenuNavigation; diff --git a/phaser-client/src/scenes/statsheet.js b/phaser-client/src/scenes/statsheet.js deleted file mode 100644 index 802a21d3..00000000 --- a/phaser-client/src/scenes/statsheet.js +++ /dev/null @@ -1,143 +0,0 @@ -const Phaser = require('phaser'); -const { POSITIONS: { MENU_MAIN }, TEXT, SKILLS } = require('./constants'); -const Item = require('./elements/item'); - -const X = MENU_MAIN.x(); -const Y = MENU_MAIN.y(); -const WIDTH = MENU_MAIN.width(); -const HEIGHT = MENU_MAIN.height(); -const TEXT_MARGIN = 24; - -const SKILL_WIDTH = Math.floor(WIDTH / 10); - - -class DeleteHitBox extends Phaser.GameObjects.Rectangle { - constructor(scene, x, y) { - super(scene, x, y, SKILL_WIDTH, SKILL_WIDTH, 0x222222); - this.setOrigin(0); - this.itemSelect = () => this.setFillStyle(0xff0000); - this.itemDeselect = () => this.setFillStyle(0x222222); - } -} - -const itemCheckHitbox = (scene, pointer) => { - const { list } = scene.scene.get('MenuConstructList').children; - const hitboxes = list.filter(c => c.construct) - .concat(scene.children.list.filter(c => c instanceof DeleteHitBox)); - - let found; - for (let i = 0; i < hitboxes.length; i += 1) { - if (Phaser.Geom.Rectangle.ContainsPoint(hitboxes[i].getBounds(), pointer.position)) { - found = hitboxes[i]; - } else { - hitboxes[i].itemDeselect(); - } - } - - return found; -}; - -class StatSheet extends Phaser.Scene { - constructor() { - super({ key: 'StatSheet' }); - } - - - updateData(parent, key, data) { - if (key === 'player') { - console.log('grep'); - console.log(data); - const construct = data.constructs.find(c => c.id === this.construct.id); - this.scene.restart(construct); - } - } - - create(construct) { - this.registry.events.on('changedata', this.updateData, this); - // const ws = this.registry.get('ws'); - - const player = this.registry.get('player'); - if (!player) return false; - // const { vbox } = player; - - this.construct = construct; - - /* - const del = this.add.existing(new DeleteHitBox(this, X + WIDTH * 0.7, Y + HEIGHT * 0.6)); - this.add.text(del.getCenter().x, del.getCenter().y, 'unequip', TEXT.HEADER) - .setOrigin(0.5, 0.5); - */ - - this.add.text(X, Y, construct.name, TEXT.HEADER); - - const constructStat = (stat, i) => { - const STAT_X = X; - const STAT_Y = Y + (i + 2) * TEXT_MARGIN; - this.add.text(STAT_X, STAT_Y, `${stat.stat}: ${stat.base} -> ${stat.value}`, TEXT.NORMAL); - }; - - const CONSTRUCT_STATS = [ - construct.hp, - construct.red_shield, - construct.blue_shield, - construct.evasion, - construct.red_damage, - construct.blue_damage, - construct.speed, - ]; - - CONSTRUCT_STATS.forEach(constructStat); - /* - const knownSkill = (skill, i) => { - const SKILL_X = X + WIDTH * 0.4 + WIDTH * 0.125 * i; - const SKILL_Y = Y + HEIGHT * 0.15; - const itemObj = new Item(this, skill.skill, i, SKILL_X, SKILL_Y, SKILL_WIDTH, Math.floor(SKILL_WIDTH / 2)); - // itemObj.on('pointerdown', () => ); - this.input.setDraggable(itemObj); - this.add.existing(itemObj); - }; - construct.skills.forEach(knownSkill); - this.add.text(X + WIDTH * 0.35, Y, 'Skills', TEXT.HEADER); - - this.add.text(X + WIDTH * 0.35, Y + HEIGHT * 0.25, 'Specs', TEXT.HEADER); - const knownSpec = (spec, i) => { - const SKILL_X = X + WIDTH * 0.4 + WIDTH * 0.125 * i; - const SKILL_Y = Y + HEIGHT * 0.4; - const itemObj = new Item(this, spec, i, SKILL_X, SKILL_Y, SKILL_WIDTH, Math.floor(SKILL_WIDTH / 2)); - // itemObj.on('pointerdown', () => ); - this.input.setDraggable(itemObj); - this.add.existing(itemObj); - }; - construct.specs.forEach(knownSpec); - - - this.input.on('drag', (pointer, item, dragX, dragY) => { - if (!(item instanceof Item)) return false; - item.setPosition(dragX, dragY); - const hitBox = itemCheckHitbox(this, pointer); - if (hitBox) hitBox.itemSelect(); - return true; - }); - - this.input.on('dragend', (pointer, item) => { - if (!(item instanceof Item)) return false; - item.setPosition(item.origX, item.origY); - const hitBox = itemCheckHitbox(this, pointer); - if (hitBox) { - hitBox.itemDeselect(); - // add socket function for unlearn here - ws.sendVboxUnequip(vbox.instance, construct.id, item.item); - } - return true; - }); - */ - return this; - } - - cleanUp() { - this.registry.events.off('changedata', this.updateData, this); - this.scene.remove(); - } -} - -module.exports = StatSheet; diff --git a/phaser-client/src/scenes/zone.controls.js b/phaser-client/src/scenes/zone.controls.js deleted file mode 100644 index bdbd4b4c..00000000 --- a/phaser-client/src/scenes/zone.controls.js +++ /dev/null @@ -1,41 +0,0 @@ -const Phaser = require('phaser'); - -const { TEXT, POSITIONS: { MENU_MAIN } } = require('./constants'); - -const X = MENU_MAIN.x(); -const Y = MENU_MAIN.y(); -const WIDTH = MENU_MAIN.width(); -const HEIGHT = MENU_MAIN.height(); - -class ZoneControls extends Phaser.Scene { - constructor() { - super({ key: 'ZoneControls' }); - } - - create(zoneId) { - this.cameras.main.setViewport(X, Y, WIDTH, HEIGHT); - - const menu = this.add - .rectangle(Math.floor(WIDTH * 0.7), Math.floor(HEIGHT * 0.8), Math.floor(WIDTH * 0.2), Math.floor(HEIGHT * 0.2), 0x888888) - .setInteractive() - .setOrigin(0); - - this.add - .text(menu.getCenter().x, menu.getCenter().y, 'Clear', TEXT.HEADER) - .setOrigin(0.5, 0.5); - - menu.on('pointerdown', () => { - this.registry.get('ws').sendZoneClose(zoneId); - this.scene.get('Zones').cleanUp(); - }); - - - return true; - } - - cleanUp() { - this.scene.remove(); - } -} - -module.exports = ZoneControls; diff --git a/phaser-client/src/scenes/zone.node.js b/phaser-client/src/scenes/zone.node.js deleted file mode 100644 index cd81e4cd..00000000 --- a/phaser-client/src/scenes/zone.node.js +++ /dev/null @@ -1,31 +0,0 @@ -const Phaser = require('phaser'); - -class ZoneNode extends Phaser.GameObjects.Sprite { - constructor(scene, x, y, id, success, tag) { - super(scene, x, y); - this.setTexture('eye'); - this.scene = scene; - this.success = success; - // this.text = (text.indexOf(',') > -1) ? text.split(',') : text; - this.id = id; - this.setPosition(x, y); - - const nodeNoDigits = tag.replace(/[0-9]/g, ''); - switch (nodeNoDigits) { - case 'BOSS': - this.setScale(0.25); - break; - case 'MINIBOSS': - this.setScale(0.1); - break; - default: - this.setScale(0.05); - } - if (this.success) { - this.setTint(0xff0000); - } - this.text = tag; - } -} - -module.exports = ZoneNode; diff --git a/phaser-client/src/scenes/zones.js b/phaser-client/src/scenes/zones.js deleted file mode 100644 index fcedab65..00000000 --- a/phaser-client/src/scenes/zones.js +++ /dev/null @@ -1,129 +0,0 @@ -const Phaser = require('phaser'); -const Node = require('./zone.node'); -const ZoneControls = require('./zone.controls'); -const { POSITIONS: { MENU_MAIN }, TEXT } = require('./constants'); - -const X = MENU_MAIN.x(); -const Y = MENU_MAIN.y(); -const WIDTH = MENU_MAIN.width(); -const HEIGHT = MENU_MAIN.height(); - - -// Mouse click hold to move, Q + E to zoom in and out -// Press 'A' to reset allocated passive nodes - -class Zones extends Phaser.Scene { - constructor() { - super({ key: 'Zones' }); - } - - preload() { - this.load.image('eye', 'https://labs.phaser.io/assets/particles/green-orb.png'); - } - - create(zone) { - if (!zone) return false; - if (!this.scene.get('ZoneControls')) this.scene.manager.add('ZoneControls', ZoneControls, true, zone.id); - this.graphics = this.add.graphics(); - this.cameras.main.setViewport(X, Y, WIDTH, HEIGHT); - this.addNodes(zone.graph.nodes); - this.drawEdges(zone.graph.edges); - this.addCameraControl(); - this.addEvents(zone.id); - return this; - } - - addNodes(nodeData) { - this.nodes = []; - nodeData.forEach((n, i) => { - this.nodes[i] = this.add.existing( - new Node(this, n.x * 50 + 200, n.y * 50 + 200, i, n.success, n.tag) - ).setInteractive(); - }); - } - - addCameraControl() { - this.controls = new Phaser.Cameras.Controls.SmoothedKeyControl({ - camera: this.cameras.main, - zoomIn: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.Q), - zoomOut: this.input.keyboard.addKey(Phaser.Input.Keyboard.KeyCodes.E), - acceleration: 0.005, - drag: 0.0005, - maxSpeed: 0.001, - }); - } - - addEvents(zoneId) { - this.input.on('pointerover', (pointer, gameObjects) => { - if (gameObjects[0] instanceof Node) { - this.displayNodeText(gameObjects[0], pointer); - } - }); - this.input.on('pointerout', (pointer, gameObjects) => { - if (gameObjects[0] instanceof Node) { - this.nodeText.destroy(); - } - }); - this.input.on('pointerup', (pointer, gameObjects) => { - if (Math.abs(pointer.upX - pointer.downX) < 5 - && Math.abs(pointer.upY - pointer.downY) < 5) { - // Check cursor hasn't significantly moved during point allocation - // If panning and mouse release is on node it won't allocate - if (gameObjects[0] instanceof Node) { - const team = this.registry.get('constructs').filter(c => c.active).map(c => c.id); - if (gameObjects[0].success) return false; - this.registry.get('ws').sendZoneJoin(zoneId, gameObjects[0].id, team); - } - } - return true; - }); - this.input.on('pointermove', (pointer) => { - const zoomFactor = 2 / this.cameras.main.zoom; - if (this.registry.get('pan')) { - const points = pointer.getInterpolatedPosition(2); - this.cameras.main.scrollX -= zoomFactor * (points[1].x - points[0].x); - this.cameras.main.scrollY -= zoomFactor * (points[1].y - points[0].y); - } - }, this); - } - - drawEdges(edgeData) { - this.graphics.clear(); - edgeData.forEach((e) => { - const nodeA = this.nodes[e[0]]; - const nodeB = this.nodes[e[1]]; - if (nodeA.success && nodeB.success) { - this.graphics.lineStyle(10, 0xfff00f, 0.2); - } else { - this.graphics.lineStyle(2, 0xffffff, 0.2); - } - this.graphics.lineBetween(nodeA.x, nodeA.y, nodeB.x, nodeB.y); - return true; - }); - } - - displayNodeText(node, pointer) { - if (this.nodeText) this.nodeText.destroy(); - this.nodeText = this.add.text(node.x, node.y, node.text, TEXT.HOVER).setPadding(32); - this.nodeText.setAlpha(0.8); - this.nodeText.setOrigin(pointer.x >= WIDTH * 0.65 ? 1 : 0, - pointer.y >= HEIGHT * 0.25 ? 1 : 0); - this.nodeText.setWordWrapWidth(450); - this.nodeText.setScale(1 / this.cameras.main.zoom); - } - - camPan(bool) { - this.pan = bool; - } - - update(delta) { - this.controls.update(delta); - } - - cleanUp() { - if (this.scene.get('ZoneControls')) this.scene.get('ZoneControls').cleanUp(); - this.scene.remove(); - } -} - -module.exports = Zones; diff --git a/phaser-client/src/socket.js b/phaser-client/src/socket.js deleted file mode 100644 index 26c58848..00000000 --- a/phaser-client/src/socket.js +++ /dev/null @@ -1,335 +0,0 @@ -const toast = require('izitoast'); -const cbor = require('borc'); - - -const SOCKET_URL = process.env.NODE_ENV === 'production' ? 'wss://constructs.gg/ws' : 'ws://localhost:40000'; - -function errorToast(err) { - console.error(err); - return toast.error({ - title: 'BEEP BOOP', - message: err, - position: 'topRight', - }); -} - -function createSocket(events) { - let ws; - - // handle account auth within the socket itself - // https://www.christian-schneider.net/CrossSiteWebSocketHijacking.html - let account = null; - - // ------------- - // Outgoing - // ------------- - function send(msg) { - console.log('outgoing msg', msg); - msg.token = account && account.token; - ws.send(cbor.encode(msg)); - } - - function sendAccountLogin(name, password) { - send({ method: 'account_login', params: { name, password } }); - } - - function sendAccountCreate(name, password) { - send({ method: 'account_create', params: { name, password } }); - } - - function sendAccountDemo() { - send({ method: 'account_demo', params: {} }); - } - - function sendAccountConstructs() { - send({ method: 'account_constructs', params: {} }); - } - - function sendAccountInstances() { - send({ method: 'account_instances', params: {} }); - } - - function sendAccountZone() { - send({ method: 'account_zone', params: {} }); - } - - function sendConstructSpawn(name) { - send({ method: 'construct_spawn', params: { name } }); - } - - function sendConstructLearn(id, skill) { - send({ method: 'construct_learn', params: { id, skill } }); - } - - function sendConstructForget(id, skill) { - send({ method: 'construct_forget', params: { id, skill } }); - } - - function sendGameState(id) { - send({ method: 'game_state', params: { id } }); - } - - function sendGamePve(constructIds, mode) { - send({ method: 'game_pve', params: { construct_ids: constructIds, mode } }); - } - - function sendGamePvp(constructIds) { - send({ method: 'game_pvp', params: { construct_ids: constructIds } }); - } - - function sendGameJoin(gameId, constructIds) { - send({ method: 'game_join', params: { game_id: gameId, construct_ids: constructIds } }); - } - - function sendSpecForget(id, spec) { - send({ method: 'construct_unspec', params: { id, spec } }); - } - - function sendPlayerConstructsSet(instanceId, constructIds) { - send({ method: 'player_constructs_set', params: { instance_id: instanceId, construct_ids: constructIds } }); - } - - function sendPlayerState(instanceId) { - send({ method: 'player_state', params: { instance_id: instanceId } }); - } - - function sendVboxAccept(instanceId, group, index) { - send({ method: 'player_vbox_accept', params: { instance_id: instanceId, group, index } }); - } - - function sendVboxApply(instanceId, constructId, index) { - send({ method: 'player_vbox_apply', params: { instance_id: instanceId, construct_id: constructId, index } }); - } - - function sendVboxUnequip(instanceId, constructId, target) { - send({ method: 'player_vbox_unequip', params: { instance_id: instanceId, construct_id: constructId, target } }); - } - - function sendVboxDiscard(instanceId) { - send({ method: 'player_vbox_discard', params: { instance_id: instanceId } }); - } - - function sendVboxCombine(instanceId, indices) { - send({ method: 'player_vbox_combine', params: { instance_id: instanceId, indices } }); - } - - function sendVboxReclaim(instanceId, index) { - send({ method: 'player_vbox_reclaim', params: { instance_id: instanceId, index } }); - } - - function sendGameSkill(gameId, constructId, targetConstructId, skill) { - send({ - method: 'game_skill', - params: { - game_id: gameId, construct_id: constructId, target_construct_id: targetConstructId, skill, - }, - }); - events.setActiveSkill(null); - } - - function sendGameTarget(gameId, constructId, skillId) { - send({ method: 'game_target', params: { game_id: gameId, construct_id: constructId, skill_id: skillId } }); - events.setActiveSkill(null); - } - - function sendZoneCreate() { - send({ method: 'zone_create', params: {} }); - } - - function sendZoneJoin(zoneId, nodeId, constructIds) { - send({ method: 'zone_join', params: { zone_id: zoneId, node_id: nodeId, construct_ids: constructIds } }); - } - - function sendZoneClose(zoneId) { - send({ method: 'zone_close', params: { zone_id: zoneId } }); - } - - function sendInstanceJoin(constructs) { - send({ method: 'instance_join', params: { construct_ids: constructs, pve: true } }); - } - - function sendInstanceReady(instanceId) { - send({ method: 'instance_ready', params: { instance_id: instanceId } }); - } - - function sendInstanceScores(instanceId) { - send({ method: 'instance_scores', params: { instance_id: instanceId } }); - } - - - // ------------- - // Incoming - // ------------- - function accountLogin(res) { - const [struct, login] = res; - - account = login; - events.setAccount(login); - sendAccountConstructs(); - } - - function accountInstanceList(res) { - const [struct, instanceList] = res; - events.setInstanceList(instanceList); - } - - function accountConstructs(response) { - const [structName, constructs] = response; - events.setConstructList(constructs); - } - - function gameState(response) { - const [structName, game] = response; - events.setGame(game); - } - - function constructSpawn(response) { - const [structName, construct] = response; - } - - function gamePve(response) { - const [structName, game] = response; - } - - function zoneState(response) { - const [structName, zone] = response; - events.setZone(zone); - } - - function playerState(response) { - const [structName, player] = response; - events.setPlayer(player); - } - - function instanceScores(response) { - const [structName, scores] = response; - events.setScores(scores); - } - - // ------------- - // Setup - // ------------- - - // when the server sends a reply it will have one of these message types - // this object wraps the reply types to a function - const handlers = { - construct_spawn: constructSpawn, - construct_forget: () => true, - construct_learn: () => true, - game_pve: gamePve, - game_state: gameState, - account_login: accountLogin, - account_create: accountLogin, - account_constructs: accountConstructs, - account_instances: accountInstanceList, - instance_scores: instanceScores, - zone_create: res => console.log(res), - zone_state: zoneState, - zone_close: res => console.log(res), - player_state: playerState, - }; - - function errHandler(error) { - switch (error) { - case 'no active zone': return sendZoneCreate(); - case 'no constructs selected': return events.errorPrompt('select_constructs'); - case 'node requirements not met': return events.errorPrompt('complete_nodes'); - case 'construct at max skills (4)': return events.errorPrompt('max_skills'); - - default: return errorToast(error); - - } - } - - // decodes the cbor and - // calls the handlers defined above based on message type - function onMessage(event) { - // decode binary msg from server - const blob = new Uint8Array(event.data); - const res = cbor.decode(blob); - const { method, params } = res; - - console.log(res); - - // check for error and split into response type and data - if (res.err) return errHandler(res.err); - if (!handlers[method]) return errorToast(`${method} handler missing`); - return handlers[method](params); - } - - function connect() { - ws = new WebSocket(SOCKET_URL); - ws.binaryType = 'arraybuffer'; - - // Connection opened - ws.addEventListener('open', () => { - toast.info({ - message: 'connected', - position: 'topRight', - }); - - if (!account) events.loginPrompt(); - if (process.env.NODE_ENV !== 'production') { - // send({ method: 'account_login', params: { name: 'ntr', password: 'grepgrepgrep' } }); - } - - return true; - }); - - // Listen for messages - ws.addEventListener('message', onMessage); - - ws.addEventListener('error', (event) => { - console.error('WebSocket error', event); - // account = null; - // return setTimeout(connect, 5000); - }); - - ws.addEventListener('close', (event) => { - console.error('WebSocket closed', event); - toast.warning({ - message: 'disconnected', - position: 'topRight', - }); - return setTimeout(connect, 5000); - }); - - return ws; - } - - return { - sendAccountLogin, - sendAccountCreate, - sendAccountDemo, - sendAccountConstructs, - sendAccountInstances, - sendAccountZone, - sendGameState, - sendGamePve, - sendGamePvp, - sendGameJoin, - sendGameSkill, - sendGameTarget, - sendConstructSpawn, - sendConstructLearn, - sendConstructForget, - sendSpecForget, - sendZoneCreate, - sendZoneJoin, - sendZoneClose, - sendInstanceJoin, - sendInstanceReady, - sendInstanceScores, - sendPlayerConstructsSet, - sendPlayerState, - sendVboxAccept, - sendVboxApply, - sendVboxReclaim, - sendVboxCombine, - sendVboxDiscard, - sendVboxUnequip, - connect, - }; -} - -module.exports = createSocket; diff --git a/phaser-client/src/tutorial.js b/phaser-client/src/tutorial.js deleted file mode 100644 index 186927c7..00000000 --- a/phaser-client/src/tutorial.js +++ /dev/null @@ -1,135 +0,0 @@ -const toast = require('izitoast'); - -const OK_BUTTON = ''; -const NO_MORE_BUTTON = ''; - -function noMore(instance, thisToast) { - window.localStorage.setItem('tutorial', 'none'); - return instance.hide({ transitionOut: 'fadeOut' }, thisToast); -} - -const WELCOME_MESSAGE = ` -Welcome to constructs.gg -Enter a username and password and press register to sign up, -or just press DEMO to quick start. -`; - -const HOMEPAGE_MESSAGE = ` -This homepage shows your constructs, joinable online games, PVE options and your items.\n -If you have no constructs yet, press SPAWN and give your construct a name to create one. -Once you have made a construct, click on them to visit their stat page and teach them some SKILLS. -The stat page also has descriptions of each skill and their effects. -constructs have 3 basic stats: hp, red damage and magic damage. -Toggle whether a construct is selected for your team by clicking the coloured stripes next to the construct or press 1,2,3. -Once you have a team ready press the New PVE Game button to start playing. -`; - -const SKILL_PHASE_MESSAGE = ` -A constructs battle has two main phases. This first phase is called the SKILL PHASE. -Your constructs are positioned on the left, your opponent's are on the right. -In the centre are your constructs' SKILLS, grayed out SKILLS are currently ON COOLDOWN. -A skill's cooldown reduces on every turn that construct does not use a skill with a cooldown. -For the moment, drag ATTACK onto the opponent team to have your constructs attack them with red damage. -`; - -// const TARGET_PHASE_MESSAGE = ` -// This phase is the TARGET PHASE. -// In constructs you do not directly attack your opponent's constructs, you attack the opponent as a team -// and you and your opponent choose which construct is the TARGET of each ability. -// Drag the incoming ATTACKS from the right hand side onto your own constructs. -// It's wise to spread the damage around! -// `; - -const RESOLUTION_PHASE_MESSAGE = ` -The second phase is called the RESOLUTION PHASE. -This phase happens automatically, every skill is RESOLVED in order of its SPEED. -This is important because attacks only RESOLVE while their caster is still able to use the skill, -a fast skill that does a small amount of damage may KO an opponent construct, causing any SKILLS -they have used to no longer RESOLVE! -Another example of this is the skill STUN. STUN causes an opponent construct to be unable to use any -abilities for TWO TURNS including the turn it resolves on. In other words it lasts for the rest of the turn it resolves on -and the whole next turn. -Try it now! -`; - -const FINISH_PHASE_MESSAGE = ` -gg! The game has now concluded, if you were the winner you have been awarded with a STAT REROLL ITEM. -You can use this to reroll a stat on a construct which may be lacking. -A good metric is that if a stat is more than 1/2 of its STAMINA that's a good roll. -Now that you have learned the basics, press BACKSPACE to return to the main menu -and experiment with some combinations of SKILLS or replace the ones your constructs know in the STAT PAGE. -glhf! -`; - -const STEPS = [ - 'init', - 'welcome', - 'homepage', - 'skillPhase', - // 'targetPhase', - 'resolutionPhase', - 'finishPhase', - 'none', -]; - -function showTutorial(message, step, nextStep) { - const existing = document.querySelector(`#${step}`); // Selector of your toast - - if (existing) return false; - - toast.info({ - id: step, - theme: 'dark', - color: 'black', - timeout: false, - drag: false, - title: 'TUTORIAL', - position: 'bottomCenter', - maxWidth: window.innerWidth / 2, - close: false, - buttons: [ - [NO_MORE_BUTTON, noMore], - [OK_BUTTON, (instance, thisToast) => { - const thisStep = STEPS.indexOf(step); - const storageStep = STEPS.indexOf(window.localStorage.getItem('tutorial')); - if (thisStep >= storageStep) { - window.localStorage.setItem('tutorial', nextStep); - } - - return instance.hide({ transitionOut: 'fadeOut' }, thisToast); - }], - ], - message, - }); - - return true; -} - -function tutorial() { - function show(step) { - const currentStage = window.localStorage.getItem('tutorial'); - if (currentStage === 'none') { - return false; - } - - const thisStep = STEPS.indexOf(step); - const storageStep = STEPS.indexOf(window.localStorage.getItem('tutorial')); - - if (thisStep < storageStep) return false; - - if (step === 'welcome') return showTutorial(WELCOME_MESSAGE, 'welcome', 'homepage'); - if (step === 'homepage') return showTutorial(HOMEPAGE_MESSAGE, 'homepage', 'skillPhase'); - if (step === 'skillPhase') return showTutorial(SKILL_PHASE_MESSAGE, 'skillPhase', 'targetPhase'); - // if (step === 'targetPhase') return showTutorial(TARGET_PHASE_MESSAGE, 'targetPhase', 'resolutionPhase'); - if (step === 'resolutionPhase') return showTutorial(RESOLUTION_PHASE_MESSAGE, 'resolutionPhase', 'finishPhase'); - if (step === 'finishPhase') return showTutorial(FINISH_PHASE_MESSAGE, 'finishPhase', 'none'); - - return true; - } - - if (window.localStorage.getItem('tutorial') !== 'none') window.localStorage.setItem('tutorial', 'init'); - - return show; -} - -module.exports = tutorial; diff --git a/phaser-client/src/utils.js b/phaser-client/src/utils.js deleted file mode 100644 index e48b03ef..00000000 --- a/phaser-client/src/utils.js +++ /dev/null @@ -1,36 +0,0 @@ -const get = require('lodash/get'); - -const stringSort = (k, desc) => { - if (desc) { - return (a, b) => { - if (!get(a, k)) return 1; - if (!get(b, k)) return -1; - return get(b, k).localeCompare(get(a, k)); - }; - } - return (a, b) => { - if (!get(a, k)) return 1; - if (!get(b, k)) return -1; - return get(a, k).localeCompare(get(b, k)); - }; -}; - -const numSort = (k, desc) => { - if (desc) { - return (a, b) => { - if (!get(a, k)) return 1; - if (!get(b, k)) return -1; - return get(b, k) - get(a, k); - }; - } - return (a, b) => { - if (!get(a, k)) return 1; - if (!get(b, k)) return -1; - return get(a, k) - get(b, k); - }; -}; - -module.exports = { - stringSort, - numSort, -}; diff --git a/server/src/cryp.rs b/server/src/construct.rs similarity index 100% rename from server/src/cryp.rs rename to server/src/construct.rs