コード例 #1
0
ファイル: ui_main_bar.go プロジェクト: genbattle/haunts
func MakeMainBar(game *Game) (*MainBar, error) {
	var mb MainBar
	datadir := base.GetDataDir()
	err := base.LoadAndProcessObject(filepath.Join(datadir, "ui", "main_bar.json"), "json", &mb.layout)
	if err != nil {
		return nil, err
	}
	mb.all_buttons = []*Button{
		&mb.layout.EndTurn,
		&mb.layout.UnitLeft,
		&mb.layout.UnitRight,
		&mb.layout.ActionLeft,
		&mb.layout.ActionRight,
	}
	mb.no_actions_buttons = []*Button{
		&mb.layout.EndTurn,
		&mb.layout.UnitLeft,
		&mb.layout.UnitRight,
	}
	mb.layout.EndTurn.f = buttonFuncEndTurn
	mb.layout.UnitRight.f = buttonFuncUnitRight
	mb.layout.UnitRight.key = gin.Tab
	mb.layout.UnitLeft.f = buttonFuncUnitLeft
	mb.layout.UnitLeft.key = gin.ShiftTab
	mb.layout.ActionLeft.f = buttonFuncActionLeft
	mb.layout.ActionRight.f = buttonFuncActionRight
	mb.game = game
	return &mb, nil
}
コード例 #2
0
ファイル: ui_credits.go プロジェクト: genbattle/haunts
func InsertCreditsMenu(ui gui.WidgetParent) error {
	var cm CreditsMenu
	datadir := base.GetDataDir()
	err := base.LoadAndProcessObject(filepath.Join(datadir, "ui", "start", "credits", "layout.json"), "json", &cm.layout)
	if err != nil {
		return err
	}
	cm.buttons = []ButtonLike{
		&cm.layout.Back,
		&cm.layout.Up,
		&cm.layout.Down,
	}
	cm.layout.Back.f = func(interface{}) {
		ui.RemoveChild(&cm)
		InsertStartMenu(ui)
	}
	d := base.GetDictionary(cm.layout.Credits.Size)
	cm.layout.Credits.Scroll.Height = len(cm.layout.Credits.Lines) * int(d.MaxHeight())
	cm.layout.Down.valid_func = func() bool {
		return cm.layout.Credits.Scroll.Height > cm.layout.Credits.Scroll.Dy
	}
	cm.layout.Up.valid_func = cm.layout.Down.valid_func
	cm.layout.Down.f = func(interface{}) {
		cm.layout.Credits.Scroll.Down()
	}
	cm.layout.Up.f = func(interface{}) {
		cm.layout.Credits.Scroll.Up()
	}
	cm.ui = ui

	ui.AddChild(&cm)
	return nil
}
コード例 #3
0
ファイル: ui_versus.go プロジェクト: genbattle/haunts
func makeChooserFromOptionBasicsFile(path string) (*Chooser, <-chan []string, error) {
	var bops []OptionBasic
	err := base.LoadAndProcessObject(path, "json", &bops)
	if err != nil {
		return nil, nil, err
	}
	var opts []Option
	algorithm.Map2(bops, &opts, func(ob OptionBasic) Option { return &ob })
	return MakeChooser(opts)
}
コード例 #4
0
ファイル: house.go プロジェクト: genbattle/haunts
func MakeHouseFromPath(path string) (*HouseDef, error) {
	var house HouseDef
	err := base.LoadAndProcessObject(path, "json", &house)
	if err != nil {
		return nil, err
	}
	house.Normalize()
	house.setDoorsOpened(false)
	return &house, nil
}
コード例 #5
0
ファイル: ui_chooser.go プロジェクト: genbattle/haunts
func MakeChooser(opts []Option) (*Chooser, <-chan []string, error) {
	var ch Chooser
	datadir := base.GetDataDir()
	err := base.LoadAndProcessObject(filepath.Join(datadir, "ui", "chooser", "layout.json"), "json", &ch.layout)
	if err != nil {
		return nil, nil, err
	}
	ch.options = opts
	ch.buttons = []*Button{
		&ch.layout.Up,
		&ch.layout.Down,
		&ch.layout.Back,
		&ch.layout.Next,
	}
	ch.non_scroll_buttons = []*Button{
		&ch.layout.Back,
		&ch.layout.Next,
	}
	ch.layout.Up.f = func(interface{}) {
		ch.layout.Options.Up()
	}
	ch.layout.Down.f = func(interface{}) {
		ch.layout.Options.Down()
	}
	done := make(chan []string, 1)
	ch.selected = make(map[int]bool)
	ch.layout.Back.f = func(interface{}) {
		done <- nil
		close(done)
	}
	ch.layout.Next.f = func(interface{}) {
		var res []string
		for i := range ch.options {
			if ch.selected[i] {
				res = append(res, ch.options[i].String())
			}
		}
		done <- res
		close(done)
	}
	ch.layout.Next.valid_func = func() bool {
		return ch.selector(-1, ch.selected, false)
	}
	ch.min, ch.max = 1, 1
	if ch.min == 1 && ch.max == 1 {
		ch.selector = SelectExactlyOne
	} else {
		ch.selector = SelectInRange(ch.min, ch.max)
	}
	ch.info_region = gui.Region{
		gui.Point{ch.layout.Info.X, ch.layout.Info.Y},
		gui.Dims{ch.layout.Info.Dx, ch.layout.Info.Dy},
	}
	return &ch, done, nil
}
コード例 #6
0
ファイル: room.go プロジェクト: genbattle/haunts
func (rep *RoomEditorPanel) Load(path string) error {
	var room roomDef
	err := base.LoadAndProcessObject(path, "json", &room)
	if err == nil {
		rep.room = room
		for _, tab := range rep.widgets {
			tab.Reload()
		}
	}
	return err
}
コード例 #7
0
ファイル: ui_start.go プロジェクト: genbattle/haunts
func InsertStartMenu(ui gui.WidgetParent) error {
	var sm StartMenu
	datadir := base.GetDataDir()
	err := base.LoadAndProcessObject(filepath.Join(datadir, "ui", "start", "layout.json"), "json", &sm.layout)
	if err != nil {
		return err
	}
	sm.buttons = []ButtonLike{
		&sm.layout.Menu.Credits,
		&sm.layout.Menu.Versus,
		&sm.layout.Menu.Online,
		&sm.layout.Menu.Settings,
	}
	sm.layout.Menu.Credits.f = func(interface{}) {
		ui.RemoveChild(&sm)
		err := InsertCreditsMenu(ui)
		if err != nil {
			base.Error().Printf("Unable to make Credits Menu: %v", err)
			return
		}
	}
	sm.layout.Menu.Versus.f = func(interface{}) {
		ui.RemoveChild(&sm)
		err := InsertMapChooser(
			ui,
			func(name string) {
				ui.AddChild(MakeGamePanel(name, nil, nil, ""))
			},
			InsertStartMenu,
		)
		if err != nil {
			base.Error().Printf("Unable to make Map Chooser: %v", err)
			return
		}
	}
	sm.layout.Menu.Settings.f = func(interface{}) {}
	sm.layout.Menu.Online.f = func(interface{}) {
		ui.RemoveChild(&sm)
		err := InsertOnlineMenu(ui)
		if err != nil {
			base.Error().Printf("Unable to make Online Menu: %v", err)
			return
		}
	}
	ui.AddChild(&sm)
	return nil
}
コード例 #8
0
ファイル: ui_system.go プロジェクト: genbattle/haunts
func MakeSystemMenu(gp *GamePanel, player *Player) (gui.Widget, error) {
	var sm SystemMenu
	datadir := base.GetDataDir()
	err := base.LoadAndProcessObject(filepath.Join(datadir, "ui", "system", "layout.json"), "json", &sm.layout)
	if err != nil {
		return nil, err
	}

	sm.layout.Main.f = func(interface{}) {}

	sm.buttons = []ButtonLike{
		&sm.layout.Sub.Return,
		&sm.layout.Sub.Save,
	}

	sm.layout.Sub.Return.f = func(_ui interface{}) {
		ui := _ui.(*gui.Gui)
		gp.game.Ents = nil
		gp.game.Think(1) // This should clean things up
		ui.DropFocus()
		Restart()
	}

	sm.layout.Sub.Save.Entry.text = player.Name
	sm.layout.Sub.Save.Button.f = func(interface{}) {
		UpdatePlayer(player, gp.script.L)
		str, err := base.ToGobToBase64(gp.game)
		if err != nil {
			base.Error().Printf("Error gobbing game state: %v", err)
			return
		}
		player.Game_state = str
		player.Name = sm.layout.Sub.Save.Text()
		player.No_init = true
		base.Log().Printf("Saving player: %v", player)
		err = SavePlayer(player)
		if err != nil {
			base.Warn().Printf("Unable to save player: %v", err)
			return
		}
		sm.saved_time = time.Now()
		sm.saved_alpha = 1.0
	}

	return &sm, nil
}
コード例 #9
0
ファイル: roster_chooser.go プロジェクト: genbattle/haunts
func MakeRosterChooser(options []Option, selector Selector, on_complete func(map[int]bool), on_undo func()) *RosterChooser {
	var rc RosterChooser
	rc.options = options
	err := base.LoadAndProcessObject(filepath.Join(base.GetDataDir(), "ui", "widgets", "roster_chooser.json"), "json", &rc.layout)
	if err != nil {
		base.Error().Printf("Failed to create RosterChooser: %v", err)
		return nil
	}
	rc.Request_dims = gui.Dims{
		rc.layout.Down.Data().Dx() + rc.layout.Option.Dx,
		rc.layout.Num_options*rc.layout.Option.Dy + 2*int(base.GetDictionary(15).MaxHeight()),
	}
	rc.selected = make(map[int]bool)
	rc.selector = selector
	rc.on_complete = on_complete
	rc.on_undo = on_undo
	rc.render.options = make([]gui.Region, len(rc.options))
	return &rc
}
コード例 #10
0
ファイル: ui_select_map.go プロジェクト: genbattle/haunts
func MakeUiSelectMap(gp *GamePanel) (gui.Widget, <-chan string, error) {
	var ui UiSelectMap

	datadir := base.GetDataDir()
	err := base.LoadAndProcessObject(filepath.Join(datadir, "ui", "select_map", "config.json"), "json", &ui.layout)
	if err != nil {
		return nil, nil, err
	}

	ui.region.Dx = 1024
	ui.region.Dy = 768
	var options []hui.Option
	// TODO: may want to reload the registry on this one?  If we want to pik up
	// new changes to files that is.
	for _, name := range base.GetAllNamesInRegistry("houses") {
		var mo MapOption
		mo.house_def = house.MakeHouseFromName(name)
		mo.layout = &ui.layout
		options = append(options, &mo)
	}
	out := make(chan string, 2)
	chooser := hui.MakeRosterChooser(options, hui.SelectExactlyOne, func(m map[int]bool) {
		var index int
		base.Log().Printf("On complete: %v", m)
		for index = range m {
			out <- options[index].(*MapOption).house_def.Name
			base.Log().Printf("Sent '%s'", options[index].(*MapOption).house_def.Name)
			break
		}
		base.Log().Printf("Closing")
		close(out)
	},
		nil)
	ui.chooser = chooser

	return &ui, out, nil
}
コード例 #11
0
ファイル: ui_chooser.go プロジェクト: genbattle/haunts
func InsertMapChooser(ui gui.WidgetParent, chosen func(string), resert func(ui gui.WidgetParent) error) error {
	var bops []OptionBasic
	datadir := base.GetDataDir()
	err := base.LoadAndProcessObject(filepath.Join(datadir, "ui", "start", "versus", "map_select.json"), "json", &bops)
	if err != nil {
		base.Error().Printf("Unable to insert MapChooser: %v", err)
		return err
	}
	var opts []Option
	algorithm.Map2(bops, &opts, func(ob OptionBasic) Option { return &ob })
	for _, opt := range opts {
		base.Log().Printf(opt.String())
	}

	var ch Chooser
	err = base.LoadAndProcessObject(filepath.Join(datadir, "ui", "chooser", "layout.json"), "json", &ch.layout)
	if err != nil {
		base.Error().Printf("Unable to insert MapChooser: %v", err)
		return err
	}
	ch.options = opts
	ch.buttons = []*Button{
		&ch.layout.Up,
		&ch.layout.Down,
		&ch.layout.Back,
		&ch.layout.Next,
	}
	ch.non_scroll_buttons = []*Button{
		&ch.layout.Back,
		&ch.layout.Next,
	}
	ch.layout.Up.f = func(interface{}) {
		ch.layout.Options.Up()
	}
	ch.layout.Down.f = func(interface{}) {
		ch.layout.Options.Down()
	}
	ch.selected = make(map[int]bool)
	ch.layout.Back.f = func(interface{}) {
		ui.RemoveChild(&ch)
		err := resert(ui)
		if err != nil {
			base.Error().Printf("Unable to make Start Menu: %v", err)
			return
		}
	}
	ch.layout.Next.f = func(interface{}) {
		for i := range ch.options {
			if ch.selected[i] {
				ui.RemoveChild(&ch)
				chosen(ch.options[i].String())
			}
		}
	}
	ch.layout.Next.valid_func = func() bool {
		return ch.selector(-1, ch.selected, false)
	}
	ch.min, ch.max = 1, 1
	if ch.min == 1 && ch.max == 1 {
		ch.selector = SelectExactlyOne
	} else {
		ch.selector = SelectInRange(ch.min, ch.max)
	}
	ch.info_region = gui.Region{
		gui.Point{ch.layout.Info.X, ch.layout.Info.Y},
		gui.Dims{ch.layout.Info.Dx, ch.layout.Info.Dy},
	}
	ui.AddChild(&ch)
	return nil
}
コード例 #12
0
ファイル: ui_dialog.go プロジェクト: genbattle/haunts
func MakeDialogBox(source string, args map[string]string) (*MediumDialogBox, <-chan string, error) {
	var mdb MediumDialogBox
	datadir := base.GetDataDir()
	err := base.LoadAndProcessObject(filepath.Join(datadir, source), "json", &mdb.data)
	if err != nil {
		return nil, nil, err
	}
	err = base.LoadAndProcessObject(filepath.Join(datadir, "ui", "dialog", fmt.Sprintf("%s.json", mdb.data.Size)), "json", &mdb.layout)
	if err != nil {
		return nil, nil, err
	}

	if _, ok := mdb.data.Pages["Start"]; !ok {
		return nil, nil, errors.New("Section 'Start' was not specified.")
	}

	// Make sure that all of the pages specified by "Next"s are available
	// in the map
	for _, page := range mdb.data.Pages {
		if page.Next != "" {
			return nil, nil, errors.New(fmt.Sprintf("Specified 'Next': '%s' on a page, but must be in a section on the page.", page.Next))
		}
		for _, section := range page.Sections {
			if section.Next == "" {
				continue
			}
			if _, ok := mdb.data.Pages[section.Next]; !ok {
				return nil, nil, errors.New(fmt.Sprintf("Section '%s' specified but doesn't exist.", section.Next))
			}
		}
		if _, ok := mdb.layout.Formats[page.Format]; !ok {
			return nil, nil, errors.New(fmt.Sprintf("Unknown dialog box format '%s'.", page.Format))
		}
		if len(page.Sections) != len(mdb.layout.Formats[page.Format].Sections) {
			return nil, nil, errors.New(fmt.Sprintf("Format '%s' requires exactly %d sections.", page.Format, len(mdb.layout.Formats[page.Format].Sections)))
		}
	}

	mdb.data.cur_page = "Start"
	mdb.format = mdb.layout.Formats[mdb.data.Pages[mdb.data.cur_page].Format]

	// return nil, nil, errors.New(fmt.Sprintf("Unknown format string: '%s'.", format))

	mdb.buttons = []*Button{
		&mdb.layout.Next,
		&mdb.layout.Prev,
	}

	mdb.result = make(chan string, 1)

	mdb.layout.Next.valid_func = func() bool {
		sections := mdb.data.Pages[mdb.data.cur_page].Sections
		return len(sections) == 1
	}

	mdb.layout.Next.f = func(_data interface{}) {
		sections := mdb.data.Pages[mdb.data.cur_page].Sections
		if len(sections) == 1 {
			if sections[0].Next == "" {
				if !mdb.done {
					close(mdb.result)
					mdb.done = true
				}
			} else {
				mdb.data.prev = append(mdb.data.prev, mdb.data.cur_page)
				mdb.data.cur_page = sections[0].Next
				mdb.format = mdb.layout.Formats[mdb.data.Pages[mdb.data.cur_page].Format]
			}
		}
	}

	mdb.layout.Prev.valid_func = func() bool {
		return len(mdb.data.prev) > 0
	}

	mdb.layout.Prev.f = func(_data interface{}) {
		if len(mdb.data.prev) > 0 {
			mdb.data.cur_page = mdb.data.prev[len(mdb.data.prev)-1]
			mdb.data.prev = mdb.data.prev[0 : len(mdb.data.prev)-1]
			mdb.format = mdb.layout.Formats[mdb.data.Pages[mdb.data.cur_page].Format]
		}
	}

	mdb.data.process(args)

	return &mdb, mdb.result, nil
}
コード例 #13
0
ファイル: ui_online.go プロジェクト: genbattle/haunts
func InsertOnlineMenu(ui gui.WidgetParent) error {
	var sm OnlineMenu
	datadir := base.GetDataDir()
	err := base.LoadAndProcessObject(filepath.Join(datadir, "ui", "start", "online", "layout.json"), "json", &sm.layout)
	if err != nil {
		return err
	}
	sm.buttons = []ButtonLike{
		&sm.layout.Back,
		&sm.layout.Unstarted.Up,
		&sm.layout.Unstarted.Down,
		&sm.layout.Active.Up,
		&sm.layout.Active.Down,
		&sm.layout.User,
		&sm.layout.NewGame,
	}
	sm.control.in = make(chan struct{})
	sm.control.out = make(chan struct{})
	sm.layout.Back.f = func(interface{}) {
		ui.RemoveChild(&sm)
		InsertStartMenu(ui)
	}
	sm.ui = ui

	fmt.Sscanf(base.GetStoreVal("netid"), "%d", &net_id)
	if net_id == 0 {
		net_id = mrgnet.NetId(mrgnet.RandomId())
		base.SetStoreVal("netid", fmt.Sprintf("%d", net_id))
	}

	in_newgame := false
	sm.layout.NewGame.f = func(interface{}) {
		if in_newgame {
			return
		}
		in_newgame = true
		go func() {
			var req mrgnet.NewGameRequest
			req.Id = net_id
			var resp mrgnet.NewGameResponse
			done := make(chan bool, 1)
			go func() {
				mrgnet.DoAction("new", req, &resp)
				done <- true
			}()
			select {
			case <-done:
			case <-time.After(5 * time.Second):
				resp.Err = "Couldn't connect to server."
			}
			<-sm.control.in
			defer func() {
				in_newgame = false
				sm.control.out <- struct{}{}
			}()
			if resp.Err != "" {
				sm.layout.Error.err = resp.Err
				base.Error().Printf("Couldn't make new game: %v", resp.Err)
				return
			}
			ui.RemoveChild(&sm)
			err := InsertMapChooser(
				ui,
				func(name string) {
					ui.AddChild(MakeGamePanel(name, nil, nil, resp.Game_key))
				},
				InsertOnlineMenu,
			)
			if err != nil {
				base.Error().Printf("Error making Map Chooser: %v", err)
			}
		}()
	}

	for _, _glb := range []*gameListBox{&sm.layout.Active, &sm.layout.Unstarted} {
		glb := _glb
		glb.Up.f = func(interface{}) {
			glb.Scroll.Up()
		}
		glb.Up.valid_func = func() bool {
			return glb.Scroll.Height > glb.Scroll.Dy
		}
		glb.Down.f = func(interface{}) {
			glb.Scroll.Down()
		}
		glb.Down.valid_func = func() bool {
			return glb.Scroll.Height > glb.Scroll.Dy
		}

		glb.update = make(chan mrgnet.ListGamesResponse)
	}
	go func() {
		var resp mrgnet.ListGamesResponse
		mrgnet.DoAction("list", mrgnet.ListGamesRequest{Id: net_id, Unstarted: true}, &resp)
		sm.layout.Unstarted.update <- resp
	}()
	go func() {
		var resp mrgnet.ListGamesResponse
		mrgnet.DoAction("list", mrgnet.ListGamesRequest{Id: net_id, Unstarted: false}, &resp)
		sm.layout.Active.update <- resp
	}()

	sm.layout.User.Button.f = func(interface{}) {
		var req mrgnet.UpdateUserRequest
		req.Name = sm.layout.User.Entry.text
		req.Id = net_id
		var resp mrgnet.UpdateUserResponse
		go func() {
			mrgnet.DoAction("user", req, &resp)
			<-sm.control.in
			sm.layout.User.SetText(resp.Name)
			sm.update_alpha = 1.0
			sm.update_time = time.Now()
			sm.control.out <- struct{}{}
		}()
	}
	go func() {
		var resp mrgnet.UpdateUserResponse
		mrgnet.DoAction("user", mrgnet.UpdateUserRequest{Id: net_id}, &resp)
		<-sm.control.in
		sm.layout.User.SetText(resp.Name)
		sm.update_alpha = 1.0
		sm.update_time = time.Now()
		sm.control.out <- struct{}{}
	}()

	ui.AddChild(&sm)
	return nil
}
コード例 #14
0
ファイル: ui_entity_placer.go プロジェクト: genbattle/haunts
func MakeEntityPlacer(game *Game, roster_names []string, roster_costs []int, min, max int, pattern string) (*EntityPlacer, <-chan []*Entity, error) {
	var ep EntityPlacer
	err := base.LoadAndProcessObject(filepath.Join(base.GetDataDir(), "ui", "entity_placer", "config.json"), "json", &ep.layout)
	if err != nil {
		return nil, nil, err
	}
	if len(roster_names) != len(roster_costs) {
		return nil, nil, errors.New("Must have as many names as costs.")
	}
	if len(roster_names) <= 0 || len(roster_names) > ep.layout.Roster.Max_options {
		return nil, nil, errors.New(fmt.Sprintf("Can't have more than %d ents in a roster.", ep.layout.Roster.Max_options))
	}

	ep.layout.Undo.valid_func = func() bool {
		return len(ep.ents) > 0
	}
	ep.layout.Undo.f = func(interface{}) {
		ent := ep.ents[len(ep.ents)-1]
		ep.points += ep.roster[ent.Name]
		ep.ents = ep.ents[0 : len(ep.ents)-1]
		algorithm.Choose(&game.Ents, func(e *Entity) bool { return e != ent })
		game.viewer.RemoveDrawable(ent)
	}

	ep.layout.Done.valid_func = func() bool {
		return ep.points >= 0 && min <= (max-ep.points)
	}
	done := make(chan []*Entity)
	ep.layout.Done.f = func(interface{}) {
		done <- ep.ents
		close(done)
		house.PopSpawnRegexp()
		game.viewer.RemoveDrawable(game.new_ent)
		game.new_ent = nil
	}
	ep.roster_names = roster_names
	ep.roster = make(map[string]int)
	for i, name := range ep.roster_names {
		ep.roster[name] = roster_costs[i]
	}
	ep.game = game
	ep.show_points = !(min == 1 && max == 1)
	ep.points = max
	ep.pattern = pattern
	house.PushSpawnRegexp(ep.pattern)
	x := ep.layout.Roster.X
	for _, name := range ep.roster_names {
		var b Button
		b.X = x
		x += (ep.layout.Roster.X2 - ep.layout.Roster.X) / (ep.layout.Roster.Max_options - 1)
		b.Y = ep.layout.Roster.Y
		ent := Entity{Defname: name}
		base.GetObject("entities", &ent)
		b.Texture = ent.Still
		cost := ep.roster[name]
		b.valid_func = func() bool {
			return ep.points >= cost
		}
		b.f = func(interface{}) {
			ep.game.viewer.RemoveDrawable(ep.game.new_ent)
			ep.game.new_ent = MakeEntity(ent.Name, ep.game)
			ep.game.viewer.AddDrawable(ep.game.new_ent)
		}
		ep.ent_buttons = append(ep.ent_buttons, &b)
	}

	ep.buttons = []*Button{
		&ep.layout.Undo,
		&ep.layout.Done,
	}
	for _, b := range ep.ent_buttons {
		ep.buttons = append(ep.buttons, b)
	}

	return &ep, done, nil
}