########################################################################################
# This file is part of Spheres.
# Copyright (C) 2019 Jesusalva
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
########################################################################################
# Battle Module - Common functions
from utils import stdout, Battle
from consts import (SC_ATKUP, SC_DEFDOWN, SC_DEFUP, SC_ATKDOWN, Ele_Fire,
Ele_Water, Ele_Nature, Ele_Light, Ele_Shadow)
import random
# Check victory condition
def check_enemy_alive(token):
for i in Battle[token]["enemy"]:
if (i["hp"] > 0):
return True
return False
# Check defeat condition
def check_player_alive(token):
for i in Battle[token]["party"]:
if (i["hp"] > 0):
return True
return False
# Calculate damage. Unit is a member from Battle[token][scope]. Base is dmg value
# crit is a customizable critical chance
def calc_dmg(token, attacker, defender, base, crit=0.1):
sca=attacker["status_effects"]
scd=defender["status_effects"]
dmg=0+base
# ATK/DEF up will double or not
if (sca & SC_ATKUP):
dmg*=2
if (scd & SC_DEFDOWN):
dmg*=2
if (scd & SC_DEFUP):
dmg/=2
if (sca & SC_ATKDOWN):
dmg/=2
# Critical chance (Crit: +50% DMG)
if (random.random() < crit):
dmg*=1.5
# Elemental advantage: 30%
ea=attacker["ele"]
ed=defender["ele"]
if (ea == Ele_Fire and ed == Ele_Water):
dmg*=0.7
elif (ea == Ele_Fire and ed == Ele_Nature):
dmg*=1.3
elif (ea == Ele_Water and ed == Ele_Nature):
dmg*=0.7
elif (ea == Ele_Water and ed == Ele_Fire):
dmg*=1.3
elif (ea == Ele_Nature and ed == Ele_Water):
dmg*=0.7
elif (ea == Ele_Nature and ed == Ele_Fire):
dmg*=1.3
elif (ea == Ele_Light and ed == Ele_Shadow):
dmg*=1.3
elif (ea == Ele_Shadow and ed == Ele_Light):
dmg*=1.3
# Impossible to move or miss is handled before
return int(dmg)
# Attack all, scope can be: "enemy" or "party"
def attackall(token, atker, scope):
for c, i in enumerate(Battle[token][scope]):
if (i["hp"] < 0):
continue
i["hp"]-=calc_dmg(token, atker, i, atker["atk"], 0.0)
# If passed with a negative value...
if (i["hp"] > i["max_hp"]):
i["hp"]=0+i["max_hp"]
#Battle[token]["log"].append(["party", idx, sphere, dmg, scope, c])
return False
# Find and return target ID in Battle[token][scope].
def find_target(token, scope):
global Battle
targets=[]
i=-1
#stdout("Request to find a target on scope %s" % scope)
#stdout("Length is: %d" % len(Battle[token][scope]))
while (i+1) < len(Battle[token][scope]):
i+=1
try:
if (Battle[token][scope][i]["hp"] < 0):
continue
except:
try:
stdout("(%d) Faulty structure: %s" % (i, str(Battle[token][scope][i])), 0)
except:
stdout("(%d) TOTALLY Faulty structure: %s" % (i, str(Battle[token][scope])), 0)
continue
continue
targets.append(i)
#stdout("While loop has finished")
stdout("List of targets: %s" % str(targets), 2)
# When a player selects an target, it should always be the first enemy in list
if scope == "enemy":
opt=targets[0]
else:
opt=random.choice(targets)
stdout("Selected: %d" % opt, 2)
return opt