Merge branch 'doc' into 'master'
Doc Closes #53 See merge request ynerant/squirrel-battle!55
This commit is contained in:
commit
ea58d5b426
|
@ -3,21 +3,16 @@ stages:
|
||||||
- quality-assurance
|
- quality-assurance
|
||||||
- build
|
- build
|
||||||
|
|
||||||
py37:
|
|
||||||
stage: test
|
|
||||||
image: python:3.7-alpine
|
|
||||||
before_script:
|
|
||||||
- apk add --no-cache gettext
|
|
||||||
- pip install tox
|
|
||||||
script: tox -e py3
|
|
||||||
|
|
||||||
py38:
|
py310:
|
||||||
stage: test
|
stage: test
|
||||||
image: python:3.8-alpine
|
image: python:rc-alpine
|
||||||
before_script:
|
before_script:
|
||||||
- apk add --no-cache gettext
|
- apk add --no-cache gettext
|
||||||
- pip install tox
|
- pip install tox
|
||||||
script: tox -e py3
|
script: tox -e py3
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
|
||||||
py39:
|
py39:
|
||||||
|
@ -28,6 +23,38 @@ py39:
|
||||||
- pip install tox
|
- pip install tox
|
||||||
script: tox -e py3
|
script: tox -e py3
|
||||||
|
|
||||||
|
|
||||||
|
py38:
|
||||||
|
stage: test
|
||||||
|
image: python:3.8-alpine
|
||||||
|
before_script:
|
||||||
|
- apk add --no-cache gettext
|
||||||
|
- pip install tox
|
||||||
|
script: tox -e py3
|
||||||
|
|
||||||
|
|
||||||
|
py37:
|
||||||
|
stage: test
|
||||||
|
image: python:3.7-alpine
|
||||||
|
before_script:
|
||||||
|
- apk add --no-cache gettext
|
||||||
|
- pip install tox
|
||||||
|
script: tox -e py3
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
|
||||||
|
py36:
|
||||||
|
stage: test
|
||||||
|
image: python:3.6-alpine
|
||||||
|
before_script:
|
||||||
|
- apk add --no-cache gettext
|
||||||
|
- pip install tox
|
||||||
|
script: tox -e py3
|
||||||
|
only:
|
||||||
|
- master
|
||||||
|
|
||||||
|
|
||||||
linters:
|
linters:
|
||||||
stage: quality-assurance
|
stage: quality-assurance
|
||||||
image: python:3-alpine
|
image: python:3-alpine
|
||||||
|
@ -36,11 +63,15 @@ linters:
|
||||||
script: tox -e linters
|
script: tox -e linters
|
||||||
allow_failure: true
|
allow_failure: true
|
||||||
|
|
||||||
|
|
||||||
build-deb:
|
build-deb:
|
||||||
image: debian:buster-slim
|
image: debian:buster-slim
|
||||||
stage: build
|
stage: build
|
||||||
before_script:
|
before_script:
|
||||||
- apt-get update && apt-get -y --no-install-recommends install build-essential debmake dh-python debhelper gettext python3-all python3-setuptools
|
- >
|
||||||
|
apt-get update && apt-get -y --no-install-recommends install
|
||||||
|
build-essential debmake dh-python debhelper gettext python3-all
|
||||||
|
python3-setuptools
|
||||||
script:
|
script:
|
||||||
- dpkg-buildpackage
|
- dpkg-buildpackage
|
||||||
- mkdir build && cp ../*.deb build/
|
- mkdir build && cp ../*.deb build/
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
[![pipeline status](https://gitlab.crans.org/ynerant/squirrel-battle/badges/master/pipeline.svg)](https://gitlab.crans.org/ynerant/squirrel-battle/-/commits/master)
|
[![pipeline status](https://gitlab.crans.org/ynerant/squirrel-battle/badges/master/pipeline.svg)](https://gitlab.crans.org/ynerant/squirrel-battle/-/commits/master)
|
||||||
[![coverage report](https://gitlab.crans.org/ynerant/squirrel-battle/badges/master/coverage.svg)](https://gitlab.crans.org/ynerant/squirrel-battle/-/commits/master)
|
[![coverage report](https://gitlab.crans.org/ynerant/squirrel-battle/badges/master/coverage.svg)](https://gitlab.crans.org/ynerant/squirrel-battle/-/commits/master)
|
||||||
[![Documentation Status](https://readthedocs.org/projects/squirrel-battle/badge/?version=latest)](https://squirrel-battle.readthedocs.io/fr/latest/?badge=latest)
|
[![Documentation Status](https://readthedocs.org/projects/squirrel-battle/badge/?version=latest)](https://squirrel-battle.readthedocs.io/fr/latest/?badge=latest)
|
||||||
|
[![Supported Python versions](https://img.shields.io/pypi/pyversions/squirrel-battle)](https://pypi.org/project/squirrel-battle/)
|
||||||
[![PyPI](https://img.shields.io/pypi/v/squirrel-battle)](https://pypi.org/project/squirrel-battle/)
|
[![PyPI](https://img.shields.io/pypi/v/squirrel-battle)](https://pypi.org/project/squirrel-battle/)
|
||||||
[![PYPI downloads](https://img.shields.io/pypi/dm/squirrel-battle)](https://pypi.org/project/squirrel-battle/)
|
[![PYPI downloads](https://img.shields.io/pypi/dm/squirrel-battle)](https://pypi.org/project/squirrel-battle/)
|
||||||
[![AUR version](https://img.shields.io/aur/version/python-squirrel-battle)](https://aur.archlinux.org/packages/python-squirrel-battle/)
|
[![AUR version](https://img.shields.io/aur/version/python-squirrel-battle)](https://aur.archlinux.org/packages/python-squirrel-battle/)
|
||||||
|
|
|
@ -275,7 +275,7 @@ Construction du paquet Debian
|
||||||
-----------------------------
|
-----------------------------
|
||||||
|
|
||||||
Structure du paquet
|
Structure du paquet
|
||||||
-------------------
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
L'ensemble des instructions pour construire le paquet Debian est situé dans le
|
L'ensemble des instructions pour construire le paquet Debian est situé dans le
|
||||||
dossier ``debian/``.
|
dossier ``debian/``.
|
||||||
|
@ -292,14 +292,14 @@ Le paquet ``fonts-noto-color-emoji`` est en dépendance pour le bon affichage
|
||||||
des émojis.
|
des émojis.
|
||||||
|
|
||||||
Mettre à jour le paquet
|
Mettre à jour le paquet
|
||||||
-----------------------
|
~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Pour changer la version du paquet, il faut ajouter des lignes dans le fichier
|
Pour changer la version du paquet, il faut ajouter des lignes dans le fichier
|
||||||
``changelog``.
|
``changelog``.
|
||||||
|
|
||||||
|
|
||||||
Construire le paquet
|
Construire le paquet
|
||||||
--------------------
|
~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
Il faut partir d'une installation de Debian.
|
Il faut partir d'une installation de Debian.
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Affichage de l'historique
|
Affichage de l'historique
|
||||||
=========================
|
=========================
|
||||||
|
|
||||||
Pas encore documenté.
|
L'historique des actions est affiché en bas de l'écran. À chaque action d'une entité, comme frapper quelqu'un, ou lorsque le joueur parle à une entité, cela s'affiche dans l'historique.
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
Affichage de la carte
|
Affichage de la carte
|
||||||
=====================
|
=====================
|
||||||
|
|
||||||
Pas encore documenté.
|
La carte s'affiche dans la partie en haut à gauche de l'écran, sur la plus grande partie de l'écran. On affiche les tuiles une par une, selon le texture pack sélectionné. La map est actualisée à chaque action d'une entité.
|
||||||
|
|
||||||
|
L'afffichage de la carte suit les déplacements du joueur.
|
||||||
|
|
|
@ -1,4 +1,14 @@
|
||||||
Affichage des menus
|
Affichage des menus
|
||||||
===================
|
===================
|
||||||
|
|
||||||
Pas encore documenté.
|
Les menus sont affichés dans une boîte. On peut naviguer dedans avec les flèches haut et bas,
|
||||||
|
et valider avec la touche entrée.
|
||||||
|
|
||||||
|
Il y a plusieurs menus dans le jeu :
|
||||||
|
|
||||||
|
* Le main menu, qui s'affiche au lancement du jeu.
|
||||||
|
* Le menu des paramètres : si on sélectionne un choix de touche et qu'on appuie sur entrée, on peut ensuite appuyer sur une touche pour remplacer la touche utilisée.
|
||||||
|
* Le menu des crédits : ce menu fonctionne avec la souris. En cliquant on affiche une image.
|
||||||
|
* Le menu d'inventaire : dans l'inventaire, on peut utiliser les touches pour utiliser un item ou l'équiper...
|
||||||
|
* Le menu de vente : on peut utiliser les touches gauche et droite pour switcher entre l'inventaire du joueur et celui du marchand.
|
||||||
|
* Menu des warnings : Pas vraiment un menu, mais affiche juste un message dans une petite boite pour prévenir le joueur que quelquechose ne va pas.
|
||||||
|
|
|
@ -1,4 +1,26 @@
|
||||||
Affichage des statistiques
|
Affichage des statistiques
|
||||||
==========================
|
==========================
|
||||||
|
|
||||||
Pas encore documenté.
|
.. _Hazel: ../index.html
|
||||||
|
|
||||||
|
Les statistiques du joueur sont affichées en haut à droite de l'écran
|
||||||
|
et séparées du reste de l'affichage par une barre verticale.
|
||||||
|
|
||||||
|
Les informations affichées sont :
|
||||||
|
|
||||||
|
* **LVL** - le niveau du joueur
|
||||||
|
* **EXP** - la quantité d'expérience que le joueur a gagné et combien il lui en faut avant le prochain niveau.
|
||||||
|
* **HP** - la quantité de vie que le joueur a actuellement et combien il peut en avoir au maximum.
|
||||||
|
* **STR** - la force du joueur.
|
||||||
|
* **INT** - l'intelligence du joueur.
|
||||||
|
* **CHR** - le charisme du joueur.
|
||||||
|
* **DEX** - la dextérité du joueur.
|
||||||
|
* **CON** - la constitution du joueur.
|
||||||
|
* **CRI** - le pourcentage de chance de coup critique.
|
||||||
|
* **Inventory** - le contenu de l'inventaire du joueur.
|
||||||
|
* **Equipped main** - l'objet équipé dans la main principale.
|
||||||
|
* **Equipped secondary** - l'objet équipé dans la main secondaire.
|
||||||
|
* **Equipped armor** - le plastron porté par le joueur.
|
||||||
|
* **Equipped helmet** - le casque porté par le joueur.
|
||||||
|
* **Hazel** - le nombre d'Hazel_ que le joueur possède.
|
||||||
|
* **Vous êtes mort** - Éventuellement, si le joueur est mort.
|
|
@ -0,0 +1,70 @@
|
||||||
|
Entités pacifiques
|
||||||
|
==================
|
||||||
|
|
||||||
|
.. _`entité attaquante`: index.html#entites-attaquantes
|
||||||
|
.. _`pack de textures`: ../texture-pack.html
|
||||||
|
|
||||||
|
Chaque entité pacifique est en particulier une `entité attaquante`_,
|
||||||
|
et hérite donc de ses attributs, et peut alors être attaquée.
|
||||||
|
Ils sont cependant non-hostiles.
|
||||||
|
|
||||||
|
Il est possible d'interagir avec ces entités. En s'approchant d'elles, en
|
||||||
|
appuyant sur la touche ``T`` suivie de la direction où regarder, un échange
|
||||||
|
débute.
|
||||||
|
|
||||||
|
Si l'on s'adresse à un marchand, on devrait voir à l'écran l'inventaire du joueur
|
||||||
|
et l'inventaire du marchand. Les flèches haut et bas permettent de sélectionner
|
||||||
|
un objet, les touches droite et gauche de passer d'un inventaire à l'autre, et la
|
||||||
|
touche entrée valide l'action.
|
||||||
|
|
||||||
|
On dénombre actuellement 3 types d'entités pacifiques :
|
||||||
|
|
||||||
|
Tournesol
|
||||||
|
---------
|
||||||
|
|
||||||
|
Son nom est fixé à `sunflower`. Il a par défaut une **15** points de vie.
|
||||||
|
|
||||||
|
Interagir avec un tournesol n'a pas de réel intérêt, si ce n'est déclencher
|
||||||
|
le « pouvoir des fleurs !! » ou bien savoir que « le soleil est chaud
|
||||||
|
aujourd'hui ».
|
||||||
|
|
||||||
|
Dans le `pack de textures`_ ASCII, il est représenté par le caractère ``I``.
|
||||||
|
|
||||||
|
Dans le `pack de textures`_ écureuil, il est représenté par l'émoji ``🌻``.
|
||||||
|
|
||||||
|
|
||||||
|
Marchand
|
||||||
|
--------
|
||||||
|
|
||||||
|
Son nom est fixé à `merchant`. Il a par défaut **5** points de vie.
|
||||||
|
|
||||||
|
En interagissant avec un marchand, il est possible de lui acheter et de lui
|
||||||
|
vendre différents objets contre des Hazels, la monnaie du jeu.
|
||||||
|
Les prix sont fixés :
|
||||||
|
|
||||||
|
* Bombe : 4 Hazels
|
||||||
|
* Coeur : 3 Hazels
|
||||||
|
* Potion d'arrachage de corps : 14 Hazels
|
||||||
|
* Épée : 20 Hazels
|
||||||
|
* Bouclier : 16 Hazels
|
||||||
|
* Casque : 18 Hazels
|
||||||
|
* Plastron : 30 Hazels
|
||||||
|
|
||||||
|
Le marchand commence avec 75 Hazels en sa possession, contre 42 pour le joueur.
|
||||||
|
|
||||||
|
Dans le `pack de textures`_ ASCII, il est représenté par le caractère ``M``.
|
||||||
|
|
||||||
|
Dans le `pack de textures`_ écureuil, il est représenté par l'émoji ``🦜``.
|
||||||
|
|
||||||
|
Trompette
|
||||||
|
---------
|
||||||
|
|
||||||
|
Son nom est fixé à 'trumpet'. Une trompette est un familier, c'est à dire que
|
||||||
|
c'est une entité attaquante qui suit globalement le joueurs et attaque les monstres
|
||||||
|
qui se rapprochent trop du joueur.
|
||||||
|
|
||||||
|
Elle a 20 point de vie et une attaque de 3.
|
||||||
|
|
||||||
|
Dans le `pack de textures`_ ASCII, elle est représentée par le caractère ``/``.
|
||||||
|
|
||||||
|
Dans le `pack de textures`_ écureuil, elle est représentée par l'émoji ``🎺``.
|
|
@ -7,6 +7,7 @@ Entités
|
||||||
|
|
||||||
player
|
player
|
||||||
monsters
|
monsters
|
||||||
|
friendly
|
||||||
items
|
items
|
||||||
|
|
||||||
Entité
|
Entité
|
||||||
|
@ -38,11 +39,12 @@ Entité attaquante
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
.. _monstre: monsters.html
|
.. _monstre: monsters.html
|
||||||
|
.. _entité pacifique: friendly.html
|
||||||
.. _joueur: player.html
|
.. _joueur: player.html
|
||||||
|
|
||||||
Une entité attaquante (``FightingEntity``) est un type d'entités représentant
|
Une entité attaquante (``FightingEntity``) est un type d'entités représentant
|
||||||
les personnages présents sur la carte, pouvant alors se battre. Ce peut être
|
les personnages présents sur la carte, pouvant alors se battre. Ce peut être
|
||||||
un monstre_ ou bien le joueur_.
|
un monstre_, une `entité pacifique`_ ou bien le joueur_.
|
||||||
|
|
||||||
Elles disposent toutes, en plus des paramètres d'entité, des attributs suivants :
|
Elles disposent toutes, en plus des paramètres d'entité, des attributs suivants :
|
||||||
|
|
||||||
|
@ -77,3 +79,14 @@ en-dessous de 0 point de vie. À ce moment-là, l'entité est retirée de la car
|
||||||
|
|
||||||
Lorsqu'une entité en frappe une autre, celle-ci inflige autant de dégâts qu'elle
|
Lorsqu'une entité en frappe une autre, celle-ci inflige autant de dégâts qu'elle
|
||||||
n'a de force, et autant de points de vie sont perdus.
|
n'a de force, et autant de points de vie sont perdus.
|
||||||
|
|
||||||
|
|
||||||
|
Entité pacifique
|
||||||
|
----------------
|
||||||
|
|
||||||
|
Une entité pacifique (``FriendlyEntity``) est un cas particulier d'entité
|
||||||
|
attaquante. Contrairement aux montres, elles ne peuvent pas attaquer le joueur.
|
||||||
|
|
||||||
|
On peut parler à une entité pacifique en appuyant sur la touche ``T`` puis en
|
||||||
|
appuyant sur la direction dans laquelle on veut parler à l'entité.
|
||||||
|
|
||||||
|
|
|
@ -19,7 +19,7 @@ Un objet dispose de deux paramètres :
|
||||||
Si l'objet est dans l'inventaire, renvoie son propriétaire.
|
Si l'objet est dans l'inventaire, renvoie son propriétaire.
|
||||||
|
|
||||||
|
|
||||||
Deux types d'objets sont pour l'instant présents :
|
Il y a plusieurs types d'objets :
|
||||||
|
|
||||||
|
|
||||||
Bombe
|
Bombe
|
||||||
|
@ -28,23 +28,94 @@ Bombe
|
||||||
.. _entités attaquantes: index.html#entite-attaquante
|
.. _entités attaquantes: index.html#entite-attaquante
|
||||||
|
|
||||||
Une bombe est un objet que l'on peut ramasser. Une fois ramassée, elle est placée
|
Une bombe est un objet que l'on peut ramasser. Une fois ramassée, elle est placée
|
||||||
dans l'inventaire. Le joueur peut ensuite lâcher la bombe, qui fera alors
|
dans l'inventaire. Le joueur peut ensuite utiliser la bombe, via l'inventaire
|
||||||
3 dégâts à toutes les `entités attaquantes`_ situées à moins de une case.
|
ou après l'avoir équipée, qui fera alors 3 dégâts à toutes les
|
||||||
|
`entités attaquantes`_ situées à moins de trois cases au bout de 4 ticks de jeu.
|
||||||
|
|
||||||
Elle est représentée dans le `pack de textures`_ ASCII par le caractère ``o``
|
Elle est représentée dans le `pack de textures`_ ASCII par le caractère ``o``
|
||||||
et dans le `pack de textures`_ écureuil par l'émoji ``💣``.
|
et dans le `pack de textures`_ écureuil par l'émoji ``💣``. Lors de l'explosion,
|
||||||
|
la bombe est remplacée par un symbole ``%`` ou l'émoji ``💥`` selon le pack de
|
||||||
|
textures utilisé.
|
||||||
|
|
||||||
.. note::
|
La bombe coûte 4 Hazels auprès des marchands.
|
||||||
|
|
||||||
La gestion de l'inventaire n'ayant pas encore été implémentée, il n'est à
|
|
||||||
l'heure actuelle pas possible de lancer une bombe.
|
|
||||||
|
|
||||||
|
|
||||||
Cœur
|
Cœur
|
||||||
----
|
----
|
||||||
|
|
||||||
Une cœur est un objet que l'on ne peut pas ramasser. Dès que le joueur s'en
|
Un cœur est un objet que l'on ne peut pas ramasser. Dès que le joueur s'en
|
||||||
approche, il est régénéré automatiquement de 3 points de vie, et le cœur disparaît.
|
approche ou qu'il l'achète auprès d'un marchand, il est régénéré automatiquement
|
||||||
|
de 3 points de vie, et le cœur disparaît.
|
||||||
|
|
||||||
Elle est représentée dans le `pack de textures`_ ASCII par le caractère ``❤``
|
Il est représenté dans le `pack de textures`_ ASCII par le caractère ``❤``
|
||||||
et dans le `pack de textures`_ écureuil par l'émoji ``💜``.
|
et dans le `pack de textures`_ écureuil par l'émoji ``💜``.
|
||||||
|
|
||||||
|
Le cœur coûte 3 Hazels auprès des marchands.
|
||||||
|
|
||||||
|
|
||||||
|
Potion d'arrachage de corps
|
||||||
|
---------------------------
|
||||||
|
|
||||||
|
Cette potion permet, une fois utilisée, d'échanger toutes ses caractéristiques
|
||||||
|
avec une autre entité aléatoire sur la carte. Cela inclut la force, la position,
|
||||||
|
l'icône, ...
|
||||||
|
|
||||||
|
Elle est représentée par les caractères ``I`` et ``🔀``
|
||||||
|
|
||||||
|
Cette potion coûte 14 Hazels auprès des marchands.
|
||||||
|
|
||||||
|
|
||||||
|
Épée
|
||||||
|
----
|
||||||
|
|
||||||
|
L'épée est un objet que l'on peut trouver uniquement par achat auprès d'un
|
||||||
|
marchand pour le coût de 20 Hazels. Une fois équipée, l'épée ajoute 3 de force
|
||||||
|
à son porteur.
|
||||||
|
|
||||||
|
Elle est représentée par les caractères ``†`` et ``🗡️``.
|
||||||
|
|
||||||
|
|
||||||
|
Bouclier
|
||||||
|
--------
|
||||||
|
|
||||||
|
Le bouclier est un objet que l'on peut trouver uniquement par achat auprès d'un
|
||||||
|
marchand pour le coût de 16 Hazels. Il s'équippe dans la main secondaire.
|
||||||
|
Une fois équipé, le bouclier ajoute 1 de
|
||||||
|
constitution à son porteur, lui permettant de parer mieux les coups.
|
||||||
|
|
||||||
|
Il est représenté par les caractères ``D`` et ``🛡️``.
|
||||||
|
|
||||||
|
Casque
|
||||||
|
------
|
||||||
|
|
||||||
|
Le casque est un objet que l'on peut trouver uniquement par achat auprès d'un
|
||||||
|
marchand pour le coût de 18 Hazels. Il s'équippe sur la tête.
|
||||||
|
Une fois équipé, le casque ajoute 2 de
|
||||||
|
constitution à son porteur, lui permettant de prendre moins de dêgats.
|
||||||
|
|
||||||
|
Il est représenté par les caractères ``0`` et ``⛑️``.
|
||||||
|
|
||||||
|
Plastron
|
||||||
|
--------
|
||||||
|
|
||||||
|
Le plastron est un objet que l'on peut trouver uniquement par achat auprès d'un
|
||||||
|
marchand pour le coût de 30 Hazels. Il s'équippe sur le corps.
|
||||||
|
Une fois équipé, le casque ajoute 4 de
|
||||||
|
constitution à son porteur, lui permettant de prendre moins de dêgats.
|
||||||
|
|
||||||
|
Il est représenté par les caractères ``(`` et ``🦺``.
|
||||||
|
|
||||||
|
Anneau
|
||||||
|
------
|
||||||
|
|
||||||
|
L'anneau est un objet que l'on peut trouver uniquement par achat auprès d'un
|
||||||
|
marchand. Il s'équippe sur la main secondaire.
|
||||||
|
Une fois équipé, l'anneau ajoute un bonus à une ou plusieurs statistiques du
|
||||||
|
joueur, améliorant sa capacité à se débarasser des monstres.
|
||||||
|
|
||||||
|
Il y a plusieurs types d'anneaux :
|
||||||
|
|
||||||
|
* **Anneau de coup critique**, qui augmente la chance de coup critique de 20%. Il coute 15 Hazels.
|
||||||
|
* **Anneau de gain d'expérience amélioré**, qui multiplie le gain d'expérience du joueur par 2. Il coûte 25 Hazels.
|
||||||
|
|
||||||
|
Un anneau est représenté par les caractères ``o`` et ``💍``.
|
|
@ -13,7 +13,7 @@ au plus vite sur le joueur pour le frapper selon l'algorithme de Dijkstra,
|
||||||
et s'il est suffisamment proche frappe le joueur et lui fait autant de dégâts
|
et s'il est suffisamment proche frappe le joueur et lui fait autant de dégâts
|
||||||
qu'il n'a de force.
|
qu'il n'a de force.
|
||||||
|
|
||||||
On dénombre actuellement 4 types de monstres :
|
On dénombre actuellement 5 types de monstres :
|
||||||
|
|
||||||
Hérisson
|
Hérisson
|
||||||
--------
|
--------
|
||||||
|
@ -40,6 +40,8 @@ Lapin
|
||||||
|
|
||||||
Son nom est fixé à `rabbit`. Il a par défaut une force à **1** et **15** points de vie.
|
Son nom est fixé à `rabbit`. Il a par défaut une force à **1** et **15** points de vie.
|
||||||
|
|
||||||
|
Il a une chance de coup critique de 30%.
|
||||||
|
|
||||||
Dans le `pack de textures`_ ASCII, il est représenté par le caractère ``Y``.
|
Dans le `pack de textures`_ ASCII, il est représenté par le caractère ``Y``.
|
||||||
|
|
||||||
Dans le `pack de textures`_ écureuil, il est représenté par l'émoji ``🐇``.
|
Dans le `pack de textures`_ écureuil, il est représenté par l'émoji ``🐇``.
|
||||||
|
@ -53,3 +55,14 @@ Son nom est fixé à `teddy_bear`. Il n'a pas de force et **50** points de vie.
|
||||||
Dans le `pack de textures`_ ASCII, il est représenté par le caractère ``8``.
|
Dans le `pack de textures`_ ASCII, il est représenté par le caractère ``8``.
|
||||||
|
|
||||||
Dans le `pack de textures`_ écureuil, il est représenté par l'émoji ``🧸``.
|
Dans le `pack de textures`_ écureuil, il est représenté par l'émoji ``🧸``.
|
||||||
|
|
||||||
|
|
||||||
|
Pyguargue
|
||||||
|
---------
|
||||||
|
Son nom est fixé à `eagle`. Il a par défaut une force à **1000** et **5000** points de vie.
|
||||||
|
|
||||||
|
Il s'agit d'un boss difficilement tuable, qui apparait plus rarement que les autres monstres.
|
||||||
|
|
||||||
|
Dans le `pack de textures`_ ASCII, il est représenté par le caractère ``µ``.
|
||||||
|
|
||||||
|
Dans le `pack de textures`_ écureuil, il est représenté par l'émoji ``🦅``.
|
||||||
|
|
|
@ -17,6 +17,10 @@ Bienvenue dans la documentation de Squirrel Battle !
|
||||||
:target: https://pypi.org/project/squirrel-battle/
|
:target: https://pypi.org/project/squirrel-battle/
|
||||||
:alt: PyPI
|
:alt: PyPI
|
||||||
|
|
||||||
|
.. image:: https://img.shields.io/pypi/pyversions/squirrel-battle
|
||||||
|
:target: https://pypi.org/project/squirrel-battle/
|
||||||
|
:alt: Supported Python versions
|
||||||
|
|
||||||
.. image:: https://img.shields.io/pypi/dm/squirrel-battle
|
.. image:: https://img.shields.io/pypi/dm/squirrel-battle
|
||||||
:target: https://pypi.org/project/squirrel-battle/
|
:target: https://pypi.org/project/squirrel-battle/
|
||||||
:alt: PyPI downloads
|
:alt: PyPI downloads
|
||||||
|
|
|
@ -1,2 +1,2 @@
|
||||||
sphinx
|
sphinx>=3.3
|
||||||
sphinx-rtd-theme
|
sphinx-rtd-theme>=0.5
|
||||||
|
|
|
@ -1,4 +1,38 @@
|
||||||
Paramètres
|
Paramètres
|
||||||
==========
|
==========
|
||||||
|
|
||||||
Pas encore documenté.
|
.. _pack de textures: texture-pack.html
|
||||||
|
|
||||||
|
Il est possible de changer les touches utilisées dans le jeu dans le menu des paramètres.
|
||||||
|
|
||||||
|
On peut aussi changer le `pack de textures`_ utilisé.
|
||||||
|
|
||||||
|
Touches
|
||||||
|
-------
|
||||||
|
|
||||||
|
Les touches utilisées de base sont :
|
||||||
|
|
||||||
|
* **Aller vers le haut** : z
|
||||||
|
* **Aller vers le haut (secondaire)** : ↑
|
||||||
|
* **Aller vers le bas** : s
|
||||||
|
* **Aller vers le bas (secondaire)** : ↓
|
||||||
|
* **Aller à droite** : d
|
||||||
|
* **Aller à droite (secondaire)** : →
|
||||||
|
* **Aller à gauche** : q
|
||||||
|
* **Aller à gauche (secondaire)** : ←
|
||||||
|
* **Valider le choix** : Entrée
|
||||||
|
* **Inventaire** : i
|
||||||
|
* **Utiliser un objet** : u
|
||||||
|
* **Équiper un objet** : e
|
||||||
|
* **Lacher un objet** : r
|
||||||
|
* **Parler** : t
|
||||||
|
* **Attendre** : w
|
||||||
|
|
||||||
|
Autres
|
||||||
|
------
|
||||||
|
|
||||||
|
.. _ascii: texture-pack.html#Pack ASCII
|
||||||
|
.. _squirrel: texture-pack.html#Pack Écureuil
|
||||||
|
|
||||||
|
* **Texture pack utilisé** : parmi ascii_ et squirrel_
|
||||||
|
* **Langue utilisée** : parmi anglais, français, espagnol, allemand
|
|
@ -9,18 +9,30 @@ Pack de textures
|
||||||
|
|
||||||
.. _Joueur: entities/player.html
|
.. _Joueur: entities/player.html
|
||||||
.. _Hérisson: entities/monsters.html#herisson
|
.. _Hérisson: entities/monsters.html#herisson
|
||||||
.. _Cœur: entities/items.html#coeur
|
|
||||||
.. _Bombe: entities/items.html#bombe
|
|
||||||
.. _Lapin: entities/monsters.html#lapin
|
.. _Lapin: entities/monsters.html#lapin
|
||||||
.. _Tigre: entities/monsters.html#tigre
|
.. _Tigre: entities/monsters.html#tigre
|
||||||
.. _Nounours: entities/monsters.html#nounours
|
.. _Nounours: entities/monsters.html#nounours
|
||||||
|
.. _Tournesol: entities/friendly.html#tournesol
|
||||||
|
.. _Marchand: entities/friendly.html#marchand
|
||||||
|
.. _Cœur: entities/items.html#coeur
|
||||||
|
.. _Bombe: entities/items.html#bombe
|
||||||
|
.. _Explosion: entities/items.html#bombe
|
||||||
|
.. _Potion d'arrachage de corps: entities/items.html
|
||||||
|
.. _Épée: entities/items.html#epee
|
||||||
|
.. _Bouclier: entities/items.html#bouclier
|
||||||
|
.. _Hazel: ../index.html
|
||||||
|
.. _Plastron: ../entities/items.html#plastron
|
||||||
|
.. _Pyguargue: ../entities/monsters.html#Pyguargue
|
||||||
|
.. _Casque: ../entities/items.html#Casque
|
||||||
|
.. _Anneau: ../entities/items.html#Anneau
|
||||||
|
.. _Trompette: ../entities/items.html#Trompette
|
||||||
|
|
||||||
Chaque entité_ et chaque tuile_ de la carte_ est associé à un caractère pour
|
Chaque entité_ et chaque tuile_ de la carte_ est associé à un caractère pour
|
||||||
être affiché dans le terminal. Cependant, afin de pouvoir proposer plusieurs
|
être affiché dans le terminal. Cependant, afin de pouvoir proposer plusieurs
|
||||||
expériences graphiques (notamment en fonction du support des émojis), différents
|
expériences graphiques (notamment en fonction du support des émojis), différents
|
||||||
packs de textures sont proposés.
|
packs de textures sont proposés.
|
||||||
|
|
||||||
Il est possible de changer de pack dans les paramètres.
|
Il est possible de changer de pack dans les paramètres_.
|
||||||
|
|
||||||
Les packs de textures peuvent influencer la taille que prennent les tuiles_,
|
Les packs de textures peuvent influencer la taille que prennent les tuiles_,
|
||||||
en raison du fait que les émojis ne sont pas monospace.
|
en raison du fait que les émojis ne sont pas monospace.
|
||||||
|
@ -39,11 +51,23 @@ Chaque tuile fait un caractère de large.
|
||||||
* Entités
|
* Entités
|
||||||
* Joueur_ : ``@``
|
* Joueur_ : ``@``
|
||||||
* Hérisson_ : ``*``
|
* Hérisson_ : ``*``
|
||||||
* Cœur_ : ``❤``
|
|
||||||
* Bombe_ : ``o``
|
|
||||||
* Lapin_ : ``Y``
|
* Lapin_ : ``Y``
|
||||||
* Tigre_ : ``n``
|
* Tigre_ : ``n``
|
||||||
* Nounours_ : ``8``
|
* Nounours_ : ``8``
|
||||||
|
* Tournesol_ : ``I``
|
||||||
|
* Marchand_ : ``M``
|
||||||
|
* Cœur_ : ``❤``
|
||||||
|
* Bombe_ : ``o``
|
||||||
|
* Explosion_ : ``%``
|
||||||
|
* `Potion d'arrachage de corps`_ : ``S``
|
||||||
|
* Épée_ : ``†``
|
||||||
|
* Bouclier_ : ``D``
|
||||||
|
* Hazel_ : ``¤``
|
||||||
|
* Plastron_ : ``(``
|
||||||
|
* Pyguargue_ : ``µ``
|
||||||
|
* Casque_ : ``0``
|
||||||
|
* Anneau_ : ``o``
|
||||||
|
* Trompette_ : ``/``
|
||||||
|
|
||||||
|
|
||||||
Pack Écureuil
|
Pack Écureuil
|
||||||
|
@ -58,8 +82,20 @@ Chaque tuile fait 2 caractères de large pour afficher les émojis proprement.
|
||||||
* Entités
|
* Entités
|
||||||
* Joueur_ : ``🐿``
|
* Joueur_ : ``🐿``
|
||||||
* Hérisson_ : ``🦔``
|
* Hérisson_ : ``🦔``
|
||||||
* Cœur_ : ``💜``
|
|
||||||
* Bombe_ : ``💣``
|
|
||||||
* Lapin_ : ``🐇``
|
* Lapin_ : ``🐇``
|
||||||
* Tigre_ : ``🐅``
|
* Tigre_ : ``🐅``
|
||||||
* Nounours_ : ``🧸``
|
* Nounours_ : ``🧸``
|
||||||
|
* Tournesol_ : ``🌻``
|
||||||
|
* Marchand_ : ``🦜``
|
||||||
|
* Cœur_ : ``💜``
|
||||||
|
* Bombe_ : ``💣``
|
||||||
|
* Explosion_ : ``💥``
|
||||||
|
* `Potion d'arrachage de corps`_ : ``🔀``
|
||||||
|
* Épée_ : ``🗡️``
|
||||||
|
* Bouclier_ : ``🛡️``
|
||||||
|
* Hazel_ : ``🌰``
|
||||||
|
* Plastron_ : ``🦺``
|
||||||
|
* Pyguargue_ : ``🦅``
|
||||||
|
* Casque_ : ``⛑️``
|
||||||
|
* Anneau_ : ``💍``
|
||||||
|
* Trompette_ : ``🎺``
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
# SPDX-License-Identifier: GPL-3.0-or-later
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
import curses
|
import curses
|
||||||
|
import sys
|
||||||
from typing import Any, Optional, Tuple, Union
|
from typing import Any, Optional, Tuple, Union
|
||||||
|
|
||||||
from squirrelbattle.display.texturepack import TexturePack
|
from squirrelbattle.display.texturepack import TexturePack
|
||||||
|
@ -104,6 +105,8 @@ class Display:
|
||||||
attr |= curses.A_BOLD if bold else 0
|
attr |= curses.A_BOLD if bold else 0
|
||||||
attr |= curses.A_DIM if dim else 0
|
attr |= curses.A_DIM if dim else 0
|
||||||
attr |= curses.A_INVIS if invis else 0
|
attr |= curses.A_INVIS if invis else 0
|
||||||
|
# Italic is supported since Python 3.7
|
||||||
|
italic &= sys.version_info >= (3, 7,)
|
||||||
attr |= curses.A_ITALIC if italic else 0
|
attr |= curses.A_ITALIC if italic else 0
|
||||||
attr |= curses.A_NORMAL if normal else 0
|
attr |= curses.A_NORMAL if normal else 0
|
||||||
attr |= curses.A_PROTECT if protect else 0
|
attr |= curses.A_PROTECT if protect else 0
|
||||||
|
|
|
@ -21,26 +21,26 @@ class TexturePack:
|
||||||
|
|
||||||
BODY_SNATCH_POTION: str
|
BODY_SNATCH_POTION: str
|
||||||
BOMB: str
|
BOMB: str
|
||||||
HEART: str
|
CHESTPLATE: str
|
||||||
HEDGEHOG: str
|
EAGLE: str
|
||||||
EMPTY: str
|
EMPTY: str
|
||||||
FLOOR: str
|
FLOOR: str
|
||||||
HAZELNUT: str
|
HAZELNUT: str
|
||||||
|
HEART: str
|
||||||
|
HEDGEHOG: str
|
||||||
|
HELMET: str
|
||||||
MERCHANT: str
|
MERCHANT: str
|
||||||
PLAYER: str
|
PLAYER: str
|
||||||
RABBIT: str
|
RABBIT: str
|
||||||
|
RING_OF_CRITICAL_DAMAGE: str
|
||||||
|
RING_OF_MORE_EXPERIENCE: str
|
||||||
|
SHIELD: str
|
||||||
SUNFLOWER: str
|
SUNFLOWER: str
|
||||||
SWORD: str
|
SWORD: str
|
||||||
TEDDY_BEAR: str
|
TEDDY_BEAR: str
|
||||||
TIGER: str
|
TIGER: str
|
||||||
TRUMPET: str
|
TRUMPET: str
|
||||||
WALL: str
|
WALL: str
|
||||||
EAGLE: str
|
|
||||||
SHIELD: str
|
|
||||||
CHESTPLATE: str
|
|
||||||
HELMET: str
|
|
||||||
RING_OF_MORE_EXPERIENCE: str
|
|
||||||
RING_OF_CRITICAL_DAMAGE: str
|
|
||||||
|
|
||||||
ASCII_PACK: "TexturePack"
|
ASCII_PACK: "TexturePack"
|
||||||
SQUIRREL_PACK: "TexturePack"
|
SQUIRREL_PACK: "TexturePack"
|
||||||
|
@ -73,6 +73,8 @@ TexturePack.ASCII_PACK = TexturePack(
|
||||||
|
|
||||||
BODY_SNATCH_POTION='S',
|
BODY_SNATCH_POTION='S',
|
||||||
BOMB='ç',
|
BOMB='ç',
|
||||||
|
CHESTPLATE='(',
|
||||||
|
EAGLE='µ',
|
||||||
EMPTY=' ',
|
EMPTY=' ',
|
||||||
EXPLOSION='%',
|
EXPLOSION='%',
|
||||||
FLOOR='.',
|
FLOOR='.',
|
||||||
|
@ -80,9 +82,12 @@ TexturePack.ASCII_PACK = TexturePack(
|
||||||
HAZELNUT='¤',
|
HAZELNUT='¤',
|
||||||
HEART='❤',
|
HEART='❤',
|
||||||
HEDGEHOG='*',
|
HEDGEHOG='*',
|
||||||
|
HELMET='0',
|
||||||
MERCHANT='M',
|
MERCHANT='M',
|
||||||
PLAYER='@',
|
PLAYER='@',
|
||||||
RABBIT='Y',
|
RABBIT='Y',
|
||||||
|
RING_OF_CRITICAL_DAMAGE='o',
|
||||||
|
RING_OF_MORE_EXPERIENCE='o',
|
||||||
SHIELD='D',
|
SHIELD='D',
|
||||||
SUNFLOWER='I',
|
SUNFLOWER='I',
|
||||||
SWORD='\u2020',
|
SWORD='\u2020',
|
||||||
|
@ -90,11 +95,6 @@ TexturePack.ASCII_PACK = TexturePack(
|
||||||
TIGER='n',
|
TIGER='n',
|
||||||
TRUMPET='/',
|
TRUMPET='/',
|
||||||
WALL='#',
|
WALL='#',
|
||||||
EAGLE='µ',
|
|
||||||
CHESTPLATE='(',
|
|
||||||
HELMET='0',
|
|
||||||
RING_OF_MORE_EXPERIENCE='o',
|
|
||||||
RING_OF_CRITICAL_DAMAGE='o',
|
|
||||||
)
|
)
|
||||||
|
|
||||||
TexturePack.SQUIRREL_PACK = TexturePack(
|
TexturePack.SQUIRREL_PACK = TexturePack(
|
||||||
|
@ -108,6 +108,8 @@ TexturePack.SQUIRREL_PACK = TexturePack(
|
||||||
|
|
||||||
BODY_SNATCH_POTION='🔀',
|
BODY_SNATCH_POTION='🔀',
|
||||||
BOMB='💣',
|
BOMB='💣',
|
||||||
|
CHESTPLATE='🦺',
|
||||||
|
EAGLE='🦅',
|
||||||
EMPTY=' ',
|
EMPTY=' ',
|
||||||
EXPLOSION='💥',
|
EXPLOSION='💥',
|
||||||
FLOOR='██',
|
FLOOR='██',
|
||||||
|
@ -116,9 +118,12 @@ TexturePack.SQUIRREL_PACK = TexturePack(
|
||||||
HAZELNUT='🌰',
|
HAZELNUT='🌰',
|
||||||
HEART='💜',
|
HEART='💜',
|
||||||
HEDGEHOG='🦔',
|
HEDGEHOG='🦔',
|
||||||
|
HELMET='⛑️',
|
||||||
PLAYER='🐿️ ️',
|
PLAYER='🐿️ ️',
|
||||||
MERCHANT='🦜',
|
MERCHANT='🦜',
|
||||||
RABBIT='🐇',
|
RABBIT='🐇',
|
||||||
|
RING_OF_CRITICAL_DAMAGE='💍',
|
||||||
|
RING_OF_MORE_EXPERIENCE='💍',
|
||||||
SHIELD='🛡️ ',
|
SHIELD='🛡️ ',
|
||||||
SUNFLOWER='🌻',
|
SUNFLOWER='🌻',
|
||||||
SWORD='🗡️ ',
|
SWORD='🗡️ ',
|
||||||
|
@ -126,9 +131,4 @@ TexturePack.SQUIRREL_PACK = TexturePack(
|
||||||
TIGER='🐅',
|
TIGER='🐅',
|
||||||
TRUMPET='🎺',
|
TRUMPET='🎺',
|
||||||
WALL='🧱',
|
WALL='🧱',
|
||||||
EAGLE='🦅',
|
|
||||||
CHESTPLATE='🦺',
|
|
||||||
HELMET='⛑️',
|
|
||||||
RING_OF_MORE_EXPERIENCE='💍',
|
|
||||||
RING_OF_CRITICAL_DAMAGE='💍',
|
|
||||||
)
|
)
|
||||||
|
|
|
@ -79,7 +79,7 @@ class Item(Entity):
|
||||||
"""
|
"""
|
||||||
Returns the list of all item classes.
|
Returns the list of all item classes.
|
||||||
"""
|
"""
|
||||||
return [BodySnatchPotion, Bomb, Heart, Shield, Sword,
|
return [BodySnatchPotion, Bomb, Heart, Shield, Sword,\
|
||||||
Chestplate, Helmet, RingCritical, RingXP]
|
Chestplate, Helmet, RingCritical, RingXP]
|
||||||
|
|
||||||
def be_sold(self, buyer: InventoryHolder, seller: InventoryHolder) -> bool:
|
def be_sold(self, buyer: InventoryHolder, seller: InventoryHolder) -> bool:
|
||||||
|
@ -279,20 +279,17 @@ class Shield(Armor):
|
||||||
"""
|
"""
|
||||||
Class of shield items, they can be equipped in the other hand.
|
Class of shield items, they can be equipped in the other hand.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name: str = "shield", constitution: int = 2,
|
def __init__(self, name: str = "shield", constitution: int = 2,
|
||||||
price: int = 6, *args, **kwargs):
|
price: int = 16, *args, **kwargs):
|
||||||
super().__init__(name=name, constitution=constitution, price=price,
|
super().__init__(name=name, constitution=constitution, price=price,
|
||||||
*args, **kwargs)
|
*args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
class Helmet(Armor):
|
class Helmet(Armor):
|
||||||
"""
|
"""
|
||||||
Class of helmet items, they can be equipped on the head.
|
Class of helmet items, they can be equipped on the head.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name: str = "helmet", constitution: int = 2,
|
def __init__(self, name: str = "helmet", constitution: int = 2,
|
||||||
price: int = 8, *args, **kwargs):
|
price: int = 18, *args, **kwargs):
|
||||||
super().__init__(name=name, constitution=constitution, price=price,
|
super().__init__(name=name, constitution=constitution, price=price,
|
||||||
*args, **kwargs)
|
*args, **kwargs)
|
||||||
|
|
||||||
|
@ -302,14 +299,12 @@ class Helmet(Armor):
|
||||||
self.held_by.remove_from_inventory(self)
|
self.held_by.remove_from_inventory(self)
|
||||||
self.held_by.equipped_helmet = self
|
self.held_by.equipped_helmet = self
|
||||||
|
|
||||||
|
|
||||||
class Chestplate(Armor):
|
class Chestplate(Armor):
|
||||||
"""
|
"""
|
||||||
Class of chestplate items, they can be equipped on the body.
|
Class of chestplate items, they can be equipped on the body.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name: str = "chestplate", constitution: int = 4,
|
def __init__(self, name: str = "chestplate", constitution: int = 4,
|
||||||
price: int = 15, *args, **kwargs):
|
price: int = 30, *args, **kwargs):
|
||||||
super().__init__(name=name, constitution=constitution, price=price,
|
super().__init__(name=name, constitution=constitution, price=price,
|
||||||
*args, **kwargs)
|
*args, **kwargs)
|
||||||
|
|
||||||
|
@ -319,7 +314,6 @@ class Chestplate(Armor):
|
||||||
self.held_by.remove_from_inventory(self)
|
self.held_by.remove_from_inventory(self)
|
||||||
self.held_by.equipped_armor = self
|
self.held_by.equipped_armor = self
|
||||||
|
|
||||||
|
|
||||||
class BodySnatchPotion(Item):
|
class BodySnatchPotion(Item):
|
||||||
"""
|
"""
|
||||||
The body-snatch potion allows to exchange all characteristics with a random
|
The body-snatch potion allows to exchange all characteristics with a random
|
||||||
|
|
|
@ -604,9 +604,10 @@ class Entity:
|
||||||
from squirrelbattle.entities.items import BodySnatchPotion, Bomb, Heart
|
from squirrelbattle.entities.items import BodySnatchPotion, Bomb, Heart
|
||||||
from squirrelbattle.entities.monsters import Tiger, Hedgehog, \
|
from squirrelbattle.entities.monsters import Tiger, Hedgehog, \
|
||||||
Rabbit, TeddyBear, GiantSeaEagle
|
Rabbit, TeddyBear, GiantSeaEagle
|
||||||
from squirrelbattle.entities.friendly import Merchant, Sunflower
|
from squirrelbattle.entities.friendly import Merchant, Sunflower, \
|
||||||
|
Trumpet
|
||||||
return [BodySnatchPotion, Bomb, Heart, Hedgehog, Rabbit, TeddyBear,
|
return [BodySnatchPotion, Bomb, Heart, Hedgehog, Rabbit, TeddyBear,
|
||||||
Sunflower, Tiger, Merchant, GiantSeaEagle]
|
Sunflower, Tiger, Merchant, GiantSeaEagle, Trumpet]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_weights() -> list:
|
def get_weights() -> list:
|
||||||
|
@ -615,7 +616,7 @@ class Entity:
|
||||||
be used to spawn random entities with a certain probability.
|
be used to spawn random entities with a certain probability.
|
||||||
"""
|
"""
|
||||||
return [3, 5, 6, 5, 5, 5,
|
return [3, 5, 6, 5, 5, 5,
|
||||||
5, 4, 4, 1]
|
5, 4, 4, 1, 2]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def get_all_entity_classes_in_a_dict() -> dict:
|
def get_all_entity_classes_in_a_dict() -> dict:
|
||||||
|
|
Loading…
Reference in New Issue