''' Movement system - Show squares in range *
1. Negate sqaures with terrain and other chars
- Move to squares in range *
- Calculate paths between terrain *
- Create turn system
1. Prevent movement after first move*
a. Show that move is over using color (gray)*
2. Once other player moves, give control again*
Combat System
-Display stats*
1. Hover over unit to get stat details*
2. Print details to message screen*
3. Have colored bar for unit size*
4. Have tags for other stats (morale, fatigue)*
-Implement attack system
1. Melee units
a. Target enemy units with mouse*
-Highlight enemies in range*
-Attack if enemy is clicked*
2. Ranged units*
-Implement stats:
1. Unit size (num of units)*
a. Decrement value when attacked*
b. Destroy (don't draw) unit when = 0*
2. Morale
a. Vary based on surrounding units*
-Numbers*
-Exp (General vs. Veteran vs. Recruits)
b. Vary based on Fatigue*
c. Implement Morale effects*
-RNG from 0 to 100, if higher than*
morale, unit is inactive*
3. Power
a. Vary by multipler
-Unit Size*
-Fatigue*
-Morale*
-Weapons
-Exp
-Terrain
4. Fatigue*
a. Track total movement*
Maps
-Randomly/Procedrually generate maps
1. Mix of terrain
a. Terrain is grouped and sensible
b. Terrain types
-Forests
I. Hides troops
II. Lowers range of sight
III. Possible surprise attack modifiers
IV. Lowers movement (unless special troop)
-Mountains
I. Impassible
II. Blocks sight range
III. Cannot be shot over (ranged)
-Hills
I. Increases range of sight
II. Gives morale boost and power boost
III. Gives range boost for ranged units
IV. Costs extra to move into
-Rivers
I. Lowers movement
II. Lowers power, morale
2. Different map archetypes
a. Plains
b. Forests
c. Deserts
-Fatigue cost is greater
d. Tundra
3. Weather
a. Percipitation
-Rain
I. Slows down troops
II. Increases Fatigue
-Snow
I. Slows down troops
II. Increases Fatigue
c. Temperature
-Controls wether snow or rain
-High temperatures increase fatigue
-Create/Save maps of famous battles
-Allow player to create own maps
'''
import libtcodpy as libtcod
import random
#click coords are empty
lclick_x = None
lclick_y = None
#lists of the coords in range of the characters (movement and atk range)
coord_in_range = []
coord_in_atk_range = []
#Counts for number of turns passed and number of times attacked (the latter is
#used for the Unit.attack method
turn_counter = 0
times_attacked = 0
random.seed()
#actual size of the window
SCREEN_WIDTH = 80
SCREEN_HEIGHT = 70
#size of the map
MAP_WIDTH = 80
MAP_HEIGHT = 60
LIMIT_FPS = 20 #20 frames-per-second maximum
class Tile:
#a tile of the map and its properties
def __init__(self, name, coord_x, coord_y, move_cost, effect):
self.terrain_name = name
self.x = coord_x
self.y = coord_y
self.move_cost = move_cost
self.terrain_effect = effect
def show_tile_info(self):
libtcod.console_print(msg_panel, 42, 0, 'Terrain Type: %s'%(self.terrain_name))
libtcod.console_print(msg_panel, 42, 1, 'Terrain Effect: X%s (Power, Defence)'%(self.terrain_effect))
#by default, if a tile is blocked, it also blocks sight
#These functions generate noise and heightmaps then interpolate noise onto the
#heightmaps
coef = {}
coef[9] = [2 for i in range(10)]
noise = libtcod.noise_new(2)
new_hm = libtcod.heightmap_new(MAP_WIDTH, MAP_HEIGHT)
cont_points_x = [0, random.randint(1,MAP_WIDTH-1), random.randint(1,MAP_WIDTH-1), MAP_WIDTH]
cont_points_y = [i+random.randint(1, MAP_HEIGHT) for i in range(4)]
hm2 = libtcod.heightmap_new(MAP_WIDTH, MAP_HEIGHT)
hm3 = libtcod.heightmap_new(MAP_WIDTH, MAP_HEIGHT)
libtcod.heightmap_add_fbm(new_hm, noise, 1, 1, 0, 0, 7, 3, 1)
libtcod.heightmap_scale_fbm(new_hm, noise, .7, 1, 0, 0, 5, 4, 1)
#libtcod.heightmap_add_voronoi(new_hm, 30, 10, coef[9], 0)
for n in range(random.randint(3, 10)):
libtcod.heightmap_add_hill(new_hm, random.randint(0, MAP_WIDTH), random.randint(0, MAP_HEIGHT), random.randint(5, 25), 6)
for n in range(random.randint(3, 10)):
libtcod.heightmap_add_hill(new_hm, random.randint(0, MAP_WIDTH), random.randint(0, MAP_HEIGHT), random.randint(5, 25), 3)
libtcod.heightmap_rain_erosion(new_hm, MAP_HEIGHT*MAP_WIDTH, 1, 1, 0)
libtcod.heightmap_dig_bezier(new_hm, cont_points_x, cont_points_y, random.randint(1, 3), -1, random.randint(1, 3), -1)
new_map = libtcod.map_new (MAP_WIDTH, MAP_HEIGHT)
#This function generates the map
class T_Map:
def __init__(self):
self.tileset_plains = {0:'~', 1:'.', 2:'.', 3:'Y', 4:'.', 5:'^', 6:'^'}
self.colors_plains = {0:libtcod.light_blue, 1:libtcod.dark_green, 2:libtcod.green, 3:libtcod.lighter_green, 4:libtcod.white}
self.terrain_plains = {0:'Water', 1:'Plains', 2:'Plains', 3:'Tall Grass', 4:'Plains', 5:'Hills', 6:'Mountains'}
self.tileset_desert = {0:'~', 1:'~', 2:'~', 3:'~', 4:'~', 5:'^', 6:'^'}
self.colors_desert = {0:libtcod.yellow, 1:libtcod.yellow, 2:libtcod.yellow, 3:libtcod.yellow, 4:libtcod.lighter_yellow}
self.terrain_desert = {0:'Water', 1:'Desert', 2:'Desert', 3:'Desert', 4:'Desert', 5:'Hills', 6:'Mountains'}
self.tileset_forest = {0:'~', 1:'.', 2:'.', 3:'T', 4:'.', 5:'^', 6:'^', 7:'^'}
self.colors_forest= {0:libtcod.light_blue, 1:libtcod.dark_green, 2:libtcod.green, 3:libtcod.lighter_green, 4:libtcod.white}
self.terrain_forest = {0:'Water', 1:'Plains', 2:'Plains', 3:'Forest', 4:'Plains', 5:'Hills', 6:'Mountains', 7:'Peak'}
self.tileset_tundra = {0:'~', 1:'~', 2:'~', 3:'~', 5:'^', 6:'^', 7:'^'}
self.colors_tundra = {n:libtcod.white for n in range(5)} #{0:libtcod.white, 1:libtcod.white, 2:libtcod.white, 3:libtcod.white, 4:libtcod.white }
self.terrain_tundra = {0:'Water', 1:'Snow', 2:'Snow', 3:'Snow', 4:'Snow', 5:'Hills', 6:'Mountains', 7:'Peak'}
self.tile_array = []
def make_map(self, tiles, color_scheme, name):
global new_hm
if map_archetype == 'forest' or map_archetype == 'plains':
libtcod.heightmap_normalize(new_hm, 0, len(tiles)-1)
else:
libtcod.heightmap_normalize(new_hm, 1, len(tiles)-1)
#These are the tiles, followed by normalization of the noise
#Prints to console, based on the tiles
for x in range(MAP_WIDTH):
for y in range(MAP_HEIGHT):
libtcod.map_set_properties(new_map, x, y, True, True)
n = int(libtcod.heightmap_get_value(new_hm, x, y))
if n == 0:
libtcod.console_put_char_ex(con, x, y, tiles[n], color_scheme[0], libtcod.BKGND_SET)
self.tile_array += ([Tile(name[n], x, y, 4, .5)])
elif n == 1 or n == 4:
libtcod.console_put_char_ex(con, x, y, tiles[n], color_scheme[1], libtcod.BKGND_SET)
self.tile_array += ([Tile(name[n],x, y, 1, 1)])
elif n == 2:
libtcod.console_put_char_ex(con, x, y, tiles[n], color_scheme[2], libtcod.BKGND_SET)
self.tile_array += ([Tile(name[n],x, y, 1, 1)])
elif n == 3:
libtcod.console_put_char_ex(con, x, y, tiles[n], color_scheme[3], libtcod.BKGND_SET)
if map_archetype == 'forest' or map_archetype == 'plains':
self.tile_array += ([Tile(name[n], x, y, 2, .75)])
libtcod.map_set_properties(new_map, x, y, False, True)
else:
self.tile_array += ([Tile(name[n], x, y, 1, 1)])
elif n == 5:
libtcod.console_put_char_ex(con, x, y, tiles[n], color_scheme[2], libtcod.BKGND_SET)
self.tile_array += ([Tile(name[n], x, y, 3, 1.5)])
elif n >= 6:
libtcod.console_put_char_ex(con, x, y, tiles[n], color_scheme[4], libtcod.BKGND_SET)
self.tile_array += ([Tile(name[n], x, y, 0, 0)])
libtcod.map_set_properties(new_map, x, y, False, False)
#print self.tile_array
class Unit:
#This is a generic unit: cavalry, infantry etc.
def __init__(self, name, x, y, char, color,
move_range, atk_range, unit_size, morale, base_power, base_defence,
fatigue, team):
self.name = name
self.x = x
self.y = y
self.char = char
self.color = color
self.range = move_range
self.move_counter = 0
self.atk_range = atk_range
self.sight_range = 3
self.exp = 0
self.rank = ''
self.rank_level = self.exp/10
self.unit_size = unit_size
self.current_unit_size = unit_size
self.morale = self.exp + morale
self.current_morale = morale
self.fatigue = fatigue + self.exp
self.current_fatigue = fatigue
self.base_power = base_power + self.rank_level
self.base_defence = base_defence + self.rank_level
self.power_multiplier = 1
self.power = self.power_multiplier*self.base_power
self.defence = self.power_multiplier*self.base_defence
self.team = team
self.targeted = False
self.can_move = False
self.can_attack = False
self.inactive_color = libtcod.gray
def move(self, x, y):
#move to the given coordinate
self.move_counter = 0
self.move_counter += (abs(self.x - x) + abs(self.y - y))
self.current_fatigue -= (10*self.move_counter)
self.current_fatigue= max(0, self.current_fatigue)
self.x = x
self.y = y
for team in teams:
for unit in team:
unit.adjust_morale()
unit.adjust_power()
if not self.can_move == False:
self.can_move == False
def adjust_power(self):
#Vary by fatigue
#self.power = self.base_power*self.current_unit_size
self.power_multiplier = 1
if self.current_fatigue < 100:
self.power_multiplier -= ((100.0 - self.current_fatigue)/200.0)
self.power_multiplier = max(0.1, self.power_multiplier)
#Vary by morale
if self.current_morale < 70:
self.power_multiplier -= ((100.0 - self.current_morale)/100.0)
self.power_multiplier = max(0.1, self.power_multiplier)
elif self.current_morale >= 80:
self.power_multiplier += ((self.current_morale - 50.0)/100.0)
#Vary by weapons
#Vary by terrain
for Tile in T_Map.tile_array:
if (self.x, self.y) == (Tile.x, Tile.y):
self.power_multiplier *= Tile.terrain_effect
break
self.power = self.power_multiplier*(self.base_power+self.rank_level)
self.defence = self.power_multiplier*(self.base_defence+self.rank_level)
def attack(self, enemy_x, enemy_y):
global times_attacked
#total_damage_done_self = 0
total_damage_taken_self = 0
#total_damage_done_enemy = 0
total_damage_taken_enemy = 0
enemy_list = []
for team in teams:
for unit in team:
if unit.team != self.team:
enemy_list.append(unit)
for enemy in enemy_list:
if (enemy.x, enemy.y) == (enemy_x, enemy_y):
#Damage enemy
attack_score_self = []
def_score_enemy = []
for i in range(self.unit_size):
attack_score_self += [random.uniform(0, self.power)]
for i in range(enemy.unit_size):
def_score_enemy += [random.uniform(0, enemy.defence)]
for i in range(len(attack_score_self)):
if (i >= len(def_score_enemy)) or attack_score_self[i] > def_score_enemy[i]:
total_damage_taken_enemy += 1
#Damage self
attack_score_enemy = []
def_score_self = []
for i in range(enemy.unit_size):
attack_score_enemy += [random.uniform(0, enemy.power)]
for i in range(self.unit_size):
def_score_self += [random.uniform(0, self.defence)]
for i in range(len(attack_score_enemy)):
if (i >= len(def_score_self)) or attack_score_enemy[i] > def_score_self[i]:
total_damage_taken_self += 1
total_damage_taken_self = max(0, int(total_damage_taken_self))
total_damage_taken_enemy = max(0, int(total_damage_taken_enemy))
self.current_unit_size -= total_damage_taken_self
enemy.current_unit_size -= total_damage_taken_enemy
self.current_fatigue -= 10
enemy.current_fatigue -= 10
set_team_coord()
self.can_attack = False
self.can_move = False
for team in teams:
for unit in team:
unit.adjust_morale()
unit.adjust_power()
if unit.current_unit_size <= 0:
for enemy in enemy_list:
if (enemy.x, enemy.y) == (enemy_x, enemy_y):
self.adjust_exp(self.exp, enemy.exp)
self.adjust_rank()
team.remove(unit)
def adjust_fatigue(self):
if self.current_fatigue < 100:
self.current_fatigue += 5
self.current_fatigue = min(self.current_fatigue, self.fatigue)
def check_morale(self, morale):
morale_check_score = random.randint(0, 100)
if morale_check_score <= morale:
return True
else:
return False
def adjust_morale(self):
tiles_in_sight = get_tiles_in_range(self.x, self.y, self.sight_range)
tiles_in_sup_range = get_tiles_in_range(self.x, self.y, 1)
self.current_morale = 0
morale_boost = 0
morale_drain = 0
for team in teams:
for unit in team:
if unit.current_fatigue < 100:
morale_drain += ((100 - unit.current_fatigue)/2)
if (unit.x, unit.y) in tiles_in_sight and (unit.x, unit.y) not in tiles_in_sup_range:
if unit.team == self.team:
morale_boost += 10#+unit.exp
else:
morale_drain += 5#+unit.exp
elif (unit.x, unit.y) in tiles_in_sup_range:
local_sup = self.calculate_local_sup()
allied_units_count = self.unit_size
enemy_units_count= 0
if local_sup[0] > local_sup[1]:
morale_boost += 10*local_sup[0]/local_sup[1]
elif local_sup[1] < local_sup[0]:
morale_drain += 10*local_sup[1]/local_sup[0]
if unit.team == self.team:
morale_boost += 10#*(unit.exp/10)
else:
enemy_units_atking = [unit for unit in team if unit.team != self.team and (unit.x, unit.y) in tiles_in_sup_range]
for number in range(len(enemy_units_atking)-1):
morale_drain += 10*number#+unit.exp
self.current_morale = self.morale + morale_boost - morale_drain
self.current_morale = max(0, self.current_morale)
def calculate_local_sup(self):
tiles_in_sup_range = get_tiles_in_range(self.x, self.y, 1)
allied_units = 0
enemy_units = 0
for team in teams:
for unit in team:
if (unit.x, unit.y) in tiles_in_sup_range:
if unit.team == self.team:
allied_units += unit.unit_size
else:
enemy_units += unit.unit_size
if allied_units != 0 and enemy_units != 0:
#local_sup_ratio = allied_units - enemy_units
return allied_units, enemy_units
else:
return 0, 0
def adjust_exp(self, self_exp, enemy_exp):
if self_exp < enemy_exp:
self.exp += 5 + enemy_exp - self_exp
elif self_exp >= enemy_exp:
self.exp += 5
def adjust_rank(self):
rank_sigs = {0:'', 1:'>', 2:'>>', 3:'>>>', 4:'|', 5:'||', 6:'*', 7:'**', 8:'|*|'}
self.rank = rank_sigs[int(self.rank_level)]
def activity_set(self):
global turn_counter
self.targeted = False
self.can_move = False
self.can_attack = False
self.adjust_rank()
is_not_routing = self.check_morale(self.current_morale)
if turn_counter%2 == 0 and self.team == 1 and is_not_routing == True:
self.can_move = True
self.can_attack = True
elif turn_counter%2 == 1 and self.team == 2 and is_not_routing == True:
self.can_move = True
self.can_attack = True
def draw(self):
#set the color and then draw the character that represents this object at its position
if self.can_move == True or self.can_attack == True:
libtcod.console_set_default_foreground(con, self.color)
elif self.can_move == False and self.can_attack == False:
libtcod.console_set_default_foreground(con, self.inactive_color)
libtcod.console_put_char(con, self.x, self.y, self.char, libtcod.BKGND_NONE)
libtcod.map_set_properties(new_map, self.x, self.y, False, False)
def show_move_tiles(self, team):
global mouse
global color_move_tile
global coord_in_range
coord_in_range = []
coord_in_range = get_total_squares(self.range, self.x, self.y, team)
if self.can_move == True and self.can_attack == True and self.targeted == True:
for (x,y) in coord_in_range:
libtcod.console_set_char_background(con, x, y, libtcod.blue, libtcod.BKGND_SET)
show_atk_tiles(self.x, self.y, self.atk_range, self.team)
elif self.can_move == True and self.can_attack == True and self.targeted == False:
for [x,y] in coord_in_range:
libtcod.console_set_char_background(con, x, y, self.color, libtcod.BKGND_SET)
show_atk_tiles(self.x, self.y, self.atk_range, self.team)
elif self.can_move == False and self.can_attack == True:
for [x,y] in coord_in_range:
libtcod.console_set_char_background(con, x, y, self.inactive_color, libtcod.BKGND_SET)
show_atk_tiles(self.x, self.y, self.atk_range, self.team)
else:
for [x,y] in coord_in_range:
libtcod.console_set_char_background(con, x, y, self.inactive_color, libtcod.BKGND_SET)
def display_info(self):
libtcod.console_set_color_control(libtcod.COLCTRL_1, libtcod.orange, libtcod.black)
morale_tags = ['Unbreakable', 'Confident', 'Steady', 'Shaken', 'Shattered']
fatigue_tags = ['Fresh', 'Warmed Up', 'Winded', 'Tired', 'Exhausted']
libtcod.console_print(msg_panel, 0, 0, '%s %c%s%c'%(self.name, libtcod.COLCTRL_1, self.rank, libtcod.COLCTRL_STOP))
render_bar(0, 1, 40, 'Unit Size', self.current_unit_size, self.unit_size, libtcod.black, libtcod.darker_red)
print_attribute_w_tags('Morale', self.current_morale, 0, 2, 100, morale_tags)
print_attribute_w_tags('Fatigue', self.current_fatigue, 0, 5, 100, fatigue_tags)
libtcod.console_print(msg_panel, 0, 3, 'Power: %s'%(self.power))
libtcod.console_print(msg_panel, 0, 4, 'Defence: %s'%(self.defence))
libtcod.console_print(msg_panel, 0, 6, 'Effective Force Multiplier: %s'%(self.power_multiplier))
libtcod.console_print(msg_panel, 0, 8, 'Experience: %s'%(self.exp))
def clear(self):
#erase the character that represents this object
libtcod.console_set_char_background(con, self.x, self.y, libtcod.green, libtcod.BKGND_SET)
def get_tiles_in_range(ori_x, ori_y, given_range):
coord_list = [(ori_x+a, ori_y+b) for a in range(-given_range, given_range+1)
for b in range(-given_range, given_range+1) if abs(a) != abs(b)]
return coord_list
def show_atk_tiles(ori_x, ori_y, atk_range, team):
global coord_in_atk_range
global team_1_coord, team_2_coord
coord_in_atk_range = []
coord_in_atk_range = get_tiles_in_range(ori_x, ori_y, atk_range)
if team == 1:
for (x, y) in coord_in_atk_range:
for (enemy_x, enemy_y) in team_2_coord:
if x == enemy_x and y == enemy_y:
libtcod.console_set_char_background(con, x, y, libtcod.red, libtcod.BKGND_SET)
elif team == 2:
for (x, y) in coord_in_atk_range:
for (enemy_x, enemy_y) in team_1_coord:
if x == enemy_x and y == enemy_y:
libtcod.console_set_char_background(con, x, y, libtcod.red, libtcod.BKGND_SET)
def print_attribute_w_tags(attr_name, attribute, x_coord, y_coord, max_value, tag_list):
libtcod.console_set_color_control(libtcod.COLCTRL_1, libtcod.green, libtcod.black)
libtcod.console_set_color_control(libtcod.COLCTRL_2, libtcod.lighter_green, libtcod.black)
libtcod.console_set_color_control(libtcod.COLCTRL_3, libtcod.yellow, libtcod.black)
libtcod.console_set_color_control(libtcod.COLCTRL_4, libtcod.lighter_red, libtcod.black)
libtcod.console_set_color_control(libtcod.COLCTRL_5, libtcod.red, libtcod.black)
if attribute >= max_value:
libtcod.console_print(msg_panel, x_coord, y_coord, '%s: %s %c(%s)%c'%(attr_name, attribute, libtcod.COLCTRL_1, tag_list[0], libtcod.COLCTRL_STOP))
elif attribute in range(int(max_value*.75), int(max_value)):
libtcod.console_print(msg_panel, x_coord, y_coord, '%s: %s %c(%s)%c'%(attr_name, attribute, libtcod.COLCTRL_2, tag_list[1], libtcod.COLCTRL_STOP))
elif attribute in range(int(max_value/2), int(max_value*.75)):
libtcod.console_print(msg_panel, x_coord, y_coord, '%s: %s %c(%s)%c'%(attr_name, attribute, libtcod.COLCTRL_3, tag_list[2], libtcod.COLCTRL_STOP))
elif attribute in range(int(max_value/4), int(max_value/2)):
libtcod.console_print(msg_panel, x_coord, y_coord, '%s: %s %c(%s)%c'%(attr_name, attribute, libtcod.COLCTRL_4, tag_list[3], libtcod.COLCTRL_STOP))
elif attribute < max_value/4:
libtcod.console_print(msg_panel, x_coord, y_coord, '%s: %s %c(%s)%c'%(attr_name, attribute, libtcod.COLCTRL_5, tag_list[4], libtcod.COLCTRL_STOP))
def render_bar(x, y, total_width, name, value, maximum, bar_color, back_color):
#render a bar (HP, experience, etc). first calculate the width of the bar
bar_width = int(float(value) / maximum * total_width)
#render the background first
libtcod.console_set_default_background(msg_panel, back_color)
libtcod.console_rect(msg_panel, x, y, total_width, 1, False, libtcod.BKGND_SCREEN)
#now render the bar on top
libtcod.console_set_default_background(msg_panel, bar_color)
if bar_width > 0:
libtcod.console_rect(msg_panel, x, y, bar_width, 1, False, libtcod.BKGND_SCREEN)
libtcod.console_set_default_foreground(msg_panel, libtcod.white)
libtcod.console_print_ex(msg_panel, x + total_width / 2, y, libtcod.BKGND_NONE, libtcod.CENTER,
name + ': ' + str(value) + '/' + str(maximum))
def handle_keys(team):
#key = libtcod.console_check_for_keypress() #real-time
global key #turn-based
#if key.vk == libtcod.KEY_ENTER and key.lalt:
#Alt+Enter: toggle fullscreen
# libtcod.console_set_fullscreen(not libtcod.console_is_fullscreen())
if key.vk == libtcod.KEY_ENTER:
end_turn()
elif key.vk == libtcod.KEY_ESCAPE:
return True #exit game
def get_total_squares(max_range, playerx, playery, team):
global coord_in_range
path = libtcod.dijkstra_new(new_map, 0)
libtcod.dijkstra_compute(path, playerx, playery)
for x in range(MAP_WIDTH):
for y in range (MAP_HEIGHT):
if libtcod.dijkstra_get_distance(path, x, y)<=max_range:
libtcod.dijkstra_path_set(path, x, y)
for i in range(libtcod.dijkstra_size(path)):
for unit in team:
coord_in_range.append(libtcod.dijkstra_get(path, i))
break
#coord_in_range = [[x,y] for x,y in coord_in_range if [x,y] != [unit.x, unit.y]]
return coord_in_range
def end_turn():
global turn_counter
global lclick_x, lclick_y
lclick_x = None
lclick_y = None
set_team_coord()
turn_counter += 1
for team in teams:
for unit in team:
if turn_counter%2 == 0 and unit.team == 1:
unit.adjust_fatigue()
elif turn_counter%2 == 1 and unit.team ==2:
unit.adjust_fatigue()
unit.adjust_morale()
unit.adjust_power()
unit.activity_set()
def render_all():
global color_dark_wall
global color_dark_ground
global lclick_x, lclick_y
global coord_in_range
global new_map
#render map
if map_archetype == 'forest':
T_Map.make_map(T_Map.tileset_forest, T_Map.colors_forest, T_Map.terrain_forest)
elif map_archetype == 'desert':
T_Map.make_map(T_Map.tileset_desert, T_Map.colors_desert, T_Map.terrain_desert)
elif map_archetype == 'tundra':
T_Map.make_map(T_Map.tileset_tundra, T_Map.colors_tundra, T_Map.terrain_tundra)
elif map_archetype == 'plains':
T_Map.make_map(T_Map.tileset_plains, T_Map.colors_plains, T_Map.terrain_forest)
#draw all objects in the list and show movement if mouse hovers over player
for team in teams:
for unit in team:
unit.draw()
#Show movement tiles if left click on any character
if mouse.lbutton_pressed:
(lclick_x, lclick_y) = (mouse.cx, mouse.cy)
for Tile in T_Map.tile_array:
if (mouse.cx, mouse.cy) == (Tile.x, Tile.y):
Tile.show_tile_info()
break
for team in teams:
for unit in team:
if mouse.cx == unit.x and mouse.cy == unit.y:
unit.show_move_tiles(team)
unit.display_info()
break
elif unit.x == lclick_x and unit.y == lclick_y and (unit.can_move == True or unit.can_attack == True):
unit.targeted = True
unit.show_move_tiles(team)
elif unit.can_move == False and unit.can_attack == True and unit.targeted == True:
if (lclick_x, lclick_y) in coord_in_atk_range:
unit.attack(lclick_x, lclick_y)
lclick_x = None
lclick_y = None
elif unit.can_move == True and unit.can_attack == True and unit.targeted == True:
if (lclick_x, lclick_y) in coord_in_range:
unit.move(lclick_x, lclick_y)
lclick_x = None
lclick_y = None
unit.can_move = False
unit.targeted = False
elif (lclick_x, lclick_y) in coord_in_atk_range:
unit.attack(lclick_x, lclick_y)
lclick_x = None
lclick_y = None
else:
unit.targeted = False
libtcod.console_set_default_background(msg_panel, libtcod.black)
#blit the contents of "con" to the root console
libtcod.console_blit(con, 0, 0, SCREEN_WIDTH, SCREEN_HEIGHT, 0, 0, 0)
libtcod.console_blit(msg_panel, 0, 0, 0, 0, 0, 0, MAP_HEIGHT)
libtcod.console_clear(msg_panel)
#############################################
# Initialization & Main Loop
#############################################
mouse = libtcod.Mouse()
key = libtcod.Key()
libtcod.console_set_custom_font('arial10x10.png', libtcod.FONT_TYPE_GREYSCALE | libtcod.FONT_LAYOUT_TCOD)
libtcod.console_init_root(SCREEN_WIDTH, SCREEN_HEIGHT, 'Strategos', False)
libtcod.sys_set_fps(LIMIT_FPS)
con = libtcod.console_new(SCREEN_WIDTH, SCREEN_HEIGHT)
msg_panel = libtcod.console_new(SCREEN_WIDTH, SCREEN_HEIGHT-MAP_HEIGHT)
T_Map = T_Map()
#create units for team 1
#(self, name, x, y, char, color, move_range, atk_range, unit_size, morale, power, defence, fatigue, team)
team1 = [(Unit('Cavalry', i+30, 10, 'A', libtcod.yellow, 4, 1, 1000, 40, 4.0, 2.0, 500, 1)) for i in range(3) ]
team1 += [(Unit('Heavy Infantry', i+30, 9, '=', libtcod.yellow, 2, 1, 2000, 50, 2.0, 4.0, 200, 1)) for i in range(2)]
team1 += [(Unit('War Elephants', 30, 8, 'R', libtcod.yellow, 3, 1, 37, 100, 50, 800, 600, 1)) for i in range(2)]
#create units for team 2
team2 = [(Unit('Roman Cavalry', 30+i, 12, 'A', libtcod.green, 4, 1, 1000, 40, 3.0, 1.0, 500, 2)) for i in range (5)]
team2 += [(Unit('Roman Infantry', 20+i, 13, '=', libtcod.green, 2, 1, 2000, 50, 1, 2, 200, 2)) for i in range(5)]
#the list of objects with those two
teams = [team1, team2]
for team in teams:
for unit in team:
unit.adjust_morale()
unit.adjust_power()
unit.activity_set()
team_1_coord = [(unit.x, unit.y) for unit in team1]
team_2_coord = [(unit.x, unit.y) for unit in team2]
def set_team_coord():
global team_1_coord, team_2_coord
team_1_coord = [(unit.x, unit.y) for unit in team1]
team_2_coord = [(unit.x, unit.y) for unit in team2]
map_archetype = 'forest'
if map_archetype == 'forest':
T_Map.make_map(T_Map.tileset_forest, T_Map.colors_forest, T_Map.terrain_forest)
elif map_archetype == 'desert':
T_Map.make_map(T_Map.tileset_desert, T_Map.colors_desert, T_Map.terrain_desert)
elif map_archetype == 'tundra':
T_Map.make_map(T_Map.tileset_tundra, T_Map.colors_tundra, T_Map.terrain_tundra)
elif map_archetype == 'plains':
T_Map.make_map(T_Map.tileset_plains, T_Map.colors_plains, T_Map.terrain_forest)
while not libtcod.console_is_window_closed():
libtcod.sys_check_for_event(libtcod.EVENT_KEY_PRESS|libtcod.EVENT_MOUSE,key,mouse)
#render the screen
render_all()
libtcod.console_flush()
#erase all objects at their old locations, before they move
for unit in team1:
unit.clear()
#handle keys and exit game if needed
exit = handle_keys(team1)
if exit:
break