mirror of
https://github.com/Steffo99/royalspells.git
synced 2024-11-25 01:14:20 +00:00
✨ Add some more stuff
This commit is contained in:
parent
b2e2b94b75
commit
0ea42f7579
8 changed files with 184 additions and 79 deletions
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
5
.idea/codeStyles/codeStyleConfig.xml
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
<component name="ProjectCodeStyleConfiguration">
|
||||||
|
<state>
|
||||||
|
<option name="PREFERRED_PROJECT_CODE_STYLE" value="Default" />
|
||||||
|
</state>
|
||||||
|
</component>
|
|
@ -1,5 +1,6 @@
|
||||||
<component name="InspectionProjectProfileManager">
|
<component name="InspectionProjectProfileManager">
|
||||||
<settings>
|
<settings>
|
||||||
|
<option name="PROJECT_PROFILE" value="Default" />
|
||||||
<option name="USE_PROJECT_PROFILE" value="false" />
|
<option name="USE_PROJECT_PROFILE" value="false" />
|
||||||
<version value="1.0" />
|
<version value="1.0" />
|
||||||
</settings>
|
</settings>
|
||||||
|
|
|
@ -1,4 +1,7 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<project version="4">
|
<project version="4">
|
||||||
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8" project-jdk-type="Python SDK" />
|
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8" project-jdk-type="Python SDK" />
|
||||||
|
<component name="PythonCompatibilityInspectionAdvertiser">
|
||||||
|
<option name="version" value="3" />
|
||||||
|
</component>
|
||||||
</project>
|
</project>
|
|
@ -19,10 +19,15 @@
|
||||||
<select />
|
<select />
|
||||||
</component>
|
</component>
|
||||||
<component name="ChangeListManager">
|
<component name="ChangeListManager">
|
||||||
<list default="true" id="5a564ebd-fc70-42c4-839e-ada1568e38a3" name="Default Changelist" comment="">
|
<list default="true" id="5a564ebd-fc70-42c4-839e-ada1568e38a3" name="Default Changelist" comment="✨ Create the starting spell framework">
|
||||||
<change afterPath="$PROJECT_DIR$/royalspells/mixins.py" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/.idea/codeStyles/codeStyleConfig.xml" afterDir="false" />
|
||||||
<change afterPath="$PROJECT_DIR$/royalspells/spells.py" afterDir="false" />
|
<change afterPath="$PROJECT_DIR$/royalspells/buffs.py" afterDir="false" />
|
||||||
|
<change afterPath="$PROJECT_DIR$/royalspells/formulas.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/inspectionProfiles/profiles_settings.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/inspectionProfiles/profiles_settings.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/.idea/misc.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/misc.xml" afterDir="false" />
|
||||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/royalspells/mixins.py" beforeDir="false" afterPath="$PROJECT_DIR$/royalspells/mixins.py" afterDir="false" />
|
||||||
|
<change beforePath="$PROJECT_DIR$/royalspells/spells.py" beforeDir="false" afterPath="$PROJECT_DIR$/royalspells/spells.py" afterDir="false" />
|
||||||
</list>
|
</list>
|
||||||
<option name="SHOW_DIALOG" value="false" />
|
<option name="SHOW_DIALOG" value="false" />
|
||||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||||
|
@ -47,6 +52,7 @@
|
||||||
</component>
|
</component>
|
||||||
<component name="PropertiesComponent">
|
<component name="PropertiesComponent">
|
||||||
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
|
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
|
||||||
|
<property name="SHARE_PROJECT_CONFIGURATION_FILES" value="true" />
|
||||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||||
<property name="last_opened_file_path" value="$USER_HOME$/Code" />
|
<property name="last_opened_file_path" value="$USER_HOME$/Code" />
|
||||||
<property name="node.js.detected.package.eslint" value="true" />
|
<property name="node.js.detected.package.eslint" value="true" />
|
||||||
|
@ -55,7 +61,7 @@
|
||||||
<property name="node.js.path.for.package.tslint" value="project" />
|
<property name="node.js.path.for.package.tslint" value="project" />
|
||||||
<property name="node.js.selected.package.eslint" value="(autodetect)" />
|
<property name="node.js.selected.package.eslint" value="(autodetect)" />
|
||||||
<property name="node.js.selected.package.tslint" value="(autodetect)" />
|
<property name="node.js.selected.package.tslint" value="(autodetect)" />
|
||||||
<property name="settings.editor.selected.configurable" value="reference.settingsdialog.IDE.editor.colors" />
|
<property name="settings.editor.selected.configurable" value="preferences.sourceCode" />
|
||||||
</component>
|
</component>
|
||||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||||
<component name="TaskManager">
|
<component name="TaskManager">
|
||||||
|
@ -65,7 +71,8 @@
|
||||||
<option name="number" value="Default" />
|
<option name="number" value="Default" />
|
||||||
<option name="presentableId" value="Default" />
|
<option name="presentableId" value="Default" />
|
||||||
<updated>1600037431143</updated>
|
<updated>1600037431143</updated>
|
||||||
<workItem from="1600037432337" duration="5980000" />
|
<workItem from="1600037432337" duration="6228000" />
|
||||||
|
<workItem from="1600044301469" duration="3993000" />
|
||||||
</task>
|
</task>
|
||||||
<task id="LOCAL-00001" summary="1️⃣ First 4.0 commit">
|
<task id="LOCAL-00001" summary="1️⃣ First 4.0 commit">
|
||||||
<created>1600037920485</created>
|
<created>1600037920485</created>
|
||||||
|
@ -74,7 +81,14 @@
|
||||||
<option name="project" value="LOCAL" />
|
<option name="project" value="LOCAL" />
|
||||||
<updated>1600037920485</updated>
|
<updated>1600037920485</updated>
|
||||||
</task>
|
</task>
|
||||||
<option name="localTasksCounter" value="2" />
|
<task id="LOCAL-00002" summary="✨ Create the starting spell framework">
|
||||||
|
<created>1600043652299</created>
|
||||||
|
<option name="number" value="00002" />
|
||||||
|
<option name="presentableId" value="LOCAL-00002" />
|
||||||
|
<option name="project" value="LOCAL" />
|
||||||
|
<updated>1600043652299</updated>
|
||||||
|
</task>
|
||||||
|
<option name="localTasksCounter" value="3" />
|
||||||
<servers />
|
<servers />
|
||||||
</component>
|
</component>
|
||||||
<component name="TypeScriptGeneratedFilesManager">
|
<component name="TypeScriptGeneratedFilesManager">
|
||||||
|
@ -90,15 +104,29 @@
|
||||||
</entry>
|
</entry>
|
||||||
</map>
|
</map>
|
||||||
</option>
|
</option>
|
||||||
|
<option name="oldMeFiltersMigrated" value="true" />
|
||||||
</component>
|
</component>
|
||||||
<component name="VcsManagerConfiguration">
|
<component name="VcsManagerConfiguration">
|
||||||
<MESSAGE value="1️⃣ First 4.0 commit" />
|
<MESSAGE value="1️⃣ First 4.0 commit" />
|
||||||
<option name="LAST_COMMIT_MESSAGE" value="1️⃣ First 4.0 commit" />
|
<MESSAGE value="✨ Create the starting spell framework" />
|
||||||
|
<option name="LAST_COMMIT_MESSAGE" value="✨ Create the starting spell framework" />
|
||||||
</component>
|
</component>
|
||||||
<component name="WindowStateProjectService">
|
<component name="WindowStateProjectService">
|
||||||
<state x="1840" y="278" key="Vcs.Push.Dialog.v2" timestamp="1600037924417">
|
<state x="1874" y="238" key="#Inspections" timestamp="1600047310334">
|
||||||
<screen x="1280" y="0" width="1920" height="1080" />
|
<screen x="1280" y="0" width="1920" height="1080" />
|
||||||
</state>
|
</state>
|
||||||
<state x="1840" y="278" key="Vcs.Push.Dialog.v2/1280.0.1920.1080/3200.0.1280.1024/0.32.1280.992@1280.0.1920.1080" timestamp="1600037924417" />
|
<state x="1874" y="238" key="#Inspections/1280.0.1920.1080/3200.0.1280.1024/0.32.1280.992@1280.0.1920.1080" timestamp="1600047310334" />
|
||||||
|
<state x="2347" y="32" width="853" height="1048" key="#com.intellij.refactoring.rename.AutomaticRenamingDialog" timestamp="1600044528395">
|
||||||
|
<screen x="1280" y="0" width="1920" height="1080" />
|
||||||
|
</state>
|
||||||
|
<state x="2347" y="32" width="853" height="1048" key="#com.intellij.refactoring.rename.AutomaticRenamingDialog/1280.0.1920.1080/3200.0.1280.1024/0.32.1280.992@1280.0.1920.1080" timestamp="1600044528395" />
|
||||||
|
<state x="1877" y="242" key="SettingsEditor" timestamp="1600046303544">
|
||||||
|
<screen x="1280" y="0" width="1920" height="1080" />
|
||||||
|
</state>
|
||||||
|
<state x="1877" y="242" key="SettingsEditor/1280.0.1920.1080/3200.0.1280.1024/0.32.1280.992@1280.0.1920.1080" timestamp="1600046303544" />
|
||||||
|
<state x="1840" y="278" key="Vcs.Push.Dialog.v2" timestamp="1600043653452">
|
||||||
|
<screen x="1280" y="0" width="1920" height="1080" />
|
||||||
|
</state>
|
||||||
|
<state x="1840" y="278" key="Vcs.Push.Dialog.v2/1280.0.1920.1080/3200.0.1280.1024/0.32.1280.992@1280.0.1920.1080" timestamp="1600043653452" />
|
||||||
</component>
|
</component>
|
||||||
</project>
|
</project>
|
3
royalspells/buffs.py
Normal file
3
royalspells/buffs.py
Normal file
|
@ -0,0 +1,3 @@
|
||||||
|
class Buff:
|
||||||
|
# TODO
|
||||||
|
...
|
83
royalspells/formulas.py
Normal file
83
royalspells/formulas.py
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
from typing import *
|
||||||
|
|
||||||
|
import abc
|
||||||
|
import random
|
||||||
|
import math
|
||||||
|
|
||||||
|
from .mixins import *
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"Formula",
|
||||||
|
"RandNonNegativeGaussFormula",
|
||||||
|
"RandNonNegativeGaussFormula",
|
||||||
|
"FixedFormula",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
class Formula(Selectable, metaclass=abc.ABCMeta):
|
||||||
|
"""A int-returning function that will be evaluated at a later time."""
|
||||||
|
|
||||||
|
@abc.abstractmethod
|
||||||
|
def calc(self, rand: random.Random) -> int:
|
||||||
|
"""Calculate the value of the Formula."""
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def select(cls, rand: random.Random) -> Formula:
|
||||||
|
# TODO: I'm not sure if it's a good idea leaving it here
|
||||||
|
type_ = rand.randrange(1, 101)
|
||||||
|
mean = rand.randrange(1, 80) * 10
|
||||||
|
delta = rand.randrange(1, 300)
|
||||||
|
|
||||||
|
if type_ <= 70:
|
||||||
|
return RandNonNegativeGaussFormula(mu=mean, sigma=math.sqrt(delta))
|
||||||
|
elif type_ <= 90:
|
||||||
|
return RandNonNegativeUniformFormula(min_=mean-delta, max_=mean+delta)
|
||||||
|
else:
|
||||||
|
return FixedFormula(mean)
|
||||||
|
|
||||||
|
|
||||||
|
class RandNonNegativeUniformFormula(Formula):
|
||||||
|
"""A :class:`Formula` that implements the ``calc`` method using a uniform distribution, setting to 0 the
|
||||||
|
result if it is negative and finally ceiling the result."""
|
||||||
|
|
||||||
|
def __init__(self, min_: float, max_: float, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.min: float = min_
|
||||||
|
self.max: float = max_
|
||||||
|
|
||||||
|
def calc(self, rand: random.Random) -> int:
|
||||||
|
n = rand.uniform(self.min, self.max)
|
||||||
|
n = n if n > 0 else 0
|
||||||
|
n = math.ceil(n)
|
||||||
|
return n
|
||||||
|
|
||||||
|
|
||||||
|
class RandNonNegativeGaussFormula(Formula):
|
||||||
|
"""A :class:`Formula` that implements the ``calc`` method using a gaussian (normal) distribution, setting to 0 the
|
||||||
|
result if it is negative and finally ceiling the result."""
|
||||||
|
|
||||||
|
def __init__(self, mu: float, sigma: float, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.mu: float = mu
|
||||||
|
self.sigma: float = sigma
|
||||||
|
|
||||||
|
def calc(self, rand: random.Random) -> int:
|
||||||
|
"""A mixin that implements the ``calculate`` method using a gaussian (normal) distribution."""
|
||||||
|
n = rand.gauss(self.mu, self.sigma)
|
||||||
|
n = n if n > 0 else 0
|
||||||
|
n = math.ceil(n)
|
||||||
|
return n
|
||||||
|
|
||||||
|
|
||||||
|
class FixedFormula(Formula):
|
||||||
|
"""A :class:`Formula` that implements the ``calc`` method by always returning a fixed value."""
|
||||||
|
|
||||||
|
def __init__(self, value: int, *args, **kwargs):
|
||||||
|
super().__init__(*args, **kwargs)
|
||||||
|
self.value = value
|
||||||
|
|
||||||
|
def calc(self, rand: random.Random) -> int:
|
||||||
|
return self.value
|
|
@ -1,14 +1,24 @@
|
||||||
from typing import *
|
from typing import *
|
||||||
|
import abc
|
||||||
import random
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
__all__ = [
|
||||||
|
"SeededMixin",
|
||||||
|
"Selectable",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
class SeededMixin:
|
class SeededMixin:
|
||||||
def __init__(self, seed: Hashable, *args, **kwargs):
|
def __init__(self, seed: Hashable, *args, **kwargs):
|
||||||
super().__init__(*args, **kwargs)
|
super().__init__(*args, **kwargs)
|
||||||
self.rand = random.Random(hash(seed))
|
self.rand = random.Random(hash(seed))
|
||||||
|
|
||||||
|
|
||||||
class RandomMixin:
|
class Selectable(metaclass=abc.ABCMeta):
|
||||||
def __init__(self, rand: random.Random, *args, **kwargs):
|
"""A class from which an instance can be generated through the :meth:`.select` method."""
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.rand = rand
|
@classmethod
|
||||||
|
@abc.abstractmethod
|
||||||
|
def select(cls, rand: random.Random):
|
||||||
|
raise NotImplementedError()
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
from typing import *
|
from typing import *
|
||||||
import math
|
|
||||||
import enum
|
import enum
|
||||||
import abc
|
import random
|
||||||
|
|
||||||
from .mixins import *
|
from .mixins import *
|
||||||
|
from .formulas import *
|
||||||
|
from .buffs import *
|
||||||
|
|
||||||
|
|
||||||
class Spell(SeededMixin):
|
class Spell(SeededMixin):
|
||||||
|
@ -14,24 +15,7 @@ class Spell(SeededMixin):
|
||||||
self.cost = ...
|
self.cost = ...
|
||||||
|
|
||||||
|
|
||||||
class Effect(RandomMixin):
|
class Target(enum.Enum, Selectable):
|
||||||
"""A single consequence of a spell."""
|
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
|
|
||||||
self.target: Target = Target.select(self.rand)
|
|
||||||
"""The :class:`Target` of the effect."""
|
|
||||||
|
|
||||||
self.damage: Optional[Damage] = ...
|
|
||||||
"""The :class:`Damage` of the effect, or :const:`None` if it doesn't do any damage."""
|
|
||||||
|
|
||||||
self.healing = ...
|
|
||||||
self.buffs = ...
|
|
||||||
self.attributes = ...
|
|
||||||
|
|
||||||
|
|
||||||
class Target(enum.Enum):
|
|
||||||
"""A target for a spell."""
|
"""A target for a spell."""
|
||||||
|
|
||||||
RANDOM_ENEMY = enum.auto()
|
RANDOM_ENEMY = enum.auto()
|
||||||
|
@ -43,10 +27,9 @@ class Target(enum.Enum):
|
||||||
USELESS_THING = enum.auto()
|
USELESS_THING = enum.auto()
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def select(cls, seed: random.Random):
|
def select(cls, rand: random.Random):
|
||||||
"""Pick a target using the default distribution."""
|
"""Pick a target using the default distribution."""
|
||||||
|
result = rand.randrange(1, 101)
|
||||||
result = seed.randrange(1, 101)
|
|
||||||
"""A number from 1 to 100, determining the chosen target."""
|
"""A number from 1 to 100, determining the chosen target."""
|
||||||
|
|
||||||
# 50%: RANDOM_ENEMY
|
# 50%: RANDOM_ENEMY
|
||||||
|
@ -72,56 +55,45 @@ class Target(enum.Enum):
|
||||||
return Target.USELESS_THING
|
return Target.USELESS_THING
|
||||||
|
|
||||||
|
|
||||||
class Damage(RandomMixin, metaclass=abc.ABCMeta):
|
class Effect(Selectable):
|
||||||
"""The damage of a spell effect. Should be extended, implementing its methods.
|
"""A single consequence of a spell."""
|
||||||
|
|
||||||
Examples:
|
def __init__(self,
|
||||||
See :class:`UniformDamage`, :class:`NormalDamage` and :class:`FixedDamage`."""
|
target: Target,
|
||||||
|
damage: Optional[Formula] = None,
|
||||||
|
healing: Optional[Formula] = None,
|
||||||
|
buffs: Optional[List[Buff]] = None):
|
||||||
|
|
||||||
@abc.abstractmethod
|
self.target: Target = target
|
||||||
def select(self, rand: random.Random) -> int:
|
"""The :class:`Target` of the effect."""
|
||||||
"""Calculate the damage of the spell. It should always return a non-negative :class:`int`.
|
|
||||||
|
|
||||||
Note:
|
self.damage: Optional[Formula] = damage
|
||||||
It uses a separate RNG than the one passed to the damage class!"""
|
"""The :class:`Formula` that calculates the damage of the effect, or :const:`None` if it doesn't do any
|
||||||
raise NotImplementedError()
|
damage."""
|
||||||
|
|
||||||
|
self.healing: Optional[Formula] = healing
|
||||||
|
"""The :class:`Formula` that calculates the healing of the effect, or :const:`None` if it doesn't do any
|
||||||
|
damage."""
|
||||||
|
|
||||||
class UniformDamage(Damage):
|
self.buffs: List[Buff] = buffs if buffs else []
|
||||||
"""The damage of a spell effect, following a gaussian distribution."""
|
"""A :class:`list` of :class:`Buff` that will be applied to the target after the damage/healing is applied."""
|
||||||
|
|
||||||
def __init__(self, min_: float, max_: float, *args, **kwargs):
|
@classmethod
|
||||||
super().__init__(*args, **kwargs)
|
def select(cls, rand: random.Random):
|
||||||
self.min: float = min_
|
# noinspection PyDictCreation
|
||||||
self.max: float = max_
|
kw = {}
|
||||||
|
|
||||||
def select(self, rand: random.Random) -> int:
|
kw["target"] = Target.select(rand)
|
||||||
n = self.rand.uniform(self.min, self.max)
|
|
||||||
n = math.ceil(n)
|
|
||||||
return n
|
|
||||||
|
|
||||||
|
type_ = rand.randrange(1, 101)
|
||||||
|
# 70%: Damaging
|
||||||
|
if type_ <= 70:
|
||||||
|
kw["damage"] = Formula.select(rand)
|
||||||
|
# 20%: Healing
|
||||||
|
elif type_ <= 90:
|
||||||
|
kw["healing"] = Formula.select(rand) if rand.randrange(1, 101) <= 20 else None
|
||||||
|
# 10%: Neither
|
||||||
|
|
||||||
class NormalDamage(Damage):
|
kw["buffs"] = []
|
||||||
"""The damage of a spell effect, following a gaussian distribution."""
|
|
||||||
|
|
||||||
def __init__(self, mu: float, sigma: float, *args, **kwargs):
|
return cls(**kw)
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.mu: float = mu
|
|
||||||
self.sigma: float = sigma
|
|
||||||
|
|
||||||
def select(self, rand: random.Random) -> int:
|
|
||||||
n = self.rand.gauss(self.mu, self.sigma)
|
|
||||||
n = n if n > 0 else 0
|
|
||||||
n = math.ceil(n)
|
|
||||||
return n
|
|
||||||
|
|
||||||
|
|
||||||
class FixedDamage(Damage):
|
|
||||||
"""The damage of a spell effect, which is always constant."""
|
|
||||||
|
|
||||||
def __init__(self, value: int, *args, **kwargs):
|
|
||||||
super().__init__(*args, **kwargs)
|
|
||||||
self.value = value
|
|
||||||
|
|
||||||
def select(self, rand: random.Random) -> int:
|
|
||||||
return self.value
|
|
||||||
|
|
Loading…
Reference in a new issue