コード例 #1
0
ファイル: events.go プロジェクト: Cristofori/kmud
func (self DeathEvent) ToString(receiver EventReceiver) string {
	if receiver == self.Character {
		return types.Colorize(types.ColorRed, ">> You have died")
	}

	return types.Colorize(types.ColorRed, fmt.Sprintf(">> %s has died", self.Character.GetName()))
}
コード例 #2
0
ファイル: events.go プロジェクト: Cristofori/kmud
// CombatStop
func (self CombatStopEvent) ToString(receiver EventReceiver) string {
	if receiver == self.Attacker {
		return types.Colorize(types.ColorGreen, fmt.Sprintf("You stopped attacking %s", self.Defender.GetName()))
	} else if receiver == self.Defender {
		return types.Colorize(types.ColorGreen, fmt.Sprintf("%s has stopped attacking you", self.Attacker.GetName()))
	}

	return ""
}
コード例 #3
0
ファイル: events.go プロジェクト: Cristofori/kmud
// CombatStart
func (self CombatStartEvent) ToString(receiver EventReceiver) string {
	if receiver == self.Attacker {
		return types.Colorize(types.ColorRed, fmt.Sprintf("You are attacking %s!", self.Defender.GetName()))
	} else if receiver == self.Defender {
		return types.Colorize(types.ColorRed, fmt.Sprintf("%s is attacking you!", self.Attacker.GetName()))
	}

	return ""
}
コード例 #4
0
ファイル: events.go プロジェクト: Cristofori/kmud
// Tell
func (self TellEvent) ToString(receiver EventReceiver) string {
	if receiver == self.To {
		return types.Colorize(types.ColorMagenta,
			fmt.Sprintf("Message from %s: %s", self.From.GetName(), types.Colorize(types.ColorWhite, self.Message)))
	} else {
		return types.Colorize(types.ColorMagenta,
			fmt.Sprintf("Message to %s: %s", self.To.GetName(), types.Colorize(types.ColorWhite, self.Message)))
	}
}
コード例 #5
0
ファイル: events.go プロジェクト: Cristofori/kmud
func (self LockEvent) ToString(receiver EventReceiver) string {
	status := "unlocked"
	if self.Locked {
		status = "locked"
	}

	return types.Colorize(types.ColorBlue,
		fmt.Sprintf("The exit to the %s has been %s", self.Exit.ToString(),
			types.Colorize(types.ColorWhite, status)))
}
コード例 #6
0
ファイル: character.go プロジェクト: Cristofori/kmud
func (self *Npc) PrettyConversation() string {
	conv := self.GetConversation()

	if conv == "" {
		return fmt.Sprintf("%s has nothing to say", self.GetName())
	}

	return fmt.Sprintf("%s%s",
		types.Colorize(types.ColorBlue, self.GetName()),
		types.Colorize(types.ColorWhite, ": "+conv))
}
コード例 #7
0
ファイル: menu.go プロジェクト: Cristofori/kmud
func (self *Menu) Print(comm types.Communicable, page int, filter string) int {
	border := types.Colorize(types.ColorWhite, "-=-=-")
	title := types.Colorize(types.ColorBlue, self.title)
	header := fmt.Sprintf("%s %s %s", border, title, border)

	if filter != "" {
		header = fmt.Sprintf("%s (/%s)", header, filter)
	}

	comm.WriteLine(header)

	options := make([]string, len(self.actions))

	for i, action := range self.actions {
		index := strings.Index(strings.ToLower(action.text), action.key)

		actionText := ""

		if index == -1 {
			actionText = fmt.Sprintf("%s[%s%s%s]%s%s",
				types.ColorDarkBlue,
				types.ColorBlue,
				strings.ToUpper(action.key),
				types.ColorDarkBlue,
				types.ColorWhite,
				action.text)
		} else {
			keyLength := len(action.key)
			actionText = fmt.Sprintf("%s%s[%s%s%s]%s%s",
				action.text[:index],
				types.ColorDarkBlue,
				types.ColorBlue,
				action.text[index:index+keyLength],
				types.ColorDarkBlue,
				types.ColorWhite,
				action.text[index+keyLength:])
		}

		options[i] = fmt.Sprintf("  %s", actionText)
	}

	options = Filter(options, filter)

	width, height := comm.GetWindowSize()
	pages := Paginate(options, width, height/2)

	if len(options) == 0 && filter != "" {
		comm.WriteLine("No items match your search")
	} else {
		comm.Write(pages[page])
	}

	return len(pages)
}
コード例 #8
0
ファイル: events.go プロジェクト: Cristofori/kmud
// Say
func (self SayEvent) ToString(receiver EventReceiver) string {
	who := ""
	if receiver == self.Character {
		who = "You say"
	} else {
		who = self.Character.GetName() + " says"
	}

	return types.Colorize(types.ColorBlue, who+", ") +
		types.Colorize(types.ColorWhite, "\""+self.Message+"\"")
}
コード例 #9
0
ファイル: menu.go プロジェクト: Cristofori/kmud
func ExecMenu(title string, comm types.Communicable, build func(*Menu)) {
	pageIndex := 0
	pageCount := 1
	filter := ""

	for {
		var menu Menu
		menu.title = title
		build(&menu)

		pageIndex = Bound(pageIndex, 0, pageCount-1)
		pageCount = menu.Print(comm, pageIndex, filter)
		filter = ""

		prompt := ""
		if pageCount > 1 {
			prompt = fmt.Sprintf("Page %v of %v (<, >, <<, >>)\r\n> ", pageIndex+1, pageCount)
		} else {
			prompt = "> "
		}

		input := comm.GetInput(types.Colorize(types.ColorWhite, prompt))

		if input == "" {
			if menu.exitHandler != nil {
				menu.exitHandler()
			}
			return
		}

		if input == ">" {
			pageIndex++
		} else if input == "<" {
			pageIndex--
		} else if input == ">>" {
			pageIndex = pageCount - 1
		} else if input == "<<" {
			pageIndex = 0
		} else if input[0] == '/' {
			filter = input[1:]
		} else {
			action := menu.getAction(input)

			if action.handler != nil {
				if !action.handler() {
					return
				}
			} else if input != "?" && input != "help" {
				comm.WriteLine(types.Colorize(types.ColorRed, "Invalid selection"))
			}
		}
	}
}
コード例 #10
0
ファイル: events.go プロジェクト: Cristofori/kmud
// Combat
func (self CombatEvent) ToString(receiver EventReceiver) string {
	skillMsg := ""
	if self.Skill != nil {
		skillMsg = fmt.Sprintf(" with %s", self.Skill.GetName())
	}

	if receiver == self.Attacker {
		return types.Colorize(types.ColorRed, fmt.Sprintf("You hit %s%s for %v damage", self.Defender.GetName(), skillMsg, self.Power))
	} else if receiver == self.Defender {
		return types.Colorize(types.ColorRed, fmt.Sprintf("%s hits you%s for %v damage", self.Attacker.GetName(), skillMsg, self.Power))
	}

	return ""
}
コード例 #11
0
ファイル: mapbuilder.go プロジェクト: Cristofori/kmud
func (self *mapBuilder) toString() string {
	str := ""

	for z := 0; z < self.depth; z++ {
		var rows []string
		for y := 0; y < self.height; y++ {
			row := ""
			for x := 0; x < self.width; x++ {
				tile := self.data[z][y][x].toString()
				row = row + tile
			}
			rows = append(rows, row)
		}

		rows = utils.TrimLowerRows(rows)

		if self.depth > 1 {
			divider := types.Colorize(types.ColorWhite, "================================================================================\r\n")
			rows = append(rows, divider)
		}

		for _, row := range rows {
			str = str + row + "\r\n"
		}
	}

	return str
}
コード例 #12
0
ファイル: mapbuilder.go プロジェクト: Cristofori/kmud
func (self *mapTile) toString() string {
	if self.char == ' ' {
		return string(self.char)
	}

	return types.Colorize(self.color, string(self.char))
}
コード例 #13
0
ファイル: utils.go プロジェクト: Cristofori/kmud
func DirectionToExitString(direction types.Direction) string {
	letterColor := types.ColorBlue
	bracketColor := types.ColorDarkBlue
	textColor := types.ColorWhite

	colorize := func(letters string, text string) string {
		return fmt.Sprintf("%s%s%s%s",
			types.Colorize(bracketColor, "["),
			types.Colorize(letterColor, letters),
			types.Colorize(bracketColor, "]"),
			types.Colorize(textColor, text))
	}

	switch direction {
	case types.DirectionNorth:
		return colorize("N", "orth")
	case types.DirectionNorthEast:
		return colorize("NE", "North East")
	case types.DirectionEast:
		return colorize("E", "ast")
	case types.DirectionSouthEast:
		return colorize("SE", "South East")
	case types.DirectionSouth:
		return colorize("S", "outh")
	case types.DirectionSouthWest:
		return colorize("SW", "South West")
	case types.DirectionWest:
		return colorize("W", "est")
	case types.DirectionNorthWest:
		return colorize("NW", "North West")
	case types.DirectionUp:
		return colorize("U", "p")
	case types.DirectionDown:
		return colorize("D", "own")
	case types.DirectionNone:
		return types.Colorize(types.ColorWhite, "None")
	}

	panic("Unexpected code path")
}
コード例 #14
0
ファイル: session.go プロジェクト: Cristofori/kmud
func (self *Session) GetPrompt() string {
	prompt := self.prompt
	prompt = strings.Replace(prompt, "%h", strconv.Itoa(self.pc.GetHitPoints()), -1)
	prompt = strings.Replace(prompt, "%H", strconv.Itoa(self.pc.GetHealth()), -1)

	if len(self.states) > 0 {
		states := make([]string, len(self.states))

		i := 0
		for key, value := range self.states {
			states[i] = fmt.Sprintf("%s:%s", key, value)
			i++
		}

		prompt = fmt.Sprintf("%s %s", states, prompt)
	}

	return types.Colorize(types.ColorWhite, prompt)
}
コード例 #15
0
ファイル: commands.go プロジェクト: Cristofori/kmud
func toggleExitMenu(s *Session) {
	onOrOff := func(direction types.Direction) string {
		text := "Off"
		if s.GetRoom().HasExit(direction) {
			text = "On"
		}
		return types.Colorize(types.ColorBlue, text)
	}

	toggleExit := func(direction types.Direction) func() bool {
		return func() bool {
			room := s.GetRoom()

			enable := !room.HasExit(direction)
			room.SetExitEnabled(direction, enable)

			loc := room.NextLocation(direction)
			otherRoom := model.GetRoomByLocation(loc, room.GetZoneId())
			if otherRoom != nil {
				otherRoom.SetExitEnabled(direction.Opposite(), enable)
			}
			return false
		}
	}

	utils.ExecMenu("Edit Exits", s, func(menu *utils.Menu) {
		menu.AddAction("n", "North: "+onOrOff(types.DirectionNorth), toggleExit(types.DirectionNorth))
		menu.AddAction("ne", "North East: "+onOrOff(types.DirectionNorthEast), toggleExit(types.DirectionNorthEast))
		menu.AddAction("e", "East: "+onOrOff(types.DirectionEast), toggleExit(types.DirectionEast))
		menu.AddAction("se", "South East: "+onOrOff(types.DirectionSouthEast), toggleExit(types.DirectionSouthEast))
		menu.AddAction("s", "South: "+onOrOff(types.DirectionSouth), toggleExit(types.DirectionSouth))
		menu.AddAction("sw", "South West: "+onOrOff(types.DirectionSouthWest), toggleExit(types.DirectionSouthWest))
		menu.AddAction("w", "West: "+onOrOff(types.DirectionWest), toggleExit(types.DirectionWest))
		menu.AddAction("nw", "North West: "+onOrOff(types.DirectionNorthWest), toggleExit(types.DirectionNorthWest))
		menu.AddAction("u", "Up: "+onOrOff(types.DirectionUp), toggleExit(types.DirectionUp))
		menu.AddAction("d", "Down: "+onOrOff(types.DirectionDown), toggleExit(types.DirectionDown))
	})
}
コード例 #16
0
ファイル: commands.go プロジェクト: Cristofori/kmud
func init() {
	commands = map[string]*command{
		"help": {
			usage: "/help <command name>",
			exec: func(self *command, s *Session, arg string) {
				if arg == "" {
					s.WriteLine("List of commands:")
					var names []string
					for name, command := range commands {
						if command.alias == "" {
							names = append(names, name)
						}
					}
					sort.Strings(names)
					width, height := s.user.GetWindowSize()

					pages := utils.Paginate(names, width, height/2)

					for _, page := range pages {
						s.WriteLine(page)
					}
				} else {
					command, found := commands[arg]
					if found {
						command.Usage(s)
					} else {
						s.printError("Command not found")
					}
				}
			},
		},
		"store": {
			admin: true,
			exec: func(self *command, s *Session, arg string) {
				utils.ExecMenu("Store", s, func(menu *utils.Menu) {
					store := model.StoreIn(s.pc.GetRoomId())

					if store != nil {
						menu.AddAction("r", "Rename", func() bool {
							name := s.getCleanUserInput("New name: ")
							if name != "" {
								store.SetName("Name")
							}
							return true
						})
						menu.AddAction("d", "Delete", func() bool {
							model.DeleteStore(store.GetId())
							return true
						})
					} else {
						menu.AddAction("n", "New Store", func() bool {
							name := s.getCleanUserInput("Store name: ")
							if name != "" {
								model.CreateStore(name, s.pc.GetRoomId())
							}
							return true
						})
					}
				})
			},
		},
		"loc": cAlias("location"),
		"location": {
			admin: false,
			exec: func(self *command, s *Session, arg string) {
				s.WriteLine("%v", s.GetRoom().GetLocation())
			},
		},
		"room": {
			admin: true,
			exec: func(self *command, s *Session, arg string) {
				utils.ExecMenu(
					"Room", s,
					func(menu *utils.Menu) {
						menu.AddAction("t", fmt.Sprintf("Title - %s", s.GetRoom().GetTitle()), func() bool {
							title := s.getRawUserInput("Enter new title: ")
							if title != "" {
								s.GetRoom().SetTitle(title)
							}
							return true
						})

						menu.AddAction("d", "Description", func() bool {
							description := s.getRawUserInput("Enter new description: ")
							if description != "" {
								s.GetRoom().SetDescription(description)
							}
							return true
						})

						menu.AddAction("e", "Exits", func() bool {
							toggleExitMenu(s)
							return true
						})

						areaId := s.GetRoom().GetAreaId()
						areaName := "(None)"
						if areaId != nil {
							area := model.GetArea(areaId)
							areaName = area.GetName()
						}

						menu.AddAction("a", fmt.Sprintf("Area - %s", areaName), func() bool {
							utils.ExecMenu("Change Area", s, func(menu *utils.Menu) {
								menu.AddAction("n", "None", func() bool {
									s.GetRoom().SetAreaId(nil)
									return true
								})

								for i, area := range model.GetAreas(s.currentZone()) {
									actionText := area.GetName()
									if area.GetId() == s.GetRoom().GetAreaId() {
										actionText += "*"
									}

									a := area
									menu.AddActionI(i, actionText, func() bool {
										s.GetRoom().SetAreaId(a.GetId())
										return true
									})
								}
							})
							return true
						})
					})

				s.PrintRoom()
			},
		},
		"map": {
			admin: false,
			exec: func(self *command, s *Session, arg string) {
				zoneRooms := model.GetRoomsInZone(s.currentZone().GetId())
				roomsByLocation := map[types.Coordinate]types.Room{}

				for _, room := range zoneRooms {
					roomsByLocation[room.GetLocation()] = room
				}

				width, height := s.user.GetWindowSize()
				height /= 2
				width /= 2

				// width and height need to be odd numbers so that we keep the current location centered
				// and we don't go off the edge of the available space
				width += (width % 2) - 1
				height += (height % 2) - 1

				builder := newMapBuilder(width, height, 1)
				builder.setUserRoom(s.GetRoom())
				center := s.GetRoom().GetLocation()

				startX := center.X - (width / 2)
				endX := center.X + (width / 2)
				startY := center.Y - (height / 2)
				endY := center.Y + (height / 2)

				for y := startY; y <= endY; y++ {
					for x := startX; x <= endX; x++ {
						loc := types.Coordinate{X: x, Y: y, Z: center.Z}
						room := roomsByLocation[loc]

						if room != nil {
							// Translate to 0-based coordinates
							builder.addRoom(room, x-startX, y-startY, 0)
						}
					}
				}

				s.WriteLine(utils.TrimEmptyRows(builder.toString()))
			},
		},
		"zone": {
			admin: true,
			usage: "/zone [list|rename <name>|new <name>|delete <name>]",
			exec: func(self *command, s *Session, arg string) {
				subcommand, arg := utils.Argify(arg)
				if subcommand == "" {
					s.WriteLine("Current zone: " + types.Colorize(types.ColorBlue, s.currentZone().GetName()))
				} else if subcommand == "list" {
					s.WriteLineColor(types.ColorBlue, "Zones")
					s.WriteLineColor(types.ColorBlue, "-----")
					for _, zone := range model.GetZones() {
						s.WriteLine(zone.GetName())
					}
				} else if arg != "" {
					if subcommand == "rename" {
						zone := model.GetZoneByName(arg)

						if zone != nil {
							s.printError("A zone with that name already exists")
							return
						}

						s.currentZone().SetName(arg)
					} else if subcommand == "new" {
						newZone, err := model.CreateZone(arg)

						if err != nil {
							s.printError(err.Error())
							return
						}

						newRoom, err := model.CreateRoom(newZone, types.Coordinate{X: 0, Y: 0, Z: 0})
						utils.HandleError(err)

						model.MoveCharacterToRoom(s.pc, newRoom)

						s.PrintRoom()
					} else if subcommand == "delete" {
						zone := model.GetZoneByName(arg)

						if zone != nil {
							if zone == s.currentZone() {
								s.printError("You can't delete the zone you are in")
							} else {
								model.DeleteZone(zone.GetId())
								s.WriteLine("Zone deleted")
							}
						} else {
							s.printError("Zone not found")
						}
					} else {
						self.Usage(s)
					}
				} else {
					self.Usage(s)
				}
			},
		},
		"b": cAlias("broadcast"),
		"broadcast": {
			admin: false,
			exec: func(self *command, s *Session, arg string) {
				if arg == "" {
					s.printError("Nothing to say")
				} else {
					model.BroadcastMessage(s.pc, arg)
				}
			},
		},
		"s": cAlias("say"),
		"say": {
			admin: false,
			exec: func(self *command, s *Session, arg string) {
				if arg == "" {
					s.printError("Nothing to say")
				} else {
					model.Say(s.pc, arg)
				}
			},
		},
		"me": {
			admin: false,
			exec: func(self *command, s *Session, arg string) {
				model.Emote(s.pc, arg)
			},
		},
		"w":    cAlias("whisper"),
		"tell": cAlias("whisper"),
		"whisper": {
			admin: false,
			usage: "/whisper <player> <message>",
			exec:  whisper,
		},
		"tp": cAlias("teleport"),
		"teleport": {
			admin: true,
			usage: "/teleport [<zone>|<X> <Y> <Z>]",
			exec: func(self *command, s *Session, arg string) {
				newZone := model.GetZoneByName(arg)
				var newRoom types.Room

				if newZone != nil {
					if newZone.GetId() == s.GetRoom().GetZoneId() {
						s.WriteLine("You're already in that zone")
					} else {
						zoneRooms := model.GetRoomsInZone(newZone.GetId())
						if len(zoneRooms) > 0 {
							newRoom = zoneRooms[0]
						}
					}
				} else {
					coords, err := utils.Atois(strings.Fields(arg))

					var x, y, z int

					if len(coords) != 3 || err != nil {
						s.printError("Zone not found: %s", arg)
						self.Usage(s)
					} else {
						x, y, z = coords[0], coords[1], coords[2]
					}

					newRoom = model.GetRoomByLocation(types.Coordinate{X: x, Y: y, Z: z}, s.currentZone().GetId())

					if newRoom == nil {
						s.printError("Invalid coordinates")
					}
				}

				if newRoom != nil {
					model.MoveCharacterToRoom(s.pc, newRoom)
					s.PrintRoom()
				}
			},
		},
		"who": {
			admin: false,
			exec: func(self *command, s *Session, arg string) {
				chars := model.GetOnlinePlayerCharacters()

				s.WriteLine("")
				s.WriteLine("Online Players")
				s.WriteLine("--------------")

				for _, char := range chars {
					s.WriteLine(char.GetName())
				}
				s.WriteLine("")
			},
		},
		"colors": {
			admin: false,
			exec: func(self *command, s *Session, arg string) {
				s.WriteLineColor(types.ColorNormal, "Normal")
				s.WriteLineColor(types.ColorRed, "Red")
				s.WriteLineColor(types.ColorDarkRed, "Dark Red")
				s.WriteLineColor(types.ColorGreen, "Green")
				s.WriteLineColor(types.ColorDarkGreen, "Dark Green")
				s.WriteLineColor(types.ColorBlue, "Blue")
				s.WriteLineColor(types.ColorDarkBlue, "Dark Blue")
				s.WriteLineColor(types.ColorYellow, "Yellow")
				s.WriteLineColor(types.ColorDarkYellow, "Dark Yellow")
				s.WriteLineColor(types.ColorMagenta, "Magenta")
				s.WriteLineColor(types.ColorDarkMagenta, "Dark Magenta")
				s.WriteLineColor(types.ColorCyan, "Cyan")
				s.WriteLineColor(types.ColorDarkCyan, "Dark Cyan")
				s.WriteLineColor(types.ColorBlack, "Black")
				s.WriteLineColor(types.ColorWhite, "White")
				s.WriteLineColor(types.ColorGray, "Gray")
			},
		},
		"cm": cAlias("colormode"),
		"colormode": {
			admin: false,
			exec: func(self *command, s *Session, arg string) {
				if arg == "" {
					message := "Current color mode is: "
					switch s.user.GetColorMode() {
					case types.ColorModeNone:
						message = message + "None"
					case types.ColorModeLight:
						message = message + "Light"
					case types.ColorModeDark:
						message = message + "Dark"
					}
					s.WriteLine(message)
				} else {
					switch strings.ToLower(arg) {
					case "none":
						s.user.SetColorMode(types.ColorModeNone)
						s.WriteLine("Color mode set to: None")
					case "light":
						s.user.SetColorMode(types.ColorModeLight)
						s.WriteLine("Color mode set to: Light")
					case "dark":
						s.user.SetColorMode(types.ColorModeDark)
						s.WriteLine("Color mode set to: Dark")
					default:
						s.WriteLine("Valid color modes are: None, Light, Dark")
					}
				}
			},
		},
		"dr": cAlias("destroyroom"),
		"destroyroom": {
			admin: true,
			usage: "/destroyroom <direction>",
			exec: func(self *command, s *Session, arg string) {
				if arg == "" {
					self.Usage(s)
				} else {
					direction := types.StringToDirection(arg)

					if direction == types.DirectionNone {
						s.printError("Not a valid direction")
					} else {
						loc := s.GetRoom().NextLocation(direction)
						roomToDelete := model.GetRoomByLocation(loc, s.GetRoom().GetZoneId())
						if roomToDelete != nil {
							model.DeleteRoom(roomToDelete)
							s.WriteLine("Room destroyed")
						} else {
							s.printError("No room in that direction")
						}
					}
				}
			},
		},
		"npc": {
			admin: true,
			exec: func(self *command, s *Session, arg string) {

				utils.ExecMenu("NPCs", s, func(menu *utils.Menu) {
					var npcs types.NPCList
					npcs = model.GetNpcs()

					menu.AddAction("n", "New", func() bool {
						name := getNpcName(s)
						if name != "" {
							model.CreateNpc(name, s.pc.GetRoomId(), nil)
						}
						return true
					})

					for i, npc := range npcs {
						n := npc
						menu.AddActionI(i, npc.GetName(), func() bool {
							specificNpcMenu(s, n)
							return true
						})
					}
				})

				s.PrintRoom()
			},
		},
		"items": {
			admin: true,
			usage: "Usage: /items",
			exec: func(self *command, s *Session, arg string) {
				utils.ExecMenu("Items", s, func(menu *utils.Menu) {
					menu.AddAction("n", "New", func() bool {
						name := s.getRawUserInput("Item name: ")
						if name != "" {
							template := model.CreateTemplate(name)
							templateMenu(s, template)
						}
						return true
					})

					for i, template := range model.GetAllTemplates() {
						t := template
						menu.AddActionI(i, template.GetName(), func() bool {
							templateMenu(s, t)
							return true
						})
					}
				})
			},
		},
		"destroyitem": {
			admin: true,
			usage: "/destroyitem <item name>",
			exec: func(self *command, s *Session, arg string) {
				if arg == "" {
					self.Usage(s)
					return
				} else {
					itemsInRoom := model.ItemsIn(s.GetRoom().GetId())
					name := strings.ToLower(arg)

					for _, item := range itemsInRoom {
						if strings.ToLower(item.GetName()) == name {
							model.DeleteItem(item.GetId())
							s.WriteLine("Item destroyed")
							return
						}
					}

					s.printError("Item not found")
				}
			},
		},
		"roomid": {
			admin: true,
			exec: func(self *command, s *Session, arg string) {
				s.WriteLine("Room ID: %v", s.GetRoom().GetId())
			},
		},
		"cash": {
			admin: true,
			usage: "/cash give <amount>",
			exec: func(self *command, s *Session, arg string) {
				subcommand, arg := utils.Argify(arg)

				if subcommand == "give" {
					amount, err := utils.Atoir(arg, 1, math.MaxInt32)
					if err == nil {
						s.pc.AddCash(amount)
						s.WriteLine("Received: %v monies", amount)
					} else {
						s.printError(err.Error())
						self.Usage(s)
					}
				} else {
					self.Usage(s)
				}
			},
		},
		"ws": cAlias("windowsize"),
		"windowsize": {
			admin: false,
			exec: func(self *command, s *Session, arg string) {
				width, height := s.user.GetWindowSize()

				header := fmt.Sprintf("Width: %v, Height: %v", width, height)

				topBar := header + " " + strings.Repeat("-", int(width)-2-len(header)) + "+"
				bottomBar := "+" + strings.Repeat("-", int(width)-2) + "+"
				outline := "|" + strings.Repeat(" ", int(width)-2) + "|"

				s.WriteLine(topBar)

				for i := 0; i < int(height)-3; i++ {
					s.WriteLine(outline)
				}

				s.WriteLine(bottomBar)
			},
		},
		"tt": cAlias("terminaltype"),
		"terminaltype": {
			admin: false,
			exec: func(self *command, s *Session, arg string) {
				s.WriteLine("Terminal type: %s", s.user.GetTerminalType())
			},
		},
		"silent": {
			admin: false,
			usage: "/silent [on|off]",
			exec: func(self *command, s *Session, arg string) {
				if arg == "" {
					s.silentMode = !s.silentMode
				} else if arg == "on" {
					s.silentMode = true
				} else if arg == "off" {
					s.silentMode = false
				} else {
					self.Usage(s)
				}

				if s.silentMode {
					s.WriteLine("Silent mode on")
				} else {
					s.WriteLine("Silent mode off")
				}
			},
		},
		"r": cAlias("reply"),
		"reply": {
			admin: false,
			exec: func(self *command, s *Session, arg string) {
				targetChar := model.GetPlayerCharacter(s.replyId)

				if targetChar == nil {
					s.asyncMessage("No one to reply to")
				} else if arg == "" {
					prompt := "Reply to " + targetChar.GetName() + ": "
					input := s.getRawUserInput(prompt)

					if input != "" {
						newArg := fmt.Sprintf("%s %s", targetChar.GetName(), input)
						whisper(commands["whisper"], s, newArg)
					}
				} else {
					newArg := fmt.Sprintf("%s %s", targetChar.GetName(), arg)
					whisper(commands["whisper"], s, newArg)
				}
			},
		},
		"area": {
			admin: true,
			exec: func(self *command, s *Session, arg string) {
				utils.ExecMenu("Areas", s, func(menu *utils.Menu) {
					menu.AddAction("n", "New", func() bool {
						name := s.getRawUserInput("Area name: ")
						if name != "" {
							model.CreateArea(name, s.currentZone())
						}
						return true
					})

					for i, area := range model.GetAreas(s.currentZone()) {
						a := area
						menu.AddActionI(i, area.GetName(), func() bool {
							specificAreaMenu(s, a)
							return true
						})
					}
				})
			},
		},
		"link": {
			admin: true,
			usage: "Usage: /link <name> [single|double*] to start, /link to finish, /link remove <name> [single|double*], /link rename <old name> <new name>, /link cancel",
			exec: func(self *command, s *Session, arg string) {
				args := strings.Split(arg, " ")
				StateName := "Linking"

				linkName, linking := s.states[StateName]

				if linking {
					if len(args) == 1 && args[0] == "cancel" {
						linkData.source = nil
						delete(s.states, StateName)
					} else if len(args) != 0 {
						self.Usage(s)
					} else {
						sourceRoom := model.GetRoom(linkData.source)

						sourceRoom.SetLink(linkName, s.pc.GetRoomId())
						if linkData.mode == LinkDouble {
							s.GetRoom().SetLink(linkName, linkData.source)
						}

						linkData.source = nil
						delete(s.states, StateName)

						s.PrintRoom()
					}
				} else {
					if len(args) == 0 {
						self.Usage(s)
						return
					}

					if args[0] == "remove" {
						mode := "double"
						if len(args) == 3 {
							if args[2] == "single" || args[2] == "double" {
								mode = args[2]
							} else {
								self.Usage(s)
								return
							}
						}

						if len(args) != 2 {
							self.Usage(s)
							return
						}

						linkNames := s.GetRoom().LinkNames()
						index := utils.BestMatch(args[1], linkNames)

						if index == -2 {
							s.printError("Which one do you mean?")
						} else if index == -1 {
							s.printError("Link not found")
						} else {
							linkName := linkNames[index]

							if mode == "double" {
								links := s.GetRoom().GetLinks()
								linkedRoom := model.GetRoom(links[linkName])
								linkedRoom.RemoveLink(linkName)
							}

							s.GetRoom().RemoveLink(linkName)
							s.PrintRoom()
						}
					} else if args[0] == "rename" {
						// TODO
					} else {
						if len(args) == 2 {
							if args[1] == LinkSingle || args[1] == LinkDouble {
								linkData.mode = args[1]
							} else {
								self.Usage(s)
								return
							}
						} else {
							linkData.mode = LinkDouble
						}

						// New link
						s.states[StateName] = utils.FormatName(args[0])
						linkData.source = s.pc.GetRoomId()
					}
				}
			},
		},
		"kill": {
			admin: true,
			usage: "/kill [npc name]",
			exec: func(self *command, s *Session, arg string) {
				if arg == "" {
					self.Usage(s)
				} else {
					npcs := model.NpcsIn(s.pc.GetRoomId())
					index := utils.BestMatch(arg, npcs.Characters().Names())

					if index == -1 {
						s.printError("Not found")
					} else if index == -2 {
						s.printError("Which one do you mean?")
					} else {
						npc := npcs[index]
						combat.Kill(npc)
						s.WriteLine("Killed %s", npc.GetName())
					}
				}
			},
		},
		"inspect": {
			admin: true,
			usage: "/inspect [name]",
			exec: func(self *command, s *Session, arg string) {
				if arg == "" {
					self.Usage(s)
				} else {
					characters := model.CharactersIn(s.pc.GetRoomId())
					index := utils.BestMatch(arg, characters.Names())

					if index == -1 {
						s.printError("Not found")
					} else if index == -2 {
						s.printError("Which one do you mean?")
					} else {
						char := characters[index]

						s.WriteLine(char.GetName())
						s.WriteLine("Health: %v/%v", char.GetHitPoints(), char.GetHealth())
					}
				}
			},
		},
		"skills": {
			admin: true,
			exec: func(self *command, s *Session, arg string) {
				utils.ExecMenu("Skills", s, func(menu *utils.Menu) {
					menu.AddAction("n", "New", func() bool {
						for {
							name := s.getCleanUserInput("Skill name: ")

							if name == "" {
								break
							}

							skill := model.GetSkillByName(name)

							if skill != nil {
								s.printError("A skill with that name already exists")
							} else {
								model.CreateSkill(name)
								break
							}
						}
						return true
					})

					skills := model.GetAllSkills()
					for i, skill := range skills {
						sk := skill
						menu.AddActionI(i, skill.GetName(), func() bool {
							specificSkillMenu(s, sk)
							return true
						})
					}
				})
			},
		},
		"testmenu": {
			admin: true,
			exec: func(self *command, s *Session, arg string) {
				utils.ExecMenu("Menu Test", s, func(menu *utils.Menu) {
					for i := 0; i < 500; i++ {
						menu.AddActionI(i, "Test Item", func() bool {
							return false
						})
					}
				})
			},
		},
		"path": {
			admin: true,
			usage: "/path <coordinates>",
			exec: func(self *command, s *Session, arg string) {
				coords, err := utils.Atois(strings.Fields(arg))
				if err == nil {
					if len(coords) == 2 || len(coords) == 3 {
						x, y := coords[0], coords[1]

						z := s.GetRoom().GetLocation().Z
						if len(coords) == 3 {
							z = coords[2]
						}

						room := model.GetRoomByLocation(types.Coordinate{X: x, Y: y, Z: z}, s.GetRoom().GetZoneId())
						if room != nil {
							path := engine.FindPath(s.GetRoom(), room)
							/*
								s.WriteLine("Path:")
								for _, room := range path {
									s.WriteLine(fmt.Sprintf("%v", room.GetLocation()))
								}
							*/
							if len(path) > 0 {
								for _, room := range path {
									time.Sleep(200 * time.Millisecond)
									model.MoveCharacterToRoom(s.pc, room)
									s.PrintRoom()
									s.handleCommand("map", "")
								}
							} else {
								s.printError("No path found")
							}
						} else {
							s.printError("No room found at the given coordinates")
						}
					} else {
						self.Usage(s)
					}
				} else {
					self.Usage(s)
				}
			},
		},
		"time": {
			admin: false,
			usage: "/time",
			exec: func(self *command, s *Session, arg string) {
				s.WriteLine("%v", model.GetWorld().GetTime())
			},
		},
		"join": {
			admin: true,
			usage: "/join <player name>",
			exec: func(self *command, s *Session, arg string) {
				target := model.GetCharacterByName(arg)
				if target == nil {
					s.printError("Target not found")
				} else {
					model.MoveCharacterToRoom(s.pc, model.GetRoom(target.GetRoomId()))
					s.PrintRoom()
				}
			},
		},
		"bring": {
			admin: true,
			usage: "/bring <player name>",
			exec: func(self *command, s *Session, arg string) {
				// TODO - The target receives no indication that they've been moved
				target := model.GetCharacterByName(arg)
				if target == nil {
					s.printError("Target not found")
				} else {
					model.MoveCharacterToRoom(target, s.GetRoom())
				}
			},
		},
	}
}
コード例 #17
0
ファイル: session.go プロジェクト: Cristofori/kmud
func (self *Session) printRoom(room types.Room) {
	pcs := model.PlayerCharactersIn(self.pc.GetRoomId(), self.pc.GetId())
	npcs := model.NpcsIn(room.GetId())
	items := model.ItemsIn(room.GetId())
	store := model.StoreIn(room.GetId())

	var area types.Area
	if room.GetAreaId() != nil {
		area = model.GetArea(room.GetAreaId())
	}

	var str string

	areaStr := ""
	if area != nil {
		areaStr = fmt.Sprintf("%s - ", area.GetName())
	}

	str = fmt.Sprintf("\r\n %v>>> %v%s%s %v<<< %v(%v %v %v)\r\n\r\n %v%s\r\n\r\n",
		types.ColorWhite, types.ColorBlue,
		areaStr, room.GetTitle(),
		types.ColorWhite, types.ColorBlue,
		room.GetLocation().X, room.GetLocation().Y, room.GetLocation().Z,
		types.ColorWhite,
		room.GetDescription())

	if store != nil {
		str = fmt.Sprintf("%s Store: %s\r\n\r\n", str, types.Colorize(types.ColorBlue, store.GetName()))
	}

	extraNewLine := ""

	if len(pcs) > 0 {
		str = fmt.Sprintf("%s %sAlso here:", str, types.ColorBlue)

		names := make([]string, len(pcs))
		for i, char := range pcs {
			names[i] = types.Colorize(types.ColorWhite, char.GetName())
		}
		str = fmt.Sprintf("%s %s \r\n", str, strings.Join(names, types.Colorize(types.ColorBlue, ", ")))

		extraNewLine = "\r\n"
	}

	if len(npcs) > 0 {
		str = fmt.Sprintf("%s %s", str, types.Colorize(types.ColorBlue, "NPCs: "))

		names := make([]string, len(npcs))
		for i, npc := range npcs {
			names[i] = types.Colorize(types.ColorWhite, npc.GetName())
		}
		str = fmt.Sprintf("%s %s \r\n", str, strings.Join(names, types.Colorize(types.ColorBlue, ", ")))

		extraNewLine = "\r\n"
	}

	if len(items) > 0 {
		itemMap := make(map[string]int)
		var nameList []string

		for _, item := range items {
			if item == nil {
				continue
			}

			_, found := itemMap[item.GetName()]
			if !found {
				nameList = append(nameList, item.GetName())
			}
			itemMap[item.GetName()]++
		}

		sort.Strings(nameList)

		str = str + " " + types.Colorize(types.ColorBlue, "Items: ")

		var names []string
		for _, name := range nameList {
			if itemMap[name] > 1 {
				name = fmt.Sprintf("%s x%v", name, itemMap[name])
			}
			names = append(names, types.Colorize(types.ColorWhite, name))
		}
		str = str + strings.Join(names, types.Colorize(types.ColorBlue, ", ")) + "\r\n"

		extraNewLine = "\r\n"
	}

	str = str + extraNewLine + " " + types.Colorize(types.ColorBlue, "Exits: ")

	var exitList []string
	for _, direction := range room.GetExits() {
		exitList = append(exitList, utils.DirectionToExitString(direction))
	}

	if len(exitList) == 0 {
		str = str + types.Colorize(types.ColorWhite, "None")
	} else {
		str = str + strings.Join(exitList, " ")
	}

	if len(room.GetLinks()) > 0 {
		str = fmt.Sprintf("%s\r\n\r\n %s %s",
			str,
			types.Colorize(types.ColorBlue, "Other exits:"),
			types.Colorize(types.ColorWhite, strings.Join(room.LinkNames(), ", ")),
		)
	}

	str = str + "\r\n"

	self.WriteLine(str)
}
コード例 #18
0
ファイル: session.go プロジェクト: Cristofori/kmud
func (self *Session) getConfirmation(prompt string) bool {
	answer := self.getCleanUserInput(types.Colorize(types.ColorWhite, prompt))
	return answer == "y" || answer == "yes"
}
コード例 #19
0
ファイル: session.go プロジェクト: Cristofori/kmud
func (self *Session) WriteLineColor(color types.Color, line string, a ...interface{}) {
	self.printLine(types.Colorize(color, fmt.Sprintf(line, a...)))
}
コード例 #20
0
ファイル: events.go プロジェクト: Cristofori/kmud
func (self BroadcastEvent) ToString(receiver EventReceiver) string {
	return types.Colorize(types.ColorCyan, "Broadcast from "+self.Character.GetName()+": ") +
		types.Colorize(types.ColorWhite, self.Message)
}
コード例 #21
0
ファイル: events.go プロジェクト: Cristofori/kmud
// Emote
func (self EmoteEvent) ToString(receiver EventReceiver) string {
	return types.Colorize(types.ColorYellow, self.Character.GetName()+" "+self.Emote)
}
コード例 #22
0
ファイル: events.go プロジェクト: Cristofori/kmud
// RoomUpdate
func (self RoomUpdateEvent) ToString(receiver EventReceiver) string {
	return types.Colorize(types.ColorWhite, "This room has been modified")
}
コード例 #23
0
ファイル: events.go プロジェクト: Cristofori/kmud
// Login
func (self LoginEvent) ToString(receiver EventReceiver) string {
	return types.Colorize(types.ColorBlue, self.Character.GetName()) +
		types.Colorize(types.ColorWhite, " has connected")
}