diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..da599f4 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,12 @@ +root = true + +[*] +charset = utf-8 +indent_style = space +indent_size = 4 +end_of_line = lf +insert_final_newline = true +trim_trailing_whitespace = true + +[*.md] +trim_trailing_whitespace = false diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000..dfe0770 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,2 @@ +# Auto detect text files and perform LF normalization +* text=auto diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..98da1c8 --- /dev/null +++ b/.gitignore @@ -0,0 +1,110 @@ +# Created by https://www.toptal.com/developers/gitignore/api/macos,linux,symfony,windows,composer,visualstudiocode +# Edit at https://www.toptal.com/developers/gitignore?templates=macos,linux,symfony,windows,composer,visualstudiocode + +### Composer ### +composer.phar +/vendor/ + +# Commit your application's lock file https://getcomposer.org/doc/01-basic-usage.md#commit-your-composer-lock-file-to-version-control +# You may choose to ignore a library lock file http://getcomposer.org/doc/02-libraries.md#lock-file +composer.lock + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### Symfony ### +/var/ + +# PHPUnit +/phpunit.xml +.phpunit.result.cache + +# Build data +/build/ + +# Composer PHAR +/composer.phar + +### VisualStudioCode ### +.vscode/* +!.vscode/tasks.json +!.vscode/launch.json +*.code-workspace + +### VisualStudioCode Patch ### +# Ignore all local history of files +.history +.ionide + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# dist files/folder +*.dist +# Not ignore +!phpunit.xml.dist + +# End of https://www.toptal.com/developers/gitignore/api/macos,linux,symfony,windows,composer,visualstudiocode diff --git a/.php_cs-fixer.php b/.php_cs-fixer.php new file mode 100644 index 0000000..ac44c1e --- /dev/null +++ b/.php_cs-fixer.php @@ -0,0 +1,110 @@ +setRiskyAllowed(true) + ->setRules([ + '@DoctrineAnnotation' => true, + '@PHP70Migration' => true, + '@PHP71Migration' => true, + '@PSR2' => true, + '@Symfony' => true, + '@PHP73Migration' => true, + // Each line of multi-line DocComments must have an asterisk [PSR-5] and must be aligned with the first one. + 'align_multiline_comment' => true, + // Each element of an array must be indented exactly once. + 'array_indentation' => true, + // PHP arrays should be declared using the configured syntax. + 'array_syntax' => ['syntax' => 'short'], + // Binary operators should be surrounded by space as configured. + 'binary_operator_spaces' => ['default' => 'align_single_space_minimal'], + // An empty line feed must precede any configured statement. + 'blank_line_before_statement' => true, + // The body of each structure MUST be enclosed by braces. Braces should be properly placed. Body of braces should be properly indented. + 'braces' => ['position_after_anonymous_constructs' => 'next', 'position_after_control_structures' => 'next', 'position_after_functions_and_oop_constructs' => 'next'], + // Using `isset($var) &&` multiple times should be done in one call. + 'combine_consecutive_issets' => true, + // Calling `unset` on multiple items should be done in one call. + 'combine_consecutive_unsets' => true, + // Replace multiple nested calls of `dirname` by only one call with second `$level` parameter. Requires PHP >= 7.0. + 'combine_nested_dirname' => true, + // Remove extra spaces in a nullable typehint. + 'compact_nullable_typehint' => true, + // Equal sign in declare statement should be surrounded by spaces or not following configuration. + 'declare_equal_normalize' => ['space' => 'single'], + // Replaces `dirname(__FILE__)` expression with equivalent `__DIR__` constant. + 'dir_constant' => true, + // Replace deprecated `ereg` regular expression functions with `preg`. + 'ereg_to_preg' => true, + // Add curly braces to indirect variables to make them clear to understand. Requires PHP >= 7.0. + 'explicit_indirect_variable' => true, + // Converts implicit variables into explicit ones in double-quoted strings or heredoc syntax. + 'explicit_string_variable' => true, + // Replace core functions calls returning constants with the constants. + 'function_to_constant' => true, + // Convert `heredoc` to `nowdoc` where possible. + 'heredoc_to_nowdoc' => true, + // Ensure there is no code on the same line as the PHP open tag. + 'linebreak_after_opening_tag' => true, + // Method chaining MUST be properly indented. Method chaining with different levels of indentation is not supported. + 'method_chaining_indentation' => true, + // Replaces `intval`, `floatval`, `doubleval`, `strval` and `boolval` function calls with according type casting operator. + 'modernize_types_casting' => true, + // DocBlocks must start with two asterisks, multiline comments must start with a single asterisk, after the opening slash. Both must end with a single asterisk before the closing slash. + 'multiline_comment_opening_closing' => true, + // Forbid multi-line whitespace before the closing semicolon or move the semicolon to the new line for chained calls. + 'multiline_whitespace_before_semicolons' => ['strategy' => 'new_line_for_chained_calls'], + // Add leading `\` before function invocation to speed up resolving. + 'native_function_invocation' => true, + // Master functions shall be used instead of aliases. + 'no_alias_functions' => true, + // Replace control structure alternative syntax to use braces. + 'no_alternative_syntax' => true, + // Properties MUST not be explicitly initialized with `null` except when they have a type declaration (PHP 7.4). + 'no_null_property_initialization' => true, + // Variables must be set `null` instead of using `(unset)` casting. + 'no_unset_cast' => true, + // There should not be an empty `return` statement at the end of a function. + 'no_useless_return' => true, + // Logical NOT operators (`!`) should have leading and trailing whitespaces. + 'not_operator_with_space' => true, + // Adds or removes `?` before type declarations for parameters with a default `null` value. + 'nullable_type_declaration_for_default_null_value' => true, + // Orders the elements of classes/interfaces/traits. + 'ordered_class_elements' => true, + // Ordering `use` statements. + 'ordered_imports' => true, + // All PHPUnit test classes should be marked as internal. + 'php_unit_internal_class' => true, + // Enforce camel (or snake) case for PHPUnit test methods, following configuration. + 'php_unit_method_casing' => true, + // Adds a default `@coversNothing` annotation to PHPUnit test classes that have no `@covers*` annotation. + 'php_unit_test_class_requires_covers' => true, + // PHPDoc should contain `@param` for all params. + 'phpdoc_add_missing_param_annotation' => true, + // `@return void` and `@return null` annotations should be omitted from PHPDoc. + 'phpdoc_no_empty_return' => true, + // Annotations in PHPDoc should be ordered so that `@param` annotations come first, then `@throws` annotations, then `@return` annotations. + 'phpdoc_order' => true, + // `@var` and `@type` annotations must have type and name in the correct order. + 'phpdoc_var_annotation_correct_order' => true, + // Local, dynamic and directly referenced variables should not be assigned and directly returned by a function or method. + 'return_assignment' => true, + // Converts explicit variables in double-quoted strings and heredoc syntax from simple to complex format (`${` to `{$`). + 'simple_to_complex_string_variable' => true, + // Simplify `if` control structures that return the boolean result of their condition. + 'simplified_if_return' => true, + // A return statement wishing to return `void` should not return `null`. + 'simplified_null_return' => true, + ]) + ->setFinder( + PhpCsFixer\Finder::create() + ->exclude('vendor') + ->in(__DIR__) + ) +; diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..7c28b07 --- /dev/null +++ b/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2021, IDMarinas +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..7c7011a --- /dev/null +++ b/README.md @@ -0,0 +1,28 @@ +# LoTGD Bunde Garden Party + +Party in the Garden of all cities. + +# Install +```bash +composer require lotgd-core/bundle-garden-party +``` + +# Default configuration +```yaml +# Note: party duration is 24 hours always. +lotgd_garden_party: + # When does the part start. Valid format for DateTime object + start: null # Required, Example: '2015-01-20 use this format YYYY-MM-DD' + # How often is the party repeated? By default repeated every year + repeat: P1Y # Example: 'http://php.net/manual/en/dateinterval.construct.php for examples of format' + cake: + # Cost per level for cake + cost: 20 + # How many slices of cake can a player buy in one day? + max: 3 + drink: + # Cost per level for drink + cost: 20 + # How many party drinks can a player buy in one day? + max: 3 +``` diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..78f8eaf --- /dev/null +++ b/composer.json @@ -0,0 +1,71 @@ +{ + "name": "lotgd-core/bundle-garden-party", + "description": "Party in the Garden of all cities.", + "version": "0.1.0", + "type": "lotgd-bundle", + "license": "BSD-3-Clause", + "authors": [ + { + "name": "Iván Diaz Marinas (IDMarinas)", + "email": "35842929+idmarinas@users.noreply.github.com", + "homepage": "https://github.com/lotgd-core/bundle-garden-party", + "role": "Developer" + }, + { + "name": "Eric Stevens", + "role": "Original Idea" + } + ], + "config": { + "optimize-autoloader": true, + "preferred-install": { + "*": "dist" + }, + "process-timeout": 5000, + "sort-packages": true + }, + "support": { + "issues": "https://github.com/lotgd-core/bundle-garden-party/issues" + }, + "minimum-stability": "dev", + "prefer-stable": true, + "require": { + "php": ">=7.3", + "idmarinas/lotgd-contracts": "^0.2.0", + "symfony/dependency-injection": "^4.4|^5.0", + "symfony/framework-bundle": "^4.4|^5.0", + "symfony/http-kernel": "^4.4|^5.0", + "symfony/yaml": "^4.4|^5.0" + }, + "require-dev": { + "idmarinas/lotgd": "^6.0", + "matthiasnoback/symfony-config-test": "^4.2", + "matthiasnoback/symfony-dependency-injection-test": "^4.2", + "nyholm/symfony-bundle-test": "^1.7", + "phpunit/phpunit": "^8.5", + "symfony/phpunit-bridge": "^5.3", + "symfony/test-pack": "^1.0" + }, + "conflict": { + "idmarinas/lotgd": "<6.0" + }, + "autoload": { + "psr-4": { + "Lotgd\\Bundle\\GardenParty\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Lotgd\\Bundle\\GardenParty\\Tests\\": "tests/" + } + }, + "scripts": { + "test": "phpunit" + }, + "funding": [ + { + "type": "paypal", + "url": "https://www.paypal.me/idmarinas" + } + ] +} diff --git a/phpunit.xml.dist b/phpunit.xml.dist new file mode 100644 index 0000000..9eeba0b --- /dev/null +++ b/phpunit.xml.dist @@ -0,0 +1,54 @@ + + + + + + + + + + + + + + + + + + + ./tests + + + + + + + + + + + + + + + + + ./src + + + diff --git a/src/Controller/GardenPartyController.php b/src/Controller/GardenPartyController.php new file mode 100644 index 0000000..695df78 --- /dev/null +++ b/src/Controller/GardenPartyController.php @@ -0,0 +1,164 @@ +parameter = $parameter; + $this->translator = $translator; + $this->buffer = $buffer; + $this->settings = $settings; + $this->commentary = $commentary; + $this->response = $response; + $this->navigation = $navigation; + } + + public function cake(): Response + { + global $session; + + //- See if the party is currently running. + if ( ! $this->checkPartyRunning()) + { + return $this->redirect('gardens.php'); + } + + $cakeToday = get_module_pref('cake_today', 'bundle_garden_party'); + $cost = $this->parameter->get('lotgd_bundle.garden_party.cake.cost') * $session['user']['level']; + + $cake = $this->translator->trans('consumption.cake.name', [], self::TRANSLATION_DOMAIN); + + if ($session['user']['gold'] >= $cost) + { + $session['user']['gold'] -= $cost; + + set_module_pref('cake_today', $cakeToday + 1, 'bundle_garden_party'); + + $this->buyedType($cake, 'cake'); + + return redirect('gardens.php'); + } + + return $this->render('@LotgdGardenParty/cake.html.twig', $this->notHaveGold($cake)); + } + + public function drink(): Response + { + global $session; + + //- See if the party is currently running. + if ( ! $this->checkPartyRunning()) + { + return $this->redirect('gardens.php'); + } + + $drinksToday = get_module_pref('drinks_today', 'bundle_garden_party'); + $cost = $this->parameter->get('lotgd_bundle.garden_party.drink.cost') * $session['user']['level']; + + $drink = $this->translator->trans('consumption.drink.name', [], self::TRANSLATION_DOMAIN); + + if ($session['user']['gold'] >= $cost) + { + $session['user']['gold'] -= $cost; + + set_module_pref('drinks_today', $drinksToday + 1, 'bundle_garden_party'); + + $this->buyedType($drink, 'drink'); + + return redirect('gardens.php'); + } + + return $this->render('@LotgdGardenParty/drink.html.twig', $this->notHaveGold($drink)); + } + + private function buyedType(string $name, string $type): void + { + $this->commentary->saveComment([ + 'section' => 'gardens', + 'comment' => ': '.$this->translator->trans("consumption.{$type}.mote", [], self::TRANSLATION_DOMAIN), + ]); + + $buff = [ + 'name' => $name, + 'atkmod' => 1.05, + 'roundmsg' => $this->translator->trans("buff.msg.{$type}", ['name' => $name], self::TRANSLATION_DOMAIN), + 'rounds' => 20, + 'schema' => self::TRANSLATION_DOMAIN, + ]; + + $this->buffer->applyBuff("bundle_garden_party.{$type}", $buff); + + $buff = [ + 'name' => $this->translator->trans('buff.name.miss', [], self::TRANSLATION_DOMAIN), + 'minioncount' => 1, + 'maxbadguydamage' => 0, + 'minbadguydamage' => 0, + 'effectnodmgmsg' => $this->translator->trans('buff.msg.miss', [], self::TRANSLATION_DOMAIN), + 'rounds' => -1, + 'schema' => self::TRANSLATION_DOMAIN, + ]; + + $this->buffer->applyBuff('bundle_garden_party', $buff); + } + + private function notHaveGold(string $name): array + { + $this->response->pageTitle('title', [ + 'barman' => $this->settings->getSetting('barkeep', '`tCedrik`0'), + 'clothes' => $this->translator->trans('section.hook.gardens.party.barman.clothes', [], self::TRANSLATION_DOMAIN), + ], self::TRANSLATION_DOMAIN); + + $this->navigation->addNav('navigation.nav.return', 'gardens.php', ['textDomain' => self::TRANSLATION_DOMAIN]); + + return [ + 'translation_domain' => self::TRANSLATION_DOMAIN, + 'buy_type' => $name, + 'barman' => $this->settings->getSetting('barkeep', '`tCedrik`0'), + 'party_type' => $this->translator->trans('party.type', [], self::TRANSLATION_DOMAIN), + ]; + } +} diff --git a/src/DependencyInjection/Configuration.php b/src/DependencyInjection/Configuration.php new file mode 100644 index 0000000..e221a5e --- /dev/null +++ b/src/DependencyInjection/Configuration.php @@ -0,0 +1,110 @@ +getRootNode() + ->addDefaultsIfNotSet() + ->info('Note: party duration is 24 hours always.') + ->children() + ->scalarNode('start') + ->defaultValue(null) + ->isRequired() + ->cannotBeEmpty() + ->validate() + ->ifTrue(function ($value) + { + try + { + (new DateTime($value)); + } + catch (\Throwable $th) + { + return true; + } + + return false; + }) + ->thenInvalid('%s not is a valid date for DateTime object.') + ->end() + ->info('When does the part start. Valid format for DateTime object') + ->example('2015-01-20 use this format YYYY-MM-DD') + ->end() + ->scalarNode('repeat') + ->defaultValue('P1Y') + ->info('How often is the party repeated? By default repeated every year') + ->example('http://php.net/manual/en/dateinterval.construct.php for examples of format') + ->validate() + ->ifTrue(function ($value) + { + try + { + (new DateInterval($value)); + } + catch (\Throwable $th) + { + return true; + } + + return false; + }) + ->thenInvalid('%s cannot be parsed as an interval.') + ->end() + ->end() + ->arrayNode('cake') + ->addDefaultsIfNotSet() + ->children() + ->integerNode('cost') + ->defaultValue(20) + ->min(0) + ->info('Cost per level for cake') + ->end() + ->integerNode('max') + ->defaultValue(3) + ->min(1) + ->info('How many slices of cake can a player buy in one day?') + ->end() + ->end() + ->end() + ->arrayNode('drink') + ->addDefaultsIfNotSet() + ->children() + ->integerNode('cost') + ->defaultValue(20) + ->min(0) + ->info('Cost per level for drink') + ->end() + ->integerNode('max') + ->defaultValue(3) + ->min(1) + ->info('How many party drinks can a player buy in one day?') + ->end() + ->end() + ->end() + ->end() + ; + + return $treeBuilder; + } +} diff --git a/src/DependencyInjection/LotgdGardenPartyExtension.php b/src/DependencyInjection/LotgdGardenPartyExtension.php new file mode 100644 index 0000000..2dc3f37 --- /dev/null +++ b/src/DependencyInjection/LotgdGardenPartyExtension.php @@ -0,0 +1,38 @@ +load('services.php'); + + $container->setParameter('lotgd_bundle.garden_party.start', $mergedConfig['start']); + $container->setParameter('lotgd_bundle.garden_party.repeat', $mergedConfig['repeat']); + + $container->setParameter('lotgd_bundle.garden_party.cake.cost', $mergedConfig['cake']['cost']); + $container->setParameter('lotgd_bundle.garden_party.cake.max', $mergedConfig['cake']['max']); + + $container->setParameter('lotgd_bundle.garden_party.drink.cost', $mergedConfig['drink']['cost']); + $container->setParameter('lotgd_bundle.garden_party.drink.max', $mergedConfig['drink']['max']); + } +} diff --git a/src/EventSubscriber/GardenPartySubscriber.php b/src/EventSubscriber/GardenPartySubscriber.php new file mode 100644 index 0000000..c0812d9 --- /dev/null +++ b/src/EventSubscriber/GardenPartySubscriber.php @@ -0,0 +1,112 @@ +parameter = $parameter; + $this->setting = $setting; + $this->navigation = $navigation; + $this->translator = $translator; + } + + public function newday(): void + { + set_module_pref('cake_today', 0, 'bundle_garden_party'); + set_module_pref('drinks_today', 0, 'bundle_garden_party'); + } + + public function garden(GenericEvent $event): void + { + global $session; + + //-- See if the party is currently running. + if ( ! $this->checkPartyRunning()) + { + return; + } + + $this->navigation->setTextDomain(self::TRANSLATION_DOMAIN); + + $params = [ + 'translation_domain' => self::TRANSLATION_DOMAIN, + 'barman' => $this->setting->getSetting('barkeep', '`tCedrik`0'), + ]; + + $args['includeTemplatesPost']['@LotgdGardenParty/garden_party_info.html.twig'] = $params; + + $this->navigation->addHeader('navigation.category.party'); + + $cakeToday = get_module_pref('cake_today', 'bundle_garden_party'); + $drinkstoday = get_module_pref('drinks_today', 'bundle_garden_party'); + $cakeCost = $this->parameter->get('lotgd_bundle.garden_party.cake.cost') * $session['user']['level']; + $drinkCost = $this->parameter->get('lotgd_bundle.garden_party.drink.cost') * $session['user']['level']; + + if ($cakeToday < $this->parameter->get('lotgd_bundle.garden_party.cake.max') && $session['user']['gold'] >= $cakeCost) + { + $cake = $this->translator->trans('consumption.cake.name', [], self::TRANSLATION_DOMAIN); + $this->navigation->addNav('navigation.nav.consumption', $this->getModuleUrl('cake'), [ + 'params' => ['name' => $cake, 'cost' => $cakeCost], + ]); + } + + if ($drinkstoday < $this->parameter->get('lotgd_bundle.garden_party.drink.max') && $session['user']['gold'] >= $drinkCost) + { + $drink = $this->translator->trans('consumption.drink.name', [], self::TRANSLATION_DOMAIN); + $this->navigation->addNav('navigation.nav.consumption', $this->getModuleUrl('drink'), [ + 'params' => ['name' => $drink, 'cost' => $drinkCost], + ]); + } + + $this->navigation->setTextDomain(); + } + + /** + * @return array + */ + public static function getSubscribedEvents(): array + { + return [ + Core::NEWDAY => 'newday', + Events::PAGE_GARDEN_POST => 'garden', + ]; + } +} diff --git a/src/LotgdGardenPartyBundle.php b/src/LotgdGardenPartyBundle.php new file mode 100644 index 0000000..4e7a948 --- /dev/null +++ b/src/LotgdGardenPartyBundle.php @@ -0,0 +1,51 @@ + 'What will display in the conversation when you order drink?|takes a big swig of Grape Soda.', + + /** + * @inheritDoc + */ + public function getLotgdVersion(): string + { + return '0.1.0'; + } + + /** + * @inheritDoc + */ + public function getLotgdIcon(): ?string + { + return 'party'; + } + + /** + * @inheritDoc + */ + public function getLotgdDescription(): string + { + return 'Party in the Garden of all cities.'; + } +} diff --git a/src/Pattern/CheckPartyRunningTrait.php b/src/Pattern/CheckPartyRunningTrait.php new file mode 100644 index 0000000..26b36f6 --- /dev/null +++ b/src/Pattern/CheckPartyRunningTrait.php @@ -0,0 +1,35 @@ +parameter->get('lotgd_bundle.garden_party.repeat')); + $start = new \DateTime($this->parameter->get('lotgd_bundle.garden_party.start')); + $end = new \DateTime('now'); + + $period = new \DatePeriod($start, $interval, $end); + + $periodArray = iterator_to_array($period); + $lastPeriod = end($periodArray); + + return (bool) (strtotime($lastPeriod->format('Y-m-d')) == strtotime($end->format('Y-m-d'))); + } + +} diff --git a/src/Pattern/ModuleUrlTrait.php b/src/Pattern/ModuleUrlTrait.php new file mode 100644 index 0000000..34030a0 --- /dev/null +++ b/src/Pattern/ModuleUrlTrait.php @@ -0,0 +1,24 @@ +services() + //-- Controllers + ->set(GardenPartyController::class) + ->autoconfigure() + ->args([ + new ReferenceConfigurator('parameter_bag'), + new ReferenceConfigurator('translator'), + new ReferenceConfigurator(Buffer::class), + new ReferenceConfigurator('lotgd_core.settings'), + new ReferenceConfigurator(Commentary::class), + new ReferenceConfigurator(Response::class), + new ReferenceConfigurator(Navigation::class) + ]) + ->call('setContainer', [ + new ReferenceConfigurator('service_container') + ]) + ->tag('controller.service_arguments') + + //-- Event Subscribers + ->set(GardenPartySubscriber::class) + ->args([ + new ReferenceConfigurator('parameter_bag'), + new ReferenceConfigurator('lotgd_core.settings'), + new ReferenceConfigurator(Navigation::class), + new ReferenceConfigurator('translator') + ]) + ->tag('kernel.event_subscriber') + ; +}; diff --git a/src/Resources/translations/bundle_garden_party+intl-icu.en.yaml b/src/Resources/translations/bundle_garden_party+intl-icu.en.yaml new file mode 100644 index 0000000..24a7df8 --- /dev/null +++ b/src/Resources/translations/bundle_garden_party+intl-icu.en.yaml @@ -0,0 +1,39 @@ +title: '{barman} in {clothes}' + +section: + gardens: + time: "There's a party going on! It's a {name}!" + inn: '{barman} is here, wearing (of all things) {clothes}, serving food and drinks.`n`n' + run: + paragraph: > + You wander over to where {barman} is standing in the gardens, and ask to buy {buy_type}, but he tells you that you don't have enough gold to buy it. + You think it's a little odd that you're being charged for food and drinks at {party_type}, but ignore this, eager to get back to the revelry. + +party: + type: birthday party for MightyE + barman.clothes: a Hawaiian shirt + miss: + item: 'a bogus item' + comment: 'mutters something that you cannot make out.' + +consumption: + cake: + name: Birthday Cake + mote: pigs out and takes a huge bite of Birthday Cake. + drink: + name: Grape Soda + mote: takes a big swig of Grape Soda. + +buff: + name.miss: 'Party Fever' + msg: + cake: '`b{name}´b increased your defense.' + drink: '`b{name}´b increased your attack.' + miss: 'In the distance you hear the sounds of "Happy Birthday" being sung.' + +navigation: + category: + party: 'Party Treats!' + nav: + consumption: '{name} (`^{cost,number} gold`0)' + return: 'Back to the party' diff --git a/src/Resources/views/cake.html.twig b/src/Resources/views/cake.html.twig new file mode 100644 index 0000000..7efbabc --- /dev/null +++ b/src/Resources/views/cake.html.twig @@ -0,0 +1,3 @@ +{% trans_default_domain translation_domain %} + +{{ 'section.run.paragraph'|trans(_context)|colorize }} diff --git a/src/Resources/views/drink.html.twig b/src/Resources/views/drink.html.twig new file mode 100644 index 0000000..7efbabc --- /dev/null +++ b/src/Resources/views/drink.html.twig @@ -0,0 +1,3 @@ +{% trans_default_domain translation_domain %} + +{{ 'section.run.paragraph'|trans(_context)|colorize }} diff --git a/src/Resources/views/garden_party_info.html.twig b/src/Resources/views/garden_party_info.html.twig new file mode 100644 index 0000000..e8df447 --- /dev/null +++ b/src/Resources/views/garden_party_info.html.twig @@ -0,0 +1,4 @@ +{% trans_default_domain translation_domain %} + +{{ 'section.gardens.time'|trans({'name': 'party.type'|trans })|colorize }} +{{ 'section.gardens.inn'|trans({'clothes': 'party.barman.clothes'|trans })|colorize }}