summaryrefslogtreecommitdiff
path: root/game/combat.rpy
diff options
context:
space:
mode:
Diffstat (limited to 'game/combat.rpy')
-rw-r--r--game/combat.rpy754
1 files changed, 0 insertions, 754 deletions
diff --git a/game/combat.rpy b/game/combat.rpy
deleted file mode 100644
index 9537146..0000000
--- a/game/combat.rpy
+++ /dev/null
@@ -1,754 +0,0 @@
-########################################################################################
-# This file is part of Spheres.
-# Copyright (C) 2019 Jesusalva
-
-# This library is free software; you can redistribute it and/or
-# modify it under the terms of the GNU Lesser General Public
-# License as published by the Free Software Foundation; either
-# version 2.1 of the License, or (at your option) any later version.
-
-# This library 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
-# Lesser General Public License for more details.
-
-# You should have received a copy of the GNU Lesser General Public
-# License along with this library; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-########################################################################################
-# Combat Interface
-
-init python:
- import json, copy
- ######################## Server Communications
- def loadquest(quest_id, party_id=1):
- import json
- raw=send_packet("begin_quest", questdata(quest_id, party_id))
-
- bt=json_decode(raw)
- if (bt == ERR_JSONDECODER):
- return ERR_JSONDECODER
- return bt
-
- def loadbattle(new_arrange):
- raw=send_packet("battle", battledata(new_arrange, use_sphere))
-
- bt=json_decode(raw)
- if (bt == ERR_JSONDECODER):
- return ERR_JSONDECODER
- return bt
-
- def reload_battle():
- raw=send_packet("reload_battle", "")
-
- bt=json_decode(raw)
- if (bt == ERR_JSONDECODER):
- return ERR_JSONDECODER
- return bt
-
-
- ####################### Client rendering
- def c_dragid(dg):
- if dg == "party1":
- return 0
- elif dg == "party2":
- return 1
- elif dg == "party3":
- return 2
- elif dg == "party4":
- return 3
- elif dg == "party5":
- return 4
- else:
- return 0# We can't return -1...
-
- def combat_action(drags, drop):
- global use_sphere
- if not drop:
- return
-
- # Define your char slot, and reset the sphere usage for it
- idn=c_dragid(drags[0].drag_name)
- use_sphere[idn]=AP_NONE
-
- # Check if you asked for a skill
- if (drop.drag_name == "Skill"):
- renpy.notify("You can't use a skill!")
- drags[0].snap(0, 30, delay=0.1)
- #use_sphere[idn]=AP_SKILL
- return
-
- # Check if you asked for a sphere
- if (drop.drag_name == "Sphere"):
- if (Battle["spheres"][idn]):
- # Mark to use the sphere - if it exists!
- drags[0].snap(0, 60, delay=0.1)
- use_sphere[idn]=AP_SPHERE
- return
- else:
- renpy.notify("You can't use a sphere!")
- drags[0].snap(0, 30, delay=0.1)
- return
- return
-
-screen battle():
- # Background
- add "bg battle"
-
- # Load variables
- python:
- try:
- fx1="unit_"+str(Battle["party"][0]["unit_id"])
- show_img(fx1, False) # Validate
- except:
- fx1=""
- try:
- fx2="unit_"+str(Battle["party"][1]["unit_id"])
- show_img(fx2, False) # Validate
- except:
- fx2=""
- try:
- fx3="unit_"+str(Battle["party"][2]["unit_id"])
- show_img(fx3, False) # Validate
- except:
- fx3=""
- try:
- fx4="unit_"+str(Battle["party"][3]["unit_id"])
- show_img(fx4, False) # Validate
- except:
- fx4=""
- try:
- fx5="unit_"+str(Battle["party"][4]["unit_id"])
- show_img(fx5, False) # Validate
- except:
- fx5=""
- try:
- en1=Battle["enemy"][0]
- show_img("mob_"+str(en1["unit_id"]), False) # Validate
- except:
- en1={"hp": 0}
- try:
- en2=Battle["enemy"][1]
- show_img("mob_"+str(en2["unit_id"]), False) # Validate
- except:
- en2={"hp": 0}
- try:
- en3=Battle["enemy"][2]
- show_img("mob_"+str(en3["unit_id"]), False) # Validate
- except:
- en3={"hp": 0}
-
- ####################################################
- # Render HUD
- frame:
- xalign 0.0
- yalign 0.0
- xfill True
- ymaximum 60
- yfill True
- background Frame("gui/frame.png", 0, 0)
- hbox:
- # Preferences button
- imagebutton auto "gfx/gui/cog_%s.png" action ShowMenu('preferences')
- textbutton _("Party") action Function(blayout)
- null width 20
- text "%d " % (Battle["turn"])
- text _(" Turn")
- null width 300
- text _("Wave %d/%d" % (Battle["wave"], Battle["max_wave"]))
- null width 300
- textbutton _("I'm ready") action Return()
-
- ####################################################
- # Render enemies
-
- # Enemy 1
- if (en1["hp"] > 0):
- add At("mob_"+str(en1["unit_id"]), enemy1)
- vbox:
- xalign 0.5
- yanchor 0.5
- ypos 0.24
- xmaximum 180
- ymaximum 20
- text en1["name"]
- bar value en1["hp"] range en1["max_hp"]
-
- # Enemy 2
- if (en2["hp"] > 0):
- add At("mob_"+str(en2["unit_id"]), enemy2)
- vbox:
- xalign 1.0
- yanchor 0.5
- ypos 0.24
- xmaximum 180
- ymaximum 20
- text en2["name"]
- bar value en2["hp"] range en2["max_hp"]
-
- # Enemy 3
- if (en3["hp"] > 0):
- add At("mob_"+str(en3["unit_id"]), enemy3)
- vbox:
- xalign 0.0
- yanchor 0.5
- ypos 0.24
- xmaximum 180
- ymaximum 20
- text en3["name"]
- bar value en3["hp"] range en3["max_hp"]
-
- ####################################################
- # Render allies
- # TODO: Gray out and unmovable if dead
- # One drag group per party member defined in Battle
- draggroup:
- xalign 0.2
- yalign 1.0
- xmaximum 160
- ymaximum 300 # 240 + 60: 30 px each dimension
- # Display the background
- drag:
- child At("gfx/action.png", c_party1)
- draggable False
- droppable False
- # Display the card (if there's one)
- if (fx1):
- drag:
- drag_name "party1"
- child At(fx1, c_party1)
- droppable False
- if (Battle["party"][0]["hp"] > 0):
- dragged combat_action
- else:
- draggable False
- ypos 30
- # The action areas
- drag:
- drag_name "Skill"
- child At("gfx/actionarea.png", c_party1)
- draggable False
- ypos 0.0
- drag:
- drag_name "Sphere"
- child At("gfx/actionarea.png", c_party1)
- draggable False
- yalign 1.0
- # Display the sphere
- drag:
- child ("gfx/sphere/"+str(Battle["spheres"][0])+".png")
- draggable False
- droppable False
- yalign 1.0
- xalign 0.5
- if (fx1 and Battle["party"][0]["hp"] <= 0):
- add At("gfx/off.png", c_party1)
-
- # One drag group per party member defined in Battle
- draggroup:
- xalign 0.4
- yalign 1.0
- xmaximum 160
- ymaximum 300
- drag:
- child At("gfx/action.png", c_party2)
- draggable False
- droppable False
- if (fx2):
- drag:
- drag_name "party2"
- child At(fx2, c_party2)
- droppable False
- if (Battle["party"][1]["hp"] > 0):
- dragged combat_action
- else:
- draggable False
- ypos 30
- drag:
- drag_name "Skill"
- child At("gfx/actionarea.png", c_party2)
- draggable False
- ypos 0.0
- drag:
- drag_name "Sphere"
- child At("gfx/actionarea.png", c_party2)
- draggable False
- yalign 1.0
- drag:
- child ("gfx/sphere/"+str(Battle["spheres"][1])+".png")
- draggable False
- droppable False
- yalign 1.0
- xalign 0.5
-
- if (fx2 and Battle["party"][1]["hp"] <= 0):
- add At("gfx/off.png", c_party2)
- # One drag group per party member defined in Battle
- draggroup:
- xalign 0.6
- yalign 1.0
- xmaximum 160
- ymaximum 300
- drag:
- child At("gfx/action.png", c_party3)
- draggable False
- droppable False
- if (fx3):
- drag:
- drag_name "party3"
- child At(fx3, c_party3)
- droppable False
- if (Battle["party"][2]["hp"] > 0):
- dragged combat_action
- else:
- draggable False
- ypos 30
- drag:
- drag_name "Skill"
- child At("gfx/actionarea.png", c_party3)
- draggable False
- ypos 0.0
- drag:
- drag_name "Sphere"
- child At("gfx/actionarea.png", c_party3)
- draggable False
- yalign 1.0
- drag:
- child ("gfx/sphere/"+str(Battle["spheres"][2])+".png")
- draggable False
- droppable False
- yalign 1.0
- xalign 0.5
-
- if (fx3 and Battle["party"][2]["hp"] <= 0):
- add At("gfx/off.png", c_party3)
- # One drag group per party member defined in Battle
- draggroup:
- xalign 0.8
- yalign 1.0
- xmaximum 160
- ymaximum 300
- drag:
- child At("gfx/action.png", c_party4)
- draggable False
- droppable False
- if (fx4):
- drag:
- drag_name "party4"
- child At(fx4, c_party4)
- droppable False
- if (Battle["party"][3]["hp"] > 0):
- dragged combat_action
- else:
- draggable False
- ypos 30
- drag:
- drag_name "Skill"
- child At("gfx/actionarea.png", c_party4)
- draggable False
- ypos 0.0
- drag:
- drag_name "Sphere"
- child At("gfx/actionarea.png", c_party4)
- draggable False
- yalign 1.0
- drag:
- child ("gfx/sphere/"+str(Battle["spheres"][3])+".png")
- draggable False
- droppable False
- yalign 1.0
- xalign 0.5
-
- if (fx4 and Battle["party"][3]["hp"] <= 0):
- add At("gfx/off.png", c_party4)
-
-
- ####################################################
- # Render HPBARs
- if (fx1):
- frame:
- xalign 0.21
- yalign 1.0
- ymaximum 10
- xmaximum 120
- bar value Battle["party"][0]["hp"] range Battle["party"][0]["max_hp"] xmaximum 120
-
- if (fx2):
- frame:
- xalign 0.4
- yalign 1.0
- ymaximum 10
- xmaximum 120
- bar value Battle["party"][1]["hp"] range Battle["party"][1]["max_hp"] xmaximum 120
-
- if (fx3):
- frame:
- xalign 0.6
- yalign 1.0
- ymaximum 10
- xmaximum 120
- bar value Battle["party"][2]["hp"] range Battle["party"][2]["max_hp"] xmaximum 120
-
- if (fx4):
- frame:
- xalign 0.8
- yalign 1.0
- ymaximum 10
- xmaximum 120
- bar value Battle["party"][3]["hp"] range Battle["party"][3]["max_hp"] xmaximum 120
-
-screen battle_layout(lb="Select unit"):
- vbox:
- xalign 0.5
- yalign 0.3
- label _("{size=32}{color=#f00}%s{/color}{/size}" % lb)
- null height 20
- hbox:
- for i, item in enumerate(Battle["party"]):
- imagebutton:
- if item["unit_id"] > 0:
- idle At(Composite(
- (340, 340),
- (0, 0), "gfx/square/bg.png",
- (0, 0), "gfx/square/units/%d.png" % item["unit_id"],
- (0, 0), "gfx/square/%d.png" % allunits[item["unit_id"]]["rare"],
- ), czoom_70)
- else:
- idle At("gfx/square/bg.png", czoom_70)
- action Return(i)
- null height 80
- # The close button returns -1 and comes last (TODO)
- imagebutton:
- idle At("gfx/square/back_idle.png", czoom_75)
- hover At("gfx/square/back_hover.png", czoom_75)
- action Return(-1)
-
-init 2:
- python:
- def blayout():
- renpy.call_in_new_context("bl_context")
- return
- def blayout2():
- o1=renpy.call_screen("battle_layout", "Select unit to swap")
- o2=renpy.call_screen("battle_layout", "Select unit to swap with")
- if (o1 == o2):
- return
- tmp=copy.copy(Battle["party"][o2])
- Battle["party"][o2]=copy.copy(Battle["party"][o1])
- Battle["party"][o1]=tmp
- renpy.notify("Done!")
- return
-
-label bl_context:
- $ blayout2()
- return
-
-###################################################################
-# TODO: Quest menus and selections should be auto-generated
-# World map structure: ["name", min_level, {quest1}, {quest2} ...]
-label quest_select:
- $ show_img("bg battle2", False, ext=".jpg")
- scene bg battle2
- play music MUSIC_WORLDMAP.id() fadein 0.5
- python:
- from copy import copy
- worldmap=[]
- areamap=[]
- for arx in allworld:
- arena=copy(arx)
- name=arena.pop(0)
- req=arena.pop(0)
- if Player["quest"] >= req:
- worldmap.append((name, arena))
-
- # Display world map menu
- worldmap.append(("Return", -1))
- mapselected=renpy.display_menu(worldmap)
- del worldmap
- if mapselected == -1:
- renpy.jump("restore")
-
- # Now we have the mapselected array, with dict
- for arx in mapselected:
- quest=copy(arx)
- name=quest["name"]
- qid=quest["quest_id"]
-
- # We also want to show cost and requeriments
- entry=dl_search(allquests, "quest_id", qid)
- if entry != ERR_INVALID:
- cost=entry["cost"]
- req=entry["requeriment"]
- else:
- cost=-1
- req=99999
-
- # Add entry (if valid)
- if Player["quest"] >= req:
- if Player["ap"] >= cost:
- areamap.append(("%s (%d AP)" % (name, cost), qid))
- else:
- areamap.append(("{s}%s (%d AP){/s}" % (name, cost), None))
-
- # Display area menu
- areamap.append(("Return", -1))
- qid=renpy.display_menu(areamap)
- del areamap
- if qid == -1 or qid is None:
- renpy.jump("quest_select")
-
- jump quest_selected
-
-###################################################################
-label quest_selected:
- # Get quest data
- python:
- quest=dl_search(allquests, "quest_id", qid)
-
- # Uhm, how did this happen? Means client-data is not fully updated!
- if (quest == ERR_INVALID):
- renpy.call_screen("msgbox", "ERROR:\n\nRequested Quest does not exist client-side\nAn update is required. We'll now close the app.")
- raise KeyboardInterrupt()
-
- # Confirm the quest cost
- $apmsg=_("Quest cost: %d/%d AP" % (quest["cost"], Player["ap"]))
- menu:
- "[apmsg]"
- "Accept Quest" if Player["ap"] >= quest["cost"]:
- pass
- "Decline Quest":
- jump quest_select
-
- # Begin the quest
- $ Battle=loadquest(qid)
-
- # Check for error
- if (Battle in [FAILUREMSG, OFFLINEMSG, ERR_JSONDECODER, ERR_LOGIN_DEFAULT]):
- $ renpy.call_screen("msgbox", "Error:\n\n%s\nYou'll be taken to town." % Battle)
- jump restore
-
- # Reduce the paid AP
- python:
-
- # Consume the AP
- update_ap(-(quest["cost"]))
-
- # Before fighting, should we perhaps show story?
- if Player["quest"] < qid:
- story=dl_search(allstory, "quest_id", qid)
-
- if (story != ERR_INVALID):
- hud_story()
- print ".:: Story logs (%d) ::." % qid
-
- if isinstance(story["pre_dialog"], str) or isinstance(story["pre_dialog"], unicode):
- renpy.call_in_new_context(story["pre_dialog"])
- else:
- bg_is_showing=False
- for dial in story["pre_dialog"]:
- # Background
- if str(dial["bg"]) != "":
- if bg_is_showing:
- renpy.hide("sbg")
- show_img("bg "+dial["bg"], tag="sbg", ext=".jpg")
- bg_is_showing=True
-
- show_img("dialog_"+dial["left_sprite"], at_list=[left], tag="l")
- show_img("dialog_"+dial["center_sprite"], at_list=[center], tag="c")
- show_img("dialog_"+dial["right_sprite"], at_list=[right], tag="r")
- renpy.say(dial["name"], dial["message"])
- renpy.hide("l")
- renpy.hide("c")
- renpy.hide("r")
- print "%s: %s" % (dial["name"], dial["message"])
- # Background Clean up
- if bg_is_showing:
- renpy.hide("sbg")
- del bg_is_showing
-
- # Okay, story-telling time is over: To arms!
- play music MUSIC_BATTLE.id() fadein 0.5
- $ renpy.free_memory()
- window hide
-
-label combat:
- # Implement combat view
- $ hud_clear()
- $ show_img("bg battle", False)
- scene bg battle
- $stdout("================= call begin")
-
- # TODO: Swap units support
- # TODO: Display Spheres in the right place
- $ use_sphere=[AP_NONE, AP_NONE, AP_NONE, AP_NONE, AP_NONE]
- call screen battle
- $stdout("================= call ended")
- # TODO: Send to server new arrangement of units
-
- # Update Battle with server response
- $ response=loadbattle(Battle["party"])
-
- # Maybe we error'ed out and should relog
- if (response in [FAILUREMSG, OFFLINEMSG, ERR_JSONDECODER, ERR_LOGIN_DEFAULT]):
- $ renpy.call_screen("msgbox", "Error:\n\n%s" % response)
- # Try again (x2)
- $ response=loadbattle(Battle["party"])
- # Maybe we error'ed out and should relog
- if (response in [FAILUREMSG, OFFLINEMSG, ERR_JSONDECODER, ERR_LOGIN_DEFAULT]):
- $ renpy.call_screen("msgbox", "Error:\n\n%s" % response)
- # Try again (x3)
- $ response=loadbattle(Battle["party"])
- # Maybe we error'ed out and should relog
- if (response in [FAILUREMSG, OFFLINEMSG, ERR_JSONDECODER, ERR_LOGIN_DEFAULT]):
- $ renpy.call_screen("msgbox", "Error:\n\n%s\nYou'll be taken to main screen." % response)
- # Better no longer insist
- return
-
-
- # TODO The server should send a JSON of results...
-
- # Wait for server to confirm the fight end
- if (response["result"] != ""):
- $ renpy.free_memory()
- # TODO: Announce the result screen
- jump results
-
- # Fight continues
- # TODO this is suboptimal, and the loops are also wrong
- # Maybe we should get info about what was used and whatnot?
- show screen battle
- python:
- # TODO: Render sphere usage
- # Render enemy damage
- idx=0
- while idx < len(Battle["enemy"]):
- try:
- # TODO: Draw the updates in "sequence"
- if (response["wave"] != Battle["wave"]):
- hit_someone_verbose(Battle["enemy"][idx],
- Battle["enemy"][idx]["hp"])
- else:
- hit_someone_verbose(Battle["enemy"][idx],
- Battle["enemy"][idx]["hp"]-response["enemy"][idx]["hp"])
- idx+=1
- renpy.pause(0.1)
- except:
- idx+=1
- pass
-
- # Render party damage
- idx=0
- try:
- while idx < len(Battle["party"]):
- hit_someone_verbose(Battle["party"][idx], Battle["party"][idx]["hp"]-response["party"][idx]["hp"])
- idx+=1
- renpy.pause(0.1)
- except:
- idx+=1
- pass
-
- # We may be going to boss fight
- if (response["wave"] != Battle["wave"] and response["wave"] == response["max_wave"]):
- play music MUSIC_BOSS.id() fadein 0.5
- $ renpy.notify("BOSS FIGHT!")
-
- $ Battle=response
- jump combat
-
-label results:
- $ Player["status"]=ST_TOWN
- if (response["result"] == "DEFEAT"):
- $ renpy.call_screen("msgbox", "Result:\n%s" % _("DEFEAT"))
- jump restore
-
- play music MUSIC_VICTORY.id() fadein 0.5
-
- # TODO: Use small icons
- python:
- # Save current quest to 'quest' variable (wasn't it set before?)
- quest=dl_search(allquests, "quest_id", Battle["quest_id"])
- if (quest == ERR_INVALID):
- raise Exception("ERROR, QUEST NOT FOUND, %d" % Battle["quest_id"])
-
- # Update other data
- Player["crystals"]+=int(response["crystals"])
- Player["gp"]+=int(response["gp"])
- Player["exp"]+=int(response["exp"])
- # Write loot array
- loot="\n"
- if (response["crystals"]):
- loot+="%d Crystals\n" % response["crystals"]
- for unit in response["loot"]:
- try:
- loot+="%s %s\n" % (star_write(allunits[unit]["rare"]), allunits[unit]["name"])
- except:
- loot+="error"
-
- # Maybe you ranked up?
- expmsg="Exp: %d -> %d" % (Player["exp"]-response["exp"], Player["exp"])
- if (response["rank"]):
- Player["level"]+=1
- Player["max_ap"]+=response["rank"]-1
- update_ap(Player["max_ap"]-Player["ap"])
- #Player["exp"]+=1
- expmsg="PLAYER {b}RANK UP!{/b} (Max Ap: %d -> %d)" % (Player["max_ap"]-response["rank"]+1, Player["max_ap"])
-
- # Report screen
- renpy.call_screen("msgbox", "Result:\n%s\n\nGp: %d\n%s\nLoot:\n%s" % (
- _("VICTORY!"),
- response["gp"],
- expmsg,
- "{size=12}"+loot+"{/size}"
- ))
-
- # Update inventory data and restore
- $ inv=get_inventory()
- python:
- try:
- renpy.call_screen("msgbox", "Error: %d" % int(inv))
- except:
- Player["inv"]=dlist()
- for a in inv:
- Player["inv"].append(a)
-
- qid=Battle["quest_id"]
- # WAIT THERE! Perhaps we have some sort of history to show?!
- if Player["quest"] < qid:
- story=dl_search(allstory, "quest_id", qid)
-
- if (story != ERR_INVALID):
- hud_story()
- print ".:: Story logs (%d) ::." % qid
-
- if isinstance(story["post_dialog"], str) or isinstance(story["post_dialog"], unicode):
- renpy.call_in_new_context(story["post_dialog"])
- else:
- bg_is_showing=False
- for dial in story["post_dialog"]:
- # Background
- if str(dial["bg"]) != "":
- if bg_is_showing:
- renpy.hide("sbg")
- show_img("bg "+dial["bg"], tag="sbg", ext=".jpg")
- bg_is_showing=True
-
- show_img("dialog_"+dial["left_sprite"], at_list=[left], tag="l")
- show_img("dialog_"+dial["center_sprite"], at_list=[center], tag="c")
- show_img("dialog_"+dial["right_sprite"], at_list=[right], tag="r")
- renpy.say(dial["name"], dial["message"])
- renpy.hide("l")
- renpy.hide("c")
- renpy.hide("r")
- print "%s: %s" % (dial["name"], dial["message"])
- # Background Clean up
- if bg_is_showing:
- renpy.hide("sbg")
- del bg_is_showing
-
- # Maybe we should update player quest
- if not (quest["flags"] & 4):
- if Player["quest"] < Battle["quest_id"]:
- Player["quest"]=Battle["quest_id"]
-
- jump restore
-