From e1ebed24977502ec52227c6365998718dc656165 Mon Sep 17 00:00:00 2001 From: mibi88 Date: Sat, 7 Jan 2023 11:37:39 +0100 Subject: [PATCH] Small fix. --- LIBSCII.py | 552 ++++++++++++++++++++++++++--------------------------- 1 file changed, 276 insertions(+), 276 deletions(-) diff --git a/LIBSCII.py b/LIBSCII.py index 20d38eb..83b18ce 100644 --- a/LIBSCII.py +++ b/LIBSCII.py @@ -1,276 +1,276 @@ -""" - SCII - make ASCII RPG with multiple layered maps. - Copyright (C) 2023 Mibi88 - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with this program. If not, see https://www.gnu.org/licenses/. -""" - -# e-mail : mbcontact50@gmail.com - -#--- scii - make ASCII RPG with multiple layered maps --- - -# Map drawing modes - -STICKY = 0 -CENTERED = 1 -BLOCKS = 2 -STICKYBLOCKS = 3 - -class Scii: - def __init__(self, world, player, on_npc_collision, scii_keys = None, get_input_text = None, no_collision = None, collision_checker = None, - message_history_max = None, screen_width = 21, screen_height = 7): - self.world = world - self.player = player - self.map_num = world["map_num"] - self.screen_width = screen_width - self.screen_height = screen_height-1 - self.screen_x_middle = self.screen_width//2 - self.screen_y_middle = self.screen_height//2 - self.screen_size = self.screen_width*self.screen_height - self._vram = [' ' for i in range(self.screen_size)] - self.on_char_handlers = {} - if scii_keys: self.scii_keys = scii_keys - else: self.scii_keys = {"left": '4', "right": '6', "up": '8', "down": '2', "quit": 'q', "old_messages": '0'} - if get_input_text: self.get_input_text = get_input_text - else: self.get_input_text = self._default_intext - if collision_checker: self.collision_checker = collision_checker - else: self.collision_checker = self._default_collision_check - self.last_key = "" - if not message_history_max: self.message_history_max = 20 - else: self.message_history_max = message_history_max - self.old_messages = [] - self.on_npc_collision = on_npc_collision - if no_collision: self.no_collision = no_collision - else: self.no_collision = " ^" - self.collision_npc = None - def _default_collision_check(self, world, player, x, y): - collision = 0 - for i in self.world["maps"][self.map_num]["layers"]: - data = i["data"].split("\n") - while("" in data): data.remove("") - try: - c = data[y][x] - if c != i["transp_char"] and not (c in self.no_collision): - return 1 - for npc in world["npc"]: - if npc["map"] == self.map_num and npc["x"] == x and npc["y"] == y and npc["collision_check"]: - self.collision_npc = npc - return 2 - except: - if x >= 0 and x < self.get_map_width() and y >= 0 and y < self.get_map_height(): return 0 - else: return 1 - return 0 - def _default_intext(self): - return "> " - def _input(self): - i = input(self.get_input_text()) - if len(i) > 0: - self.last_key = i[0] - return self.last_key - return self.last_key - def _mainloop(self): - key = "" - while key != self.scii_keys["quit"]: - self.draw_map(self.world["dmode"], self.player["isvisible"]) - key = self._input() - nx = self.player["x"] - ny = self.player["y"] - if key == self.scii_keys["left"]: nx = self.player["x"]-1 - elif key == self.scii_keys["right"]: nx = self.player["x"]+1 - elif key == self.scii_keys["up"]: ny = self.player["y"]-1 - elif key == self.scii_keys["down"]: ny = self.player["y"]+1 - collision = self.collision_checker(self.world, self.player, nx, ny) - if self.player["collision_check"] and not collision: - self.player["x"] = nx - self.player["y"] = ny - elif collision == 2 and self.collision_npc != None: - self.on_npc_collision(self, self.collision_npc) - for jump in self.world["maps"][self.map_num]["jumps"]: - if jump["isactive"] and self.player["x"] == jump["x"] and self.player["y"] == jump["y"]: - self.player["x"] = jump["to_x"] - self.player["y"] = jump["to_y"] - self.map_num = jump["to_map"] - self.world["map_num"] = self.map_num - if key == self.scii_keys["old_messages"]: self.show_old_messages() - def mainloop(self): - try: - self._mainloop() - except Exception as e: print("Ow there was an error in SCII : {}".format(e)) - def _setc(self, x, y, c): - if len(c) == 1 and x>=0 and x=0 and ymax_len: max_len = len(line) - return max_len - def get_map_height(self, map_data): - max_len = 0 - for i in map_data["layers"]: - data = i["data"].split("\n") - while("" in data): data.remove("") - if len(data) > max_len: - max_len = len(data) - return max_len - def draw_map(self, mode, show_player): - map_data = self.world["maps"][self.map_num] - osx = self.player["x"] - osy = self.player["y"] - sx = osx - sy = osy - if mode == STICKY: - sx -= self.screen_x_middle - sy -= self.screen_y_middle - # Fix x - if sx < 0: - sx = 0 - elif sx + self.screen_width > self.get_map_width(map_data): - sx = self.get_map_width(map_data) - self.screen_width - px = osx - sx - # Fix y - if sy < 0: - sy = 0 - elif sy + self.screen_height > self.get_map_height(map_data): - sy = self.get_map_height(map_data) - self.screen_height - py = osy - sy - elif mode == CENTERED: - px = self.screen_x_middle - py = self.screen_y_middle - sx -= self.screen_x_middle - sy -= self.screen_y_middle - elif mode == BLOCKS: - sx = sx // self.screen_width * self.screen_width - sy = sy // self.screen_height * self.screen_height - px = osx-sx - py = osy-sy - elif mode == STICKYBLOCKS: - sx = sx // self.screen_width * self.screen_width - sy = sy // self.screen_height * self.screen_height - if sx > self.get_map_width(map_data) - self.screen_width: - sx = self.get_map_width(map_data) - self.screen_width - if sy > self.get_map_height(map_data) - self.screen_height: - sy = self.get_map_height(map_data) - self.screen_height - px = osx-sx - py = osy-sy - self._cvram() - layerc = 0 - for i in map_data["layers"]: - data = i["data"].split("\n") - while("" in data): data.remove("") - map_width = self.get_map_width(map_data) - map_height = self.get_map_height(map_data) - for y in range(self.screen_height): - for x in range(self.screen_width): - try: - if sx+x >= 0 and sx+x < map_width and sy+y >= 0 and sy+y < map_height: - c = data[sy+y][sx+x] - if c != i["transp_char"]: - self._setc(x, y, c) - except: pass - for npc in self.world["npc"]: - if npc["layer"] == layerc and npc["map"] == self.map_num and npc["isvisible"]: - self._setc(px + (npc["x"] - osx), py + (npc["y"] - osy), npc["char"]) - if layerc == self.player["layer"]: self._setc(px, py, self.player["playerc"]) - layerc += 1 - self._dvram() - def show_text(self, text): - dwidth = self.screen_width - 2 - self._cvram() - dtext = "" - sz = 0 - y = 0 - for i in text.split(" "): - if len(i) > dwidth: - count = sz - for c in i: - dtext += c - count += 1 - if count >= dwidth - 1: - dtext += "-\n" - count = 0 - y += 1 - dtext += ' ' - sz = count + 1 - elif sz + len(i) + 1 < dwidth: - dtext += i + ' ' - sz += len(i) + 1 - y += i.count('\n') - else: - dtext += '\n' + i + ' ' - sz = len(i) + 1 - y += i.count('\n') + 1 - x = 0 - y = 0 - msg = "" - for i in dtext: - if i == '\n': - y += 1 - x = 0 - if y >= self.screen_height: - self._setc(self.screen_width - 1, self.screen_y_middle, '>') - self._dvram() - intxt = input("Continue > ") - if len(intxt) > 0: - if intxt[0] == self.scii_keys["quit"]: return - y = 0 - x = 0 - self._add_message(msg) - msg = "" - self._cvram() - else: - self._setc(x, y, i) - x += 1 - msg += i - self._dvram() - if msg != "": self._add_message(msg) - input("End of the text > ") - def _add_message(self, message): - self.old_messages.append(message) - while(len(self.old_messages) > self.message_history_max): del self.old_messages[0] - def show_old_messages(self): - if len(self.old_messages) < 1: - self._cvram() - x = 1 - for i in "No messages.": - self._setc(x, self.screen_y_middle, i) - x += 1 - self._dvram() - input("Go back > ") - c = len(self.old_messages) - for i in [i for i in self.old_messages[::-1]]: - self.show_text(i) - c -= 1 - if c < 1: input("Go back > ") - else: intxt = input("Next message > ") - if len(intxt) > 0: - if intxt[0] == 'q': return - def ask_choice(self, text, choices): - choice = 0 - while choice < 1 or choice > len(choices): - newtext = text + "\n\n" - c = 1 - for i in choices: - newtext += "{} - {}\n".format(c, i) - c += 1 - self.show_text(newtext) - try: - choice = int(input("Choice > ")) - except: choice = -1 - return choice -#--- +""" + SCII - make ASCII RPG with multiple layered maps. + Copyright (C) 2023 Mibi88 + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + You should have received a copy of the GNU General Public License + along with this program. If not, see https://www.gnu.org/licenses/. +""" + +# e-mail : mbcontact50@gmail.com + +#--- scii - make ASCII RPG with multiple layered maps --- + +# Map drawing modes + +STICKY = 0 +CENTERED = 1 +BLOCKS = 2 +STICKYBLOCKS = 3 + +class Scii: + def __init__(self, world, player, on_npc_collision, scii_keys = None, get_input_text = None, no_collision = None, collision_checker = None, + message_history_max = None, screen_width = 21, screen_height = 7): + self.world = world + self.player = player + self.map_num = world["map_num"] + self.screen_width = screen_width + self.screen_height = screen_height-1 + self.screen_x_middle = self.screen_width//2 + self.screen_y_middle = self.screen_height//2 + self.screen_size = self.screen_width*self.screen_height + self._vram = [' ' for i in range(self.screen_size)] + self.on_char_handlers = {} + if scii_keys: self.scii_keys = scii_keys + else: self.scii_keys = {"left": '4', "right": '6', "up": '8', "down": '2', "quit": 'q', "old_messages": '0'} + if get_input_text: self.get_input_text = get_input_text + else: self.get_input_text = self._default_intext + if collision_checker: self.collision_checker = collision_checker + else: self.collision_checker = self._default_collision_check + self.last_key = "" + if not message_history_max: self.message_history_max = 20 + else: self.message_history_max = message_history_max + self.old_messages = [] + self.on_npc_collision = on_npc_collision + if no_collision: self.no_collision = no_collision + else: self.no_collision = " ^" + self.collision_npc = None + def _default_collision_check(self, world, player, x, y): + collision = 0 + for i in self.world["maps"][self.map_num]["layers"]: + data = i["data"].split("\n") + while("" in data): data.remove("") + try: + c = data[y][x] + if c != i["transp_char"] and not (c in self.no_collision): + return 1 + for npc in world["npc"]: + if npc["map"] == self.map_num and npc["x"] == x and npc["y"] == y and npc["collision_check"]: + self.collision_npc = npc + return 2 + except: + if x >= 0 and x < self.get_map_width() and y >= 0 and y < self.get_map_height(): return 0 + else: return 1 + return 0 + def _default_intext(self): + return "> " + def _input(self): + i = input(self.get_input_text()) + if len(i) > 0: + self.last_key = i[0] + return self.last_key + return self.last_key + def _mainloop(self): + key = "" + while key != self.scii_keys["quit"]: + self.draw_map(self.world["dmode"], self.player["isvisible"]) + key = self._input() + nx = self.player["x"] + ny = self.player["y"] + if key == self.scii_keys["left"]: nx = self.player["x"]-1 + elif key == self.scii_keys["right"]: nx = self.player["x"]+1 + elif key == self.scii_keys["up"]: ny = self.player["y"]-1 + elif key == self.scii_keys["down"]: ny = self.player["y"]+1 + collision = self.collision_checker(self.world, self.player, nx, ny) + if self.player["collision_check"] and not collision: + self.player["x"] = nx + self.player["y"] = ny + elif collision == 2 and self.collision_npc != None: + self.on_npc_collision(self, self.collision_npc) + for jump in self.world["maps"][self.map_num]["jumps"]: + if jump["isactive"] and self.player["x"] == jump["x"] and self.player["y"] == jump["y"]: + self.player["x"] = jump["to_x"] + self.player["y"] = jump["to_y"] + self.map_num = jump["to_map"] + self.world["map_num"] = self.map_num + if key == self.scii_keys["old_messages"]: self.show_old_messages() + def mainloop(self): + try: + self._mainloop() + except Exception as e: print("Ow there was an error in SCII : {}".format(e)) + def _setc(self, x, y, c): + if len(c) == 1 and x>=0 and x=0 and ymax_len: max_len = len(line) + return max_len + def get_map_height(self, map_data): + max_len = 0 + for i in map_data["layers"]: + data = i["data"].split("\n") + while("" in data): data.remove("") + if len(data) > max_len: + max_len = len(data) + return max_len + def draw_map(self, mode, show_player): + map_data = self.world["maps"][self.map_num] + osx = self.player["x"] + osy = self.player["y"] + sx = osx + sy = osy + if mode == STICKY: + sx -= self.screen_x_middle + sy -= self.screen_y_middle + # Fix x + if sx < 0: + sx = 0 + elif sx + self.screen_width > self.get_map_width(map_data): + sx = self.get_map_width(map_data) - self.screen_width + px = osx - sx + # Fix y + if sy < 0: + sy = 0 + elif sy + self.screen_height > self.get_map_height(map_data): + sy = self.get_map_height(map_data) - self.screen_height + py = osy - sy + elif mode == CENTERED: + px = self.screen_x_middle + py = self.screen_y_middle + sx -= self.screen_x_middle + sy -= self.screen_y_middle + elif mode == BLOCKS: + sx = sx // self.screen_width * self.screen_width + sy = sy // self.screen_height * self.screen_height + px = osx-sx + py = osy-sy + elif mode == STICKYBLOCKS: + sx = sx // self.screen_width * self.screen_width + sy = sy // self.screen_height * self.screen_height + if sx > self.get_map_width(map_data) - self.screen_width: + sx = self.get_map_width(map_data) - self.screen_width + if sy > self.get_map_height(map_data) - self.screen_height: + sy = self.get_map_height(map_data) - self.screen_height + px = osx-sx + py = osy-sy + self._cvram() + layerc = 0 + for i in map_data["layers"]: + data = i["data"].split("\n") + while("" in data): data.remove("") + map_width = self.get_map_width(map_data) + map_height = self.get_map_height(map_data) + for y in range(self.screen_height): + for x in range(self.screen_width): + try: + if sx+x >= 0 and sx+x < map_width and sy+y >= 0 and sy+y < map_height: + c = data[sy+y][sx+x] + if c != i["transp_char"]: + self._setc(x, y, c) + except: pass + for npc in self.world["npc"]: + if npc["layer"] == layerc and npc["map"] == self.map_num and npc["isvisible"]: + self._setc(px + (npc["x"] - osx), py + (npc["y"] - osy), npc["char"]) + if layerc == self.player["layer"] and show_player: self._setc(px, py, self.player["playerc"]) + layerc += 1 + self._dvram() + def show_text(self, text): + dwidth = self.screen_width - 2 + self._cvram() + dtext = "" + sz = 0 + y = 0 + for i in text.split(" "): + if len(i) > dwidth: + count = sz + for c in i: + dtext += c + count += 1 + if count >= dwidth - 1: + dtext += "-\n" + count = 0 + y += 1 + dtext += ' ' + sz = count + 1 + elif sz + len(i) + 1 < dwidth: + dtext += i + ' ' + sz += len(i) + 1 + y += i.count('\n') + else: + dtext += '\n' + i + ' ' + sz = len(i) + 1 + y += i.count('\n') + 1 + x = 0 + y = 0 + msg = "" + for i in dtext: + if i == '\n': + y += 1 + x = 0 + if y >= self.screen_height: + self._setc(self.screen_width - 1, self.screen_y_middle, '>') + self._dvram() + intxt = input("Continue > ") + if len(intxt) > 0: + if intxt[0] == self.scii_keys["quit"]: return + y = 0 + x = 0 + self._add_message(msg) + msg = "" + self._cvram() + else: + self._setc(x, y, i) + x += 1 + msg += i + self._dvram() + if msg != "": self._add_message(msg) + input("End of the text > ") + def _add_message(self, message): + self.old_messages.append(message) + while(len(self.old_messages) > self.message_history_max): del self.old_messages[0] + def show_old_messages(self): + if len(self.old_messages) < 1: + self._cvram() + x = 1 + for i in "No messages.": + self._setc(x, self.screen_y_middle, i) + x += 1 + self._dvram() + input("Go back > ") + c = len(self.old_messages) + for i in [i for i in self.old_messages[::-1]]: + self.show_text(i) + c -= 1 + if c < 1: input("Go back > ") + else: intxt = input("Next message > ") + if len(intxt) > 0: + if intxt[0] == 'q': return + def ask_choice(self, text, choices): + choice = 0 + while choice < 1 or choice > len(choices): + newtext = text + "\n\n" + c = 1 + for i in choices: + newtext += "{} - {}\n".format(c, i) + c += 1 + self.show_text(newtext) + try: + choice = int(input("Choice > ")) + except: choice = -1 + return choice +#---