summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--game/combat.rpy754
-rw-r--r--game/editor.rpy415
-rw-r--r--game/irc.rpy223
-rw-r--r--game/player.rpy649
-rw-r--r--game/recruit.rpy110
5 files changed, 0 insertions, 2151 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
-
diff --git a/game/editor.rpy b/game/editor.rpy
deleted file mode 100644
index dd22cdb..0000000
--- a/game/editor.rpy
+++ /dev/null
@@ -1,415 +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
-########################################################################################
-# Editor labels for developers
-screen quest_editor():
- modal True
- frame:
- background Frame("gui/frame.png", 0, 0)
- xalign 0.5
- yalign 0.5
- ymargin 15
- ypadding 10
- xmargin 10
-
- hbox:
- spacing 30
- xmaximum 0.85
- ymaximum 0.85
-
- # Navigation
- viewport:
- #child_size (350, 1000)
- mousewheel True
- draggable True
- pagekeys True
- xfill False
- xmaximum 350
- scrollbars "vertical"
-
- vbox:
- spacing 2
- label _("Quest list")
- $i=0
- for entry in allquests:
- textbutton "{size=18}"+_("%02d (D %d) (C %d)" % (entry["quest_id"], entry["difficulty"], entry["cost"]))+"{/size}" action SetVariable("current", i)
- $i+=1
- $del i
-
- # News screen
- viewport:
- #child_size (0.4, 0.8)
- mousewheel True
- #draggable True
- #arrowkeys True
- xfill False
- scrollbars "vertical"
-
- vbox:
- xalign 0.5
- spacing 20
-
- $ qedit=allquests[current]
- $ qreq=qedit["requeriment"]
-
- label _("Quest %d" % (qedit["quest_id"]))
- hbox:
- spacing 10
- textbutton _("-") action Function(qeditor, "quest_id", -1)
- label ("%d" % qedit["quest_id"])
- textbutton _("+") action Function(qeditor, "quest_id", 1)
- null height 25
-
-
- ###########################################
- label _("Requeriment")
- hbox:
- spacing 10
- textbutton _("-") action Function(qeditor, "requeriment", -1)
- label ("%d" % qedit["requeriment"])
- textbutton _("+") action Function(qeditor, "requeriment", 1)
- null height 15
-
-
- ###########################################
- label _("Difficulty")
- hbox:
- spacing 10
- textbutton _("-10") action Function(qeditor, "difficulty", -10)
- textbutton _("-5") action Function(qeditor, "difficulty", -5)
- textbutton _("-1") action Function(qeditor, "difficulty", -1)
- label _("%d" % qedit["difficulty"])
- textbutton _("+1") action Function(qeditor, "difficulty", 1)
- textbutton _("+5") action Function(qeditor, "difficulty", 5)
- textbutton _("+10") action Function(qeditor, "difficulty", 10)
- null height 15
-
-
- ###########################################
- label _("Cost")
- hbox:
- spacing 10
- textbutton _("-") action Function(qeditor, "cost", -1)
- label _("%d" % qedit["cost"])
- textbutton _("+") action Function(qeditor, "cost", 1)
- null height 15
-
-
- ###########################################
- label _("Flags")
- hbox:
- spacing 10
- textbutton _("-") action Function(qeditor, "flags", -1)
- label _("%d" % qedit["flags"])
- textbutton _("+") action Function(qeditor, "flags", 1)
- text "None: 0\nClear Gems: 1\nTutorial Gems: 2\nSpecial: 4\nFirst Loot: 8\nDouble XP: 16\nDouble GP: 32" size 12
- null height 15
-
-
- ###########################################
- label _("Loot")
- vbox:
- spacing 0
- $i=0
- for lt, ch in qedit["loot"]:
- hbox:
- spacing 1
- $ input=Input(
- value=EditorInputValue(lt, "loot", i, "str", key3=0),
- copypaste=True,
- allow="0123456789",
- length=9)
- button:
- #key_events True
- action input.enable
- add input
-
- label ": "
-
- $ input=Input(
- value=EditorInputValue(ch, "loot", i, "int", key3=1),
- copypaste=True,
- allow="0123456789",
- length=5)
- button:
- #key_events True
- action input.enable
- add input
-
- null width 40
- textbutton _("X Delete") action None
- $i+=1
- textbutton _("Add Loot") action Function(qeditor_addloot)
- null height 15
-
-
- ###########################################
- label _("Waves")
- vbox:
- spacing 0
- $ wc=0
- null height 10
- for wave in qedit["waves"]:
- $wc+=1
- label _("{size=22}Wave %d{/size}" % wc)
- $ mc=0
- for mob in wave:
- $mc+=1
- label _("{size=20}%s{/size}" % mob["name"])
- textbutton "{size=20}%d{/size}" % mob["sprite"] action None
- hbox:
- spacing 7
- textbutton "{size=20}Ele: %d{/size}" % mob["attribute"] action None
- textbutton "{size=20}Boss: %s{/size}" % str(mob["boss"]) action Function(qeditor_input, "waves", wc-1, "bool", key3=mc-1, key4="boss")
- null width 20
- textbutton _("X Delete") action Function(qeditor_delete, "waves", wc-1, mc-1)
- null height 20
- textbutton "{size=22}"+_("Add Monster")+"{/size}" action Function(qeditor_addmonster, wc)
- textbutton "{size=22}"+_("Delete Wave")+"{/size}" action Function(qeditor_delete, "waves", wc-1)
- null height 20
- null height 20
- text "Fire: 1 Water: 2\nNature: 3 Light: 4\nDark: 5" size 12
- textbutton _("Add Wave") action Function(qeditor_addwave)
-
-
- # TODO: Loot, waves
- ###########################################
- null height 40
- hbox:
- spacing 25
-
- textbutton _("Save") action Function(qeditor_save)
-
- textbutton _("Close") action Return()
- textbutton _("New Quest") action Function(qeditor_new)
- textbutton _("New S.") action Function(qeditor_new, 1)
-
- ## Right-click and escape refresh screen
- key "game_menu" action Function(RestartInteraction)#Return()
- key "K_RETURN" action Function(RestartInteraction)#Return()
-
-init python:
- import json, copy
- def RestartInteraction():
- renpy.restart_interaction()
- return
-
-
- def qeditor(key, operation, override=False):
- global qedit
- qedit=allquests[current]
- print str(qedit["quest_id"])
- if override:
- qedit[key]=operation
- else:
- qedit[key]+=operation
- return
-
- def qeditor_save():
- global allquests
- f=open(get_path("editor.json"), "w")
- json.dump(allquests, f, indent=4, separators=(',', ': '))
- f.close()
- renpy.notify("File saved as editor.json")
- return
-
- def qeditor_new(special=False):
- global allquests
- if not special:
- qeid=len(allquests)
- qefl=1
- qec=1
- else:
- qeid=90000
- qefl=4
- qec=20
-
- allquests.append({
- "quest_id": qeid,
- "difficulty": 0,
- "requeriment": 0,
- "cost": qec,
- "flags": qefl,
- "loot": [
- ["1010", 1000],
- ["1020", 100],
- ["1030", 10]
- ],
- "waves": []})
- renpy.notify("New quest added: %d" % qeid)
- return
-
- def qeditor_addloot():
- global qedit
- qedit=allquests[current]
- qedit["loot"].append(["1000", 0])
- renpy.notify("Added new loot field id 1000 (an invalid ID)")
- return
-
- def qeditor_addmonster(wave):
- global qedit
- qedit=allquests[current]
- pointer=qedit["waves"][wave-1]
- if len(pointer) < 3:
- pointer.append({
- "name": "New Monster",
- "sprite": 950000,
- "attribute": 1,
- "boss": False
- })
- else:
- renpy.notify("Max monsters per wave reached!")
- return
-
- def qeditor_addwave():
- global qedit
- qedit=allquests[current]
- qedit["waves"].append([])
- renpy.notify("Blank wave created\nThis is buggy, remember to add monsters")
- return
-
-
- def qeditor_delete(key1, key2=None, key3=None, key4=None):
- global qedit
- qedit=allquests[current]
- if key2 is None:
- del qedit[key1]
- #del allquests[current][key1]
- elif key3 is None:
- del qedit[key1][key2]
- #del allquests[current][key1][key2]
- elif key4 is None:
- del qedit[key1][key2][key3]
- #del allquests[current][key1][key2][key3]
- else:
- del qedit[key1][key2][key3][key4]
- #del allquests[current][key1][key2][key3][key4]
- return
-
- def qeditor_input(key1, key2=None, tp="int", temp="", key3=None, key4=None):
- #temp=renpy.input("Please insert new value for this variable.\nCurrent value: [variable]")
- global qedit
- qedit=allquests[current]
- variable=""
-
- # Key looping
- if key2 is None:
- target=qedit[key1]
- elif key3 is None:
- target=qedit[key1][key2]
- elif key4 is None:
- target=qedit[key1][key2][key3]
- else:
- target=qedit[key1][key2][key3][key4]
-
- # Convert input if needed
- # tp int → convert to int
- # tp key → Replace the key
- # tp bool → Toogles the value
- if tp == "int":
- try:
- variable=int(temp)
- except:
- renpy.notify("Invalid numeric input")
- variable=0 # Sorry, but gets bad otherwise
- elif tp == "key":
- try:
- qedit[key1][temp]=copy.copy(target)
- renpy.notify("Key replaced")
- del qedit[key1][key2] # Not sure "del target" would work
- return
- except:
- renpy.notify("ERROR, doing nothing")
- variable=target
- elif tp == "bool":
- try:
- variable=(not target)
- print "New boolean: %s" % str(variable)
- except:
- print "Illegal boolean"
- renpy.notify("Illegal boolean")
- variable=target
- else:
- try:
- variable=str(temp)
- except:
- renpy.notify("Invalid string input")
-
- # Save input
- # Key looping
- if key2 is None:
- target=qedit[key1]=variable
- elif key3 is None:
- target=qedit[key1][key2]=variable
- elif key4 is None:
- target=qedit[key1][key2][key3]=variable
- else:
- target=qedit[key1][key2][key3][key4]=variable
-
- return
-
- class EditorInputValue(InputValue):
- def __init__(self, variable, key1, key2, inpu="int", key3=None, key4=None):
- try:
- self.variable = variable
- except:
- self.variable = ""
- self.inpu = inpu
-
- self.default=True
- self.editable=True
-
- self.key1=key1
- self.key2=key2
- self.key3=key3
- self.key4=key4
-
- def get_text(self):
- try:
- return str(self.variable)
- except:
- return ""
- #return globals()[self.variable]
-
- def set_text(self, s):
- #globals()[self.variable] = s
- qeditor_input(self.key1, self.key2, self.inpu, s, key3=self.key3, key4=self.key4)
-
- def enter(self):
- renpy.restart_interaction()
- #renpy.run(self.Disable())
- #raise renpy.IgnoreEvent()
-
-label quest_editors:
- $ qedit=allquests[0]
- $ current=0
- $print("")
- $print(".:: THE BUILT-IN QUEST EDITOR ::.")
- $print("Use ESC to redraw screen, saving input")
- $print("")
- call screen quest_editor
- $print("Quest Editor closed")
- jump restore
-
-label updater_editors:
- $ url=renpy.input("Please insert update server URL:", default="http://spheres.tmw2.org/updates/")
- $ updater.update(url) # , public_key="cert/certificate.pem") → Need to be RSA
-
- jump restore
-
-
diff --git a/game/irc.rpy b/game/irc.rpy
deleted file mode 100644
index 23d5f2c..0000000
--- a/game/irc.rpy
+++ /dev/null
@@ -1,223 +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
-#################################################################################
-# Chat controller
-# TODO: Pub interface, using irc_send() and irc_buffer
-
-init python:
- irc=None
- irc_online=False
-
- def irc_open():
- if persistent.irc_disable:
- return
-
- global irc, irc_buffer, irc_nick, irc_auth, irc_channel, irc_online
- import socket, sys, random
-
- reload(sys)
- sys.setdefaultencoding('utf8')
-
- irc_online=False
- server = "irc.freenode.org"
- irc_channel = "#tmw2-spheres"
- irc_nick = "GS_" + get_token()[:3] + str(random.randint(1, 10000))
- irc_auth=IRC_AUTH_NONE
- irc_buffer=[]
- irc = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- stdout("\nConnecting to:" + server)
- irc.connect((server, 6667))
- return
-
- def irc_receive(raw):
- global irc_buffer
- sender="IRC"
-
- # Control buffer length
- if (len(irc_buffer) >= MAX_IRC_BUFFER):
- nil=irc_buffer.pop(0)
- del nil
-
- # Find sender if not supplied
- try:
- p1=raw.find('<')+1
- p2=raw.find('>')
- if p2 <= p1:
- raise Exception("Invalid sender")
- sender=raw[p1:p2]
- except:
- try:
- p1=raw.find("!")
- sender="IRC."+raw[1:p1]
- except:
- sender="IRC"
-
- # Extract message
- try:
- p1=raw.find(" :") # Perhaps we're looking for ">" instead
- msg=raw[p1:]
- except:
- msg="Unparseable"
-
- # UNIX format
- msg=msg.replace('\r', '')
- irc_buffer.append((sender, msg))
- return
-
- def irc_send(sender, msg):
- global irc, irc_channel, irc_online
- if not irc_online:
- return False
- try:
- irc.send("PRIVMSG %s :<%s> %s\n" % (irc_channel, sender, msg))
- irc_buffer.append((sender, msg))
- return True
- except:
- return False
-
- def irc_kill():
- global irc, irc_online
- if irc_online:
- irc.send("QUIT :I have to go for now!\n")
- stdout("[IRC] Closing connection normally...")
- irc.shutdown(2)
- irc.close()
- irc_online=False
- stdout("[IRC] IRC Bridge is now Offline.")
- #del irc
- irc=None
- return
-
- def irc_loop():
- if persistent.irc_disable:
- return
-
- global irc, irc_buffer, irc_nick, irc_auth, irc_channel, irc_online
-
- if irc is None:
- irc_open()
-
- try:
- while 1:
- text = irc.recv(2048)
- if len(text) > 0:
- if debug:
- stdout("[IRC] %s" % text)
- else:
- continue
-
- # Handle ping requests
- if text.find("PING") != -1:
- irc.send("PONG " + text.split()[1] + "\n")
-
- # Authentication: Step 1
- if irc_auth == IRC_AUTH_NONE:
- irc.send("USER " + irc_nick + " " + irc_nick + " " + irc_nick + " :This is a fun bot\n")
- irc_auth=IRC_AUTH_USER
- continue
-
- # Authentication: Step 2
- if irc_auth == IRC_AUTH_USER:
- irc.send("NICK " + irc_nick + "\n")
- irc_auth=IRC_AUTH_NICK
- continue
-
- # Authentication: Step 3
- if text.find("255 " + irc_nick) != -1:
- irc.send("JOIN " + irc_channel + "\n")
-
- if text.find("376 " + irc_nick) != -1:
- if irc_auth == IRC_AUTH_NICK:
- irc_auth=IRC_AUTH_CHAN
- irc_online=True
- else:
- stdout("[IRC] Erroneous Authentication on 376 message")
- irc_online=True
-
- if irc_auth == IRC_AUTH_CHAN:
- # IRC Syntax
- # :nick!hostname PRIVMSG #tmw2-spheres :<nickname> msg
- # We should use <nickname>, not :nick!
-
- # TODO: Handle CTCP ACTION
- if text.find(irc_channel) != -1:
- if "PRIVMSG" in text:
- irc_receive(text)
-
- # Handle disconnections
- if not irc_online:
- raise Exception("Connection terminated.")
-
- finally:
- try:
- irc.send("QUIT :I have to go for now!\n")
- irc.shutdown(2)
- irc.close()
- except:
- stdout("[IRC] [ERROR] Connection was already closed.")
- stdout("\n")
- stdout("Closing IRC connection...")
- irc=None
-
- return
-
-screen pub():
- frame:
- background Frame("gui/frame.png", 0, 0)
- xalign 0.5
- yalign 0.5
- ymargin 15
- ypadding 10
- xmargin 10
- vbox:
- spacing 30
- textbutton _("Exit") action Return("")
- label _("PUB RAID - NOT YET IMPLEMENTED")
- null height 20
- viewport:
- #child_size (0.4, 0.8)
- mousewheel True
- draggable True
- arrowkeys True
- xfill False
- scrollbars "vertical"
-
- vbox:
- xalign 0.5
- spacing 5
- label _("%s" % persistent.nickname)
- null height 40
-
- showif irc_online:
- for chat in irc_buffer:
- label _("%s: {size=22}%s{/size}" % (chat[0], chat[1].replace("<%s>" % chat[0], "")))
-
- null height 40
- input:
- id "msgmsg"
- color ((128, 128, 128, 220))
- italic True
- size 26
- copypaste True
- allow "qwertyuiopasdfghjklzxcvbnm QWERTYUIOPASDFGHJKKLZXCVBNM,.?!+-=:;'()"
- textbutton _("Send") action None
- else:
- label _("Connecting...")
-
- timer 1.0 action Function(renpy.restart_interaction) repeat True
-
diff --git a/game/player.rpy b/game/player.rpy
deleted file mode 100644
index 1d74189..0000000
--- a/game/player.rpy
+++ /dev/null
@@ -1,649 +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
-########################################################################################
-# Player data displays
-
-init -10 python:
- import copy
-
-init python:
- import json
- from threading import Timer
-
- def inventoryplace():
- global Player
- # Return next free slot index
- try:
- return Player["inv"].index(None)
- except:
- return len(Player["inv"])
-
- def get_inventory():
- raw=send_packet("get_inv", "")
-
- pt=json_decode(raw)
- if (pt == ERR_JSONDECODER):
- return ERR_JSONDECODER
-
- if (pt == FAILUREMSG):
- # TODO: msgbox you're offline, quit
- return ERR_LOGIN_DEFAULT
-
- print "get_inv(): "+str(pt)
- return pt
-
- # Function which list all unit id on party
- def party_dupcheck(pid):
- ar=[]
- for unt in Player["party_%s" % pid]:
- ar.append(unt["unit_id"])
- return ar
-
- def get_party(pid, internal=False):
- raw=send_packet("get_party", str(pid))
-
- pt=json_decode(raw)
- if (pt == ERR_JSONDECODER):
- return ERR_JSONDECODER
-
- Player["party_%d" % pid]=pt
- if (internal):
- return False
-
- allmem=""
- for member in pt:
- # Skip'invalid members
- if member["unit_id"] <= 0:
- continue
-
- # TODO: show image
- rfc=Player["inv"][member["inv_id"]]
-
- allmem+="%d★ %s (Lv %d, %d exp)\n" % (allunits[member["unit_id"]]["rare"], allunits[member["unit_id"]]["name"], rfc["level"], rfc["exp"])
- #Player["party_1"].append(member)
-
- renpy.call_screen("msgbox", "Party %d\n %s" % (pid, allmem))
- return True
-
- def ap_restore():
- global ApTimer, Player
-
- Player["ap"]+=1
- if (Player["ap"] < Player["max_ap"]):
- try:
- ApTimer.cancel()
- except:
- pass
- ApTimer=Timer(360.0, ap_restore)
- ApTimer.daemon=True
- ApTimer.start()
- return
-
- def update_ap(newval):
- global ApTimer, Player
-
- running=False
- if (Player["ap"] < Player["max_ap"]):
- running=True
-
- # Update AP
- # TODO: Do we allow over-the-cap AP?
- Player["ap"]+=newval
-
- # Handle the timer
- if (not running and Player["ap"] < Player["max_ap"]):
- ApTimer=Timer(360.0, ap_restore)
- ApTimer.daemon=True
- ApTimer.start()
- if (running and Player["ap"] >= Player["max_ap"]):
- ApTimer.cancel()
-
- return
-
- def set_party(pid, members):
- raw=send_packet("set_party", """{"party_id": %d, "formation": %s}""" % (pid, str(members)))
-
- pt=json_decode(raw)
- if (pt == ERR_JSONDECODER):
- return ERR_JSONDECODER
-
- return True
-
- # Ping function, it keeps the connection alive.
- # DEPRECATED
- def ping_routine():
- return
-
- # Techinically a battle function, readjusts a value
- # Rarity affects directly primary stat. We should distribute 140 points
- def readjust_status(rar, job, hp=True):
- newv=50
- # Imbalanced class
- if (job == Job_Swordsman):
- if hp:
- newv+=30+rar
- else:
- newv+=10+(rar/2)
- elif (job == Job_Mage):
- if hp:
- newv+=10+(rar/2)
- else:
- newv+=30+rar
- # Balanced class
- elif (job == Job_Assassin):
- if hp:
- newv+=15+(rar/2)
- else:
- newv+=25+rar
- elif (job == Job_Archer):
- if hp:
- newv+=25+rar
- else:
- newv+=15+(rar/2)
- # All-rounder class, with no steady growth
- elif (job == Job_Gunner):
- if hp:
- newv+=20+(rar/2)
- else:
- newv+=20+(rar/2)
-
- return newv
-
- def party_update(pid, pix):
- newindex=renpy.call_screen("inventory", True)
-
- # We only need inventory id's
- # So make a Party variable with this
- Party=dlist()
- for une in Player["party_%d" % pid]:
- Party.append(une["inv_id"])
-
- if debug:
- print str(Party)
-
- # Add unit, but only if no duplicates are found
- # Exception: If it is -1, then we can add
- if newindex != -1:
- dupcheck=party_dupcheck(pid)
- dupid=Player["inv"][newindex]["unit_id"]
- if dupid in dupcheck:
- renpy.notify(_("You cannot add duplicate party members!"))
- else:
- Party[pix]=newindex
- else:
- Party[pix]=newindex
-
- if debug:
- print str(Party)
-
- # Set party
- set_party(pid, Party)
- return True
-
- def evocheck(level, unit):
- # Does an evolved form exist?
- print "evocheck lv %d" % level
- try:
- nu=unit["unit_id"]+1
- #print "nu is: %d" % int(nu)
- next_name=allunits[nu]["name"]
- #print "next name: %s" % next_name
- except:
- return False
-
- # Level requeriment
- return level == unit["max_level"]
-
-screen inventory(blank=False, filters="True"):
- # window
- # hbox
- vpgrid:
- cols 4
- spacing 5
- draggable True
- mousewheel True
- scrollbars "vertical"
- side_xalign 0.5
- xoffset 15
- #yoffset 45
- #xfill True
- yfill True
-
- # The close button returns -1 and comes first
- imagebutton:
- if not blank:
- idle At("gfx/square/back_idle.png", czoom_70)
- hover At("gfx/square/back_hover.png", czoom_70)
- else:
- idle At("gfx/square/bg.png", czoom_70)
- action Return(-1)
-
- for i, item in enumerate(Player["inv"]):
- # We don't care for None items
- if item is not None:
- # Needed because eval :rolling_eyes:
- #$ ir=copy.copy(item["rare"])
- #$ print str(locals())
- python:
- evl=False
- #print "---- repr"
- try:
- alu=allunits[item["unit_id"]]
- except:
- alu={}
- stdout("ERROR, alu: not defined, index %d" % i)
- evl=eval(filters, globals(), locals())
- #print str(evl)
- #print str(filters)
- #print str(item)
- #print str(alu)
- if evl:
- imagebutton:
- 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)
- action Return(i)
- #alternate "Show the char data chart"
-
-screen party_main():
- default party = 1
- vbox:
- xalign 0.5
- yalign 0.3
- label _("{size=32}{color=#fff}Party %d{/color}{/size}" % (party))
- null height 20
- hbox:
- for i, item in enumerate(Player["party_%d" % 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([party, 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)
-
-
-screen upgrade_char():
- vbox:
- xalign 0.5
- yalign 0.3
-
- # The unit
- hbox:
- add At(Composite(
- (340, 340),
- (0, 0), "gfx/square/bg.png",
- (0, 0), "gfx/square/units/%d.png" % unit["unit_id"],
- (0, 0), "gfx/square/%d.png" % unit["rare"],
- ), czoom_70)
- null width 10
- label _("{size=32}{color=#fff}%s{/color}{/size}" % (unit["name"]))
-
- null height 20
- $i=0
- hbox:
- for ignored in enumerate(material):
- if i < 4:
- imagebutton:
- if material[i] >= 0:
- idle At(Composite(
- (340, 340),
- (0, 0), "gfx/square/bg.png",
- (0, 0), "gfx/square/units/%d.png" % Player["inv"][material[i]]["unit_id"],
- (0, 0), "gfx/square/%d.png" % allunits[Player["inv"][material[i]]["unit_id"]]["rare"],
- ), czoom_70)
- else:
- idle At("gfx/square/bg.png", czoom_70)
- action Return(i)
- $i+=1
-
- null height 20
- hbox:
- for ignored in enumerate(material):
- if i < 8:
- imagebutton:
- if material[i] >= 0:
- idle At(Composite(
- (340, 340),
- (0, 0), "gfx/square/bg.png",
- (0, 0), "gfx/square/units/%d.png" % Player["inv"][material[i]]["unit_id"],
- (0, 0), "gfx/square/%d.png" % allunits[Player["inv"][material[i]]["unit_id"]]["rare"],
- ), czoom_70)
- else:
- idle At("gfx/square/bg.png", czoom_70)
- action Return(i)
- $i+=1
-
- null height 80
- # The close button returns -1 and comes last (TODO)
- hbox:
- textbutton _("Merge") action Return(-2)
- null width 80
- textbutton _("Leave") action Return(-1)
-
-
-screen evolve_char():
- vbox:
- xalign 0.5
- yalign 0.3
-
- # The unit
- hbox:
- add At(Composite(
- (340, 340),
- (0, 0), "gfx/square/bg.png",
- (0, 0), "gfx/square/units/%d.png" % unit["unit_id"],
- (0, 0), "gfx/square/%d.png" % unit["rare"],
- ), czoom_70)
- null width 10
- add At("gfx/evol.png", czoom_70)
- null width 10
- add At(Composite(
- (340, 340),
- (0, 0), "gfx/square/bg.png",
- (0, 0), "gfx/square/units/%d.png" % next["unit_id"],
- (0, 0), "gfx/square/%d.png" % next["rare"],
- ), czoom_70)
- #label _("{size=32}{color=#fff}%s\n↓\n%s{/color}{/size}" % (unit["name"], next["name"]))
-
- null height 120
- $i=0
- hbox:
- xalign 0.5
- spacing 150
- for ignored in enumerate(material):
- if i < 2:
- imagebutton:
- if material[i] >= 0:
- idle At(Composite(
- (340, 340),
- (0, 0), "gfx/square/bg.png",
- (0, 0), "gfx/square/units/%d.png" % Player["inv"][material[i]]["unit_id"],
- (0, 0), "gfx/square/%d.png" % allunits[Player["inv"][material[i]]["unit_id"]]["rare"],
- ), czoom_70)
- else:
- idle At("gfx/square/bg.png", czoom_70)
- action Return(i)
- $i+=1
-
- null height 80
- # The close button returns -1 and comes last (TODO)
- hbox:
- xalign 0.5
- spacing 80
- textbutton _("Evolve") action [SensitiveIf(material[0]>=0 and material[1]>=0), Return(-2)]
- textbutton _("Cancel") action Return(-1)
-
-
-screen char_details(un, hpval, akval, idx):
- style_prefix "confirm"
-
- frame:
- at msgbox_emp
-
- vbox:
- xalign 0.5
- yalign 0.5
- spacing 30
-
- label _("{b}%s{/b}\n%s\n\nHP: %d\nATK: %d\nLv %d/%d\nEXP: %d") % (
- star_write(un["rare"]), un["name"],
- hpval, akval,
- Player["inv"][idx]["level"],
- un["max_level"],
- Player["inv"][idx]["exp"]):
- style "confirm_prompt"
- xalign 0.5
-
- hbox:
- xalign 0.5
- spacing 100
-
- textbutton _("Merge") action [SensitiveIf(Player["inv"][idx]["level"] < un["max_level"]), Return(-1)]
- textbutton _("Evolve") action [SensitiveIf(evocheck(Player["inv"][idx]["level"], un)), Return(-2)]
-
- hbox:
- xalign 0.5
- spacing 100
-
- textbutton _("Ok") action Return(0)
-
- ## Right-click and escape answer "no".
- key "game_menu" action Return(0)
-
-
-# Show inventory button
-label inventory:
- play music MUSIC_PARTY.id() fadein 0.5
- $ hud_clear()
-
- # Try to update inventory
- $ 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)
-
-label show_inv:
- call screen inventory
- if (_return >= 0):
- $stdout("Selected unit index %d" % _return)
- $un=allunits[Player["inv"][_return]["unit_id"]]
- $show_img("unit_"+str(un["unit_id"]), at_list=[truecenter])
- $hpval=readjust_status(un["rare"], un["job"],
- True)*Player["inv"][_return]["level"]+un["hp"]
- $akval=readjust_status(un["rare"], un["job"],
- False)*Player["inv"][_return]["level"]+un["strength"]
-
- $ret=renpy.call_screen("char_details", un, hpval, akval, _return)
-
- # Proccess input
- if ret == -1:
- $who=_return
- call upgrade_pre
- elif ret == -2:
- $who=_return
- call evolve_pre
-
- $renpy.hide("unit_"+str(un["unit_id"]))
- else:
- jump restore
-
- jump show_inv
-
-
-label party_lobby_enter:
- play music MUSIC_PARTY.id() fadein 0.5
- $ hud_clear()
-
- # Try to update inventory
- $ 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)
-
- # FIXME
- $ get_party(1, True)
- jump party_lobby
-
-label party_lobby:
-
- call screen party_main
-
- # Return to town
- if _return == -1:
- jump restore
-
- # Update party index
- $party_update(_return[0], _return[1])
- $ get_party(_return[0], True)
-
- jump party_lobby
-
-label upgrade_pre:
- # who -> index. Set beforehand
- if who < 0:
- call screen msgbox("Error: Invalid upgrade parameters passed")
- return
-
- $ unit = allunits[Player["inv"][who]["unit_id"]]
- $ material = [-1, -1, -1, -1, -1, -1, -1, -1, -1, -1]
-
- # Try to update inventory
- $ 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)
-
- jump upgrade
-
-label upgrade:
- call screen upgrade_char()
- $message=_return
- if (message == -1):
- $who=-1
- return
- #jump restore
- if (message == -2):
- # TODO
- python:
- mats=list(set(material))
- mats.insert(0, who)
- if -1 in mats:
- mats.remove(-1)
- stdout(str(mats))
- ret=None
- ret=renpy.call_screen("confirm", "Are you sure you want to merge these units?", Return(True), Return(False))
- if ret:
- # TODO: DISPLAY ANIMATION
- message=send_packet("upgrade", str(mats))
- message=json_decode(message)
- try:
- lv=Player["inv"][who]["level"]
- narrator("Level up! %d -> %d" % (lv, int(message)+lv))
- except:
- narrator("An error occured.\n\nError code: %s" % str(message))
- renpy.jump("upgrade_pre")
- else:
- $ cand=renpy.call_screen("inventory", True)
- if cand in material and cand >= 0:
- "This unit is already to be merged!"
- elif cand == who:
- "Cannot merge unit with itself!"
- else:
- # TODO: Check for party
- #"Trying to fuse [cand], must check if in party, duplicate, etc."
- $ material[message]=cand
- $ del cand
-
- # WIP
- jump upgrade
-
-
-label evolve_pre:
- # who -> index. Set beforehand
- if who < 0:
- call screen msgbox("Error: Invalid upgrade parameters passed")
- return
-
- $ unit = allunits[Player["inv"][who]["unit_id"]]
- $ next = allunits[Player["inv"][who]["unit_id"]+1]
- $ material = [-1, -1]
-
- # Try to update inventory
- $ 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)
-
- #$renpy.call_screen("msgbox", "Feature not yet available\n%s" % next["name"])
- $renpy.hide("unit_"+str(unit["unit_id"]))
- jump evolve
-
-
-label evolve:
- call screen evolve_char()
- $message=_return
- if (message == -1):
- $who=-1
- return
- #jump restore
- if (message == -2):
- # TODO
- python:
- mats=list(set(material))
- mats.insert(0, who)
- stdout(str(mats))
- ret=None
- ret=renpy.call_screen("confirm", "Are you sure you want to evolve this units?\nReagents will be lost forever!", Return(True), Return(False))
- if ret:
- message=send_packet("evolve", str(mats))
- message=json_decode(message)
- if message in ["200", 200]:
- # TODO: DISPLAY ANIMATION
- narrator("Evolution SUCCESS!")
- else:
- narrator("Error code: 101!\n\n%s" % str(message))
- renpy.jump("inventory")
- else:
- $ cand=renpy.call_screen("inventory", True, 'alu["rare"] == %d and\
-(\
- (alu["unit_id"] == %s) or\
- (alu["flags"] & UF_EVOMAT and alu["attribute"] == %d) or\
- (alu["flags"] & UF_SUPEREVO) )' % (unit["rare"], unit["unit_id"], unit["attribute"]))
- if cand in material and cand >= 0:
- "This unit is already to be used as material!"
- elif cand == who:
- "That's the unit being evolved!"
- else:
- # TODO: Check for party
- #"Trying to fuse [cand], must check if in party, duplicate, etc."
- $ material[message]=cand
- $ del cand
-
- # WIP
- jump evolve
-
diff --git a/game/recruit.rpy b/game/recruit.rpy
deleted file mode 100644
index 4d166d1..0000000
--- a/game/recruit.rpy
+++ /dev/null
@@ -1,110 +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
-########################################################################################
-# Recruits
-init python:
- import json
- def recruit(t, a):
- global Player
- raw=send_packet("recruit", recruitdata(t, a))
-
- rc=json_decode(raw)
- try:
- return int(rc)
- except:
- pass
-
- # Update data
- try:
- Player[rc["currency"][0]]=rc["currency"][1]
- except:
- renpy.notify("ERROR, Currency is undefined.")
-
- for unit in rc["units"]:
- _window_hide(None)
- if (debug):
- print str(unit)
- idx=inventoryplace()
- unit["unit_id"]=int(unit["unit_id"])
- if (debug):
- print "Recruit index: %d" % idx
- print "Player inventory: %s" % str(Player["inv"])
- print "Unit ID: %s" % str(unit["unit_id"])
- print "Unit Name: %s" % str(allunits[int(unit["unit_id"])]["name"])
- print "Unit Rarity: %d" % allunits[int(unit["unit_id"])]["rare"]
- Player["inv"][idx]=unit
- txt=allunits[int(unit["unit_id"])]["name"]
- rar=allunits[int(unit["unit_id"])]["rare"]
- star=star_write(rar)
- sprite=str(unit["unit_id"])
- show_img("unit_"+sprite, at_list=[truecenter])
- renpy.pause(0.1)
- renpy.call_screen("msgbox", "%s\n\nRecruited %d★ %s" % (star, rar, txt))
- renpy.hide("unit_"+sprite)
- _window_show(None)
-
- # Return result
- if (rc["code"] == ERR_NOGEMS):
- renpy.notify("You don't have enough gems to complete.")
- if (rc["code"] == ERR_INVFULL):
- renpy.notify("You don't have enough space to complete!")
-
- return rc["code"]
-
-
-label tavern:
- $ show_img("bg tavern", False, ext=".jpg") # Validate
- scene bg tavern
- play music MUSIC_PARTY.id() fadein 0.5
- window hide
-
- jump tv_loop
-
-label tv_loop:
- $currencies="{size=18}Crystals: %d | GP: %d{/size}" % (Player["crystals"], Player["gp"])
- menu:
- "Recruit 1 units for 200 gems":
- $message=recruit(1, 1)
- #"Recruit 5 units for 1000 gems":
- # $message=recruit(1, 5)
- "Recruit 10 units for 2000 gems\n{i}One 4★ guaranteed!{/i}":
- $message=recruit(1, 10)
- "GP Tavern: Recruit 1 units for 1000 GP":
- $message=recruit(2, 1)
- "GP Tavern: Recruit 10 units for 10,000 GP\n{i}One Fairy or Mana Egg guaranteed!{/i}":
- $message=recruit(2, 10)
- "Chances & Info":
- # TODO WIP: Read JSON Instead
- "{b}Crystal Tavern{/b}" "\
- 4★ chance: 0.75 %%\n\
- 3★ chance: 2.00 %%\n\
- 2★ chance: 15.00 %%\n\
- 1★ chance: 82.25 %%"
- "{b}GP Tavern{/b}" "\
- Fairies: 2.00 %%\n\
- 1★ chance: 98.00 %%"
- "{b}This is a placeholder{/b}" "{i}It is possible to render each unit inidividual chance but we're not doing this (yet){/i}\nPlease be patient."
- "Do nothing\n[currencies]":
- jump restore
-
- if (message == OFFLINEMSG):
- "Server replies:" "[message]\n\nYou are offline?"
- return
-
- jump tv_loop
-