Update Asci 1.7.0 -> 1.7.2
This commit is contained in:
parent
2241356192
commit
ad617b948a
170
idk/asci.py
170
idk/asci.py
|
@ -1,4 +1,4 @@
|
|||
# Asci (1.7.0)
|
||||
# Asci (1.7.2)
|
||||
|
||||
class Asci:
|
||||
def __init__(self, maps, events_mapping, keys_mapping, behaviors=None, screen_width=21, screen_height=6):
|
||||
|
@ -11,14 +11,13 @@ class Asci:
|
|||
self._game_keys_mapping = {key: keys_mapping[key] for key in keys_mapping if not key in (1, 2, 3, 5)}
|
||||
|
||||
# Custom entities behavior
|
||||
self._behaviors = {"stand by": stand_by, "follow": follow, "walk": walk}
|
||||
self._behaviors = {"permanent": permanent, "stand by": stand_by, "follow": follow, "walk": walk}
|
||||
if behaviors:
|
||||
for i in behaviors: self._behaviors[i] = behaviors[i]
|
||||
|
||||
# Screen initialisation
|
||||
self.screen = Screen(screen_width, screen_height)
|
||||
self.current_map = None
|
||||
self.visible_entities = []
|
||||
|
||||
def _looked_case(self, direction):
|
||||
if direction == 1: # Left
|
||||
|
@ -38,18 +37,17 @@ class Asci:
|
|||
def _cell_test(self, direction):
|
||||
if direction == 1:
|
||||
if self.data[2] - 1 < 0: return -1
|
||||
else: cell = self.screen.get_cell(self.data[2: 4], self.data[2] - 1, self.data[3])
|
||||
else: cell = self.screen.get_cell(self.data[2] - 1, self.data[3])
|
||||
if direction == 3:
|
||||
if self.data[2] + 1 >= self.map_width: return -1
|
||||
else: cell = self.screen.get_cell(self.data[2: 4], self.data[2] + 1, self.data[3])
|
||||
else: cell = self.screen.get_cell(self.data[2] + 1, self.data[3])
|
||||
if direction == 5:
|
||||
if self.data[3] - 1 < 0: return -1
|
||||
else: cell = self.screen.get_cell(self.data[2: 4], self.data[2], self.data[3] - 1)
|
||||
else: cell = self.screen.get_cell(self.data[2], self.data[3] - 1)
|
||||
if direction == 2:
|
||||
if self.data[3] + 1 >= self.map_height: return -1
|
||||
else: cell = self.screen.get_cell(self.data[2: 4], self.data[2], self.data[3] + 1)
|
||||
else: cell = self.screen.get_cell(self.data[2], self.data[3] + 1)
|
||||
|
||||
print(f"'{cell}'")
|
||||
cell_patterns = self._legend
|
||||
for pattern_index in range(len(cell_patterns)):
|
||||
if cell in cell_patterns[pattern_index]: return pattern_index
|
||||
|
@ -66,12 +64,12 @@ class Asci:
|
|||
if key == 1: self.data[2] -= 1
|
||||
if key == 3: self.data[2] += 1
|
||||
if key == 5: self.data[3] -= 1
|
||||
if key == 2: self.data[3] += 1
|
||||
|
||||
if key == 2: self.data[3] += 1
|
||||
|
||||
# Change map
|
||||
elif interaction and cell_test == len(self._legend) - 2:
|
||||
new_map, self.data[2], self.data[3] = self._get_map(key)
|
||||
self._change_map(new_map)
|
||||
if self.data[1] != new_map: self._change_map(new_map)
|
||||
|
||||
# Interaction
|
||||
elif interaction and cell_test >= 0: self._interaction(key, cell_test)
|
||||
|
@ -93,10 +91,11 @@ class Asci:
|
|||
def _change_map(self, new_map):
|
||||
# Update entities
|
||||
if self.current_map:
|
||||
for i in range(len(self.current_map.entities)):
|
||||
for i in self.current_map.entities.copy():
|
||||
entity = self.current_map.entities[i]
|
||||
if entity.behavior == "follow":
|
||||
self.maps[new_map].entities.append(entity)
|
||||
entity.pos_x = entity.pos_y = -1
|
||||
self.maps[new_map].entities[entity.entity_id] = entity
|
||||
self.maps[self.data[1]].entities.pop(i)
|
||||
|
||||
# Update current map
|
||||
|
@ -106,7 +105,6 @@ class Asci:
|
|||
# Update screen configuration
|
||||
self.screen.set_world(self.current_map.map_data)
|
||||
self.map_width, self.map_height = self.screen.get_map_size()
|
||||
self._get_visible_entities()
|
||||
|
||||
def _interaction(self, direction, cell_content):
|
||||
x, y = self._looked_case(direction)
|
||||
|
@ -142,24 +140,10 @@ class Asci:
|
|||
self.data[0][quest] += answer_selected
|
||||
self._interaction(direction, cell_content)
|
||||
|
||||
# Entities gestion
|
||||
def _get_visible_entities(self):
|
||||
self.visible_entities = {}
|
||||
for entity in self.current_map.entities:
|
||||
if (0 <= entity.pos_x - self.data[2] + 10 < self.screen.screen_width) and (0 <= entity.pos_y - self.data[3] + 3 < self.screen.screen_height):
|
||||
self.visible_entities[entity.entity_id] = entity
|
||||
|
||||
def _get_entity_id(self, x, y):
|
||||
for entity_id in self.visible_entities:
|
||||
entity = self.visible_entities[entity_id]
|
||||
for entity in self.current_map.entities.values():
|
||||
if entity.pos_x == x and entity.pos_y == y:
|
||||
return entity_id
|
||||
|
||||
def _run_entities_behaviors(self):
|
||||
for entity in self.current_map.entities:
|
||||
data_copy = get_data_copy(self.data)
|
||||
self._behaviors[entity.behavior](entity, data_copy, self.stat, self.screen, self.walkable)
|
||||
self._get_visible_entities()
|
||||
return entity.entity_id
|
||||
|
||||
# Mainloop
|
||||
def mainloop(self, end_game, stat=None, data=None, routine=None, player="@", door="^", walkable=" ", exit_key=9, multi_move="."):
|
||||
|
@ -174,39 +158,46 @@ class Asci:
|
|||
else: self.data = [data[0], data[1], data[2], data[3], 0]
|
||||
|
||||
# Configuration
|
||||
self.walkable = walkable
|
||||
self._legend.append(door)
|
||||
self._legend.append(walkable)
|
||||
self._change_map(data[1])
|
||||
self.screen.load_data(self.data)
|
||||
|
||||
key = 0
|
||||
|
||||
while key != exit_key and self.stat[0] > 0 and self.data[0]["main"] < end_game:
|
||||
# Update the map
|
||||
self.screen.set_screen(self.data[2], self.data[3])
|
||||
self.screen.set_screen()
|
||||
|
||||
# Compute the player's and entities' positions
|
||||
self.screen.set_cell(self.data[2] - 10, self.data[3] - 3, self.data[2], self.data[3], player)
|
||||
self._run_entities_behaviors()
|
||||
for entity in self.visible_entities.values():
|
||||
self.screen.set_cell(self.data[2] - 10, self.data[3] - 3, entity.pos_x, entity.pos_y, entity.symbol)
|
||||
|
||||
# Display map and get the key
|
||||
key = convert(self.screen.display())
|
||||
data_copy = self.data[:]
|
||||
for entity in self.current_map.entities.values():
|
||||
self._behaviors[entity.behavior](entity, data_copy, self.stat, self.screen, walkable)
|
||||
if (0 <= entity.pos_x - self.data[2] + 10 < self.screen.screen_width) and (0 <= entity.pos_y - self.data[3] + 3 < self.screen.screen_height):
|
||||
self.screen.set_cell(entity.pos_x, entity.pos_y, entity.symbol)
|
||||
|
||||
self.screen.set_cell(self.data[2], self.data[3], player)
|
||||
|
||||
# Display map, get the key and update key buffer
|
||||
key = convert(self.screen.display())
|
||||
if not key: key = self.data[4]
|
||||
else: self.data[4] = key
|
||||
|
||||
# Multi-move and key gestion
|
||||
if type(key) == str and key[0] == multi_move:
|
||||
for i in list(key[1:]):
|
||||
self._keyboard(convert(i), False)
|
||||
self.data[4] = convert(key[-1])
|
||||
key = key[1:]
|
||||
for k, r in get_multi_move(key):
|
||||
for _ in range(r):
|
||||
self._keyboard(k, False)
|
||||
self.screen.set_screen()
|
||||
|
||||
self.data[4] = k
|
||||
else:
|
||||
self._keyboard(key)
|
||||
|
||||
# Launching the game routine
|
||||
if routine:
|
||||
data_copy = get_data_copy(self.data)
|
||||
data_copy = self.data[:]
|
||||
routine(data_copy, self.stat)
|
||||
|
||||
if self.stat[0] <= 0: self.stat[0] = 100
|
||||
|
@ -220,6 +211,10 @@ class Screen:
|
|||
self.screen_width = screen_width
|
||||
self.screen_height = screen_height
|
||||
self._on_screen = [[" " for _ in range(screen_width)] for _ in range(screen_height)]
|
||||
self._asci_data = []
|
||||
|
||||
def load_data(self, data):
|
||||
self._asci_data = data
|
||||
|
||||
def get_map_size(self):
|
||||
return self.map_width, self.map_height
|
||||
|
@ -229,8 +224,8 @@ class Screen:
|
|||
self.map_width = max([len(line) for line in self._world])
|
||||
self.map_height = len(self._world)
|
||||
|
||||
def set_screen(self, x, y):
|
||||
x -= 10 ; y -= 3
|
||||
def set_screen(self):
|
||||
x = self._asci_data[2] - 10 ; y = self._asci_data[3] - 3
|
||||
for x_map in range(x, x + self.screen_width):
|
||||
for y_map in range(y, y + self.screen_height):
|
||||
self._on_screen[y_map - y][x_map - x] = " "
|
||||
|
@ -238,6 +233,7 @@ class Screen:
|
|||
try: self._on_screen[y_map - y][x_map - x] = self._world[y_map][x_map]
|
||||
except: pass
|
||||
|
||||
|
||||
def display(self, return_input=True):
|
||||
for line in self._on_screen:
|
||||
print("".join(line))
|
||||
|
@ -256,13 +252,16 @@ class Screen:
|
|||
if index + 1 == nb_par: return input(">")
|
||||
else: input()
|
||||
|
||||
def set_cell(self, x_offset, y_offset, x, y, value):
|
||||
self._on_screen[y - y_offset][x - x_offset] = value
|
||||
def set_cell(self, x, y, value):
|
||||
x = x - (self._asci_data[2] - 10)
|
||||
y = y - (self._asci_data[3] - 3)
|
||||
if 0 <= x < self.screen_width and 0 <= y < self.screen_height:
|
||||
self._on_screen[y][x] = value
|
||||
|
||||
def get_cell(self, offsets, x, y):
|
||||
x = x - (offsets[0] - 10)
|
||||
y = y - (offsets[1] - 3)
|
||||
if 0 <= x < self.screen_width and 0 <= y <= self.screen_height:
|
||||
def get_cell(self, x, y):
|
||||
x = x - (self._asci_data[2] - 10)
|
||||
y = y - (self._asci_data[3] - 3)
|
||||
if 0 <= x < self.screen_width and 0 <= y < self.screen_height:
|
||||
return self._on_screen[y][x]
|
||||
else: return " "
|
||||
|
||||
|
@ -277,8 +276,8 @@ class Event:
|
|||
class Map:
|
||||
def __init__(self, map_data, entities, *coords):
|
||||
self.map_data = map_data
|
||||
if entities: self.entities = [Entity(*i) for i in entities]
|
||||
else: self.entities = []
|
||||
if entities: self.entities = {i[0]: Entity(*i) for i in entities}
|
||||
else: self.entities = {}
|
||||
self.coords = coords
|
||||
|
||||
class Entity:
|
||||
|
@ -291,7 +290,7 @@ class Entity:
|
|||
self.args = list(args)
|
||||
|
||||
def change_behavior(self, new_behavior):
|
||||
self.behavior = new_behavior
|
||||
if self.behavior != "permanent": self.behavior = new_behavior
|
||||
|
||||
|
||||
# Functions used by Asci
|
||||
|
@ -305,18 +304,24 @@ def convert(string, force_int=False):
|
|||
def text_formater(string, screen_width=21, screen_height=6):
|
||||
|
||||
def line_formater(string, screen_width):
|
||||
if len(string) <= screen_width: return string
|
||||
string_result = ""
|
||||
while len(string) > screen_width:
|
||||
stop_index = screen_width
|
||||
while stop_index > 0 and not string[stop_index].isspace(): stop_index -= 1
|
||||
if not stop_index: stop_index = screen_width
|
||||
|
||||
stop_index = screen_width
|
||||
while stop_index > 0 and not string[stop_index].isspace(): stop_index -= 1
|
||||
if not stop_index: stop_index = screen_width
|
||||
|
||||
return string[:stop_index].strip() + "\n" + line_formater(string[stop_index:].strip(), screen_width)
|
||||
string_result += string[:stop_index].strip() + "\n"
|
||||
string = string[stop_index:].strip()
|
||||
|
||||
return string_result + string
|
||||
|
||||
def paragraph_formater(lines, screen_height):
|
||||
if len(lines) < screen_height: return "\n".join(lines)
|
||||
paragraphs = ""
|
||||
while len(lines) >= screen_height:
|
||||
paragraphs += "\n".join(lines[:screen_height]) + "\n\n"
|
||||
lines = lines[screen_height:]
|
||||
|
||||
return "\n".join(lines[:screen_height]) + "\n\n" + paragraph_formater(lines[screen_height:], screen_height)
|
||||
return paragraphs + "\n".join(lines)
|
||||
|
||||
lines = []
|
||||
for line in string.split("\n"):
|
||||
|
@ -340,8 +345,25 @@ def read_event(data, event, quest):
|
|||
return Event(*event)
|
||||
|
||||
|
||||
def get_data_copy(data):
|
||||
return [data[0], data[1], data[2], data[3], data[4]]
|
||||
def get_multi_move(key):
|
||||
if "," in key:
|
||||
result = []
|
||||
for k in key.split(","):
|
||||
if "*" in k:
|
||||
k = k.split("*")
|
||||
result.append((convert(k[0]), convert(k[1])))
|
||||
else:
|
||||
result.append((convert(k), 1))
|
||||
|
||||
return result
|
||||
|
||||
elif "*" in key:
|
||||
key = key.split("*")
|
||||
return [(convert(key[0]), convert(key[1]))]
|
||||
|
||||
else:
|
||||
return [(convert(k), 1) for k in key]
|
||||
|
||||
|
||||
|
||||
# Extra functions
|
||||
|
@ -366,16 +388,24 @@ def print_text(text, min_value=0, max_value=0, default_value=0):
|
|||
def stand_by(entity, data, stat, screen, walkable):
|
||||
pass
|
||||
|
||||
def permanent(entity, data, stat, screen, walkable):
|
||||
pass
|
||||
|
||||
|
||||
def follow(entity, data, stat, screen, walkable):
|
||||
if data[4] == 1 and screen.get_cell(data[2: 4], data[2] + 1, data[3]) in walkable: entity.pos_x, entity.pos_y = data[2] + 1, data[3]
|
||||
elif data[4] == 2 and screen.get_cell(data[2: 4], data[2], data[3] - 1) in walkable: entity.pos_x, entity.pos_y = data[2], data[3] - 1
|
||||
elif data[4] == 3 and screen.get_cell(data[2: 4], data[2] - 1, data[3]) in walkable: entity.pos_x, entity.pos_y = data[2] - 1, data[3]
|
||||
elif data[4] == 5 and screen.get_cell(data[2: 4], data[2], data[3] + 1) in walkable: entity.pos_x, entity.pos_y = data[2], data[3] + 1
|
||||
if entity.pos_x == entity.pos_y == -1:
|
||||
entity.pos_x, entity.pos_y = data[2], data[3]
|
||||
|
||||
elif data[4] in (1, 2, 3, 5):
|
||||
if entity.args: walkable += entity.args[0]
|
||||
cases = ((data[2] + 1, data[3]), (data[2], data[3] - 1), (data[2] - 1, data[3]), 0, (data[2], data[3] + 1))[data[4] - 1]
|
||||
if not (0 <= cases[0] < screen.map_width and 0 <= cases[1] < screen.map_height): entity.pos_x, entity.pos_y = data[2], data[3]
|
||||
elif screen.get_cell(cases[0], cases[1]) in walkable: entity.pos_x, entity.pos_y = cases
|
||||
|
||||
|
||||
def walk(entity, data, stat, screen, walkable):
|
||||
frame = (entity.args[0] + 1) % len(entity.args[1])
|
||||
new_x, new_y = entity.args[1][frame]
|
||||
print(new_x, new_y)
|
||||
if screen.get_cell(data[2: 4], new_x, new_y) in walkable:
|
||||
if screen.get_cell(new_x, new_y) in walkable:
|
||||
entity.pos_x, entity.pos_y = new_x, new_y
|
||||
entity.args[0] = frame
|
||||
|
|
|
@ -79,10 +79,7 @@ def idk(save_code=None):
|
|||
name = stat[5]
|
||||
data = [{"main": 0}, 3, 44, 66]
|
||||
|
||||
print_text("Au alentour du Ve siecle, quelque part en Scandinavie. La bataille prenait place dans un champ saccage, et la nuit etait tombee depuis quelques heures lorsque l'assaut debuta.")
|
||||
print_text("Hache levee, a la seule lueur de la pleine lune, {0} et sa division se jeterent sur le camp adverse, mais, pris a revers, le combat tourna vite a la defaveur des assaillants qui furent reduit sans autres difficultes.".format(name))
|
||||
print_text("Blesse a plusieurs endroit, {0} se trainait sur le sol, tentant de se refugier dans la nuit lorsqu'une forme humaine portant un espadon dans le dos et une lourde armure d'argent s'arreta devant lui. La Valkyrie degaina son espadon et acheva {0} avant de l'emporter dans ses bras.".format(name))
|
||||
print_text("Mais Odin avait d'autres plan pour {0} qu'une retraite parmi les meilleurs guerriers, et il le renvoya dans le vaste monde avec cet ultimatum : si il trouve la voie jusqu'a Asgard et le Valaskjalf, Odin conscent a le garder a son service, sinon il sera condamne a errer dans le monde sans jamais trouver le repos.".format(name))
|
||||
print_text("Au alentour du Ve siecle, quelque part en Scandinavie. La bataille prenait place dans un champ saccage, et la nuit etait tombee depuis quelques heures lorsque l'assaut debuta. Hache levee, a la seule lueur de la pleine lune, {0} et sa division se jeterent sur le camp adverse, mais, pris a revers, le combat tourna vite a la defaveur des assaillants qui furent reduit sans autres difficultes.\nBlesse a plusieurs endroit, {0} se trainait sur le sol, tentant de se refugier dans la nuit lorsqu'une forme humaine portant un espadon dans le dos et une lourde armure d'argent s'arreta silencieusement devant lui. La Valkyrie degaina son espadon et acheva {0} avant de l'emporter dans ses bras.\nMais Odin, septique des exploits au combat de {0}, lui refusa une retraite parmi les meilleurs guerriers, et il le renvoya dans le vaste monde avec cet ultimatum : s'il trouve la voie jusqu'a Asgard et le Valaskjalf, Odin conscent a revoir son jugement, sinon il sera condamne a errer dans le monde sans jamais trouver le repos.".format(name))
|
||||
|
||||
else:
|
||||
stat, data = decode_save(save_code)
|
||||
|
|
|
@ -112,6 +112,7 @@ midgard = (r"""
|
|||
(3, '*', 66, 56, 'stand by'),
|
||||
(4, '*', 51, 60, 'stand by'),
|
||||
(5, '*', 68, 71, 'stand by'),
|
||||
(6, '*', 94, 85, 'stand by')
|
||||
|
||||
],
|
||||
|
||||
|
|
Loading…
Reference in New Issue