A couple of years ago I began working on a project that I call PythonFantay. A text based game inspired by Final Fantasy. The game is by no means complete, but I figured I could upload a sample of the game here! The game contains the follow features:
One day I want to finish the game by adding many more features. Maybe during my next break.. I shall see! Until then please enjoy!
Even though it’s not written, you can exit from most menus by typing “exit”. Good luck!
import pickle
import math
from random import randint , random
class Engine ( object ):
def __init__ ( self , scene_map ):
self . scene_map = scene_map
def play ( self ):
current_scene = self . scene_map . opening_scene ()
last_scene = self . scene_map . next_scene ( 'finished' )
prev_scene = self . scene_map . name_of_scene ( current_scene )
next_scene_name = current_scene . enter ()
current_scene = self . scene_map . next_scene ( next_scene_name )
leaving_menu = 0
outcome = None
while current_scene != last_scene :
if next_scene_name in [
'menu' , 'inv' , 'save' , 'equip' , 'load' , 'mhelp' , 'debug' ,
'magic'
]:
leaving_menu = 1
if next_scene_name != 'menu' :
next_scene_name = 'menu'
else :
next_scene_name = current_scene . enter ( prev_scene )
current_scene = self . scene_map . next_scene ( next_scene_name )
elif next_scene_name in [ 'help' ]:
next_scene_name = current_scene . enter ( prev_scene )
current_scene = self . scene_map . next_scene ( next_scene_name )
else :
logic1 = 0
logic2 = 0
if prev_scene not in self . scene_map . towns :
if prev_scene not in [ 'open' , 'start' , 'menu' ]:
logic1 = 1
if next_scene_name not in self . scene_map . towns :
if next_scene_name not in [ 'open' , 'start' , 'menu' ]:
logic2 = 1
if logic1 * logic2 == 1 :
#print "P scene %s N scene %s" % (prev_scene, next_scene_name)
#print self.scene_map.towns
if randint ( 0 , 100 ) <= 35 and leaving_menu != 1 :
outcome = Battle (). enter ( prev_scene )
if outcome :
current_scene = self . scene_map . next_scene ( outcome )
outcome = None
leaving_menu = 0
next_scene_name = current_scene . enter ()
prev_scene = self . scene_map . name_of_scene ( current_scene )
current_scene = self . scene_map . next_scene ( next_scene_name )
current_scene . enter ()
class Scene ( object ):
def enter ( self ):
print "scene not yet finished"
def game_over_scene ( self , hploss ):
hp_sum = 0
PARTY . party_subract_hp ( hploss )
for hero in PARTY . get_party_members ():
hp_sum += hero . hp
return hp_sum
def restore_party ( self ):
for hero in PARTY . get_party_members ():
hero . hp = hero . maxhp
hero . mp = hero . maxmp
battleborders ( "Party HP and MP Restored" )
#Battle is a type of Scene
class Party ( object ):
intro_text = """
Welcome. Choose a name and class for 4 heroes.
The following classes are available:
1. Warrior
2. White Mage
3. Black Mage
4. Theif
"""
def __init__ ( self ):
formatborders ( self . intro_text )
self . hero1 = eval ( self . change_job ( self . get_job ()))
self . hero2 = eval ( self . change_job ( self . get_job ()))
self . hero3 = eval ( self . change_job ( self . get_job ()))
self . hero4 = eval ( self . change_job ( self . get_job ()))
self . inv = Inventory ()
self . initialize_inventory ()
self . gil = 50
def get_job ( self ):
job = raw_input ( "Enter the job of your hero: \n > " )
return job
def change_job ( self , info ):
jobs = {
'warrior' : "Warrior()" ,
'Warrior' : "Warrior()" ,
'1' : "Warrior()" ,
'white mage' : "WhiteMage()" ,
'White Mage' : "WhiteMage()" ,
'white' : "WhiteMage()" ,
'2' : "WhiteMage()" ,
'black mage' : "BlackMage()" ,
'Black Mage' : "BlackMage()" ,
'black' : "BlackMage()" ,
'3' : "BlackMage()" ,
'theif' : "Theif()" ,
'Theif' : "Theif()" ,
'4' : "Theif()"
}
while info not in jobs . keys ():
print "You have not selected a proper job."
formatborders ( self . intro_text )
info = self . get_job ()
return jobs [ info ]
def get_party_members ( self ):
party_members = [ self . hero1 , self . hero2 , self . hero3 , self . hero4 ]
return party_members
def initialize_inventory ( self ):
self . inv . add_item ( potion , 10 )
self . inv . add_item ( ether , 5 )
self . inv . add_item ( hipotion , 1 )
self . inv . add_item ( hiether , 1 )
for hero in self . get_party_members ():
hero . initialize_equipment ()
def display_equipment ( self ):
formatborders (
"EQUIPMENT: Equipment Stats are in the format HP/MP/ATT/MATT/PARM/MARM"
)
party_members = self . get_party_members ()
print "NAME" . ljust ( 7 ),
for hero in party_members :
print hero . name . ljust ( 15 ),
print " \n " , "JOB" . ljust ( 7 ),
for hero in party_members :
print hero . job . ljust ( 15 ),
print " \n " , "WEAPON" . ljust ( 7 ),
for hero in party_members :
print hero . sword . name . ljust ( 15 ),
print " \n "
print " \n " , "" . ljust ( 7 ),
for hero in party_members :
hero . sword . print_stats (),
print " \n "
print " \n " , "HELM" . ljust ( 7 ),
for hero in party_members :
print hero . helm . name . ljust ( 15 ),
print " \n "
print " \n " , "" . ljust ( 7 ),
for hero in party_members :
hero . helm . print_stats (),
print " \n "
print " \n " , "CHEST" . ljust ( 7 ),
for hero in party_members :
print hero . chest . name . ljust ( 15 ),
print " \n "
print " \n " , "" . ljust ( 7 ),
for hero in party_members :
hero . chest . print_stats (),
print " \n "
print " \n " , "ACC" . ljust ( 7 ),
for hero in party_members :
if hero . acc :
print hero . acc . ljust ( 15 ),
else :
print 'NONE' . ljust ( 15 ),
print " \n "
def display_heros ( self ):
print " \n "
members = self . get_party_members ()
for i in range ( 4 ):
class_name = members [ i ]. __class__ . __name__
print i + 1 , ". %s" % members [ i ]. name . ljust (
10 ), "(%s)" % class_name
print " \n "
def return_avg_levels ( self ):
lvlavg = self . hero1 . lev + self . hero2 . lev + self . hero3 . lev + self . hero4 . lev
lvlavg /= 4
return lvlavg
def display_hp ( self ):
display_format = "{:<10}" + ( "{:^10}" * 4 )
hero_hp = [ "HP:" ]
heros = self . get_party_members ()
for hero in heros :
hero_hp . append ( "%d/%d" % ( hero . hp , hero . maxhp ))
print display_format . format ( * hero_hp )
def display_hero_names ( self ):
display_format = "{:<10}" + ( "{:^10}" * 4 )
hero_names = [ 'Name:' ]
for hero in self . get_party_members ():
hero_names . append ( hero . name )
print display_format . format ( * hero_names )
def display_mp ( self ):
display_format = "{:<10}" + ( "{:^10}" * 4 )
hero_mp = [ "MP:" ]
heros = self . get_party_members ()
for hero in heros :
hero_mp . append ( "%d/%d" % ( hero . mp , hero . maxmp ))
print display_format . format ( * hero_mp )
def display_stat ( self , stat ):
if stat == 'hp' :
self . display_hp ()
elif stat == 'mp' :
self . display_mp ()
else :
display_format = "{:<10}" + ( "{:^10}" * 4 )
text = [ stat . upper ()]
for hero in self . get_party_members ():
evalcode = 'hero.' + stat
text . append ( eval ( evalcode ))
print display_format . format ( * text )
if stat == 'name' :
print "-" * 50
def display_panel ( self ):
print "-" * 80
self . display_hero_names ()
self . display_hp ()
self . display_mp ()
print "-" * 80
def display_panel_numbered ( self ):
print "-" * 80
self . display_hero_names_numbered ()
self . display_hp ()
self . display_mp ()
print "-" * 80
def display_full_panel ( self ):
stat_names = [
'name' , 'job' , 'lev' , 'hp' , 'mp' , 'exp' , 'mag' , 'mdef' , 'stre' ,
'defe' , 'speed'
]
for stat_name in stat_names :
self . display_stat ( stat_name )
def display_hero_names_numbered ( self ):
display_format = "{:<10}" + "{:^10}" * 4
heros = self . get_party_members ()
display_text = [ 'NAME:' ]
for i in range ( 4 ):
name_text = "%d. %s" % ( i + 1 , heros [ i ]. name )
display_text . append ( name_text )
print display_format . format ( * display_text )
def party_subract_hp ( self , health ):
for hero in self . get_party_members ():
hero . hp -= health
if hero . hp < 0 :
hero . hp = 0
class Equipment ( object ):
equip_stat_string_list = [
'att' , 'matt' , 'parm' , 'marm' , 'health' , 'mana' , 'cost'
]
def __init__ ( self , name , att , matt , parm , marm , health , mana , cost ,
armortype ):
self . name = name
self . att = att
self . matt = matt
self . parm = parm
self . marm = marm
self . health = health
self . mana = mana
self . cost = cost
self . armortype = armortype
def return_stats ( self ):
stat_list = [
self . health , self . mana , self . att , self . matt , self . parm , self . marm
]
return stat_list
def print_stats ( self ):
stat_text = []
for stat in self . return_stats ():
stat_text . append ( str ( stat ))
print "/" . join ( stat_text ). ljust ( 15 ),
def print_stats_inventory ( self ):
print "NAME" . ljust ( 10 ), self . name
for stat in self . equip_stat_string_list :
run_code = 'self.' + stat
print stat . upper (). ljust ( 10 ), eval ( run_code )
class Accesory ( Equipment ):
pass
class Item ( object ):
def __init__ ( self , name , hp , mp , desc , itype ):
self . name = name
self . hp = hp
self . mp = mp
self . desc = desc
self . itype = itype
#Equipment Declarations name, att, matt, parm, marm, health, cost, armortype
bronzehelm = Equipment ( 'Bronze Helm' , 1 , 0 , 5 , 3 , 10 , 0 , 100 , 'whelm' )
bronzechestplate = Equipment ( 'Bronze Plate' , 1 , 0 , 10 , 5 , 0 , 0 , 100 , 'wchest' )
bronzesword = Equipment ( 'Bronze Sword' , 10 , 0 , 0 , 0 , 0 , 0 , 100 , 'wwep' )
leatherhelm = Equipment ( 'Leather Helm' , 0 , 1 , 5 , 5 , 5 , 10 , 100 , 'mhelm' )
leatherchestplate = Equipment ( 'Leather Plate' , 0 , 1 , 7 , 11 , 3 , 0 , 100 ,
'mchest' )
woodenwand = Equipment ( 'Wooden Wand' , 3 , 10 , 0 , 2 , 0 , 5 , 100 , 'mwep' )
ironhelm = Equipment ( 'Iron Helm' , 1 , 0 , 15 , 7 , 0 , 0 , 150 , 'whelm' )
ironchest = Equipment ( 'Iron Chest' , 0 , 0 , 15 , 7 , 0 , 0 , 200 , 'wchest' )
potion = Item ( 'Potion' , 100 , 0 , 'Restores 100 HP' , 'p' )
ether = Item ( 'Ether' , 0 , 20 , 'Restores 200 MP' , 'm' )
phoenixdown = Item ( 'Phoenix Down' , 10000 , 0 , 'Revives dead Hero' , 'p' )
hipotion = Item ( 'Hi-Potion' , 500 , 0 , 'Restores 500 HP' , 'p' )
hiether = Item ( 'Hi-Ether' , 0 , 500 , 'Restores 200 MP' , 'm' )
class Hero ( object ):
action_text = """
Select an action: (Press enter to skip turn)
1. Attack
2. Magic
3. Use item
4. Flee
>"""
def __init__ ( self ):
self . lev = 0
self . exp = 0
self . mag = 0
self . mdef = 0
self . stre = 0
self . defe = 0
self . maxhp = 0
self . hp = 0
self . maxmp = 0
self . mp = 0
self . name = None
self . speed = 0
self . job = self . __class__ . __name__
self . initialize ()
self . stats = {
'name' : self . name ,
'job' : self . job ,
'lev' : self . lev ,
'exp' : self . exp ,
'mag' : self . mag ,
'mdef' : self . mdef ,
'stre' : self . stre ,
'defe' : self . defe ,
'hp' : self . hp ,
'mp' : self . mp ,
'speed' : self . speed
}
self . sword = None
self . helm = None
self . chest = None
self . acc = None
self . spells = []
def initialize ( self ):
self . name = raw_input ( "Enter a hero name: \n > " )
if len ( self . name ) > 11 or len ( self . name ) < 1 :
print "Please Enter a hero name that is 10 characters or less."
self . initialize ()
def return_stats ( self ):
hero_stats = [
self . name , self . lev , self . exp , self . mag , self . mdef , self . stre ,
self . defe , self . hp , self . mp , self . speed , self . maxhp , self . maxmp
]
return hero_stats
def return_some_stats ( self ):
pass
def equip ( self , equipment , eqtype ):
if eqtype == 'sword' :
self . sword = equipment
if eqtype == 'helm' :
self . helm = equipment
if eqtype == 'chest' :
self . chest = equipment
if eqtype == 'acc' :
self . acc = equipment
def set_stats ( self , lev , exp , mag , mdef , stre , defe , hp , maxhp , mp , maxmp ,
speed ):
self . lev = lev
self . exp = exp
self . mag = mag
self . mdef = mdef
self . stre = stre
self . defe = defe
self . hp = hp
self . mp = mp
self . speed = speed
self . maxhp = maxhp
self . maxmp = maxmp
def act ( self , target_list ):
print "%s's turn:" % self . name
action = raw_input ( self . action_text )
if action in [ '1' , 'attack' , 'Attack' , 'a' , 'A' ]:
return self . attack ( target_list )
elif action in [ '2' , 'magic' , 'Magic' , 'm' , 'M' ]:
return self . magic ( target_list )
elif action in [ '3' , 'item' , 'i' , 'I' , 'Item' ]:
InventoryMenu (). enter ( 'battle' )
return 0 , 0
elif not action :
print "Skipping Turn"
return 0 , 0
else :
print "Please enter an action. Press enter to skip the turn"
return self . act ( target_list )
def attack ( self , target_list ):
self . printtargets ( target_list )
target = raw_input ( ">" )
if target . isdigit ():
target = int ( target )
#print range(1, len(target_list[4:]) + 1)
if target not in range ( 1 , len ( target_list [ 4 :]) + 1 ):
print "Target out of range."
return self . attack ( target_list )
monster = target_list [ 3 + target ]. __class__ . __name__
damage = self . generate_attack_dmg ( target_list [ 3 + target ])
battleborders ( "%s attacked %s doing %d damage." %
( self . name , monster , damage ))
return damage , 3 + target
else :
print "Please enter a number."
return self . attack ( target_list )
def printtargets ( self , target_list ):
index = 1
print "Enter a target number:"
for target in range ( 4 , len ( target_list [ 4 :]) + 4 ):
monster = target_list [ target ]
print index , ". " , monster . __class__ . __name__ , " " ,
index += 1
print ""
def generate_attack_dmg ( self , monster ):
delta = self . sword . att + self . helm . att + self . chest . att
D = ( self . stre / 2 ) + delta
damage = D + D * random () - monster . defe
return math . ceil ( damage )
#return (random() + randint (5, 10)) * ((-1) ** 2)
def print_levelup ( self ):
battleborders ( "%s has reached level %d" % ( self . name , self . lev ))
def display_levelup_stat ( self , stat_txt , old , new ):
display_format = "{:<10}" + "{:^+10}"
display_text = [ stat_txt . upper (), new - old ]
print display_format . format ( * display_text )
def display_levelup_stats ( self , old_stats , new_stats ):
stat_names = [ 'mag' , 'mdef' , 'stre' , 'defe' , 'speed' , 'maxhp' , 'maxmp' ]
for i in range ( 7 ):
self . display_levelup_stat ( stat_names [ i ], old_stats [ i ],
new_stats [ i ])
def display_spells ( self ):
print "%s Spells: " % ( self . name )
print '-' * 80
spell_count = len ( self . spells )
y = enumerate ( self . spells , 1 )
spells_numbered = list ( y )
spell_text = []
for spell in spells_numbered :
spell_text . append ( "%d. %s" % ( spell [ 0 ], spell [ 1 ]. name . upper ()))
extend_amount = ( 4 - (( len ( self . spells ) + 4 ) % 4 ))
for x in range ( extend_amount ):
spell_text . append ( " " )
i = 0
display_text = "{:>10}" * 4
while i <= spell_count :
#print "Spell %r is number %d" % (spell_text[i], i)
print display_text . format ( * spell_text [ i : i + 4 ])
i += 4
print '-' * 80
def generate_magic_dmg ( self , spell , monster ):
delta = self . sword . matt + self . helm . matt + self . chest . matt
D = ( self . mag / 2 ) + delta
self . mp -= spell . mp
damage = ( D + D * random () - monster . mdef ) * spell . potency
return math . ceil ( damage )
def generate_magic_healing ( self , spell ):
delta = self . sword . matt + self . helm . matt + self . chest . matt
D = ( self . mag / 2 ) + delta
damage = spell . potency * ( D + D * random ())
return math . ceil ( damage )
def use_spell ( self , spell , target ):
if target . __class__ not in Hero_Classes :
pass # Battle use of spell on monster
else :
if self . mp >= spell . mp :
beforehp = target . hp
healing_amount = self . generate_magic_healing ( spell )
target . hp += healing_amount
self . mp -= spell . mp
if target . hp > target . maxhp :
target . hp = target . maxhp
print "Restored %d hp to %s" % ( taget . hp - beforehp ,
target . name )
def magic ( self , target_list ):
spell = self . get_spell ()
if spell :
hero_list = PARTY . get_party_members ()
if spell . foe_target == 'friend' :
PARTY . display_panel_numbered ()
target_choice = raw_input ( " \n >" )
if ( int ( target_choice ) <= 4 ) and ( int ( target_choice ) >= 1 ):
hero . use_spell ( spell , hero_list [ int ( target_choice ) - 1 ])
return 0 , 0
else :
print "Please select a hero numbered 1 through 4"
return self . act ( target_list )
else :
self . printtargets ( target_list )
target = raw_input ( ">" )
if target . isdigit ():
target = int ( target )
#print range(1, len(target_list[4:]) + 1)
if target not in range ( 1 , len ( target_list [ 4 :]) + 1 ):
print "Target out of range."
return self . attack ( target_list )
monster = target_list [ 3 + target ]. __class__ . __name__
if self . mp > spell . mp :
damage = self . generate_magic_dmg (
spell , target_list [ 3 + target ])
battleborders ( "%s blasted %s doing %d damage." %
( self . name , monster , damage ))
return damage , 3 + target
else :
print "Not enough mp. "
return 0 , 0
else :
print "Please enter a number."
return self . act ( target_list )
else :
return self . act ( target_list )
def get_spell ( self ):
if len ( self . spells ) == 0 :
print "Hero has no spells. "
return None
else :
self . display_spells ()
print "Select spell number"
spell_choice = raw_input ( " \n >" )
if spell_choice . isdigit ():
spell_choice = int ( spell_choice )
return self . spells [ spell_choice - 1 ]
else :
print "Enter a proper spell number."
return get_spell ()
class Warrior ( Hero ):
def level_up ( self , leftover_exp ):
oldstats = self . return_stats ()
oldstats = oldstats [ 3 :]
oldstats . pop ( 4 )
oldstats . pop ( 4 )
self . lev += 1
self . exp = int ( 100 * ( 1.1 ** self . lev ) - leftover_exp )
self . mag += 1
self . mdef += 2
self . stre += 5
self . defe += 4
self . maxhp += 100 + randint ( 0 , 50 )
self . maxmp += 10
self . speed += 1
self . hp = self . maxhp
self . mp = self . maxmp
self . time = 100 / self . speed
newstats = self . return_stats ()
newstats = newstats [ 3 :]
newstats . pop ( 4 )
newstats . pop ( 4 )
self . print_levelup ()
self . display_levelup_stats ( oldstats , newstats )
def initialize_equipment ( self ):
self . equip ( bronzesword , 'sword' )
self . equip ( bronzehelm , 'helm' )
self . equip ( bronzechestplate , 'chest' )
self . set_stats ( 1 , 100 , 5 , 6 , 9 , 8 , 100 , 100 , 5 , 5 , 10 )
self . time = 100 / self . speed
class WhiteMage ( Hero ):
def level_up ( self , leftover_exp ):
oldstats = self . return_stats ()
oldstats = oldstats [ 3 :]
oldstats . pop ( 4 )
oldstats . pop ( 4 )
self . lev += 1
self . exp = int ( 100 * ( 1.1 ** self . lev ) - leftover_exp )
self . mag += 4
self . mdef += 6
self . stre += 1
self . defe += 1
self . maxhp += 20 + randint ( 0 , 30 )
self . maxmp += 10 + randint ( 0 , 5 )
self . hp = self . maxhp
self . mp = self . maxmp
self . speed += 1.5
self . time = 100 / self . speed
newstats = self . return_stats ()
newstats = newstats [ 3 :]
newstats . pop ( 4 )
newstats . pop ( 4 )
self . print_levelup ()
self . display_levelup_stats ( oldstats , newstats )
def initialize_equipment ( self ):
self . equip ( woodenwand , 'sword' )
self . equip ( leatherhelm , 'helm' )
self . equip ( leatherchestplate , 'chest' )
self . set_stats ( 1 , 100 , 10 , 7 , 1 , 3 , 60 , 60 , 60 , 60 , 10 )
self . time = 100 / self . speed
self . spells . append ( cure )
class BlackMage ( Hero ):
def level_up ( self , leftover_exp ):
oldstats = self . return_stats ()
oldstats = oldstats [ 3 :]
oldstats . pop ( 4 )
oldstats . pop ( 4 )
self . lev += 1
self . exp = int ( 100 * ( 1.1 ** self . lev ) - leftover_exp )
self . mag += 7
self . mdef += 4
self . stre += 2
self . defe += 1
self . maxhp += 20 + randint ( 0 , 30 )
self . maxmp += 10 + randint ( 0 , 5 )
self . hp = self . maxhp
self . mp = self . maxmp
self . speed += 1.5
self . time = 100 / self . speed
newstats = self . return_stats ()
newstats = newstats [ 3 :]
newstats . pop ( 4 )
newstats . pop ( 4 )
self . print_levelup ()
self . display_levelup_stats ( oldstats , newstats )
def initialize_equipment ( self ):
self . equip ( woodenwand , 'sword' )
self . equip ( leatherhelm , 'helm' )
self . equip ( leatherchestplate , 'chest' )
self . set_stats ( 1 , 100 , 10 , 7 , 1 , 3 , 60 , 60 , 60 , 60 , 10 )
self . time = 100 / self . speed
self . spells . append ( fire )
class Theif ( Hero ):
def level_up ( self , leftover_exp ):
oldstats = self . return_stats ()
oldstats = oldstats [ 3 :]
oldstats . pop ( 4 )
oldstats . pop ( 4 )
self . lev += 1
self . exp = int ( 100 * ( 1.1 ** self . lev ) - leftover_exp )
self . mag += 1
self . mdef += 2
self . stre += 6
self . defe += 2
self . maxhp += 60 + randint ( 0 , 30 )
self . maxmp += 10
self . hp = self . maxhp
self . mp = self . maxmp
self . speed += 2
self . time = 100 / self . speed
newstats = self . return_stats ()
newstats = newstats [ 3 :]
newstats . pop ( 4 )
newstats . pop ( 4 )
self . print_levelup ()
self . display_levelup_stats ( oldstats , newstats )
def initialize_equipment ( self ):
self . equip ( bronzesword , 'sword' )
self . equip ( bronzehelm , 'helm' )
self . equip ( bronzechestplate , 'chest' )
self . set_stats ( 1 , 100 , 5 , 6 , 7 , 8 , 80 , 80 , 5 , 5 , 12 )
self . time = 100 / self . speed
class Action ( object ):
def attack ( self , target_list ):
self . printtargets ( target_list )
target = raw_input ( ">" )
if target . isdigit ():
target = int ( target )
#print range(1, len(target_list[4:]) + 1)
if target not in range ( 1 , len ( target_list [ 4 :]) + 1 ):
print "Target out of range."
return self . attack ( target_list )
monster = target_list [ 3 + target ]. __class__ . __name__
damage = self . generate_attack_dmg ( target_list [ 3 + target ])
battleborders ( "%s attacked %s doing %d damage." %
( self . name , monster , damage ))
return damage , 3 + target
else :
print "Please enter a number."
return self . attack ( target_list )
def printtargets ( self , target_list ):
index = 1
print "Enter a target number:"
for target in range ( 4 , len ( target_list [ 4 :]) + 4 ):
monster = target_list [ target ]
print index , ". " , monster . __class__ . __name__ , " " ,
index += 1
print ""
def generate_attack_dmg ( self , monster ):
delta = self . sword . att + self . helm . att + self . chest . att
D = ( self . stre / 2 ) + delta
damage = D + D * random () - monster . defe
return math . ceil ( damage )
#return (random() + randint (5, 10)) * ((-1) ** 2)
def print_levelup ( self ):
battleborders ( "%s has reached level %d" % ( self . name , self . lev ))
def display_levelup_stat ( self , stat_txt , old , new ):
display_format = "{:<10}" + "{:^+10}"
display_text = [ stat_txt . upper (), new - old ]
print display_format . format ( * display_text )
def display_levelup_stats ( self , old_stats , new_stats ):
stat_names = [ 'mag' , 'mdef' , 'stre' , 'defe' , 'speed' , 'maxhp' , 'maxmp' ]
for i in range ( 7 ):
self . display_levelup_stat ( stat_names [ i ], old_stats [ i ],
new_stats [ i ])
class Spell ( Action ):
def __init__ ( self , ** kwargs ):
allowed_keys = [
'name' , 'foe_target' , 'multi_target' , 'damage_type' , 'potency' ,
'desc' , 'mp'
]
self . __dict__ . update (
( k , v ) for k , v in kwargs . iteritems () if k in allowed_keys )
cure = Spell (
name = 'Cure' ,
foe_target = 'friend' ,
damage_type = 'magical' ,
potency = 10 ,
desc = "Restores a small amount of HP" ,
mp = 5 )
fire = Spell (
name = 'Fire' ,
foe_target = 'foe' ,
damage_type = 'magical' ,
potency = 10 ,
desc = "Deals a small amount of fire damage." ,
mp = 5 )
class Monster ( object ):
action_text = """
Select an action:
1. Attack
>"""
itemdrops = [ potion ]
equipdrops = [ bronzesword ]
def __init__ ( self , lev ):
self . lev = lev
self . exp = 0
self . mag = 0
self . mdef = 0
self . stre = 0
self . defe = 0
self . maxhp = 0
self . hp = 0
self . maxmp = 0
self . mp = 0
self . speed = 0
self . job = self . __class__ . __name__
self . stats = {
'job' : self . job ,
'lev' : self . lev ,
'exp' : self . exp ,
'mag' : self . mag ,
'mdef' : self . mdef ,
'stre' : self . stre ,
'defe' : self . defe ,
'hp' : self . hp ,
'mp' : self . mp ,
'speed' : self . speed
}
def act ( self , target_list ):
print "%s is " % self . __class__ . __name__ ,
action = randint ( 1 , 1 )
if action == 1 :
return self . attack ( target_list )
return 0 , 0
def attack ( self , target_list ):
hero , target = self . find_target ( target_list )
damage = self . generate_attack_dmg ( target )
print "attacking %s for %d" % ( target . name , damage )
print "-" * 80
return damage , hero
def printtargets ( self , target_list ):
for target in target_list [: 3 ]:
print target . __class__ . __name__
def generate_attack_dmg ( self , hero ):
delta = hero . helm . parm + hero . chest . parm + hero . sword . parm
damage = . 1 * self . stre * ( self . stre - delta ) * ( 1 - ( random () / 5 ))
if damage < 0 :
damage = 0
return math . ceil ( damage )
def rewards ( self ):
loot = []
if random () <= . 3 :
loot . append ( self . itemdrops [ randint ( 0 , len ( self . itemdrops ) - 1 )])
if random () <= . 1 :
loot . append ( self . equipdrops [ randint ( 0 , len ( self . equipdrops ) - 1 )])
return loot
def find_target ( self , target_list ):
found_target = 0
while found_target == 0 :
hero = randint ( 0 , 3 )
target = target_list [ hero ]
if target . hp > 0 :
found_target = 1
return hero , target
class Slime ( Monster ):
itemdrops = [ potion ]
equipdrops = [ ironchest ]
def __init__ ( self , lev ):
super ( Slime , self ). __init__ ( lev )
self . adjust_stats ()
def adjust_stats ( self ):
#print "Stats"
self . stre = self . lev + 20
self . hp = self . lev * 50
self . maxhp = self . hp
self . speed = self . lev + 5
self . time = 100 / ( self . speed )
self . exp = 10 * self . lev
class Inventory ( object ):
item_dictionary = {
'Potion' : potion ,
'Ether' : ether ,
'Hi-Potion' : hipotion ,
'Hi-Ether' : hiether ,
'Phoenix Down' : phoenixdown ,
'Iron Helm' : ironhelm ,
'Iron Chest' : ironchest ,
'Bronze Helm' : bronzehelm ,
'Bronze Plate' : bronzechestplate ,
'Bronze Sword' : bronzesword ,
'Leather Helm' : leatherhelm ,
'Leather Plate' : leatherchestplate ,
'Wooden Wand' : woodenwand
}
def __init__ ( self ):
self . contents = {}
def add_item ( self , item , amount ):
if item . name in self . contents . keys ():
self . contents [ item . name ] += amount
else :
self . contents [ item . name ] = amount
def sub_item ( self , item , amount ):
if item . name in self . contents . keys ():
self . contents [ item . name ] -= amount
if self . contents [ item . name ] <= 0 :
del self . contents [ item . name ]
def select_item ( self , item_list ):
item_number = raw_input (
"Enter the number or of the item you wish to use:" )
try :
item_to_use = self . item_dictionary [ item_list [ int ( item_number ) -
1 ][ 1 ]]
class_name = self . item_dictionary [ item_list [ int ( item_number ) - 1 ]
[ 1 ]]. __class__ . __name__
if class_name == "Item" :
if item_number :
print item_list [ int ( item_number ) -
1 ][ 1 ], " Description: \n "
print item_to_use . desc
return item_number , item_to_use
else :
return None
elif class_name == "Equipment" :
item_to_use . print_stats_inventory ()
return None
except :
print "Improper item number entered."
formatborders ( "MENU" )
return None
def select_equipment ( self , item_list ):
item_number = raw_input (
"Enter the number of the item you wish to equip:" )
#try goes here
if item_number :
item_to_use = self . item_dictionary [ item_list [ int ( item_number ) -
1 ][ 1 ]]
wep_type = item_to_use . armortype
PARTY . display_heros ()
hero_num = raw_input (
"Enter the number of the hero to equip the %s to: " %
item_to_use . name )
members = PARTY . get_party_members ()
if hero_num :
hero = members [ int ( hero_num ) - 1 ]
if wep_type in [ 'whelm' , 'mhelm' ]:
hero_wep_type = hero . helm . armortype
if wep_type == hero_wep_type :
formatborders ( hero . name )
self . compare_equipment ( hero . helm , item_to_use )
confirm_change = raw_input (
"Do you wish to change the equipment (Y/N): \n >" )
if confirm_change in [
'y' , 'Y' , 'yes' , 'Yes' , item_to_use . name
]:
PARTY . inv . add_item ( hero . helm , 1 )
hero . helm = item_to_use
PARTY . inv . sub_item ( item_to_use , 1 )
print "%s successfully equipped. " % item_to_use . name
else :
print "This equipment is not for that class of hero."
elif wep_type in [ 'wchest' , 'mchest' ]:
hero_wep_type = hero . chest . armortype
if wep_type == hero_wep_type :
formatborders ( hero . name )
self . compare_equipment ( hero . chest , item_to_use )
confirm_change = raw_input (
"Do you wish to change the equipment (Y/N): \n >" )
if confirm_change in [
'y' , 'Y' , 'yes' , 'Yes' , item_to_use . name
]:
PARTY . inv . add_item ( hero . chest , 1 )
hero . chest = item_to_use
PARTY . inv . sub_item ( item_to_use , 1 )
print "%s successfully equipped. " % item_to_use . name
else :
print "This equipment is not for that class of hero."
elif wep_type in [ 'wwep' , 'mwep' ]:
hero_wep_type = hero . sword . armortype
if wep_type == hero_wep_type :
formatborders ( hero . name )
self . compare_equipment ( hero . sword , item_to_use )
confirm_change = raw_input (
"Do you wish to change the equipment (Y/N): \n >" )
if confirm_change in [
'y' , 'Y' , 'yes' , 'Yes' , item_to_use . name
]:
PARTY . inv . add_item ( hero . sword , 1 )
hero . sword = item_to_use
PARTY . inv . sub_item ( item_to_use , 1 )
print "%s successfully equipped. " % item_to_use . name
else :
print "This equipment is not for that class of hero."
else :
print "Something went wrong. Don't save. You might ruin your file. "
else :
print "No hero selected."
return None
else :
print "No item selected. Returning to menu"
return None
def compare_equipment ( self , equip1 , equip2 ):
print "NAME" . ljust ( 10 ), equip1 . name . ljust ( 15 ), equip2 . name . ljust (
15 ), "CHANGE"
for stat in Equipment . equip_stat_string_list :
old = eval ( 'equip1.' + stat )
new = eval ( 'equip2.' + stat )
diff = new - old
if diff > 0 :
diff = '+' + str ( diff )
print stat . upper (). ljust ( 10 ), str ( old ). ljust ( 15 ), str ( new ). ljust (
15 ), diff
def use_item ( self , item ):
members = PARTY . get_party_members ()
PARTY . display_hero_names_numbered ()
PARTY . display_hp ()
PARTY . display_mp ()
hero_number = raw_input (
"Enter the number of the hero to use the %s on: " % item . name )
if hero_number :
try :
hero = members [ int ( hero_number ) - 1 ]
#If using a potion to restore HP
if item . itype == 'p' :
hero_temp_stat = hero . hp
if hero . hp == 0 and item . name != 'Phoenix Down' :
print "Error: Must use Phoenix Down or rest at an Inn"
hero_temp_stat = 0
if hero . hp == 0 and item . name == 'Phoenix Down' :
self . use_potion ( item , hero )
self . sub_item ( item , 1 )
hero_temp_stat = hero . hp - hero_temp_stat
if hero . hp > 0 and item . name != 'Phoenix Down' :
self . use_potion ( item , hero )
self . sub_item ( item , 1 )
hero_temp_stat = hero . hp - hero_temp_stat
print "Restored %d health to %s. " % ( hero_temp_stat ,
hero . name )
#If using a potion to restore mp
if item . itype == 'm' :
hero_temp_stat = hero . mp
self . use_potion ( item , hero )
self . sub_item ( item , 1 )
hero_temp_stat = hero . mp - hero_temp_stat
print "Restored %d mana to %s. " % ( hero_temp_stat ,
hero . name )
except :
print "Improper hero number entered. Returning to menu."
formatborders ( "MENU" )
else :
print "No hero entered. Returning to menu. "
formatborders ( "MENU" )
def use_potion ( self , item , hero ):
hero_new_hp = hero . hp + item . hp
if hero_new_hp >= hero . maxhp :
hero . hp = hero . maxhp
else :
hero . hp = hero_new_hp
hero_new_mp = hero . mp + item . mp
if hero_new_mp >= hero . maxmp :
hero . mp = hero . maxmp
else :
hero . mp = hero_new_mp
def display_items ( self , option ):
if option == 'item' :
pack = self . contents
elif option == 'equip' :
pack = self . seive_equipment ()
else :
pack = self . contents
max_number = 20
number_of_items = len ( pack )
enum = enumerate ( pack . keys ())
numbered_list = list ( enum )
if number_of_items <= 20 :
for item in numbered_list :
print item [ 0 ] + 1 , ". " , item [ 1 ], ": x" , pack [ item [ 1 ]]
else :
for row in range ( 0 , max_number ):
for column in range ( 0 , 4 ):
point = row + max_number * column
if point < number_of_items :
try :
print point + 1 , numbered_list [ point ][
0 ] + 1 , ". " , numbered_list [ point ][
1 ], ": x" , pack [ numbered_list [ point ][ 1 ]],
except :
pass
print ""
return numbered_list
def seive_equipment ( self ):
equipment_dictionary = {}
for item_name in self . contents . keys ():
if self . item_dictionary [ item_name ]. __class__ . __name__ in [
'Equipment' , 'Accesory'
]:
equipment_dictionary [ item_name ] = self . contents [ item_name ]
return equipment_dictionary
class Opening ( Scene ):
def enter ( self ):
self . entrytext = """
This is the start of a game.
You can type "exit" (without the quotes) to exit from most menus.
Press enter 1 for menu
Press 2 to injure hero1 for testing
Press 3 to add Iron Helm, Iron Chest for testing
Enter 4 to go to the field.
"""
formatborders ( self . entrytext )
prompt = raw_input ( "What do you want to do: \n >" )
if prompt in [ '1' , 'menu' , 'Menu' ]:
formatborders ( "MENU" )
return 'menu'
elif prompt in [ '2' ]:
PARTY . hero1 . hp -= 20
print 'DIE HERO!!! Now his health is %d' % PARTY . hero1 . hp
return 'open'
elif prompt in [ '3' ]:
PARTY . inv . add_item ( ironhelm , 1 )
PARTY . inv . add_item ( ironchest , 1 )
print "Added Iron Helm"
return 'open'
elif prompt in [ 'quit' , 'q' , 'exit' , 'Exit' ]:
print "Game Exiting. Thank you for playing."
return 'finished'
elif prompt in [ '4' , 'field' , 'Field' ]:
print "Going to field."
return 'field_0_1'
else :
return 'open'
class GameStart ( Scene ):
global PARTY
def enter ( self ):
global PARTY
start_text = """
Python Fantasy
by Stefan Jenkins
1. New Game
2. Load Game
3. Help
4. Exit Game
"""
formatborders ( start_text )
start_option = raw_input ( "Type a Number or Command: \n >" )
if start_option in [ '1' , 'new' , 'New' , 'n' , 'N' ]:
print "Starting New Game........"
PARTY = Party ()
return 'open'
elif start_option in [ '2' , 'load' , 'Load' , 'l' , 'L' ]:
print "Loading Save File........"
load_data = self . check_memory_card ()
load_data . display_saves ()
load_slot = raw_input ( "Which file would you like to load: \n >" )
try :
load_slot = int ( load_slot )
except :
load_slot = 0
if load_slot == 1 :
if load_data . save1 :
PARTY = load_data . save1 . party
return load_data . save1 . scene_name
else :
print "No save file found. Returning to start."
return 'start'
if load_slot == 2 :
if load_data . save2 :
PARTY = load_data . save2 . party
return load_data . save2 . scene_name
else :
print "No save file found. Returning to start."
return 'start'
if load_slot == 3 :
if load_data . save3 :
PARTY = load_data . save3 . party
return load_data . save3 . scene_name
else :
print "No save file found. Returning to start."
return 'start'
if load_slot == 0 :
formatborders (
"Wrong slot name. Please enter 1,2, or 3. Returning to Start."
)
return 'start'
elif start_option in [ '3' , 'help' , 'Help' , 'h' , 'H' ]:
return 'help'
elif start_option in [ '4' , 'Exit' , 'exit' , 'q' , 'Q' , 'quit' , 'Quit' ]:
formatborders ( "Exiting game. Thank you for playing." )
quit ()
else :
print "Please select a proper option."
return 'start'
def check_memory_card ( self ):
try :
load_file = open ( 'save.txt' , 'r' )
except :
load_file = open ( 'save.txt' , 'w' )
try :
load_data = pickle . load ( load_file )
except :
load_data = MemoryCard ()
load_file . close ()
return load_data
class Finished ( Scene ):
def enter ( self ):
print "You finished"
class Monster ( object ):
pass
class Menu ( Scene ):
def enter ( self , scene_name ):
self . menu_text = """
1. Stats
2. Inventory
3. Magic
4. Equipment
5. Save
6. Load
7. Exit Menu
8. Quit Game
9. Help
10. Debug Menu
"""
print self . menu_text
choice = None
while choice not in [ "exit" , "return" , "7" , "q" , "quit" ]:
choice = raw_input ( "What would you like to do: \n >" )
if choice in [ 'stats' , 'Stats' , '1' ]:
self . stats ( PARTY )
print self . menu_text
if choice in [
'inventory' , 'Inventory' , 'inv' , 'Inv' , '2' , 'i' , 'I'
]:
return 'inv'
if choice in [ 'magic' , 'Magic' , 'm' , 'M' , '3' ]:
return 'magic'
if choice in [ 'save' , 'Save' , '5' ]:
return 'save'
if choice in [
'4' , 'equip'
'Equip' , 'equipment' , 'Equipment' , 'e' , 'E'
]:
return 'equip'
if choice in [ '6' , 'load' , 'Load' , 'l' , 'L' ]:
return 'load'
if choice in [ '8' , 'quit' , 'q' , 'Q' ]:
return 'finished'
if choice in [ '9' , 'help' , 'Help' , 'h' , 'H' ]:
return 'mhelp'
if choice in [ '10' , 'd' ]:
return 'debug'
return scene_name
def stats ( self , party ):
stat_names = [
'name' , 'job' , 'lev' , 'hp' , 'mp' , 'exp' , 'mag' , 'mdef' , 'stre' ,
'defe' , 'speed'
]
formatborders ( "STATS" )
PARTY . display_full_panel ()
raw_input ( "Press Enter" )
class SubMenu ( Scene ):
def enter ( self , scene_name ):
print "You have accessed a submenu. It hasn't been initialized yet."
return 'menu'
class InventoryMenu ( SubMenu ):
def enter ( self , scene_name ):
formatborders ( "INVENTORY" )
print "GIL : %d"
print "-" * 80
item_list = PARTY . inv . display_items ( 'item' )
item_num_type = PARTY . inv . select_item ( item_list )
if item_num_type :
PARTY . inv . use_item ( item_num_type [ 1 ])
return 'menu'
class MagicMenu ( SubMenu ):
def enter ( self , scene_name ):
formatborders ( "MAGIC" )
hero_number = 1
hero_list = []
for hero in PARTY . get_party_members ():
hero_list . append ( hero )
print str ( hero_number ) + "." ,
hero . display_spells ()
hero_number += 1
print "Enter Hero Number of spell to use: (Press enter to return to menu)"
hero_choice = raw_input ( " \n >" )
if hero_choice in [ '1' , '2' , '3' , '4' ]:
if len ( hero_list [ int ( hero_choice ) - 1 ]. spells ) == 0 :
print "Hero has no spells yet. Returning to menu"
else :
print "Enter spell number to use:"
hero = hero_list [ int ( hero_choice ) - 1 ]
spell_choice = raw_input ( " \n >" )
if spell_choice . isdigit ():
spell_choice = int ( spell_choice )
if ( spell_choice <= len ( hero . spells )) and ( spell_choice >=
1 ):
spell = hero . spells [ spell_choice - 1 ]
if spell . foe_target == 'foe' :
print spell . desc
else :
print spell . desc
print "Select a hero to use the spell on. "
PARTY . display_panel_numbered ()
target_choice = raw_input ( " \n >" )
if ( int ( target_choice ) <=
4 ) and ( int ( target_choice ) >= 1 ):
hero . use_spell (
spell , hero_list [ int ( target_choice ) - 1 ])
else :
print "Please select a hero numbered 1 through 4"
else :
print "Enter a proper spell number. returning to menu."
return 'menu'
class EquipmentMenu ( SubMenu ):
def enter ( self , scene_name ):
PARTY . display_equipment ()
equip_list = PARTY . inv . display_items ( 'equip' )
PARTY . inv . select_equipment ( equip_list )
return 'menu'
class SaveMenu ( SubMenu ):
def enter ( self , scene_name ):
load_data = self . check_memory_card ()
load_data . display_saves ()
save_slot = raw_input ( "Which slot do you want to use: \n >" )
try :
save_slot = int ( save_slot )
except :
save_slot = 0
if save_slot in [ 1 , 2 , 3 ]:
print "Saving game......."
if save_slot == 1 :
load_data . save1 = Save ()
load_data . save1 . save_game ( scene_name )
if save_slot == 2 :
load_data . save2 = Save ()
load_data . save2 . save_game ( scene_name )
if save_slot == 3 :
load_data . save3 = Save ()
load_data . save3 . save_game ( scene_name )
print "Saving Complete. Writing to file......."
save_file = open ( 'save.txt' , "w+" )
pickle . dump ( load_data , save_file )
save_file . close ()
else :
print "Improper save entered. Returning to menu. Game NOT saved."
return 'menu'
def check_memory_card ( self ):
try :
load_file = open ( 'save.txt' , 'r' )
except :
load_file = open ( 'save.txt' , 'w' )
try :
load_data = pickle . load ( load_file )
except :
load_data = MemoryCard ()
load_file . close ()
return load_data
class LoadMenu ( SubMenu ):
global PARTY
def enter ( self , scenename ):
global PARTY
print "Loading Save File........"
load_data = self . check_memory_card ()
load_data . display_saves ()
load_slot = raw_input ( "Which file would you like to load: \n >" )
try :
load_slot = int ( load_slot )
except :
load_slot = 0
if load_slot == 1 :
if load_data . save1 :
PARTY = load_data . save1 . party
return load_data . save1 . scene_name
else :
print "No save file found. Returning to Menu."
return 'menu'
if load_slot == 2 :
if load_data . save2 :
PARTY = load_data . save2 . party
return load_data . save2 . scene_name
else :
print "No save file found. Returning to Menu."
return 'menu'
if load_slot == 3 :
if load_data . save3 :
PARTY = load_data . save3 . party
return load_data . save3 . scene_name
else :
print "No save file found. Returning to Menu."
return 'menu'
if load_slot == 0 :
formatborders (
"Wrong slot name. Please enter 1,2, or 3. Returning to Menu." )
return 'menu'
def check_memory_card ( self ):
try :
load_file = open ( 'save.txt' , 'r' )
except :
load_file = open ( 'save.txt' , 'w' )
try :
load_data = pickle . load ( load_file )
except :
load_data = MemoryCard ()
load_file . close ()
return load_data
class Field_0_1 ( Scene ):
text = """
You have entered a field.
1. Menu
2. Go to town
3. Go to field.
"""
def enter ( self ):
print self . text
location = raw_input ( "Enter a number: \n >" )
if location in [ '1' , 'menu' , 'Menu' , 'm' , 'M' ]:
return 'menu'
elif location in [ '2' , 'town' , 'Town' ]:
return 'town1'
elif location in [ '3' , 'field' , 'f' , 'Field' , 'F' ]:
return 'field_1_1'
else :
return 'field_0_1'
class Field_1_1 ( Scene ):
text = """
You have entered another field.
1. Menu
2. Go back to the field.
"""
def enter ( self ):
print self . text
location = raw_input ( "Enter a number: \n >" )
if location in [ '1' , 'menu' , 'Menu' , 'm' , 'M' ]:
return 'menu'
elif location in [ '2' , 'field' , 'Field' ]:
return 'field_0_1'
else :
return 'field_1_1'
class Town1 ( Scene ):
text = """
You have entered the town of Alexandria. It is a quaint village with narrow
streets filled with villagers milling about. There is an item shop and an inn
visible from the main street.
1. Menu
2. Go to back to the field.
3. Item Shop
4. Inn
5. Poke a villager
%s
"""
def enter ( self ):
formatborders ( "ALEXANDRIA:" )
level_sum = 0
hp_sum = 0
for hero in PARTY . get_party_members ():
level_sum += hero . lev
if level_sum < 5 :
print self . text % ""
else :
print self . text % "6. Weapon Shop"
location = raw_input ( "Enter a number: \n >" )
if location in [ '1' , 'menu' , 'Menu' , 'm' , 'M' ]:
return 'menu'
if location in [ '2' , 'field' , 'Field' , 'f' , 'F' ]:
return 'field_0_1'
if location in [ '3' , 'item' , 'Item' ]:
return 'itemshop1'
if location in [ '4' , 'inn' , 'Inn' ]:
return 'inn1'
if location in [ '5' , 'poke' , 'Villager' ]:
print "-" * 80
print "OUCH! What kind of pervert goes around poking a poor old man?"
print "You should be ashamed of yourselves."
print "If you had asked me nicely I would have told you that the"
print "weapons shop only sells to parties that are level 2 and higher."
print " \n But because you're rude all I'm going to do is fart in your general direction"
print " \n *BLURTTTT*"
print "The old man is propelled forward into a wall and is knocked out."
print "Your eyes begin burning from the smell and everone loses 1 HP."
print "-" * 80
if self . game_over_scene ( 1 ) == 0 :
formatborders ( "GAME OVER: DEATH BY OLD MAN FART" )
return 'gameover'
if PARTY . gil < 50 :
print "You find 5 gil on the ground. It must have fallen from the old man's pocket."
PARTY . gil += 5
return 'town1'
if location in [ '6' , 'weapon' , 'Weapon' , 'w' , 'W' ]:
return 'weaponshop1'
else :
return 'town1'
class ItemShop1 ( Scene ):
item_text = """
You walk into through the shop doors to meet the shopkeeper sitting on a stool.
He blows a cloud of strange smelling smoke in your face and says "Welcome to the
pot shop.... I mean potion shop. You guys aren't cops right?"
You shake your head no and he proceeds to show you his wares.
Enter an option.
1. Potion 20 gil
2. Ether 100 gil
3. Phoenix Down 500 gil
4. Return to town
"""
def enter ( self ):
formatborders ( "POT SHOP: ALEXNADRIA" )
print self . item_text
option = raw_input ( ">" )
try :
if option in [ '1' , 'potion' , 'Potion' ]:
amount = raw_input ( "Enter a quantity to buy: \n >" )
if PARTY . gil >= int ( amount ) * 25 :
PARTY . inv . add_item ( potion , int ( amount ))
PARTY . gil -= int ( amount ) * 25
print "Bought x%d potions for %d Gil" % ( int ( amount ),
int ( amount ) * 25 )
print '-' * 80
else :
print "Not enough minerals."
return 'itemshop1'
elif option in [ '2' , 'ether' , 'Ether' ]:
amount = raw_input ( "Enter a quantity to buy: \n >" )
if PARTY . gil >= int ( amount ) * 100 :
PARTY . inv . add_item ( ether , int ( amount ))
PARTY . gil -= int ( amount ) * 100
print "Bought x%d ethers for %d Gil" % ( int ( amount ),
int ( amount ) * 100 )
print '-' * 80
else :
print "Not enough vespene gas."
return 'itemshop1'
elif option in [ '3' , 'phoenix' , 'down' , 'Phoenix' , 'Down' ]:
amount = raw_input ( "Enter a quantity to buy: \n >" )
if PARTY . gil >= int ( amount ) * 500 :
PARTY . inv . add_item ( phoenixdown , int ( amount ))
PARTY . gil -= int ( amount ) * 500
print "Bought x%d phoenix downss for %d Gil" % (
int ( amount ), int ( amount ) * 500 )
print '-' * 80
else :
print "Build more supply depots."
return 'itemshop1'
else :
print "Proper option not selected."
except :
print "Please enter an integer for the item amount."
print "Returning to town. "
return 'town1'
class Inn1 ( Scene ):
inn_text = """
As you walk into the inn the innkeeper offers you a room to stay for the night.
He also offers you licentious 'favors' with a wink.
It costs 100 gil to rest.
It costs 100,000,000 gil for a happy massage.
Choose an action:
1. Rest
2. Massage
3. Return to Town
"""
def enter ( self ):
formatborders ( "INN: ALEXANDRIA" )
print self . inn_text
option = raw_input ( ">" )
if option in [ '1' , 'rest' , 'Rest' , 'R' , 'r' ]:
if PARTY . gil >= 100 :
self . restore_party ()
PARTY . gil -= 100
else :
print "The inkeeper rages at you trying to stay without enough money."
print "You flee back to town as he picks up a shotgun an aims it at you."
return 'town1'
if option in [ '2' , 'massage' , 'Massage' , 'm' , 'M' ]:
if PARTY . gil >= 100000000 :
print "OH BABY."
PARTY . gil -= 100000000
else :
print "You aren't yet ready for such things."
return 'town1'
return 'town1'
class WeaponShop1 ( Scene ):
item_text = """
You walk into through the shop doors to meet the shopkeeper sitting on a stool.
He blows a cloud of strange smelling smoke in your face and says "Welcome to the
pot shop.... I mean potion shop. You guys aren't cops right?"
You shake your head no and he proceeds to show you his wares.
Enter an option.
1. Iron Sword 400 gil
2. Iron Chest 300 gil
3. Iron Helm 200 gil
4. Steel Wand 350 gil
5. Cloth Chest 250 gil
6. Cloth Helm 500 gil
7. Return to town
"""
def enter ( self ):
formatborders ( "WEAPON SHOP: ALEXNADRIA" )
print self . item_text
option = raw_input ( ">" )
try :
if option in [ '1' , 'potion' , 'Potion' ]:
amount = raw_input ( "Enter a quantity to buy: \n >" )
if PARTY . gil >= int ( amount ) * 25 :
PARTY . inv . add_item ( potion , int ( amount ))
PARTY . gil -= int ( amount ) * 25
print "Bought x%d potions for %d Gil" % ( int ( amount ),
int ( amount ) * 25 )
print '-' * 80
else :
print "Not enough minerals."
return 'itemshop1'
elif option in [ '2' , 'ether' , 'Ether' ]:
amount = raw_input ( "Enter a quantity to buy: \n >" )
if PARTY . gil >= int ( amount ) * 100 :
PARTY . inv . add_item ( ether , int ( amount ))
PARTY . gil -= int ( amount ) * 100
print "Bought x%d ethers for %d Gil" % ( int ( amount ),
int ( amount ) * 100 )
print '-' * 80
else :
print "Not enough vespene gas."
return 'itemshop1'
elif option in [ '3' , 'phoenix' , 'down' , 'Phoenix' , 'Down' ]:
amount = raw_input ( "Enter a quantity to buy: \n >" )
if PARTY . gil >= int ( amount ) * 500 :
PARTY . inv . add_item ( phoenixdown , int ( amount ))
PARTY . gil -= int ( amount ) * 500
print "Bought x%d phoenix downss for %d Gil" % (
int ( amount ), int ( amount ) * 500 )
print '-' * 80
else :
print "Build more supply depots."
return 'itemshop1'
else :
print "Proper option not selected."
except :
print "Please enter an integer for the item amount."
print "Returning to town. "
return 'town1'
class Battle ( Scene ):
calmlands = [ Slime ]
area_monsters = { 'field_0_1' : calmlands , 'field_1_1' : calmlands }
monster_text = [
"A random %s has appeared!" ,
"A %s has suddently manifested. It looks angry." ,
"A %s looks at you and you wet your pants. " ,
"You hear battle music start to play in your head as a %s charges you." ,
"POP! A %s begins twerking menacingly in your direction. " ,
]
def enter ( self , current_area ):
print "Entering a battle from %s. " % current_area
mobs = self . generate_monsters ( current_area )
Hero_Classes = [ Warrior , BlackMage , WhiteMage , Theif ]
formatborders ( "BATTLE" )
for monster in mobs :
print self . monster_text [ randint (
0 ,
len ( self . monster_text ) - 1 )] % monster . __class__ . __name__
time_table , name_table = self . generate_turn_table ( mobs )
PARTY . display_panel ()
loot = []
battle_exp = 0
gil_reward = 0
alive_table = self . generate_alive_table ()
self . display_panel ( mobs )
battle_logic = 0
k = 0
while battle_logic == 0 :
index = 0
for time in time_table :
if time_table [ index ] == 0 :
current = name_table [ index ]
if current . hp > 0 and current . __class__ in Hero_Classes :
alive_table [ index ] = 1
if current . hp > 0 :
damage , target = current . act ( name_table )
name_table [ target ]. hp -= damage
time_table [ index ] = current . time
if name_table [ target ]. hp <= 0 and (
name_table [ target ]. __class__ in Hero_Classes ) and (
current . __class__ not in Hero_Classes ):
name_table [ target ]. hp = 0
alive_table [ target ] = 0
print "%s has been slain." % name_table [ target ]. name
if 1 not in alive_table :
battle_logic = 2
formatborders ( "GAME OVER" )
return 'gameover'
if name_table [ target ]. __class__ not in Hero_Classes :
if name_table [ target ]. hp <= 0 :
print "%s has been slain." % name_table [
target ]. __class__ . __name__
loot . extend ( name_table [ target ]. rewards ())
battle_exp += name_table [ target ]. exp
gil_reward += randint ( 1 , name_table [ target ]. lev
** 1.5 )
del name_table [ target ]
del time_table [ target ]
del mobs [ target - 4 ]
if current . hp > 0 and current . __class__ in Hero_Classes :
PARTY . display_panel ()
if mobs and ( current . __class__ in Hero_Classes
) and current . hp > 0 :
self . display_panel ( mobs )
if len ( mobs ) == 0 :
if loot :
self . display_loot ( loot )
print "Recieved %s exp" % battle_exp
self . award_exp ( battle_exp )
PARTY . gil += gil_reward
print "Battle over"
battle_logic = 1
break
time_table [ index ] -= 1
index += 1
def generate_monsters ( self , current_area ):
monster_pool = self . area_monsters [ current_area ]
monster_amount = randint ( 1 , 3 )
monsters = []
level = PARTY . return_avg_levels ()
for n in range ( monster_amount ):
monster_choices = len ( monster_pool )
monster_choice = randint ( 0 , monster_choices - 1 )
monsters . append ( monster_pool [ monster_choice ]( level ))
return monsters
def generate_turn_table ( self , monsters ):
turn_table = []
turn_names = []
for hero in PARTY . get_party_members ():
turn_table . append ( hero . time )
turn_names . append ( hero )
for monster in monsters :
turn_table . append ( monster . time )
turn_names . append ( monster )
# print turn_table
# print turn_names
return turn_table , turn_names
def display_hp ( self , monsters ):
display_format = "{:<10}" + ( "{:^10}" * len ( monsters ))
monster_hp = [ "HP:" ]
for monster in monsters :
monster_hp . append ( "%d/%d" % ( monster . hp , monster . maxhp ))
print display_format . format ( * monster_hp )
def display_monster_names ( self , monsters ):
display_format = "{:<10}" + ( "{:^10}" * len ( monsters ))
monster_names = [ 'Monster:' ]
for monster in monsters :
monster_names . append ( monster . __class__ . __name__ )
print display_format . format ( * monster_names )
def display_panel ( self , monsters ):
self . display_monster_names ( monsters )
self . display_hp ( monsters )
print "-" * 80
def display_loot ( self , item_list ):
text_list = []
loot_dict = {}
for item in item_list :
text_list . append ( item . name )
PARTY . inv . add_item ( item , 1 )
for item in text_list :
try :
loot_dict [ item ] += 1
except :
loot_dict [ item ] = 1
item_text = ""
for k , v in loot_dict . items ():
item_text += "%s x %d " % ( k , v )
display_text = "Obtained: %s" % item_text
battleborders ( display_text )
def award_exp ( self , battle_exp ):
for hero in PARTY . get_party_members ():
if hero . hp > 0 :
hero . exp -= battle_exp
if hero . exp <= 0 :
leftover_exp = - hero . exp
hero . level_up ( leftover_exp )
def generate_alive_table ( self ):
alive_table = []
for hero in PARTY . get_party_members ():
if hero . hp > 0 :
alive_table . append ( 1 )
else :
alive_table . append ( 0 )
return alive_table
class Help ( Scene ):
help_text = """
Python Fantasy is a text based role playing game. You navagate through
screens by using the number of the command you wish to select, or typing out the
option itself.
For example look at the following menu:
1. Menu
2. Inventory
3. Stats
4. Exit
To access the menu you can enter 1, Menu, or menu. To access the Inventory
you can enter 2, Inventory, inv, or Inv. To exit you can enter 4, Exit, exit, or
anything other than the options given (q for instance).
Entering q on most selection options will return you to the previous menu.
To exit the game, enter the menu and select option 8.
Press Enter now to return.
"""
def enter ( self , scenename ):
formatborders ( "HELP" )
print self . help_text
go_back = raw_input ()
return scenename
class MHelp ( Scene ):
help_text = """
Python Fantasy is a text based role playing game. You navagate through screens
by using the number of the command you wish to select, or typing out the option
itself. The game mechanics are lovingly inspired by Final Fantasy by Squaresoft.
For example look at the following menu:
1. Menu
2. Inventory
3. Stats
4. Exit
To access the menu you can enter 1, Menu, or menu. To access the Inventory
you can enter 2, Inventory, inv, or Inv. To exit you can enter 4, Exit, exit, or
anything other than the options given (q for instance).
Entering q on most selection options will return you to the previous menu.
Press Enter now to return. Enter 1 to view Stat help.
"""
stat_text = """
JOB - The class of the hero
LEV - The level of the hero, the hero grows stronger with higher levels
HP - Health Points, how much health the hero has. When HP goes to 0 the
hero dies and can only be revived by using a phoenix doewn or by
resting at an inn. Can be restored with items such as a potion.
MP - Mana Points, how much energy the hero has to cast spells. Can be
replenished with items such as ethers.
EXP - Experience points remaining to level up.
MAG - Magic, magical attack effectiveness
MDEF - Magical Defence, ability to resist magical attacks
STRE - Strength, physical attack effectiveness
DEFE - Defence, ability to resist physical attacks
SPEED- How soon a hero's turn will come in battle.
Press Enter to return to menu.
"""
def enter ( self , scenename ):
formatborders ( "HELP" )
print self . help_text
go_back = raw_input ( ">" )
if go_back in [ '1' , 'stat' , 's' , 'S' ]:
print self . stat_text
go = raw_input ()
return 'menu'
class Debug ( Scene ):
def enter ( self , scenename ):
print "Debug menu"
print """
1. print MP stat for hero 1
2. print dir(hero1)
3. print party stats
4. add 90 exp to party
5. kill hero 1 add phoenix down to inventory
6. Enter command
7. Set party hp to 1
8. Enter battle from field 1
9. kill all heros but hero 4
10. Levelup heros to 50
11. Add Cure and fire to spellbook
"""
option = raw_input ( " \n >" )
if option == '1' :
PARTY . display_stat ( PARTY . hero1 . mp )
if option == '2' :
print dir ( PARTY . hero1 )
if option == '3' :
PARTY . display_full_panel ()
if option == '4' :
for hero in PARTY . get_party_members ():
hero . exp -= 90
if option == '5' :
PARTY . hero1 . hp = 0
PARTY . inv . add_item ( phoenixdown , 1 )
if option == '6' :
command = raw_input ( "Enter a Command \n >" )
exec ( command )
if option == '7' :
for hero in PARTY . get_party_members ():
hero . hp = 1
if option == '8' :
Battle (). enter ( 'field_1_1' )
if option == '9' :
for hero in PARTY . get_party_members ()[: 3 ]:
hero . hp = 0
PARTY . hero4 . hp = 1
if option == '10' :
for hero in PARTY . get_party_members ():
for x in range ( 50 ):
hero . level_up ( 0 )
if option == '11' :
PARTY . hero2 . spells . append ( cure )
PARTY . hero3 . spells . append ( fire )
return 'menu'
class GameOver ( Scene ):
game_over_text = """
Game over.
You were either unprepared or extrememly unlucky.
Or both.
You now have 3 options.
1. Load Game
2. Main Menu
3. Stop playing.
"""
def enter ( self ):
print self . game_over_text
option = raw_input ( ">" )
if option in [ '1' , 'l' , 'L' , 'load' , 'Load' ]:
return 'load'
if option in [ '2' , 'm' , 'M' , 'main' , 'Main' , 'menu' , 'Menu' ]:
return 'start'
if option in [ '3' , 'stop' , 's' ]:
print "I <3 pi. "
quit ()
if option == None :
"Please select an option."
self . enter ()
class Map ( object ):
scenes = {
'open' : Opening (),
'finished' : Finished (),
'menu' : Menu (),
'inv' : InventoryMenu (),
'magic' : MagicMenu (),
'save' : SaveMenu (),
'start' : GameStart (),
'help' : Help (),
'mhelp' : MHelp (),
'equip' : EquipmentMenu (),
'load' : LoadMenu (),
'town1' : Town1 (),
'itemshop1' : ItemShop1 (),
'inn1' : Inn1 (),
'weaponshop1' : WeaponShop1 (),
'field_0_1' : Field_0_1 (),
'field_1_1' : Field_1_1 (),
'debug' : Debug (),
'battle' : Battle (),
'gameover' : GameOver ()
}
towns = [ 'town1' , 'itemshop1' , 'inn1' , 'weaponshop1' ]
invscenes = { v : k for k , v in scenes . items ()}
def __init__ ( self , start_scene ):
self . start_scene = start_scene
def next_scene ( self , scene_name ):
val = Map . scenes . get ( scene_name )
return val
def name_of_scene ( self , scene ):
val = Map . invscenes . get ( scene )
return val
def opening_scene ( self ):
return self . next_scene ( self . start_scene )
class Save ( object ):
def save_game ( self , scene_name ):
self . scene_name = scene_name
self . party = PARTY
class MemoryCard ( object ):
def __init__ ( self ):
self . save1 = None
self . save2 = None
self . save3 = None
def display_saves ( self ):
formatborders ( "SAVE SLOTS" )
try :
print "SLOT 1 : %s" % Map . scenes [ self . save1 .
scene_name ]. __class__ . __name__
for hero in self . save1 . party . get_party_members ():
print hero . name . upper (). ljust ( 10 ), "LVL: " , str (
hero . lev ). ljust ( 2 ),
except :
print "SLOT 1 : EMPTY"
print " \n "
try :
print "SLOT 2 : %s" % Map . scenes [ self . save2 .
scene_name ]. __class__ . __name__
for hero in self . save2 . party . get_party_members ():
print hero . name . upper (). ljust ( 10 ), "LVL: " , str (
hero . lev ). ljust ( 2 ),
except :
print "SLOT 2 : EMPTY"
print " \n "
try :
print "SLOT 3 : %s" % Map . scenes [ self . save3 .
scene_name ]. __class__ . __name__
for hero in self . save3 . party . get_party_members ():
print hero . name . upper (). ljust ( 10 ), "LVL: " , str (
hero . lev ). ljust ( 2 ),
except :
print "SLOT 3 : EMPTY"
print " \n "
formatborders (
"Enter the slot number or press enter to return to previous screen"
)
print " \n "
def formatborders ( textinput ):
print '=' * 80
print textinput
print '=' * 80
def battleborders ( textinput ):
print '-' * 80
print textinput
print '-' * 80
def nl ():
print " \n "
PARTY = None
Hero_Classes = [ Warrior , BlackMage , WhiteMage , Theif ]
a_map = Map ( 'start' )
a_game = Engine ( a_map )
a_game . play ()