]> git.localhorst.tv Git - alttp.git/commitdiff
first half of AoS generator
authorDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 27 Jul 2022 07:50:43 +0000 (09:50 +0200)
committerDaniel Karbach <daniel.karbach@localhorst.tv>
Wed, 27 Jul 2022 07:50:43 +0000 (09:50 +0200)
app/Http/Controllers/AosSeedController.php
resources/js/components/aos-generate/Generate.js [new file with mode: 0644]
resources/js/components/aos/App.js
resources/js/components/pages/AosGenerate.js [new file with mode: 0644]
resources/js/i18n/de.js
resources/js/i18n/en.js
routes/api.php

index 8cdc58bf5a7b520e864e54ec14715c28cfaf285d..a1718a13fcaee60da1c91ba502edcac27e7ea00b 100644 (file)
@@ -42,6 +42,10 @@ class AosSeedController extends Controller
                return $seed->toJson();
        }
 
+       public function presets() {
+               return array_values(AosrPresetCommand::$presets);
+       }
+
        public function retry($hash) {
                $seed = AosSeed::where('hash', '=', $hash)->firstOrFail();
 
diff --git a/resources/js/components/aos-generate/Generate.js b/resources/js/components/aos-generate/Generate.js
new file mode 100644 (file)
index 0000000..cbdeeb0
--- /dev/null
@@ -0,0 +1,266 @@
+import { withFormik } from 'formik';
+import PropTypes from 'prop-types';
+import React from 'react';
+import { Button, Col, Container, Form, Row } from 'react-bootstrap';
+import { withTranslation } from 'react-i18next';
+
+import i18n from '../../i18n';
+
+const settings = [
+       'logic',
+       'nodupes',
+       'panther',
+       'area',
+       'boss',
+       'enemy',
+       'itempool',
+       'weight',
+       'grahm',
+       'kicker',
+       'startshop',
+       'shopprice',
+       'shopSouls',
+       'levelexp',
+       'telestart',
+       'mapassist',
+       'doublechaos',
+       'reqallsouls',
+       'noww',
+       'palette',
+];
+
+const settingValues = {
+       area: [
+               'AreaRandom',
+               'DoorRandom',
+               'Vanilla',
+       ],
+       boss: [
+               'Dead-endShuffle',
+               'Vanilla',
+       ],
+       doublechaos: [
+               'false',
+               'true',
+       ],
+       enemy: [
+               'RandomNoLimit',
+               'RandomP20M5',
+               'RandomP30M10',
+               'RandomPM10',
+               'RandomPM20',
+               'RandomPMaxM5',
+               'Vanilla',
+       ],
+       grahm: [
+               'AllBosses',
+               'BookSouls',
+               'NoCheck',
+       ],
+       itempool: [
+               'AllSouls',
+               'Standard',
+       ],
+       kicker: [
+               'false',
+               'true',
+       ],
+       levelexp: [
+               'Casual',
+               'Hard',
+               'Lvl1',
+               'Vanilla',
+       ],
+       logic: [
+               'AreaTechTiers',
+               'AreaTechTiersHard',
+               'ForwardFeed',
+               'ForwardFeedHard',
+               'HybridProgression',
+               'VeryRandom',
+               'VeryRandomHard',
+               'VeryRandomHardOnly',
+       ],
+       mapassist: [
+               'false',
+               'true',
+       ],
+       nodupes: [
+               'false',
+               'true',
+       ],
+       noww: [
+               'false',
+               'true',
+       ],
+       palette: [
+               'Mode1',
+               'Mode1.5',
+               'Mode2',
+               'Vanilla',
+       ],
+       panther: [
+               'AlwaysRand',
+               'ExtraFairRand',
+               'FirstAlways',
+               'NeverExists',
+               'Rand70Dup',
+       ],
+       reqallsouls: [
+               'false',
+               'true',
+       ],
+       shopprice: [
+               'RandHV',
+               'Vanilla',
+       ],
+       shopSouls: [
+               '2PerGroup',
+               'Half',
+               'OnlySouls',
+               'Vanilla',
+       ],
+       startshop: [
+               'Unlocked',
+               'Unlocked30k',
+               'Vanilla',
+       ],
+       telestart: [
+               'false',
+               'true',
+       ],
+       weight: [
+               '0',
+               '1.0',
+               '1.5',
+               '2.0',
+               '2.5',
+               '3.0',
+               '3.5',
+       ],
+};
+
+const Generate = ({
+       handleBlur,
+       handleChange,
+       handleSubmit,
+       presets,
+       setFieldValue,
+       values,
+}) =>
+<Container>
+       <h1>{i18n.t('aosGenerate.heading')}</h1>
+       <Form noValidate onSubmit={handleSubmit}>
+               <Row>
+                       <Col md={6}>
+                               <Form.Group controlId="generate.preset">
+                                       <Form.Label>
+                                               {i18n.t('aosSeeds.preset')}
+                                       </Form.Label>
+                                       <Form.Select
+                                               name="preset"
+                                               onBlur={handleBlur}
+                                               onChange={e => {
+                                                       const presetName = e.target.value;
+                                                       const preset = presets.find(p => p.value === presetName);
+                                                       if (preset) {
+                                                               setFieldValue('settings', preset.settings);
+                                                       }
+                                                       return handleChange(e);
+                                               }}
+                                               value={values.preset}
+                                       >
+                                               <option value="custom">{i18n.t('aosSeeds.presets.custom')}</option>
+                                               {presets.map(preset =>
+                                                       <option key={preset.value} value={preset.value}>
+                                                               {i18n.t(`aosSeeds.presets.${preset.value}`)}
+                                                       </option>
+                                               )}
+                                       </Form.Select>
+                               </Form.Group>
+                       </Col>
+                       <Col sm={6} md={3}>
+                               <Form.Group controlId="generate.submit">
+                                       <Form.Label>
+                                               {i18n.t('button.generate')}
+                                       </Form.Label>
+                                       <div>
+                                               <Button type="submit">
+                                                       {i18n.t('button.generate')}
+                                               </Button>
+                                       </div>
+                               </Form.Group>
+                       </Col>
+               </Row>
+               <Row>
+                       {settings.map(setting =>
+                               <Form.Group as={Col} md={4} key={setting} controlId={`generate.${setting}`}>
+                                       <Form.Label>
+                                               {i18n.t(`aosSeeds.settingName.${setting}`)}
+                                       </Form.Label>
+                                       <Form.Select
+                                               name={`settings[${setting}]`}
+                                               onBlur={handleBlur}
+                                               onChange={e => {
+                                                       setFieldValue('preset', 'custom');
+                                                       return handleChange(e);
+                                               }}
+                                               value={values.settings[setting]}
+                                       >
+                                               {settingValues[setting].map(value =>
+                                                       <option key={value} value={value}>
+                                                               {i18n.t(`aosSeeds.settingValue.${setting}.${value}`)}
+                                                       </option>
+                                               )}
+                                       </Form.Select>
+                               </Form.Group>
+                       )}
+               </Row>
+       </Form>
+</Container>;
+
+Generate.propTypes = {
+       handleBlur: PropTypes.func,
+       handleChange: PropTypes.func,
+       handleSubmit: PropTypes.func,
+       presets: PropTypes.arrayOf(PropTypes.shape({
+               settings: PropTypes.shape({
+               }),
+               value: PropTypes.string,
+       })),
+       setFieldValue: PropTypes.func,
+       values: PropTypes.shape({
+               preset: PropTypes.string,
+               settings: PropTypes.shape({
+               }),
+       }),
+};
+
+export default withFormik({
+       displayName: 'AosGenerateForm',
+       mapPropsToValues: () => ({
+               preset: 'Normal',
+               settings: {
+                       area: 'Vanilla',
+                       boss: 'Vanilla',
+                       doublechaos: 'false',
+                       enemy: 'Vanilla',
+                       grahm: 'BookSouls',
+                       itempool: 'Standard',
+                       kicker: 'false',
+                       levelexp: 'Vanilla',
+                       logic: 'AreaTechTiers',
+                       mapassist: 'false',
+                       nodupes: 'false',
+                       noww: 'false',
+                       palette: 'Vanilla',
+                       panther: 'Rand70Dup',
+                       reqallsouls: 'false',
+                       shopprice: 'Vanilla',
+                       shopSouls: 'Vanilla',
+                       startshop: 'Vanilla',
+                       telestart: 'false',
+                       weight: '2.5',
+               },
+       }),
+})(withTranslation()(Generate));
index 0001f01343e1b8e2f061fe98da82039d180f2c22..a092074fb4ed617df6cd650b5f5fbad7cd9eb89f 100644 (file)
@@ -4,6 +4,7 @@ import { BrowserRouter, Route, Routes } from 'react-router-dom';
 
 import Header from './Header';
 import AosFront from '../pages/AosFront';
+import AosGenerate from '../pages/AosGenerate';
 import AosSeed from '../pages/AosSeed';
 import Tracker from '../pages/AosTracker';
 import User from '../pages/User';
@@ -55,6 +56,7 @@ const App = () => {
                        <UserContext.Provider value={user}>
                                <Header doLogout={doLogout} />
                                <Routes>
+                                       <Route path="generate" element={<AosGenerate />} />
                                        <Route path="h/:hash" element={<AosSeed />} />
                                        <Route path="tracker" element={<Tracker />} />
                                        <Route path="users/:id" element={<User />} />
diff --git a/resources/js/components/pages/AosGenerate.js b/resources/js/components/pages/AosGenerate.js
new file mode 100644 (file)
index 0000000..0c27b06
--- /dev/null
@@ -0,0 +1,56 @@
+import axios from 'axios';
+import React, { useCallback, useEffect, useState } from 'react';
+
+import Generate from '../aos-generate/Generate';
+import ErrorBoundary from '../common/ErrorBoundary';
+import ErrorMessage from '../common/ErrorMessage';
+import Loading from '../common/Loading';
+import i18n from '../../i18n';
+
+const AosGenerate = () => {
+       const [error, setError] = useState(null);
+       const [loading, setLoading] = useState(true);
+       const [presets, setPresets] = useState([]);
+
+       const loadPresets = useCallback(ctrl => {
+               axios
+                       .get('/api/aos-presets', { signal: ctrl.signal })
+                       .then(response => {
+                               setError(null);
+                               setLoading(false);
+                               setPresets(response.data);
+                       })
+                       .catch(error => {
+                               setError(error);
+                               setLoading(false);
+                               setPresets([]);
+                       });
+       }, []);
+
+       useEffect(() => {
+               setLoading(true);
+               const ctrl = new AbortController();
+               loadPresets(ctrl);
+               return () => {
+                       ctrl.abort();
+               };
+       }, []);
+
+       useEffect(() => {
+               window.document.title = i18n.t('aosGenerate.heading');
+       }, [i18n.language]);
+
+       if (loading) {
+               return <Loading />;
+       }
+
+       if (error) {
+               return <ErrorMessage error={error} />;
+       }
+
+       return <ErrorBoundary>
+               <Generate presets={presets} />
+       </ErrorBoundary>;
+};
+
+export default AosGenerate;
index 61715480b4ce159a1b6c01739262c8db28d71e15..56b2d0699ca5dc9cec70a0ddade23aa2c67ed2bf 100644 (file)
@@ -55,6 +55,9 @@ export default {
                        setBaseRom: 'Base ROM auswählen',
                        tourneyDiscord: 'Turnier Discord',
                },
+               aosGenerate: {
+                       heading: 'AoSR Seed Generieren',
+               },
                aosSeeds: {
                        date: '{{ date, L LT }}',
                        fetchingPatch: 'Lade Patch',
@@ -80,6 +83,7 @@ export default {
                                AreaRequireAllSouls: 'Area alle Seelen',
                                AreaSpicy: 'Area spicy',
                                Beginner: 'Beginner',
+                               custom: 'Custom',
                                DoorAllBosses: 'Door alle Bosse',
                                DoorAllBossesEasy: 'Door alle Bosses einfach',
                                ExtraFastNormal: 'Extra schnell normal',
@@ -247,6 +251,7 @@ export default {
                        chart: 'Diagramm',
                        close: 'Schließen',
                        edit: 'Bearbeiten',
+                       generate: 'Generieren',
                        help: 'Hilfe',
                        login: 'Login',
                        logout: 'Logout',
index 32249ddad528d882d3527a6806a372f6581e1fe4..f91e63bdaa1fc3ce83146cf06ede3d9afd930496 100644 (file)
@@ -55,6 +55,9 @@ export default {
                        setBaseRom: 'Set base ROM',
                        tourneyDiscord: 'Tournament Discord',
                },
+               aosGenerate: {
+                       heading: 'Generate AoSR Seed',
+               },
                aosSeeds: {
                        date: '{{ date, L LT }}',
                        fetchingPatch: 'Fetching patch',
@@ -80,6 +83,7 @@ export default {
                                AreaRequireAllSouls: 'Area require all souls',
                                AreaSpicy: 'Area spicy',
                                Beginner: 'Beginner',
+                               custom: 'Custom',
                                DoorAllBosses: 'Door all bosses',
                                DoorAllBossesEasy: 'Door all bosses easy',
                                ExtraFastNormal: 'Extra fast normal',
@@ -247,6 +251,7 @@ export default {
                        chart: 'Chart',
                        close: 'Close',
                        edit: 'Edit',
+                       generate: 'Generate',
                        help: 'Help',
                        login: 'Login',
                        logout: 'Logout',
index ad624c3e60f2d964e76bbb3a3b6c6ef038a8478a..1b0ea84e4a065335e9e2d4247d8ba0ec0c2980ec 100644 (file)
@@ -22,6 +22,7 @@ Route::get('alttp-seed/{hash}', 'App\Http\Controllers\AlttpSeedController@byHash
 Route::post('alttp-seed/{hash}/retry', 'App\Http\Controllers\AlttpSeedController@retry');
 
 Route::post('aos-generate', 'App\Http\Controllers\AosSeedController@generate');
+Route::get('aos-presets', 'App\Http\Controllers\AosSeedController@presets');
 Route::get('aos-seed/{hash}', 'App\Http\Controllers\AosSeedController@byHash');
 Route::post('aos-seed/{hash}/retry', 'App\Http\Controllers\AosSeedController@retry');