Esempio n. 1
0
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.Continue,
		&sm.layout.Menu.Versus,
		&sm.layout.Menu.Online,
		&sm.layout.Menu.Settings,
	}
	sm.layout.Menu.Continue.f = func(interface{}) {}
	sm.layout.Menu.Versus.f = func(interface{}) {
		ui.RemoveChild(&sm)
		ui.AddChild(MakeGamePanel("versus/basic.lua", nil, nil))
	}
	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
}
Esempio n. 2
0
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
}
Esempio n. 3
0
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
}
Esempio n. 4
0
func chooserFromFile(gp *GamePanel) lua.GoFunction {
	return func(L *lua.State) int {
		if !LuaCheckParamsOk(L, "ChooserFromFile", LuaString) {
			return 0
		}
		gp.script.syncStart()
		defer gp.script.syncEnd()
		path := filepath.Join(base.GetDataDir(), L.ToString(-1))
		chooser, done, err := makeChooserFromOptionBasicsFile(path)
		if err != nil {
			base.Error().Printf("Error making chooser: %v", err)
			return 0
		}
		gp.AnchorBox.AddChild(chooser, gui.Anchor{0.5, 0.5, 0.5, 0.5})
		gp.script.syncEnd()

		res := <-done
		L.NewTable()
		for i, s := range res {
			L.PushInteger(i + 1)
			L.PushString(s)
			L.SetTable(-3)
		}
		gp.script.syncStart()
		gp.AnchorBox.RemoveChild(chooser)
		return 1
	}
}
Esempio n. 5
0
// Returns a map from player name to the path of that player's file.
func GetAllPlayers() map[string]string {
	root := filepath.Join(base.GetDataDir(), "players")
	players := make(map[string]string)
	filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
		if info.IsDir() {
			return nil
		}
		f, err := os.Open(path)
		if err != nil {
			base.Warn().Printf("Unable to open player file: %s.", path)
			return nil
		}
		defer f.Close()
		dec := gob.NewDecoder(f)
		var name string
		err = dec.Decode(&name)
		if err != nil {
			base.Warn().Printf("Unable to read player file: %s.", path)
			return nil
		}
		players[name] = path
		return nil
	})
	return players
}
Esempio n. 6
0
func LoadAllEntities() {
	base.RemoveRegistry("entities")
	base.RegisterRegistry("entities", make(map[string]*entityDef))
	basedir := base.GetDataDir()
	base.RegisterAllObjectsInDir("entities", filepath.Join(basedir, "entities"), ".json", "json")
	base.RegisterAllObjectsInDir("entities", filepath.Join(basedir, "objects"), ".json", "json")
}
Esempio n. 7
0
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
}
Esempio n. 8
0
func pickFromN(gp *GamePanel) lua.GoFunction {
	return func(L *lua.State) int {
		if !LuaCheckParamsOk(L, "PickFromN", LuaInteger, LuaInteger, LuaTable) {
			return 0
		}
		min := L.ToInteger(-3)
		max := L.ToInteger(-2)
		var options []hui.Option
		var option_names []string
		L.PushNil()
		for L.Next(-2) != 0 {
			name := L.ToString(-2)
			option_names = append(option_names, name)
			path := L.ToString(-1)
			if !filepath.IsAbs(path) {
				path = filepath.Join(base.GetDataDir(), path)
			}
			option := iconWithText{
				Name: name,
				Icon: texture.Object{Path: base.Path(path)},
			}
			options = append(options, &option)
			L.Pop(1)
		}
		var selector hui.Selector
		if min == 1 && max == 1 {
			selector = hui.SelectExactlyOne
		} else {
			selector = hui.SelectInRange(min, max)
		}
		var chooser *hui.RosterChooser
		done := make(chan struct{})
		on_complete := func(m map[int]bool) {
			gp.RemoveChild(chooser)
			L.NewTable()
			count := 0
			for i := range options {
				if m[i] {
					count++
					L.PushInteger(count)
					L.PushString(option_names[i])
					L.SetTable(-3)
				}
			}
			done <- struct{}{}
		}
		chooser = hui.MakeRosterChooser(options, selector, on_complete, nil)
		gp.script.syncStart()
		gp.AddChild(chooser, gui.Anchor{0.5, 0.5, 0.5, 0.5})
		gp.script.syncEnd()
		<-done
		return 1
	}
}
Esempio n. 9
0
func SavePlayer(p *Player) error {
	hash := fnv.New64()
	hash.Write([]byte(p.Name))
	name := fmt.Sprintf("%x.player", hash.Sum64())
	f, err := os.Create(filepath.Join(base.GetDataDir(), "players", name))
	if err != nil {
		return err
	}
	defer f.Close()
	base.SetStoreVal("last player", name)
	return EncodePlayer(f, p)
}
Esempio n. 10
0
func registerMoves() map[string]func() game.Action {
	move_actions := make(map[string]*MoveDef)
	base.RemoveRegistry("actions-move_actions")
	base.RegisterRegistry("actions-move_actions", move_actions)
	base.RegisterAllObjectsInDir("actions-move_actions", filepath.Join(base.GetDataDir(), "actions", "movement"), ".json", "json")
	makers := make(map[string]func() game.Action)
	for name := range move_actions {
		cname := name
		makers[cname] = func() game.Action {
			a := Move{Defname: cname}
			base.GetObject("actions-move_actions", &a)
			return &a
		}
	}
	return makers
}
Esempio n. 11
0
func registerBasicConditions() {
	registry_name := "conditions-basic_conditions"
	base.RemoveRegistry(registry_name)
	base.RegisterRegistry(registry_name, make(map[string]*BasicConditionDef))
	base.RegisterAllObjectsInDir(registry_name, filepath.Join(base.GetDataDir(), "conditions", "basic_conditions"), ".json", "json")
	names := base.GetAllNamesInRegistry(registry_name)
	for _, name := range names {
		cname := name
		f := func() Condition {
			c := BasicCondition{Defname: cname}
			base.GetObject(registry_name, &c)
			return &c
		}
		condition_makers[name] = f
	}
}
Esempio n. 12
0
func registerInteracts() map[string]func() game.Action {
	interact_actions := make(map[string]*InteractDef)
	base.RemoveRegistry("actions-interact_actions")
	base.RegisterRegistry("actions-interact_actions", interact_actions)
	base.RegisterAllObjectsInDir("actions-interact_actions", filepath.Join(base.GetDataDir(), "actions", "interacts"), ".json", "json")
	makers := make(map[string]func() game.Action)
	for name := range interact_actions {
		cname := name
		makers[cname] = func() game.Action {
			a := Interact{Defname: cname}
			base.GetObject("actions-interact_actions", &a)
			return &a
		}
	}
	return makers
}
Esempio n. 13
0
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
}
Esempio n. 14
0
func registerSummonActions() map[string]func() game.Action {
	summons_actions := make(map[string]*SummonActionDef)
	base.RemoveRegistry("actions-summons_actions")
	base.RegisterRegistry("actions-summons_actions", summons_actions)
	base.RegisterAllObjectsInDir("actions-summons_actions", filepath.Join(base.GetDataDir(), "actions", "summons"), ".json", "json")
	makers := make(map[string]func() game.Action)
	for name := range summons_actions {
		cname := name
		makers[cname] = func() game.Action {
			a := SummonAction{Defname: cname}
			base.GetObject("actions-summons_actions", &a)
			if a.Ammo > 0 {
				a.Current_ammo = a.Ammo
			} else {
				a.Current_ammo = -1
			}
			return &a
		}
	}
	return makers
}
Esempio n. 15
0
func (e *Entity) drawReticle(pos mathgl.Vec2, rgba [4]float64) {
	if !e.hovered && !e.selected && !e.controlled {
		return
	}
	gl.PushAttrib(gl.CURRENT_BIT)
	r := byte(rgba[0] * 255)
	g := byte(rgba[1] * 255)
	b := byte(rgba[2] * 255)
	a := byte(rgba[3] * 255)
	switch {
	case e.controlled:
		gl.Color4ub(0, 0, r, a)
	case e.selected:
		gl.Color4ub(r, g, b, a)
	default:
		gl.Color4ub(r, g, b, byte((int(a)*200)>>8))
	}
	glow := texture.LoadFromPath(filepath.Join(base.GetDataDir(), "ui", "glow.png"))
	dx := float64(e.last_render_width + 0.5)
	dy := float64(e.last_render_width * 150 / 100)
	glow.Render(float64(pos.X), float64(pos.Y), dx, dy)
	gl.PopAttrib()
}
Esempio n. 16
0
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
}
Esempio n. 17
0
func Init() {
	var err error
	system, err = fmod.EventSystemCreate()
	if err != nil {
		base.Error().Printf("Unable to create sound system: %v", err)
		return
	}

	err = system.Init(32, fmod.INIT_NORMAL, nil, fmod.EVENT_INIT_NORMAL)
	if err != nil {
		base.Error().Printf("Unable to initialize sound system: %v", err)
		return
	}
	version, _ := system.GetVersion()
	base.Log().Printf("Fmod version %x", version)

	err = system.SetMediaPath(filepath.Join(base.GetDataDir(), "sound") + "/")
	if err != nil {
		base.Error().Printf("Unable to set media path: %v\n", err)
		return
	}

	err = system.LoadPath("Haunts.fev", nil)
	if err != nil {
		base.Error().Printf("Unable to load fev: %v\n", err)
		return
	}

	freq = time.Millisecond * 3
	approach = 0.01
	music_volume = make(chan float64, 1)
	music_start = make(chan string, 1)
	param_control = make(chan paramRequest, 1)
	music_stop = make(chan bool, 1)
	go musicControl()
}
Esempio n. 18
0
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.Choose2(&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
}
Esempio n. 19
0
func startGameScript(gp *GamePanel, path string, player *Player, data map[string]string) {
	// Clear out the panel, now the script can do whatever it wants
	player.Script_path = path
	gp.AnchorBox = gui.MakeAnchorBox(gui.Dims{1024, 768})
	base.Log().Printf("startGameScript")
	if !filepath.IsAbs(path) {
		path = filepath.Join(base.GetDataDir(), "scripts", filepath.FromSlash(path))
	}

	// The game script runs in a separate go routine and functions that need to
	// communicate with the game will do so via channels - DUH why did i even
	// write this comment?
	prog, err := ioutil.ReadFile(path)
	if err != nil {
		base.Error().Printf("Unable to load game script file %s: %v", path, err)
		return
	}
	gp.script = &gameScript{}
	base.Log().Printf("script = %p", gp.script)

	gp.script.L = lua.NewState()
	gp.script.L.OpenLibs()
	gp.script.L.SetExecutionLimit(25000)
	gp.script.L.NewTable()
	LuaPushSmartFunctionTable(gp.script.L, FunctionTable{
		"ChooserFromFile":                   func() { gp.script.L.PushGoFunctionAsCFunction(chooserFromFile(gp)) },
		"StartScript":                       func() { gp.script.L.PushGoFunctionAsCFunction(startScript(gp, player)) },
		"SaveGameState":                     func() { gp.script.L.PushGoFunctionAsCFunction(saveGameState(gp)) },
		"LoadGameState":                     func() { gp.script.L.PushGoFunctionAsCFunction(loadGameState(gp)) },
		"DoExec":                            func() { gp.script.L.PushGoFunctionAsCFunction(doExec(gp)) },
		"SelectEnt":                         func() { gp.script.L.PushGoFunctionAsCFunction(selectEnt(gp)) },
		"FocusPos":                          func() { gp.script.L.PushGoFunctionAsCFunction(focusPos(gp)) },
		"SelectHouse":                       func() { gp.script.L.PushGoFunctionAsCFunction(selectHouse(gp)) },
		"LoadHouse":                         func() { gp.script.L.PushGoFunctionAsCFunction(loadHouse(gp)) },
		"SaveStore":                         func() { gp.script.L.PushGoFunctionAsCFunction(saveStore(gp, player)) },
		"ShowMainBar":                       func() { gp.script.L.PushGoFunctionAsCFunction(showMainBar(gp, player)) },
		"SpawnEntityAtPosition":             func() { gp.script.L.PushGoFunctionAsCFunction(spawnEntityAtPosition(gp)) },
		"GetSpawnPointsMatching":            func() { gp.script.L.PushGoFunctionAsCFunction(getSpawnPointsMatching(gp)) },
		"SpawnEntitySomewhereInSpawnPoints": func() { gp.script.L.PushGoFunctionAsCFunction(spawnEntitySomewhereInSpawnPoints(gp)) },
		"IsSpawnPointInLos":                 func() { gp.script.L.PushGoFunctionAsCFunction(isSpawnPointInLos(gp)) },
		"PlaceEntities":                     func() { gp.script.L.PushGoFunctionAsCFunction(placeEntities(gp)) },
		"RoomAtPos":                         func() { gp.script.L.PushGoFunctionAsCFunction(roomAtPos(gp)) },
		"SetLosMode":                        func() { gp.script.L.PushGoFunctionAsCFunction(setLosMode(gp)) },
		"GetAllEnts":                        func() { gp.script.L.PushGoFunctionAsCFunction(getAllEnts(gp)) },
		"DialogBox":                         func() { gp.script.L.PushGoFunctionAsCFunction(dialogBox(gp)) },
		"PickFromN":                         func() { gp.script.L.PushGoFunctionAsCFunction(pickFromN(gp)) },
		"SetGear":                           func() { gp.script.L.PushGoFunctionAsCFunction(setGear(gp)) },
		"BindAi":                            func() { gp.script.L.PushGoFunctionAsCFunction(bindAi(gp)) },
		"SetVisibility":                     func() { gp.script.L.PushGoFunctionAsCFunction(setVisibility(gp)) },
		"EndPlayerInteraction":              func() { gp.script.L.PushGoFunctionAsCFunction(endPlayerInteraction(gp)) },
		"GetLos":                            func() { gp.script.L.PushGoFunctionAsCFunction(getLos(gp)) },
		"SetVisibleSpawnPoints":             func() { gp.script.L.PushGoFunctionAsCFunction(setVisibleSpawnPoints(gp)) },
		"SetCondition":                      func() { gp.script.L.PushGoFunctionAsCFunction(setCondition(gp)) },
		"SetPosition":                       func() { gp.script.L.PushGoFunctionAsCFunction(setPosition(gp)) },
		"SetHp":                             func() { gp.script.L.PushGoFunctionAsCFunction(setHp(gp)) },
		"SetAp":                             func() { gp.script.L.PushGoFunctionAsCFunction(setAp(gp)) },
		"RemoveEnt":                         func() { gp.script.L.PushGoFunctionAsCFunction(removeEnt(gp)) },
		"PlayAnimations":                    func() { gp.script.L.PushGoFunctionAsCFunction(playAnimations(gp)) },
		"PlayMusic":                         func() { gp.script.L.PushGoFunctionAsCFunction(playMusic(gp)) },
		"StopMusic":                         func() { gp.script.L.PushGoFunctionAsCFunction(stopMusic(gp)) },
		"SetMusicParam":                     func() { gp.script.L.PushGoFunctionAsCFunction(setMusicParam(gp)) },
		"PlaySound":                         func() { gp.script.L.PushGoFunctionAsCFunction(playSound(gp)) },
		"SetWaypoint":                       func() { gp.script.L.PushGoFunctionAsCFunction(setWaypoint(gp)) },
		"RemoveWaypoint":                    func() { gp.script.L.PushGoFunctionAsCFunction(removeWaypoint(gp)) },
		"Rand":                              func() { gp.script.L.PushGoFunctionAsCFunction(randFunc(gp)) },
		"Sleep":                             func() { gp.script.L.PushGoFunctionAsCFunction(sleepFunc(gp)) },
	})
	gp.script.L.SetMetaTable(-2)
	gp.script.L.SetGlobal("Script")

	registerUtilityFunctions(gp.script.L)
	if player.Lua_store != nil {
		loadGameStateRaw(gp, player.Game_state)
		err := LuaDecodeTable(bytes.NewBuffer(player.Lua_store), gp.script.L, gp.game)
		if err != nil {
			base.Warn().Printf("Error decoding lua state: %v", err)
		}
		gp.script.L.SetGlobal("store")
	} else {
		gp.script.L.NewTable()
		gp.script.L.SetGlobal("store")
	}
	gp.script.sync = make(chan struct{})
	base.Log().Printf("Sync: %p", gp.script.sync)
	res := gp.script.L.DoString(string(prog))
	if !res {
		base.Error().Printf("There was an error running script %s:\n%s", path, prog)
	} else {
		base.Log().Printf("No_init: %v\n", player.No_init)
		go func() {
			gp.script.L.NewTable()
			for k, v := range data {
				gp.script.L.PushString(k)
				gp.script.L.PushString(v)
				gp.script.L.SetTable(-3)
			}
			gp.script.L.SetGlobal("__data")
			gp.script.L.SetExecutionLimit(250000)
			if player.No_init {
				gp.script.syncStart()
				loadGameStateRaw(gp, player.Game_state)
				gp.game.script = gp.script
				gp.script.syncEnd()
			} else {
				gp.script.L.DoString("Init(__data)")
				if gp.game.Side == SideHaunt {
					gp.game.Ai.minions.Activate()
					gp.game.Ai.denizens.Activate()
					gp.game.player_inactive = gp.game.Ai.denizens.Active()
				} else {
					gp.game.Ai.intruders.Activate()
					gp.game.player_inactive = gp.game.Ai.intruders.Active()
				}

			}
			if gp.game == nil {
				base.Error().Printf("Script failed to load a house during Init().")
			} else {
				gp.game.comm.script_to_game <- nil
			}
		}()
	}
}
Esempio n. 20
0
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

	var net_id mrgnet.NetId
	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(10 * 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.Down.f = func(interface{}) {
			glb.Scroll.Down()
		}

		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
}
Esempio n. 21
0
// bindAi(target, source)
// bindAi("denizen", "denizen.lua")
// bindAi("intruder", "intruder.lua")
// bindAi("minions", "minions.lua")
// bindAi(ent, "fudgecake.lua")
// special sources: "human", "inactive", and in the future: "net"
// special targets: "denizen", "intruder", "minions", or an entity table
func bindAi(gp *GamePanel) lua.GoFunction {
	return func(L *lua.State) int {
		if !LuaCheckParamsOk(L, "BindAi", LuaAnything, LuaString) {
			return 0
		}
		gp.script.syncStart()
		defer gp.script.syncEnd()
		source := L.ToString(-1)
		if L.IsTable(-2) {
			L.PushString("id")
			L.GetTable(-3)
			target := EntityId(L.ToInteger(-1))
			L.Pop(1)
			ent := gp.game.EntityById(target)
			if ent == nil {
				base.Error().Printf("Referenced an entity with id == %d which doesn't exist.", target)
				return 0
			}
			ent.Ai_file_override = base.Path(filepath.Join(base.GetDataDir(), "ais", filepath.FromSlash(L.ToString(-1))))
			ent.LoadAi()
			return 0
		}
		target := L.ToString(-2)
		switch target {
		case "denizen":
			switch source {
			case "human":
				gp.game.Ai.denizens = inactiveAi{}
			case "net":
				base.Error().Printf("bindAi('denizen', 'net') is not implemented.")
				return 0
			default:
				gp.game.Ai.denizens = nil
				path := filepath.Join(base.GetDataDir(), "ais", source)
				gp.game.Ai.Path.Denizens = path
				ai_maker(path, gp.game, nil, &gp.game.Ai.denizens, DenizensAi)
				if gp.game.Ai.denizens == nil {
					gp.game.Ai.denizens = inactiveAi{}
				}
			}
		case "intruder":
			switch source {
			case "human":
				gp.game.Ai.intruders = inactiveAi{}
			case "net":
				base.Error().Printf("bindAi('intruder', 'net') is not implemented.")
				return 0
			default:
				gp.game.Ai.intruders = nil
				path := filepath.Join(base.GetDataDir(), "ais", source)
				gp.game.Ai.Path.Intruders = path
				ai_maker(path, gp.game, nil, &gp.game.Ai.intruders, IntrudersAi)
				if gp.game.Ai.intruders == nil {
					gp.game.Ai.intruders = inactiveAi{}
				}
			}
		case "minions":
			gp.game.Ai.minions = nil
			path := filepath.Join(base.GetDataDir(), "ais", source)
			gp.game.Ai.Path.Minions = path
			ai_maker(path, gp.game, nil, &gp.game.Ai.minions, MinionsAi)
			if gp.game.Ai.minions == nil {
				gp.game.Ai.minions = inactiveAi{}
			}
		default:
			base.Error().Printf("Specified unknown Ai target '%s'", target)
			return 0
		}

		return 0
	}
}
Esempio n. 22
0
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
}
Esempio n. 23
0
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.Back.f = func(interface{}) {
		ui.RemoveChild(&sm)
		InsertStartMenu(ui)
	}

	var net_id mrgnet.NetId
	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))
	}

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

		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.update_user = make(chan mrgnet.UpdateUserResponse)
	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.update_user <- resp
		}()
	}
	go func() {
		var resp mrgnet.UpdateUserResponse
		mrgnet.DoAction("user", mrgnet.UpdateUserRequest{Id: net_id}, &resp)
		sm.update_user <- resp
	}()

	ui.AddChild(&sm)
	return nil
}
Esempio n. 24
0
func makeChooseVersusMetaMenu() (*Chooser, <-chan []string, error) {
	path := filepath.Join(base.GetDataDir(), "ui", "start", "versus", "meta.json")
	return makeChooserFromOptionBasicsFile(path)
}