summaryrefslogtreecommitdiff
path: root/battle/main.py
diff options
context:
space:
mode:
Diffstat (limited to 'battle/main.py')
-rw-r--r--battle/main.py270
1 files changed, 13 insertions, 257 deletions
diff --git a/battle/main.py b/battle/main.py
index 3cc92f8..19a558b 100644
--- a/battle/main.py
+++ b/battle/main.py
@@ -17,17 +17,14 @@
# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
########################################################################################
# Battle Module - Main module
-from utils import stdout, dl_search, compress, allunits, Player, Battle, allquests
-from consts import (CRYSTAL_MIN, CRYSTAL_MAX, EXPRATE_MIN, EXPRATE_MAX,
- GPPRATE_MIN, GPPRATE_MAX, ERR_ERR, ERR_BAD, ST_TOWN, ST_QUEST, ACT_SPHERE,
- SFLAG_CLEARGEMS, SFLAG_DOUBLEGEMS, SFLAG_SPECIAL,
- SFLAG_FIRSTLOOT, SFLAG_DOUBLEEXP, SFLAG_DOUBLEGP,
+from utils import stdout, compress, allunits, Player, Battle, allquests
+from consts import (ERR_ERR, ERR_BAD, ST_TOWN, ST_QUEST, ACT_SPHERE,
SPH_WIDEATTACK, SPH_PIERCE, SPH_ASSAULT, SPH_HEAL, SPH_HEALALL, SPH_ATKUP,
- SPH_DEFUP, SPH_NONE, SRV_WAVE, SRV_SPHERE)
+ SPH_DEFUP, SPH_NONE)
import json, random, traceback
import player
-from battle.common import (find_target, check_enemy_alive, check_player_alive,
- calc_dmg)
+from battle.common import (find_target, calc_dmg, conditions, advance_wave,
+ battle_endturn)
from battle.spheres import sphere_attack
#from battle.summons import summon # <-- Protocol?
#from battle.skills import skill_core, handle_skill # <-- WIP
@@ -35,170 +32,6 @@ from battle.spheres import sphere_attack
# Prepare a randomness seed
random.seed()
-#############################################
-# Structural functions
-#############################################
-# Update enemy list with the next wave data. No checks are conducted.
-def advance_wave(token, world, quest_id, next_wave):
- global Battle, allquests
- Battle[token]["enemy"]=[]
- Battle[token]["log"].append(["", 0, SRV_WAVE, 0, "", 0])
- stdout("advance_wave was called")
-
- quest=dl_search(allquests[world], "quest_id", quest_id)
- if quest == "ERROR":
- stdout("ERROR, INVALID QUEST: %d" % (quest_id), 0)
- # TODO: HANDLE THIS ERROR (FIXME)
-
- for en in quest["waves"][next_wave]:
- mil=quest["difficulty"]/10.0
- if (en["boss"]):
- mil*=5.5
-
- mil=mil
- stdout("Recording new enemy with mil: %d" % mil, 2)
- Battle[token]["enemy"].append({
- "name": en["name"],
- "unit_id": en["sprite"],
- "max_hp": int(900*mil),
- "hp": int(900*mil),
- "atk": int(100*mil),
- "ele": en["attribute"],
- "status_effects": 0
- })
-
- # Update wave
- stdout("Advancing wave", 2)
- Battle[token]["wave"]+=1
- return True
-
-# get_result(str, bool, str, int)
-def get_result(token, victory, world, quest_id):
- global Player, Battle, allquests
- result={
- "result": "",
- "gp": 0,
- "exp": 0,
- "crystals": 0,
- "loot": [],
- "rank": 0,
- "log": Battle[token]["log"]
- }
-
- stdout("GR: Begin", 2)
- # You lost?
- if not victory:
- result["result"]="DEFEAT"
- return result
-
- # Prepare data
- result["result"]="VICTORY"
- quest=dl_search(allquests[world], "quest_id", quest_id)
- if quest == "ERROR":
- print("ERROR, INVALID QUEST")
- stdout("Quest %d is invalid" % quest_id, 0)
- # TODO: HANDLE THIS ERROR (FIXME)
- return result
-
- stdout("GR: Rolling", 2)
- # Roll each wave
- # Base quest experience gain
- result["exp"]+=quest["difficulty"]*10
- for wave in quest["waves"]:
- for en in wave:
- # Roll GP for each wave
- if en["boss"]:
- result["gp"]+=quest["difficulty"]*30
- result["exp"]+=quest["difficulty"]
- else:
- result["gp"]+=quest["difficulty"]*10
- result["exp"]+=quest["difficulty"]/3
-
- # TODO: Roll the loots for every enemy in every death
-
- result["exp"]=int(result["exp"])
- stdout("GR: Looting", 2)
- # For now, loots are rolled for quest
- # 2- Roll loot list
- for loot, chance in quest["loot"]:
- if (random.randint(0, 10000) < chance):
- loot=int(loot)
- # Crystals are... Tricky
- if loot >= CRYSTAL_MIN and loot <= CRYSTAL_MAX:
- result["crystals"]+=(loot-CRYSTAL_MIN)
- elif loot >= EXPRATE_MIN and loot <= EXPRATE_MAX:
- result["exp"]*=(loot-EXPRATE_MIN)/1000.0
- result["exp"]=int(result["exp"])
- elif loot >= GPPRATE_MIN and loot <= GPPRATE_MAX:
- result["gp"]*=(loot-GPPRATE_MIN)/1000.0
- result["gp"]=int(result["gp"])
- else:
- result["loot"].append(int(loot)*100) # Fix Unit ID from base to ID
-
- stdout("GR: Flagging", 2)
- # Mark the quest as complete and grant you crystals for first clear
- # But this is based on the flags (we can have special quests)
- if (not (quest["flags"] & SFLAG_SPECIAL) and Player[token]["quest"] < quest["quest_id"]):
- Player[token]["quest"]=0+quest["quest_id"]
- if (quest["flags"] & SFLAG_CLEARGEMS):
- result["crystals"]+=100
- if (quest["flags"] & SFLAG_DOUBLEGEMS):
- result["crystals"]+=200
- if (quest["flags"] & SFLAG_FIRSTLOOT):
- loot=int(quest["loot"][0][0])
- # Crystals are... Tricky
- if loot >= CRYSTAL_MIN and loot <= CRYSTAL_MAX:
- result["crystals"]+=(loot-CRYSTAL_MIN)
- else:
- result["loot"].append(int(loot)*100) # Fix Unit ID from base to ID
- if (quest["flags"] & SFLAG_DOUBLEEXP):
- result["exp"]*=2
- if (quest["flags"] & SFLAG_DOUBLEGP):
- result["gp"]*=2
-
- stdout("GR: Applying", 2)
- # Apply the results to player data
- Player[token]["gp"]+=result["gp"]
- Player[token]["exp"]+=result["exp"]
- Player[token]["crystals"]+=result["crystals"]
- for it in result["loot"]:
- ix=player.inventoryplace(token)
- if (ix >= 0):
- unit={
- "unit_id": it,
- "level": 1,
- "exp": 0
- }
- Player[token]["inv"][ix]=unit
- else:
- result["loot"].remove(it)
- # TODO: Send result ERR_FULL
-
- stdout("GR: EXPing", 2)
- # Grant to party the same amount of experience
- pid=Battle[token]["party_id"]
- for m in Player[token]["party_"+str(pid)]:
- # This can happen normally
- if m["unit_id"] <= 0:
- continue
- player.grant_exp(token, m["inv_id"], result["exp"])
- v5=player.check_level_up(token, m["inv_id"])
- # FIXME: Don't disregard result
- stdout("Unit %d levelled up %d times" % (m["inv_id"], v5))
-
-
- stdout("GR: Ranking", 2)
- # Player rank up
- rk=player.check_rank_up(token)
- if rk["code"]:
- result["rank"]=1+rk["ap"]
- result["rk_exp"]=Player[token]["exp"]
- result["rk_mexp"]=Player[token]["max_exp"]
-
- stdout("GR: Complete")
-
- # Send data
- return result
#############################################
# Client commands
@@ -328,59 +161,6 @@ def begin_quest(args, token, client_side=True):
-# This is separate for loop logic reasons. Ends the turn.
-# Gives sphere, handle rewards if needed and sends data to client
-def battle_endturn(token, spheres):
- global Battle
- # We now have to handle turn end and conditions
- Battle[token]["turn"]+=1
- stdout("Turn has ended")
-
- # Resave spheres
- stdout("Sphere list: "+str(spheres), 2)
- Battle[token]["spheres"]=[]
- for i in spheres:
- Battle[token]["spheres"].append(int(i))
-
- # Remove an eventual none spheres
- while (Battle[token]["spheres"].count(SPH_NONE)):
- Battle[token]["spheres"].remove(SPH_NONE)
- stdout("Exceeding spheres removed", 2)
-
- # Add 1~3 random spheres; But never go over 5 spheres
- i=min(random.randint(1,3), 5 - len(Battle[token]["spheres"]))
- while i > 0:
- i-=1
- sp=random.choice([
- SPH_WIDEATTACK,
- SPH_PIERCE,
- SPH_ASSAULT,
- SPH_HEAL,
- SPH_HEALALL,
- SPH_ATKUP,
- SPH_DEFUP
- ])
- Battle[token]["log"].append(["spheres", len(Battle[token]["spheres"]), SRV_SPHERE, sp, "", 0])
- Battle[token]["spheres"].append(sp)
-
- stdout("Spheres added; Status before adjust: %s" % (str(Battle[token]["spheres"])), 2)
-
- # Add empty spheres to keep length
- while (len(Battle[token]["spheres"]) < 5):
- Battle[token]["spheres"].append(SPH_NONE)
-
- # Delete Summon data if exists
- try:
- del Battle["s"]
- except:
- pass
-
- # Send data to client
- stdout("Sending data", 2)
- sjson=compress(Battle[token])
- stdout("Data sent: %s" % sjson)
- return sjson
-
# Advance turn button. Main turn logic
# Receives a list of units position, and if they'll use sphere:
# { "unit": [uid1, uid2 ....], "sphere": [True/False array, in future will save skill as 2] }
@@ -482,34 +262,13 @@ def battle(args, token):
if (bat["hp"] > bat["max_hp"]):
bat["hp"]=0+bat["max_hp"]
- # HOLD THAT! Handle event
- if (not check_enemy_alive(token)):
- # You won! Do we have a next wave?
- stdout("You won!")
- if (Battle[token]["wave"] < Battle[token]["max_wave"]):
- stdout("Next wave detected: %s, Quest ID: %s\nWave: %s" % (token, Battle[token]["quest_id"], Battle[token]["wave"]))
- advance_wave(token, Battle[token]["world"], Battle[token]["quest_id"], Battle[token]["wave"])
- # Do not continue this loop: End the turn now
- return battle_endturn(token, spheres)
- else:
- # You won!
- stdout("Total Victory")
- Player[token]["status"]=ST_TOWN
- # TODO: enemy die = add reward
- result=get_result(token, True, Battle[token]["world"], Battle[token]["quest_id"])
- del Battle[token]
- return compress(result)
+ # HOLD THAT! Handle victory/defeat conditions
+ check = conditions(token, spheres)
+ if check is not None:
+ return check
stdout("Friends executed", 2)
- # It never harms checking for suicide...
- if (not check_player_alive(token)):
- # You lost!
- Player[token]["status"]=ST_TOWN
- result=get_result(token, False, Battle[token]["world"], Battle[token]["quest_id"])
- del Battle[token]
- return compress(result)
-
############
# Enemies
for idx, bat in enumerate(Battle[token]["enemy"]):
@@ -533,13 +292,10 @@ def battle(args, token):
bat["hp"]=0+bat["max_hp"]
continue
- # HOLD THAT! Handle event
- if (not check_player_alive(token)):
- # You lost!
- Player[token]["status"]=ST_TOWN
- result=get_result(token, False, Battle[token]["world"], Battle[token]["quest_id"])
- del Battle[token]
- return compress(result)
+ # HOLD THAT! Handle victory/defeat conditions
+ check = conditions(token, spheres)
+ if check is not None:
+ return check
stdout("Enemies executed", 2)