@@ -127,3 +127,5 @@ dmypy.json
|
|||||||
|
|
||||||
# Pyre type checker
|
# Pyre type checker
|
||||||
.pyre/
|
.pyre/
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
|||||||
+15
-3
@@ -10,6 +10,7 @@ For the full list of settings and their values, see
|
|||||||
https://docs.djangoproject.com/en/4.0/ref/settings/
|
https://docs.djangoproject.com/en/4.0/ref/settings/
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
# Build paths inside the project like this: BASE_DIR / 'subdir'.
|
||||||
@@ -32,6 +33,9 @@ ALLOWED_HOSTS = [env('HOST_1')]
|
|||||||
# Application definition
|
# Application definition
|
||||||
|
|
||||||
INSTALLED_APPS = [
|
INSTALLED_APPS = [
|
||||||
|
'main',
|
||||||
|
'links',
|
||||||
|
'faerun_calendar',
|
||||||
'django.contrib.admin',
|
'django.contrib.admin',
|
||||||
'django.contrib.auth',
|
'django.contrib.auth',
|
||||||
'django.contrib.contenttypes',
|
'django.contrib.contenttypes',
|
||||||
@@ -76,8 +80,12 @@ WSGI_APPLICATION = 'dnd_db_site.wsgi.application'
|
|||||||
|
|
||||||
DATABASES = {
|
DATABASES = {
|
||||||
'default': {
|
'default': {
|
||||||
'ENGINE': 'django.db.backends.sqlite3',
|
'ENGINE': 'django.db.backends.mysql',
|
||||||
'NAME': BASE_DIR / 'db.sqlite3',
|
'NAME': env('DB_NAME'),
|
||||||
|
'USER': env('DB_USER'),
|
||||||
|
'PASSWORD': env('DB_PASSWORD'),
|
||||||
|
'HOST': 'localhost',
|
||||||
|
'PORT': '',
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,7 +112,7 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||||||
# Internationalization
|
# Internationalization
|
||||||
# https://docs.djangoproject.com/en/4.0/topics/i18n/
|
# https://docs.djangoproject.com/en/4.0/topics/i18n/
|
||||||
|
|
||||||
LANGUAGE_CODE = 'en-us'
|
LANGUAGE_CODE = 'ru-ru'
|
||||||
|
|
||||||
TIME_ZONE = 'UTC'
|
TIME_ZONE = 'UTC'
|
||||||
|
|
||||||
@@ -117,6 +125,10 @@ USE_TZ = True
|
|||||||
# https://docs.djangoproject.com/en/4.0/howto/static-files/
|
# https://docs.djangoproject.com/en/4.0/howto/static-files/
|
||||||
|
|
||||||
STATIC_URL = 'static/'
|
STATIC_URL = 'static/'
|
||||||
|
STATIC_ROOT = '/home/ruslan/dnd-db-site.misc/static'
|
||||||
|
STATICFILES_DIRS = [
|
||||||
|
os.path.join(BASE_DIR, 'static'),
|
||||||
|
]
|
||||||
|
|
||||||
# Default primary key field type
|
# Default primary key field type
|
||||||
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
|
# https://docs.djangoproject.com/en/4.0/ref/settings/#default-auto-field
|
||||||
|
|||||||
+6
-2
@@ -15,8 +15,12 @@ Including another URLconf
|
|||||||
"""
|
"""
|
||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import include, path
|
from django.urls import include, path
|
||||||
|
from django.conf import settings
|
||||||
|
from django.conf.urls.static import static
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
path('', include('helloworld.urls')),
|
path('', include('main.urls')),
|
||||||
]
|
path('calendar/', include('faerun_calendar.urls')),
|
||||||
|
path('links/', include('links.urls')),
|
||||||
|
] + static(settings.STATIC_URL, document_root=settings.STATIC_ROOT)
|
||||||
|
|||||||
@@ -0,0 +1,6 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class FaerunCalendarConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'faerun_calendar'
|
||||||
@@ -0,0 +1,39 @@
|
|||||||
|
div.calendarpage {
|
||||||
|
margin: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.month, table.month th, table.month td {
|
||||||
|
border: 1px solid white;
|
||||||
|
border-collapse: collapse;
|
||||||
|
padding: 5px;
|
||||||
|
background: gainsboro;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.month td {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.month td.current {
|
||||||
|
background: dimgrey;
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.month th.subtitle {
|
||||||
|
font-style: italic;
|
||||||
|
font-weight: normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.calendar {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
justify-content: space-around;
|
||||||
|
}
|
||||||
|
|
||||||
|
table.month {
|
||||||
|
margin: 10px;
|
||||||
|
width: 350px;
|
||||||
|
max-width: 350px;
|
||||||
|
}
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
<div class="calendar">
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Хаммер" subtitle="Глубокозимье" %}
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Зимний солнцеворот" subtitle="Мертвозимье" oneday=1 %}
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Альтурик" subtitle="Коготь зимы" %}
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Чез" subtitle="Коготь закатов" %}
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Тарсак" subtitle="Коготь бурь" %}
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Зеленотравье" oneday=1 %}
|
||||||
|
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Миртул" subtitle="Таяние" %}
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Кайторн" subtitle="Время цветов" %}
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Флеймрул" subtitle="Разгар лета" %}
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Летний солнцеворот" oneday=1 %}
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Шильдмит*" oneday=1 %}
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Элесис" subtitle="Солнцестояние" %}
|
||||||
|
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Элейнт" subtitle="Увядание" %}
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Праздник урожая" oneday=1 %}
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Марпенот" subtitle="Листопад" %}
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Уктар" subtitle="Перегной" %}
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Пир луны" oneday=1 %}
|
||||||
|
{% include 'faerun_calendar/month.html' with title="Найтал" subtitle="Спячка" %}
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
{% extends 'main/pagetemplate.html' %}
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block additional_css %}
|
||||||
|
<link rel="stylesheet" href="{% static 'faerun_calendar/css/main.css' %}">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block pagetitle %}
|
||||||
|
Календарь
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="calendarpage">
|
||||||
|
<h1 class="title">Календарь</h1>
|
||||||
|
{% include 'faerun_calendar/calendar.html' %}
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
@@ -0,0 +1,53 @@
|
|||||||
|
<div class="month">
|
||||||
|
<table class="month">
|
||||||
|
<tr>
|
||||||
|
<th colspan="10" class="title">{{title}}</th>
|
||||||
|
</tr>
|
||||||
|
{% if subtitle %}
|
||||||
|
<th colspan="10" class="subtitle">{{subtitle}}</th>
|
||||||
|
{% endif %}
|
||||||
|
{% if oneday != 1 %}
|
||||||
|
<tr>
|
||||||
|
<td>1</td>
|
||||||
|
<td>2</td>
|
||||||
|
<td>3</td>
|
||||||
|
<td>4</td>
|
||||||
|
<td>5</td>
|
||||||
|
<td>6</td>
|
||||||
|
<td>7</td>
|
||||||
|
<td>8</td>
|
||||||
|
<td>9</td>
|
||||||
|
<td>10</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>11</td>
|
||||||
|
<td>12</td>
|
||||||
|
<td>13</td>
|
||||||
|
<td>14</td>
|
||||||
|
<td>15</td>
|
||||||
|
<td>16</td>
|
||||||
|
<td>17</td>
|
||||||
|
<td>18</td>
|
||||||
|
{% if title == "Миртул" %}
|
||||||
|
<td class="current">19</td>
|
||||||
|
{% else %}
|
||||||
|
<td>19</td>
|
||||||
|
{% endif %}
|
||||||
|
|
||||||
|
<td>20</td>
|
||||||
|
</tr>
|
||||||
|
<tr>
|
||||||
|
<td>21</td>
|
||||||
|
<td>22</td>
|
||||||
|
<td>23</td>
|
||||||
|
<td>24</td>
|
||||||
|
<td>25</td>
|
||||||
|
<td>26</td>
|
||||||
|
<td>27</td>
|
||||||
|
<td>28</td>
|
||||||
|
<td>29</td>
|
||||||
|
<td>30</td>
|
||||||
|
</tr>
|
||||||
|
{% endif %}
|
||||||
|
</table>
|
||||||
|
</div>
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
|
||||||
|
def index(request):
|
||||||
|
return render(request, 'faerun_calendar/index.html')
|
||||||
|
|
||||||
@@ -1,5 +0,0 @@
|
|||||||
from django.http import HttpResponse
|
|
||||||
|
|
||||||
def index(request):
|
|
||||||
return HttpResponse('<b>Hallo, Welt!</b>')
|
|
||||||
|
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
from .models import Link
|
||||||
|
|
||||||
|
admin.site.register(Link)
|
||||||
|
|
||||||
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
from django.apps import AppConfig
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
class HelloworldConfig(AppConfig):
|
class LinksConfig(AppConfig):
|
||||||
default_auto_field = 'django.db.models.BigAutoField'
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
name = 'helloworld'
|
name = 'links'
|
||||||
@@ -0,0 +1,10 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
|
||||||
|
class Link(models.Model):
|
||||||
|
order = models.SmallIntegerField('Order')
|
||||||
|
url = models.CharField('URL', max_length=250)
|
||||||
|
text = models.CharField('Text', max_length=250)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'({self.order}, {self.url}, {self.text})'
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
div.linkspage {
|
||||||
|
margin: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul {
|
||||||
|
list-style-type: none;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
@@ -0,0 +1,23 @@
|
|||||||
|
{% extends 'main/pagetemplate.html' %}
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
{% block additional_css %}
|
||||||
|
<link rel="stylesheet" href="{% static 'links/css/main.css' %}">
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block pagetitle %}
|
||||||
|
Полезные ссылки
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="linkspage">
|
||||||
|
<h1 class="title">Полезные ссылки</h1>
|
||||||
|
<ul>
|
||||||
|
{% for link in links %}
|
||||||
|
<li><a href="{{link.url}}">{{link.text}}</a></li>
|
||||||
|
{% endfor %}
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
from django.urls import path
|
||||||
|
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('', views.index, name='index'),
|
||||||
|
]
|
||||||
|
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
from django.shortcuts import render
|
||||||
|
from .models import Link
|
||||||
|
|
||||||
|
|
||||||
|
def index(request):
|
||||||
|
links = Link.objects.order_by('order')
|
||||||
|
|
||||||
|
return render(request, 'links/index.html', {'links': links})
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
from django.contrib import admin
|
||||||
|
|
||||||
|
# Register your models here.
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
from django.apps import AppConfig
|
||||||
|
|
||||||
|
|
||||||
|
class MainConfig(AppConfig):
|
||||||
|
default_auto_field = 'django.db.models.BigAutoField'
|
||||||
|
name = 'main'
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
from django.db import models
|
||||||
|
|
||||||
|
# Create your models here.
|
||||||
@@ -0,0 +1,44 @@
|
|||||||
|
div.mainpage {
|
||||||
|
margin: 10px;
|
||||||
|
padding: 10px;
|
||||||
|
border: 1px solid black;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside.menu {
|
||||||
|
border: 3px solid black;
|
||||||
|
border-radius: 10px;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
padding: 15px;
|
||||||
|
margin: 25px;
|
||||||
|
}
|
||||||
|
|
||||||
|
div.menu {
|
||||||
|
display: flex;
|
||||||
|
flex-flow: row wrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside.menu a {
|
||||||
|
border-radius: 10px;
|
||||||
|
text-decoration: none;
|
||||||
|
color: black;
|
||||||
|
font-weight: bold;
|
||||||
|
background: DeepSkyBlue;
|
||||||
|
padding: 10px;
|
||||||
|
margin: 10px;
|
||||||
|
|
||||||
|
max-width: 100px;
|
||||||
|
max-width: 200px;
|
||||||
|
|
||||||
|
display: flex;
|
||||||
|
flex: 1 1 0px;
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
aside.menu a:hover {
|
||||||
|
background: DodgerBlue;
|
||||||
|
}
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
{% extends 'main/pagetemplate.html' %}
|
||||||
|
|
||||||
|
{% block pagetitle %}
|
||||||
|
Главная страница
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
<div class="mainpage">
|
||||||
|
<h1 class="title">Главная страница</h1>
|
||||||
|
</div>
|
||||||
|
{% endblock %}
|
||||||
@@ -0,0 +1,38 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
{% load static %}
|
||||||
|
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>{% block pagetitle %}{% endblock %}</title>
|
||||||
|
|
||||||
|
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.2.0-beta1/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-0evHe/X+R7YkIZDRvuzKMRqM+OrBnVFBL6DOitfPri4tjfHxaWutUpFmBp4vmVor" crossorigin="anonymous">
|
||||||
|
<link rel="stylesheet" href="{% static 'main/css/main.css' %}">
|
||||||
|
|
||||||
|
{% block additional_css %}
|
||||||
|
{% endblock %}
|
||||||
|
|
||||||
|
|
||||||
|
<link rel="icon" href="{% static 'iconsmall.png' %}">
|
||||||
|
<link rel="apple-touch-icon" href="{% static 'iconbig.png' %}">
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<aside class="menu">
|
||||||
|
<div class="menu">
|
||||||
|
<a class="menuitem" href="/">
|
||||||
|
Главная
|
||||||
|
</a>
|
||||||
|
<a class="menuitem" href="/calendar">
|
||||||
|
Календарь
|
||||||
|
</a>
|
||||||
|
<a class="menuitem" href="/links">
|
||||||
|
Полезные ссылки
|
||||||
|
</a>
|
||||||
|
</div>
|
||||||
|
</aside>
|
||||||
|
|
||||||
|
{% block content %}
|
||||||
|
{% endblock %}
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
from django.test import TestCase
|
||||||
|
|
||||||
|
# Create your tests here.
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
from django.urls import path
|
||||||
|
|
||||||
|
from . import views
|
||||||
|
|
||||||
|
urlpatterns = [
|
||||||
|
path('', views.index, name='index'),
|
||||||
|
]
|
||||||
|
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
from django.shortcuts import render
|
||||||
|
|
||||||
|
|
||||||
|
def index(request):
|
||||||
|
return render(request, 'main/index.html')
|
||||||
Binary file not shown.
|
After Width: | Height: | Size: 25 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,339 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<style>
|
||||||
|
label {
|
||||||
|
background: azure;
|
||||||
|
border: solid black 1px;
|
||||||
|
border-radius: 5px;
|
||||||
|
font-weight: bold;
|
||||||
|
}
|
||||||
|
input[type=text] {
|
||||||
|
background: LightYellow;
|
||||||
|
border: solid black 1px;
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
hr {
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
input.error {
|
||||||
|
background: salmon;
|
||||||
|
}
|
||||||
|
div.misc, div.abilities, div.skills {
|
||||||
|
float: left;
|
||||||
|
min-height: 30px;
|
||||||
|
}
|
||||||
|
div.misc {
|
||||||
|
min-width: 280px;
|
||||||
|
}
|
||||||
|
div.abilities {
|
||||||
|
min-width: 200px;
|
||||||
|
}
|
||||||
|
div.skills {
|
||||||
|
min-width: 280px;
|
||||||
|
}
|
||||||
|
div.misc, div.abilities, div.skills {
|
||||||
|
margin: 5px 15px;
|
||||||
|
border: solid black 2px;
|
||||||
|
border-radius: 5px;
|
||||||
|
padding: 5px;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
div.misc *, div.abilities *, div.skills * {
|
||||||
|
margin-left: 5px;
|
||||||
|
margin-right: 5px;
|
||||||
|
}
|
||||||
|
div.abilities input, div.skills input {
|
||||||
|
max-width: 25px;
|
||||||
|
}
|
||||||
|
label.skills {
|
||||||
|
padding: 5px;
|
||||||
|
}
|
||||||
|
input[type=checkbox]:checked ~ .skills {
|
||||||
|
color: white;
|
||||||
|
background: navy;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<script>
|
||||||
|
const checkbox_suffix = "_cb";
|
||||||
|
const message_suffix = "_msg";
|
||||||
|
|
||||||
|
const min_ability = 10;
|
||||||
|
const max_ability = 80;
|
||||||
|
const max_sum_ability = 80;
|
||||||
|
|
||||||
|
class Ability {
|
||||||
|
constructor(name, short_name_rus, long_name_rus) {
|
||||||
|
this.name = name;
|
||||||
|
this.short_name_rus = short_name_rus;
|
||||||
|
this.long_name_rus = long_name_rus;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const abilities = [
|
||||||
|
new Ability("dexterity", "ЛВК", "Ловкость"),
|
||||||
|
new Ability("strength", "СИЛ", "Сила"),
|
||||||
|
new Ability("constitution", "ВЫН", "Выносливость"),
|
||||||
|
new Ability("appearance", "НАР", "Наружность"),
|
||||||
|
new Ability("charisma", "ХАР", "Харизма"),
|
||||||
|
new Ability("will", "ВОЛ", "Воля"),
|
||||||
|
new Ability("wisdom", "МУД", "Мудрость"),
|
||||||
|
new Ability("intelligence", "ИНТ", "Интеллект"),
|
||||||
|
]
|
||||||
|
|
||||||
|
class Skill {
|
||||||
|
constructor(name, base, name_rus, dependencies) {
|
||||||
|
this.name = name;
|
||||||
|
this.base = base;
|
||||||
|
this.name_rus = name_rus;
|
||||||
|
this.dependencies = dependencies;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const skills = [
|
||||||
|
new Skill("light_firearm", 5, "Лёгкий огнестрел", {}),
|
||||||
|
new Skill("medium_firearm", 5, "Средний огнестрел", {}),
|
||||||
|
new Skill("heavy_firearm", 5, "Тяжёлый огнестрел", {}),
|
||||||
|
new Skill("recon", 5, "Разведка", {}),
|
||||||
|
new Skill("gambling", 1, "Азартные игры", {}),
|
||||||
|
new Skill("artillery", 0, "Артиллерия", {}),
|
||||||
|
new Skill("barter", 10, "Бартер", {}),
|
||||||
|
new Skill("blocking", 10, "Блокирование", {}),
|
||||||
|
new Skill("accounting", 5, "Бухгалтерское дело", {}),
|
||||||
|
new Skill("riding", 5, "Верховая езда", {}),
|
||||||
|
new Skill("lockpicking", 1, "Взлом", {}),
|
||||||
|
new Skill("explosives", 0, "Взрывчатка", {}),
|
||||||
|
new Skill("pole_weapons", 5, "Древковое оружие", {}),
|
||||||
|
new Skill("blunt_weapons", 10, "Дробящее оружие", {}),
|
||||||
|
new Skill("slashing_weapons", 5, "Рубящее оружие", {}),
|
||||||
|
new Skill("pierce_weapons", 5, "Колющее оружие", {}),
|
||||||
|
<!-- new Skill("", "", {}),-->
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
function isDataValidForAbility(data) {
|
||||||
|
var value = parseInt(data);
|
||||||
|
if (value != value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (value < min_ability || value > max_ability) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateAbilities() {
|
||||||
|
var sum = 0;
|
||||||
|
for (const ability of abilities) {
|
||||||
|
var element = document.getElementById(ability.name);
|
||||||
|
const value = parseInt(element.value);
|
||||||
|
if (value == value) {
|
||||||
|
sum += value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const max = 500;
|
||||||
|
|
||||||
|
|
||||||
|
var error_desc_sum = "";
|
||||||
|
var error_desc_separate = "";
|
||||||
|
var error_desc_separate_names = [];
|
||||||
|
|
||||||
|
const is_sum_error = sum > max || sum != sum;
|
||||||
|
|
||||||
|
if (is_sum_error) {
|
||||||
|
error_desc_sum = `Неверное значение суммы характеристик. Сумма не должна превышать ${max}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const ability of abilities) {
|
||||||
|
var element = document.getElementById(ability.name);
|
||||||
|
const is_data_valid = isDataValidForAbility(element.value);
|
||||||
|
|
||||||
|
if (!is_data_valid) {
|
||||||
|
if (!error_desc_separate) {
|
||||||
|
error_desc_sum = `Неверное значение характеристик. Значение должно быть в диапазоне от ${min_ability} до ${max_ability}`;
|
||||||
|
}
|
||||||
|
error_desc_separate_names += ability.name_rus;
|
||||||
|
}
|
||||||
|
|
||||||
|
element.className = !is_sum_error && is_data_valid ? "" : "error";
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('abilities_result').textContent = max-sum;
|
||||||
|
|
||||||
|
const error_text = "";
|
||||||
|
|
||||||
|
if (error_desc_sum) {
|
||||||
|
error_text += error_desc_sum;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (error_desc_separate) {
|
||||||
|
if (error_text) error_text += "\n";
|
||||||
|
error_text += error_desc_separate;
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById(`abilities${message_suffix}`).textContent = error_text;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isDataValidForSkill(data, base, is_selected) {
|
||||||
|
var value = parseInt(data);
|
||||||
|
if (value != value) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (is_selected) {
|
||||||
|
if (value < 20 || value > 70) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (value < base || value > 70) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
function validateSkills() {
|
||||||
|
var sum_selected = 0;
|
||||||
|
var sum_unselected = 0;
|
||||||
|
var sum_unselected_base = 0;
|
||||||
|
var count_selected = 0;
|
||||||
|
|
||||||
|
for (const skill of skills) {
|
||||||
|
var element = document.getElementById(skill.name);
|
||||||
|
var cb = document.getElementById(`${skill.name}${checkbox_suffix}`);
|
||||||
|
const value = parseInt(element.value);
|
||||||
|
if (cb.checked) {
|
||||||
|
count_selected++;
|
||||||
|
}
|
||||||
|
if (value == value) {
|
||||||
|
if (cb.checked) {
|
||||||
|
sum_selected += value
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
sum_unselected += value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const base = parseInt(skill.sum_unselected_base);
|
||||||
|
if (base == base) {
|
||||||
|
sum_unselected_base += base;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const max_selected = 500;
|
||||||
|
const max_unselected = 80;
|
||||||
|
const max_count_selected = 8;
|
||||||
|
|
||||||
|
for (const skill of skills) {
|
||||||
|
var element = document.getElementById(skill.name);
|
||||||
|
var cb = document.getElementById(`${skill.name}${checkbox_suffix}`);
|
||||||
|
const base = parseInt(skill.sum_unselected_base);
|
||||||
|
if (base == base) {
|
||||||
|
sum_unselected_base += base;
|
||||||
|
}
|
||||||
|
var isValid = count_selected <= max_count_selected;
|
||||||
|
|
||||||
|
if (isValid) {
|
||||||
|
if (cb.checked) {
|
||||||
|
isValid = sum_selected <= max_selected || sum_selected != sum_selected;
|
||||||
|
cb.className = "selected";
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
var isValid = (sum_unselected-sum_unselected_base <= max_unselected ||
|
||||||
|
sum_unselected != sum_unselected);
|
||||||
|
cb.className = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isValid) {
|
||||||
|
isValid = isDataValidForSkill(element.value, base, cb.checked);
|
||||||
|
}
|
||||||
|
|
||||||
|
element.className = isValid ? "" : "error";
|
||||||
|
}
|
||||||
|
|
||||||
|
document.getElementById('skills_result_selected').textContent = max_selected-sum_selected;
|
||||||
|
document.getElementById('skills_result_unselected').textContent = max_unselected-sum_unselected;
|
||||||
|
}
|
||||||
|
|
||||||
|
function updateAfterLoading() {
|
||||||
|
for (const ability of abilities) {
|
||||||
|
var element = document.getElementById(ability.name);
|
||||||
|
element.oninput = validateAbilities;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const skill of skills) {
|
||||||
|
var element = document.getElementById(skill.name);
|
||||||
|
var cb = document.getElementById(`${skill.name}${checkbox_suffix}`);
|
||||||
|
element.oninput = validateSkills;
|
||||||
|
cb.oninput = validateSkills;
|
||||||
|
}
|
||||||
|
|
||||||
|
validateAbilities();
|
||||||
|
validateSkills();
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>Оокона</h1>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<p class="misc">
|
||||||
|
<div class="misc">
|
||||||
|
Имя: <input id="name" type="text">
|
||||||
|
</div>
|
||||||
|
<div class="misc">
|
||||||
|
Класс: <input id="class" type="text">
|
||||||
|
</div>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<p class="abilities">
|
||||||
|
<script>
|
||||||
|
for (const ability of abilities) {
|
||||||
|
document.write(`<div class="abilities">`);
|
||||||
|
document.write(`<input id="${ability.name}" type="text"></input>`);
|
||||||
|
document.write(`<label class="skills">${ability.long_name_rus}</label>`);
|
||||||
|
document.write(`</div>`);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<div class="abilities">
|
||||||
|
Осталось: <span id="abilities_result"></span>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
document.write(`<p id="abilities${message_suffix}"></p>`);
|
||||||
|
</script>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<hr>
|
||||||
|
|
||||||
|
<p class="skills">
|
||||||
|
<script>
|
||||||
|
for (const skill of skills) {
|
||||||
|
document.write(`<div class="skills">`);
|
||||||
|
document.write(`<input class="skills" id="${skill.name}${checkbox_suffix}" type="checkbox">`);
|
||||||
|
document.write(`<input id="${skill.name}" type="text">`);
|
||||||
|
document.write(`<label for="${skill.name}${checkbox_suffix}" class="skills">${skill.name_rus}</label>`);
|
||||||
|
document.write(`</div>`);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<div class="skills">
|
||||||
|
Осталось (осн/доп): <span id="skills_result_selected"></span>/<span id="skills_result_unselected"></span>
|
||||||
|
</div>
|
||||||
|
<script>
|
||||||
|
document.write(`<p id="skills${message_suffix}"></p>`);
|
||||||
|
</script>
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
updateAfterLoading();
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
||||||
Reference in New Issue
Block a user