Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

first spells

  • Loading branch information...
commit 23d0c0ba7b05f5a41de7cb7c550dac407fb84cf1 1 parent 586f6c7
@alexbft authored
View
29 tornado/effect.py
@@ -14,7 +14,7 @@ def get(id, *args):
class Effect:
# Íàçâàíèå ýôôåêòà
- name = "Unknown"
+ name = "Íåèçâåñòíî"
# Èêîíêà
icon = "+"
# Ïðèîðèòåò âûïîëíåíèÿ
@@ -49,13 +49,30 @@ def js_load(src, host):
def js(self):
''' Äëÿ âûäà÷è þçåðó '''
return {"name": self.name, "icon": self.icon, "turns_left": self.turns_left}
+
+ @property
+ def cur(self):
+ return self.host.stats.cur
-class UpMagic(Effect):
- name = "Mighty Magic"
+class Reflect(Effect):
+ name = "Îòðàæåíèå óðîíà"
+ group = "Reflect"
+
+ def __init__(self, refl, limit):
+ self.refl = refl
+ self.limit = limit
+
+ def recount(self):
+ self.cur["reflect"] = self.refl
+ self.cur["reflect_limit"] = self.limit
+
+class Mult(Effect):
priority = -10
- def __init__(self, q):
- self.q = q
+ def __init__(self, name, stat, factor):
+ self.name = name
+ self.stat = stat
+ self.factor = factor
def recount(self):
- self.host.stats.cur["matk"] *= 2
+ self.cur[self.stat] *= self.factor
View
74 tornado/fighter.py
@@ -138,15 +138,27 @@ def card_in_hand_by_id(self, id):
except StopIteration:
return None
- def heal(self, amount):
+ def heal(self, amount, source=None, log=None):
''' Похилять файтера.
int amount - на сколько hp
- Возвращает реальное кол-во вылеченных hp.
'''
old = self.hp
self.hp += amount
self.check_stats()
- return self.hp - old
+ healed = self.hp - old
+ # Запись в лог.
+ if log != None:
+ if isinstance(log, tuple):
+ msg, params = log
+ else:
+ msg, params = log, {}
+ msg = msg.replace("{heal}", unicode(healed))
+ if "{source:f}" in msg:
+ params["source"] = source.js_link()
+ if "{target:f}" in msg:
+ params["target"] = self.js_link()
+ self.fight.log(msg, params)
+ return healed
def check_stats(self):
''' Проверить корректность статов.
@@ -167,32 +179,70 @@ def attack(self, other):
Fighter other
'''
raw = level_multiplier(self.level) * self.stats["atk"]
- dmg = other.damage(raw, source=self, magic=False)
- self.fight.log(u"{attacker:f} наносит {target:f} %s урона." % dmg, {"attacker": self.js_link(), "target": other.js_link()})
+ crit_msg = ""
+ if self.stats["crit"] > 0:
+ if random.random() * 100 < self.stats["crit"]:
+ raw *= (2 + float(self.stats["crit_bonus"]))
+ crit_msg = u"Критический удар! "
+ dmg = other.damage(raw, source=self, magic=False, log = u"%s{source:f} наносит {target:f} {damage} урона." % crit_msg)
+ if self.stats["vampire"] > 0 and dmg > 0:
+ vamp = int(dmg * self.stats["vampire"] / 100)
+ if vamp > 0:
+ self.heal(vamp, source=self, log=(u"{target:f} высасывает %s жизни из {from:f}." % vamp, {"from": other.js_link()}))
- def damage(self, amount, source=None, magic=False, spec=None):
+ def damage(self, amount, source=None, magic=False, spec=None, limit = None, log=None):
''' Нанести урон файтеру.
int amount - кол-во "сырого" урона
Fighter source - источник урона
bool magic - магический или физический урон
str spec - разновидность урона (например "Fire" или "Psyonic")
-
- Возвращает кол-во, на которое уменьшились hp файтера.
+ log - что записать в лог ({damage} - дамаг, {source:f} - источник дамага, {target:f} - цель дамага)
'''
resist = self.stats["mdef"] if magic else self.stats["def"]
if resist < 1:
resist = 1
- amount = int(amount / (resist * 0.1))
- self.hp -= amount
- return amount
+ dmg = int(amount / (resist * 0.1))
+ if limit != None and dmg > limit:
+ dmg = limit
+ # Щит.
+ if dmg > 0 and self.stats["shield"] > 0 and not magic:
+ blocked = min(dmg, self.stats["shield"])
+ dmg -= blocked
+ self.stats["shield"] -= blocked
+ if source == None:
+ self.fight.log(u"Щит {target:f} поглощает %s урона от удара." % blocked, {"target": self.js_link()})
+ else:
+ self.fight.log(u"Щит {target:f} поглощает %s урона от удара {source:f}." % blocked, {"target": self.js_link(), "source": source.js_link()})
+ # Ааааргх!
+ self.hp -= dmg
+ # Запись в лог.
+ if log != None:
+ if isinstance(log, tuple):
+ msg, params = log
+ else:
+ msg, params = log, {}
+ msg = msg.replace("{damage}", unicode(dmg))
+ if "{source:f}" in msg:
+ params["source"] = source.js_link()
+ if "{target:f}" in msg:
+ params["target"] = self.js_link()
+ self.fight.log(msg, params)
+ # Рефлект.
+ if self.stats["reflect"] > 0 and spec != "reflect" and source != None:
+ reflect = int(amount * self.stats["reflect"] / 100)
+ ref_limit = None
+ if self.stats["reflect_limit"] > 0:
+ ref_limit = self.stats["reflect_limit"]
+ source.damage(reflect, source=self, magic=magic, spec="reflect", limit = ref_limit, log = u"{source:f} отражает {damage} урона обратно в {target:f}!")
+ return dmg
def draw(self, num):
' Взять num карт из колоды. '
if not self.have_deck:
return
if len(self.deck) < num:
- self.die()
self.fight.log(u"{:f} проигрывает бой из-за нехватки карт!", self.js_link())
+ self.die()
else:
cards = self.deck[:num]
self.deck = self.deck[num:]
View
2  tornado/mob.py
@@ -90,5 +90,5 @@ def select_target(self):
class RichMan(Mob):
name = "Rich man"
stats = {"hp_max": 0.3}
- loot = [ (item.card("Test"), 1), (item.scroll("Heal"), 0.5) ]
+ loot = [ (item.card("Atk"), 1), (item.scroll("Heal"), 0.5) ]
View
146 tornado/spell.py
@@ -18,16 +18,6 @@ def get(id):
else:
raise utils.MyException("Not a spell!")
-def heal_msg(f, amount):
- ''' Сообщение при лечении файтера.
- Fighter f - файтер
- int amount - кол-во вылеченных hp.
- '''
- if amount > 0:
- return (u"{healed:f} восстанавливает " + str(amount) + u" единиц здоровья.", {"healed": f.js_link()})
- else:
- return ("", None)
-
_spells = None
def spells():
global _spells
@@ -41,7 +31,7 @@ def spells():
class Spell:
# Название заклинания.
- name = "Unknown"
+ name = "Неизвестно"
# Набор допустимых целей (allies, enemies, self, not_self, dead, alive_or_dead) через пробел.
target = ""
# Приоритет заклинания.
@@ -90,28 +80,28 @@ def msg(self, message, params = None):
''' Пишет сообщение в чат.
str message - сообщение (или шаблон).
params - параметры.
- К параметрам автоматом добавляются: caster:f - кастер заклинания, target:f - цель заклинания, spell:s - заклинание.
+ К параметрам автоматом добавляются: src:f - кастер заклинания, dest:f - цель заклинания, spell:s - заклинание.
'''
if params == None:
params = {}
- params.update({"caster": self._caster.js_link(), "target": self._target.js_link(), "spell": self.js_link()})
- self._caster.fight.log(message, params)
- self._need_msg = False
+ params.update({"src": self.src.js_link(), "dest": self.dest.js_link(), "spell": self.js_link()})
+ self.src.fight.log(message, params)
+ self.need_msg = False
def cast_message(self):
' Стандартное сообщение о применении заклинания. '
- self.msg(u"{caster:f} применяет {spell:s} на %s." % (u"cебя" if self.target_self() else "{target:f}"))
+ self.msg(u"{src:f} применяет {spell:s} на %s." % (u"cебя" if self.target_self() else "{dest:f}"))
def _cast(self, caster, target):
''' Каст заклинания.
Fighter caster - кастер.
Fighter target - цель.
'''
- self._caster = caster
- self._target = target
- self._need_msg = True
+ self.src = caster
+ self.dest = target
+ self.need_msg = True
self.cast()
- if self._need_msg:
+ if self.need_msg:
self.cast_message()
def cast(self):
@@ -121,7 +111,7 @@ def cast(self):
def target_self(self):
' Возвращает, является ли целью заклинания сам кастер. '
- return self._caster == self._target
+ return self.src == self.dest
def js_link(self):
' Для ссылки '
@@ -132,42 +122,116 @@ def add_effect(self, effect, turns, target = None):
Параметры аналогичны Fighter.add_effect.
'''
if target == None:
- target = self._target
- target.add_effect(effect, turns=turns, source=self._caster)
+ target = self.dest
+ target.add_effect(effect, turns=turns, source=self.src)
-class Attack(Spell):
- name = "Attack! +20%"
+class Atk(Spell):
+ name = "Атака +2"
target = "allies"
def cast(self):
- st = self._target.stats.base
- st["atk"] = int(st["atk"] * 1.2)
+ self.dest.stats["atk"] += 2
+
+class Def(Spell):
+ name = "Защита +2"
+ target = "allies"
+ def cast(self):
+ self.dest.stats["def"] += 2
+
class Heal(Spell):
- name = "Heal 10 HP"
+ name = "Лечение"
+ target = "allies"
def cast(self):
- hmsg, hparams = heal_msg(self._target, self._target.heal(10))
if self.target_self():
- self.msg(u"{caster:f} лечится. " + hmsg, hparams)
+ hmsg = u"{target:f} лечится на {heal} здоровья."
else:
- self.msg(u"{caster:f} лечит {target:f}. " + hmsg, hparams)
-
-class UpMagic(Spell):
- name = "Mighty Magic"
+ hmsg = u"{source:f} лечит {target:f} {heal} здоровья."
+ self.dest.heal(self.src.stats["matk"], source=self.src, log=hmsg)
+ self.need_msg = False
+
+class ShieldBash(Spell):
+ name = "Удар щитом"
+ target = "enemies"
+
+ def cast(self):
+ self.dest.damage(self.src.stats["def"], source=self.src, log=u"{source:f} ударяет щитом {target:f}, нанося {damage} урона.")
+ self.need_msg = False
+
+class Reflect(Spell):
+ name = "Отражение"
target = "self"
- rarity = COMMON
+ rarity = UNCOMMON
+ shop = False
def cast(self):
- self.add_effect(effect.get("UpMagic", 2), 3)
+ self.add_effect(effect.get("Reflect", 100, 100), 1)
-class Test(Spell):
- rarity = UNIQUE
- target = "self not_self"
- name = "SUPER PISH PISH"
+class Crit(Spell):
+ name = "Крит +10%"
+ target = "self"
+ def cast(self):
+ self.dest.stats["crit"] += 10
+
+class Vamp(Spell):
+ name = "Вампиризм +10%"
+ target = "self"
+
+ def cast(self):
+ self.dest.stats["vampire"] += 10
+
+class Mdef(Spell):
+ name = "Маг. защита +2"
+ target = "allies"
+
+ def cast(self):
+ self.dest.stats["mdef"] += 2
+
+class SuperAtk(Spell):
+ name = "Кровожадность"
+ target = "self"
+ rarity = UNCOMMON
+ shop = False
+
+ def cast(self):
+ self.add_effect(effect.get("Mult", self.name, "atk", 2), 2)
+
+class Matk(Spell):
+ name = "Маг. атака +2"
+ target = "allies"
+
+ def cast(self):
+ self.dest.stats["matk"] += 2
+
+class Shield(Spell):
+ name = "Сфера защиты"
+ target = "self"
+
+ def cast(self):
+ self.dest.stats["shield"] += self.src.stats["mdef"]
+
+class Fireball(Spell):
+ name = "Огненный шар"
+ target = "enemies"
+
+ def cast(self):
+ self.dest.damage(self.src.stats["matk"] * 1.5, source=self.src, magic=True,
+ log=(u"{source:f} запускает {spell:s} в {target:f}, нанося {damage} урона!", {"spell": self.js_link()}))
+ self.need_msg = False
+
+class SuperMatk(Spell):
+ name = "Темный ритуал"
+ target = "self"
+ rarity = UNCOMMON
+ shop = False
+
+ def cast(self):
+ self.add_effect(effect.get("Mult", self.name, "matk", 2), 2)
+
class UsedScroll(Spell):
- name = "Used scroll"
+ name = "Пустой свиток"
target = "self not_self"
price = 1
shop = False
View
17 tornado/static/js/scripts.js
@@ -26,11 +26,26 @@
// + scrolls
// + прокрутка для main_area
// - game start (starting decks)
+// - enforce level limit for cards
// - shop cards
-// - some content...
+// - potions and items
+// - зоны в подземелье
+// - мобы и лут
+// - арена 2х2, 3х3 рандом
+// - gems (только возможности пока)
// - грофон:
// - старт пейдж
+// - новости
+// - вход
+// - создание перса
// - картинки заклинаний, тултипы, описания
+// - мобы и персонажи
+// - локации:
+// - старт
+// - подземелье
+// - зоны ...
+// - арена
+// - магаз
var u;
View
4 tornado/stats.py
@@ -12,13 +12,15 @@ def __init__(self, src = None):
'''
if src:
self.__dict__.update(src)
+ self.base = defaultdict(int, self.base)
+ self.cur = defaultdict(int, self.cur)
else:
self.base = defaultdict(int)
self.cur = defaultdict(int)
def reset(self):
' Устанавливает текущие статы в базовые. '
- self.cur = dict(self.base)
+ self.cur = defaultdict(int, self.base)
def __getitem__(self, key):
' По умолчанию возвращаем текущее значение стата. '
Please sign in to comment.
Something went wrong with that request. Please try again.