mirror of
https://github.com/Steffo99/royalspells.git
synced 2024-11-24 08:54:21 +00:00
✨ Create the starting spell framework
This commit is contained in:
parent
78d8f5b72b
commit
b2e2b94b75
3 changed files with 194 additions and 2 deletions
|
@ -1,14 +1,41 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<project version="4">
|
||||
<component name="BranchesTreeState">
|
||||
<expand>
|
||||
<path>
|
||||
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
|
||||
<item name="LOCAL_ROOT" type="e8cecc67:BranchNodeDescriptor" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
|
||||
<item name="REMOTE_ROOT" type="e8cecc67:BranchNodeDescriptor" />
|
||||
</path>
|
||||
<path>
|
||||
<item name="ROOT" type="e8cecc67:BranchNodeDescriptor" />
|
||||
<item name="REMOTE_ROOT" type="e8cecc67:BranchNodeDescriptor" />
|
||||
<item name="GROUP_NODE:origin" type="e8cecc67:BranchNodeDescriptor" />
|
||||
</path>
|
||||
</expand>
|
||||
<select />
|
||||
</component>
|
||||
<component name="ChangeListManager">
|
||||
<list default="true" id="5a564ebd-fc70-42c4-839e-ada1568e38a3" name="Default Changelist" comment="">
|
||||
<change afterPath="$PROJECT_DIR$/royalspells/__init__.py" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/royalspells/mixins.py" afterDir="false" />
|
||||
<change afterPath="$PROJECT_DIR$/royalspells/spells.py" afterDir="false" />
|
||||
<change beforePath="$PROJECT_DIR$/.idea/workspace.xml" beforeDir="false" afterPath="$PROJECT_DIR$/.idea/workspace.xml" afterDir="false" />
|
||||
</list>
|
||||
<option name="SHOW_DIALOG" value="false" />
|
||||
<option name="HIGHLIGHT_CONFLICTS" value="true" />
|
||||
<option name="HIGHLIGHT_NON_ACTIVE_CHANGELIST" value="false" />
|
||||
<option name="LAST_RESOLUTION" value="IGNORE" />
|
||||
</component>
|
||||
<component name="FileTemplateManagerImpl">
|
||||
<option name="RECENT_TEMPLATES">
|
||||
<list>
|
||||
<option value="Python Script" />
|
||||
</list>
|
||||
</option>
|
||||
</component>
|
||||
<component name="Git.Settings">
|
||||
<option name="RECENT_GIT_ROOT_PATH" value="$PROJECT_DIR$" />
|
||||
</component>
|
||||
|
@ -22,6 +49,12 @@
|
|||
<property name="RunOnceActivity.OpenProjectViewOnStart" value="true" />
|
||||
<property name="WebServerToolWindowFactoryState" value="false" />
|
||||
<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.tslint" value="true" />
|
||||
<property name="node.js.path.for.package.eslint" 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.tslint" value="(autodetect)" />
|
||||
<property name="settings.editor.selected.configurable" value="reference.settingsdialog.IDE.editor.colors" />
|
||||
</component>
|
||||
<component name="SpellCheckerSettings" RuntimeDictionaries="0" Folders="0" CustomDictionaries="0" DefaultDictionary="application-level" UseSingleDictionary="true" transferred="true" />
|
||||
|
@ -32,8 +65,16 @@
|
|||
<option name="number" value="Default" />
|
||||
<option name="presentableId" value="Default" />
|
||||
<updated>1600037431143</updated>
|
||||
<workItem from="1600037432337" duration="336000" />
|
||||
<workItem from="1600037432337" duration="5980000" />
|
||||
</task>
|
||||
<task id="LOCAL-00001" summary="1️⃣ First 4.0 commit">
|
||||
<created>1600037920485</created>
|
||||
<option name="number" value="00001" />
|
||||
<option name="presentableId" value="LOCAL-00001" />
|
||||
<option name="project" value="LOCAL" />
|
||||
<updated>1600037920485</updated>
|
||||
</task>
|
||||
<option name="localTasksCounter" value="2" />
|
||||
<servers />
|
||||
</component>
|
||||
<component name="TypeScriptGeneratedFilesManager">
|
||||
|
@ -50,4 +91,14 @@
|
|||
</map>
|
||||
</option>
|
||||
</component>
|
||||
<component name="VcsManagerConfiguration">
|
||||
<MESSAGE value="1️⃣ First 4.0 commit" />
|
||||
<option name="LAST_COMMIT_MESSAGE" value="1️⃣ First 4.0 commit" />
|
||||
</component>
|
||||
<component name="WindowStateProjectService">
|
||||
<state x="1840" y="278" key="Vcs.Push.Dialog.v2" timestamp="1600037924417">
|
||||
<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="1600037924417" />
|
||||
</component>
|
||||
</project>
|
14
royalspells/mixins.py
Normal file
14
royalspells/mixins.py
Normal file
|
@ -0,0 +1,14 @@
|
|||
from typing import *
|
||||
import random
|
||||
|
||||
|
||||
class SeededMixin:
|
||||
def __init__(self, seed: Hashable, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.rand = random.Random(hash(seed))
|
||||
|
||||
|
||||
class RandomMixin:
|
||||
def __init__(self, rand: random.Random, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.rand = rand
|
127
royalspells/spells.py
Normal file
127
royalspells/spells.py
Normal file
|
@ -0,0 +1,127 @@
|
|||
from typing import *
|
||||
import math
|
||||
import enum
|
||||
import abc
|
||||
|
||||
from .mixins import *
|
||||
|
||||
|
||||
class Spell(SeededMixin):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
|
||||
self.effects: List[Effect] = [...]
|
||||
self.cost = ...
|
||||
|
||||
|
||||
class Effect(RandomMixin):
|
||||
"""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."""
|
||||
|
||||
RANDOM_ENEMY = enum.auto()
|
||||
ALL_ENEMIES = enum.auto()
|
||||
RANDOM_ALLY = enum.auto()
|
||||
ALL_ALLIES = enum.auto()
|
||||
RANDOM_CREATURE = enum.auto()
|
||||
ALL_CREATURES = enum.auto()
|
||||
USELESS_THING = enum.auto()
|
||||
|
||||
@classmethod
|
||||
def select(cls, seed: random.Random):
|
||||
"""Pick a target using the default distribution."""
|
||||
|
||||
result = seed.randrange(1, 101)
|
||||
"""A number from 1 to 100, determining the chosen target."""
|
||||
|
||||
# 50%: RANDOM_ENEMY
|
||||
if result <= 50:
|
||||
return Target.RANDOM_ENEMY
|
||||
# 20%: ALL_ENEMIES
|
||||
elif result <= 70:
|
||||
return Target.ALL_ENEMIES
|
||||
# 15%: RANDOM_ALLY
|
||||
elif result <= 85:
|
||||
return Target.RANDOM_ALLY
|
||||
# 5%: ALL_ALLIES
|
||||
elif result <= 90:
|
||||
return Target.ALL_ALLIES
|
||||
# 5%: RANDOM_CREATURE
|
||||
elif result <= 95:
|
||||
return Target.RANDOM_CREATURE
|
||||
# 3%: ALL_CREATURES
|
||||
elif result <= 98:
|
||||
return Target.ALL_CREATURES
|
||||
# 2%: USELESS_THING
|
||||
else:
|
||||
return Target.USELESS_THING
|
||||
|
||||
|
||||
class Damage(RandomMixin, metaclass=abc.ABCMeta):
|
||||
"""The damage of a spell effect. Should be extended, implementing its methods.
|
||||
|
||||
Examples:
|
||||
See :class:`UniformDamage`, :class:`NormalDamage` and :class:`FixedDamage`."""
|
||||
|
||||
@abc.abstractmethod
|
||||
def select(self, rand: random.Random) -> int:
|
||||
"""Calculate the damage of the spell. It should always return a non-negative :class:`int`.
|
||||
|
||||
Note:
|
||||
It uses a separate RNG than the one passed to the damage class!"""
|
||||
raise NotImplementedError()
|
||||
|
||||
|
||||
class UniformDamage(Damage):
|
||||
"""The damage of a spell effect, following a gaussian distribution."""
|
||||
|
||||
def __init__(self, min_: float, max_: float, *args, **kwargs):
|
||||
super().__init__(*args, **kwargs)
|
||||
self.min: float = min_
|
||||
self.max: float = max_
|
||||
|
||||
def select(self, rand: random.Random) -> int:
|
||||
n = self.rand.uniform(self.min, self.max)
|
||||
n = math.ceil(n)
|
||||
return n
|
||||
|
||||
|
||||
class NormalDamage(Damage):
|
||||
"""The damage of a spell effect, following a gaussian distribution."""
|
||||
|
||||
def __init__(self, mu: float, sigma: float, *args, **kwargs):
|
||||
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