def ReloadRoom(self): """This function re-writes the GUI with current room info, available spots and connected rooms. It additionally prints the room's description if players enter the room the first time.""" gui.textScreen.Clear() listRoomsVisited = GameStats.GetRoomsVisited() if self.number not in listRoomsVisited: gui.textScreen.TypeWrite(self.description) GameStats.AddRoomsVisited() # location info gui.textScreen.TypeWrite(GameMsg.YOURE_AT[0] + str(self.number) + ": " \ + self.name + GameMsg.YOURE_AT[1]) # list spots iterator = filter(lambda id: id > 0, self.__spotList) for spotNr in iterator: gui.textScreen.LineWrite(str(spotNr) + ": " + self.__spotObjects[spotNr].name + "\n") # list connected rooms gui.textScreen.LineWrite(GameMsg.IN_REACH) iterator = filter(lambda id: id > 0, self.__roomList) for roomNr in iterator: if roomNr in listRoomsVisited: # room is known gui.textScreen.LineWrite(str(roomNr) + ": " \ + self.__roomObjects[roomNr].name + "\n") else: gui.textScreen.LineWrite(str(roomNr) + GameMsg.UNKNOWN_ROOM) gui.textScreen.LineWrite("\n")
def invokeChangeMod(mod, modType): listPlayers = GameStats.GetListPlayers() if modType == MOD.EFFONE: GameStats.GetCurrentPlayer().ChangeMod(mod) elif modType == MOD.EFFALL: for element in range(0, len(listPlayers)): listPlayers[element].ChangeMod(mod)
def CheckPlayerStats(): """Checks tiredness and motivation of current player. If the player is very tired, this will affect his/her motivation. When the player's motivation is extremely low, the game offers to share motivation between players, while 1 point is going to be lost. Should this not be successful, game will quit.""" currPl = GameStats.GetCurrentPlayer() currMod = currPl.GetMod(MOD.CURRMOD) if currMod[0] == 1: # low mod is motivation if len(GameStats.GetListPlayers()) == 1: # just one player, sharing not possible gui.textScreen.TypeWrite(GameMsg.UNMOT[0]) # Pause? else: nextPl = GameStats.GetNextPlayer() gui.textScreen.NameWrite(currPl) gui.textScreen.TypeWrite(GameMsg.UNMOT[0]) # Pause? gui.textScreen.NameWrite(nextPl) gui.textScreen.TypeWrite(GameMsg.UNMOT[1]) gui.textScreen.NameWrite(currPl) gui.textScreen.TypeWrite(GameMsg.UNMOT[2]) gui.textScreen.NameWrite(currPl) gui.textScreen.TypeWrite(GameMsg.UNMOT[3] + GameMsg.ACTIONP) # Share Mot? resp = gui.inputScreen.getNumber() if resp == 1: # shares motivation with UNMOT player. nextPlMot = int(nextPl.GetMod(MOD.CURRMOD)[0] / 2) nextPl.ChangeMod([-nextPlMot, 0]) currPl.ChangeMod([nextPlMot - 1, 0]) else: pass elif currMod[1] == 1: # low mod is tiredness gui.textScreen.NameWrite(currPl) gui.textScreen.TypeWrite(GameMsg.TIRED) currPl.ChangeMod([-1, 0]) # reduce motivation by 1 each round else: pass
def spotRoom(plAction): """Player has entered a 3-digit number which could be a spot/room. function checks for rooms, whether reachable, and if so transfers players to this room, executing its OnEnter() method. Same goes for spots.""" # init variables currentRoom = GameStats.GetCurrentRoom() currentPlayer = GameStats.GetCurrentPlayer() listPlayers = GameStats.GetListPlayers() activeSpot = currentPlayer.GetPos() spotObj = currentRoom.CheckInReach(plAction, REACH.SPOT) roomObj = currentRoom.CheckInReach(plAction, REACH.ROOM) # Logic if plAction == currentRoom.number: gui.textScreen.TypeWrite(currentRoom.description) # only show description if specifically asked elif spotObj: # player enters a valid spot if not activeSpot.number == plAction: activeSpot.OnLeave() if currentRoom.CheckInReach(plAction, REACH.SPOT): # check again whether targeted spot is still in list currentRoom.ModifyRooms(plAction) # Check if a connected room gets modified currentPlayer.SetPos(spotObj) currentPlayer.GetPos().OnEnter() else: notReachable(activeSpot, plAction) activeSpot.OnEnter() # fallback to current spot elif roomObj: # player enters a valid room GameStats.SetCurrentRoom(roomObj) # player selected another room, set and update for player in listPlayers: # players leave current spot/currentRoom player.GetPos().OnLeave() player.SetPos(roomObj) roomObj.OnEnter() else: # player selected a spot/currentRoom that is not within reach notReachable(currentRoom, plAction)
def newGame(cls, gui): """This method initializes the game with predefined values. Acts like a setter for the player list.""" startRoom = 100 gui.audioStream.play(110) # Main Theme GameStats.SetCurrentRoom(Room(startRoom)) # Setup Player list (static Class) gui.textScreen.Clear() gui.textScreen.LineWrite("\n") gui.textScreen.TitleWriteCentered("Der Winter naht") gui.textScreen.LineWrite("\n") gui.textScreen.TypeWrite(GameMsg.WELCOME) resp = gui.inputScreen.getNumber() if resp < 1: resp = 1 if resp > 4: resp = 4 gui.textScreen.TypeWrite("\nOk, %d Spieler.\n" % resp) for player in range(1, resp + 1): gui.textScreen.Clear() gui.textScreen.LineWrite("\n") gui.textScreen.TitleWriteCentered("Der Winter naht") # Get player name gui.textScreen.TypeWrite("Spieler %d, wie lautet Dein Name? " % player) playerName = gui.inputScreen.getInput() gui.textScreen.TypeWrite(playerName) # Get player color gui.textScreen.TypeWrite(GameMsg.ASKCLR) gui.textScreen.ChooseColor() colorId = gui.inputScreen.getNumber() if colorId in GUICONSTS.DICTPLAYERCOLORS: playerColor = GUICONSTS.DICTPLAYERCOLORS[colorId] else: # player didn't select a valid color gui.textScreen.TypeWrite(GameMsg.CLRNOTSET) playerColor = GUICONSTS.DICTPLAYERCOLORS[player] # Get player's motivation and tiredness gui.textScreen.TypeWrite(GameMsg.MODBEFOREGAMESTART) gui.textScreen.TypeWrite(GameMsg.GETMOT) playerMot = RandomMod.rndm_PlayerInput(gui.inputScreen.getNumber()) gui.textScreen.TypeWrite(GameMsg.GETTIR) playerTir = RandomMod.rndm_PlayerInput(gui.inputScreen.getNumber()) playerList = GameStats.GetListPlayers() # Modify player list playerList.append( Player(playerName, playerColor, [playerMot, playerTir], GameStats.GetCurrentRoom())) GameStats.SetListPlayers(playerList) gui.textScreen.Clear() gui.textScreen.LineWrite("\n") gui.textScreen.TitleWriteCentered("Der Winter naht") for player in GameStats.GetListPlayers(): gui.textScreen.NameWrite(player) gui.textScreen.TypeWrite(", ") gui.textScreen.TypeWrite("\n\n\n" + dictTexts[1]) # generate start items in inventory Item(10) # first item: Smartphone gui.textScreen.TypeWrite(GameMsg.LOADING)
def newRound(): GameStats.GetCurrentRoom().ReloadRoom() GameStats.NextPlayer() currentPlayer = GameStats.GetCurrentPlayer() currentPlayer.UpdateLastMod() # set lastMod = Mod for vanishing "modchange" indicators gui.textScreen.NameWrite(currentPlayer) gui.textScreen.TypeWrite(GameMsg.TURN[0] \ + str(currentPlayer.GetPos().number) \ + GameMsg.TURN[1])
def itemUse(generateFromNr): """Generates the item connected to the spot, if any""" # 2-digit dictInventory = GameStats.GetInventory() if generateFromNr in dictInventory: dictInventory[generateFromNr].UseItem() else: gui.textScreen.TypeWrite(GameMsg.NOT_INV)
def itemSpot(generateFromNr): """Item has been combined with a spot. Function checks if any item yield or action can be found in the corresponding dicts and performs the actions therein. The cases are mostly to catch undefined behavior.""" # 5-digit # init variables item = int(generateFromNr / 1000) spot = generateFromNr % 1000 dictInventory = GameStats.GetInventory() currentRoom = GameStats.GetCurrentRoom() spotObj = currentRoom.CheckInReach(spot, REACH.SPOT) # Logic if spotObj: if item in dictInventory: if generateFromNr in dictSpotItems: # generate item for element in range(0, len(dictSpotItems[generateFromNr])): newItemNr = dictSpotItems[generateFromNr][element] newItem = Item(newItemNr) gui.textScreen.TypeWrite(GameMsg.SUCCESS_GET + \ str(newItem.number) + \ ": " + newItem.name + "\n") dictInventory[item].DelItem() # delete old item elif generateFromNr in dictAction: gui.textScreen.TypeWrite(dictAction[generateFromNr]) currentRoom.ModifySpots(generateFromNr, EXCHANGEDIR.FORWARD) if generateFromNr in dictMods: GameStats.GetCurrentPlayer().ChangeMod(dictMods[generateFromNr]) dictInventory[item].DelItem() currentRoom.ModifyRooms(generateFromNr) # Check if a connected room gets modified else: # generate game progress only if generateFromNr in dictTexts: gui.textScreen.TypeWrite(dictTexts[generateFromNr]) dictInventory[item].DelItem() # delete old item else: gui.textScreen.TypeWrite(GameMsg.CANT_CMB) else: gui.textScreen.TypeWrite(GameMsg.NOT_INV) else: gui.textScreen.TypeWrite(GameMsg.NOT_IN_REACH)
def actionHandler(generateFromNr): """Arbitrator, deciding which handling function to be called.""" nrOfDigits = len(str(generateFromNr)) if generateFromNr == CMDINPUT.QUIT: #save and quit game gui.textScreen.TypeWrite(GameMsg.SVQT) GameStats.Quit(gui) elif generateFromNr == CMDINPUT.NO: gui.textScreen.TypeWrite(GameMsg.UNKNOWN_CMD) elif generateFromNr == CMDINPUT.YES: gui.textScreen.TypeWrite(GameMsg.UNKNOWN_CMD) elif nrOfDigits == 2: itemUse(generateFromNr) elif nrOfDigits == 3: spotRoom(generateFromNr) elif nrOfDigits == 4: itemItem(generateFromNr) elif nrOfDigits == 5: # CHEAT CHEAT CHEAT CHEAT CHEAT if generateFromNr == 32167: # Dev cheat to get all items in game print("Cheat active: Get All Items") inv = GameStats.GetInventory() for element in dictItems: if element not in inv: Item(element) elif generateFromNr // 1000 == 28: # Dev cheat to get to any room in game print("Cheat active: Go To Any Room") listPlayers = GameStats.GetListPlayers() for player in listPlayers: # players leave current spot/currentRoom player.GetPos().OnLeave() GameStats.SetCurrentRoom(Room(generateFromNr % 1000)) # player selected another room, set and update currentRoom = GameStats.GetCurrentRoom() for player in listPlayers: # players enter new currentRoom player.SetPos(currentRoom) currentRoom.OnEnter() # CHEAT CHEAT CHEAT CHEAT CHEAT else: itemSpot(generateFromNr) else: gui.textScreen.TypeWrite(GameMsg.UNKNOWN_CMD)
def OnLeave(self): """Checks dict if there's an action to be performed on exit of a spot""" if self.number in dictSpotChange: # if it can be found in the keys listPlayers = GameStats.GetListPlayers() playersOnSpot = 0 for element in listPlayers: if element.GetPos().number == self.number: playersOnSpot += 1 if playersOnSpot <= 1: self.__room.ModifySpots(self.number, EXCHANGEDIR.REVERT) else: # as at least 1 player still is on the spot, # it cannot be changed back yet. pass
def playerAction_Selector(): """This function checks the player's wish and, if valid, tries to match it to an existing object.""" plAction = gui.inputScreen.getNumber() gui.textScreen.TypeWrite(str(plAction) + "\n") if plAction == CMDINPUT.UNKNOWN: # unknown command gui.textScreen.TypeWrite(GameMsg.NAN) elif plAction == CMDINPUT.QUIT: # player wants to quit gui.textScreen.TypeWrite(GameMsg.SVQT) GameStats.Quit(gui) else: actionHandler(plAction)
def ChangeMod(self, valueList): maxMod = [10, 10] self.__lastMod = copy.copy(self.__mod) # list is mutable so "=" will not work for i in range(0, len(self.__mod)): self.__mod[i] = self.__mod[i] + valueList[i] if self.__mod[i] > maxMod[i]: self.__mod[i] = maxMod[i] elif self.__mod[i] <= 1: self.__mod[i] = 1 # show mod update gui.textScreen.NameWrite(self) gui.textScreen.TypeWrite(GameMsg.CHMOD[0] + str(valueList[0]) \ + GameMsg.CHMOD[1] + str(valueList[1]) + "\n") gui.statsScreen.Update(GameStats.GetListPlayers()) # check for "gameover" criterium Motivation if self.__mod[0] <= 1: # motivation is v ery low if self.__gameOverWarn == True: # player has been warned and is still unmotivated: end game! gui.textScreen.TypeWrite(GameMsg.UNMOT_END) gui.textScreen.TypeWrite(GameMsg.SVQT) GameStats.Quit(gui) self.__gameOverWarn = True else: self.__gameOverWarn = False
def checkLooseItem(triggerNumber): """Checks whether a spot, room or other trigger that has an 'OnEnter()' method makes players loose items from their inventory. Takes the trigger's number, checks the corresponding dict and then deletes items listed""" if triggerNumber in dictItemDelete: listDeleteItems = dictItemDelete[triggerNumber] dictInventory = GameStats.GetInventory() for item in listDeleteItems: if item in dictInventory: itemToDel = dictInventory[item] itemToDel.SetType(MOD.NOTUSABLE) gui.textScreen.TypeWrite(GameMsg.LOOSE + str(itemToDel.number) \ + ": " + itemToDel.name + "\n") itemToDel.DelItem()
def main(): resp = 3 while resp > 1: TitleScreens.printTitleMenu(gui) resp = gui.inputScreen.getNumber() if resp == 0: # continue game try: gui.textScreen.TypeWrite(GameMsg.LOAD) timeDiff = GameStats.Load() gui.inventoryScreen.Update(GameStats.GetInventory()) gui.statsScreen.Update(GameStats.GetListPlayers()) gui.textScreen.TypeWrite(GameMsg.SUCCESS) motBuff = RandomMod.rndm_BufRestart(timeDiff) invokeChangeMod([motBuff, 0], MOD.EFFALL) except: gui.textScreen.TypeWrite(GameMsg.NO_SVGAME) TitleScreens.newGame(gui) elif resp == 1: # new game gui.textScreen.TypeWrite(GameMsg.ASKOVWR) gui.textScreen.TypeWrite(GameMsg.ACTIONP) resp = gui.inputScreen.getNumber() if resp == 1: # ask if savegame file shall be overwritten TitleScreens.newGame(gui) gui.inventoryScreen.Update(GameStats.GetInventory()) gui.statsScreen.Update(GameStats.GetListPlayers()) else: gui.textScreen.TypeWrite(GameMsg.NOTOVWR) resp = 3 # to automatically resume game. elif resp == 2: # tutorial TitleScreens.playTutorial(gui) elif resp == 3: # credits TitleScreens.playCredits(gui) else: gui.textScreen.TypeWrite(GameMsg.QUIT) GameStats.Quit(gui) # gui preparation GameStats.GetCurrentRoom().OnEnter() while True: CheckPlayerStats() newRound() # update currentRoom if necessary and call player's interaction function playerAction_Selector() gui.textScreen.TypeWrite(GameMsg.LOADING) GameStats.Save()
def __init__(self, number): """Initiates the item and its properties. Properties are number, description, name, Item_type (see enum) and modificators.""" # construct item self.number = number self.description = dictTexts[number] self.name = dictItems[number] self.__type = MOD.NOTUSABLE self.__mod = None if number in dictModType: self.__type = dictModType[number] if number in dictAction: self.__action = dictAction[number] if number in dictMods: self.__mod = dictMods[number] # add to yielded items gui.inventoryScreen.Update(GameStats.AddToInventory(self))
def itemItem(generateFromNr): """Combine two items to one. The original items are deleted when complete.""" # 4-digit # init variables dictInventory = GameStats.GetInventory() item1 = int(generateFromNr / 100) item2 = generateFromNr % 100 # Logic if (item1 in dictInventory) & (item2 in dictInventory): # only add items if both are available in inventory if generateFromNr in dictSpotItems: for element in dictSpotItems[generateFromNr]: Item(element) gui.textScreen.TypeWrite(GameMsg.SUCCESS_GET + str(element) \ + ": " + dictInventory[element].name + "\n") # original items deleted on combination dictInventory[item1].DelItem() dictInventory[item2].DelItem() else: gui.textScreen.TypeWrite(GameMsg.CANT_CMB) else: gui.textScreen.TypeWrite(GameMsg.NOT_INV)
def __init__(self, playSplash): tk.Tk.__init__(self) self.withdraw() self.playSplash = playSplash screenSize = [int(self.winfo_screenwidth()), int(self.winfo_screenheight())] GUICONSTS.setGameGuiSize(screenSize) # Display splash video if self.playSplash: splash = Splash(screenSize) # call splash "loading" image # Setup main window and widgets self.title("Der Winter Naht") self.protocol("WM_DELETE_WINDOW", lambda arg=self: GameStats.Quit(arg)) # lambda needed as protocol does not take arguments # Canvas myframe = tk.Frame(self) myframe.pack(fill=tk.BOTH, expand=tk.YES) canvas = ResizingCanvas(myframe, width=GUICONSTS.screenWidth, height=GUICONSTS.screenHeight, bg="black") canvas.pack(fill=tk.BOTH, expand=tk.YES) # Frames textScrFr = tk.Frame(canvas, bg=GUICONSTS.FRAMECOLOR, bd=GUICONSTS.FRAMEBORDER) invtScrFr = tk.Frame(canvas, bg=GUICONSTS.FRAMECOLOR, bd=GUICONSTS.FRAMEBORDER) statsScrFr = tk.Frame(canvas, bg=GUICONSTS.FRAMECOLOR, bd=GUICONSTS.FRAMEBORDER) inputScrFr = tk.Frame(canvas, bg=GUICONSTS.FRAMECOLOR, bd=GUICONSTS.FRAMEBORDER) # Frame Pack textScrFr.pack(anchor=tk.W, side=tk.LEFT, fill=tk.BOTH, expand=tk.YES) invtScrFr.pack(anchor=tk.SW, side=tk.TOP, fill=tk.BOTH, expand=tk.YES) statsScrFr.pack(anchor=tk.SW, side=tk.TOP, fill=tk.X, expand=tk.NO) inputScrFr.pack(anchor=tk.SW, side=tk.TOP, fill=tk.X, expand=tk.NO) # Screens self.textScreen = OutputText(textScrFr \ , font=GUICONSTS.GUI_FONT \ , insertontime=0 \ , fg=GUICONSTS.FONTCOLOR \ , bg=GUICONSTS.BGNDCOLOR \ , width=82 \ , height=35 \ , padx=12 \ , pady=9) self.inventoryScreen = InventoryText(invtScrFr \ , font=GUICONSTS.GUI_FONT \ , insertontime=0 \ , bg=GUICONSTS.BGNDCOLOR \ , fg=GUICONSTS.FONTCOLOR \ , width=4 \ , height=10 \ , padx=12 \ , pady=9) self.statsScreen = StatusText(statsScrFr \ , font=GUICONSTS.GUI_FONT \ , insertontime=0 \ , bg=GUICONSTS.BGNDCOLOR \ , fg=GUICONSTS.FONTCOLOR \ , width=40 \ , height=10 \ , padx=12 \ , pady=9) self.inputScreen = InputText(inputScrFr, font=("Lucida Console", "69") \ , insertbackground=GUICONSTS.FONTCOLOR \ , insertofftime=1200 \ , insertontime=1200 \ , insertwidth=5 \ , width=5 \ , height=1 \ , padx=6 \ , bg=GUICONSTS.BGNDCOLOR \ , fg=GUICONSTS.FONTCOLOR \ , pady=43) # Screen Pack self.textScreen.pack(side=tk.LEFT, fill=tk.BOTH, expand=tk.YES) self.inventoryScreen.pack(side=tk.LEFT, fill=tk.BOTH, expand=tk.YES) self.statsScreen.pack(side=tk.LEFT, fill=tk.BOTH, expand=tk.YES) self.inputScreen.pack(side=tk.LEFT, fill=tk.BOTH, expand=tk.YES) self.audioStream = Audio() # finished loading so destroy splash if self.playSplash: splash.destroy() # Show main window self.deiconify()
def DelItem(self): """"Deletes an item by removing it from the inventory dict.""" if self.__type == MOD.PERMANENT: pass # item is permanent else: gui.inventoryScreen.Update(GameStats.DelFromInventory(self.number))