コード例 #1
0
ファイル: move.go プロジェクト: genbattle/haunts
func (exec *moveExec) measureCost(ent *game.Entity, g *game.Game) int {
	if len(exec.Path) == 0 {
		base.Error().Printf("Zero length path")
		return -1
	}
	if g.ToVertex(ent.Pos()) != exec.Path[0] {
		base.Error().Printf("Path doesn't begin at ent's position, %d != %d", g.ToVertex(ent.Pos()), exec.Path[0])
		return -1
	}
	graph := g.Graph(ent.Side(), true, nil)
	v := g.ToVertex(ent.Pos())
	cost := 0
	for _, step := range exec.Path[1:] {
		dsts, costs := graph.Adjacent(v)
		ok := false
		prev := v
		base.Log().Printf("Adj(%d):", v)
		for j := range dsts {
			base.Log().Printf("Node %d", dsts[j])
			if dsts[j] == step {
				cost += int(costs[j])
				v = dsts[j]
				ok = true
				break
			}
		}
		base.Log().Printf("%d -> %d: %t", prev, v, ok)
		if !ok {
			return -1
		}
	}
	return cost
}
コード例 #2
0
ファイル: ui_versus.go プロジェクト: genbattle/haunts
func InsertVersusMenu(ui gui.WidgetParent, replace func(gui.WidgetParent) error) error {
	// return doChooserMenu(ui, makeChooseVersusMetaMenu, replace, inserter(insertGoalMenu))
	chooser, done, err := makeChooseVersusMetaMenu()
	if err != nil {
		return err
	}
	ui.AddChild(chooser)
	go func() {
		m := <-done
		ui.RemoveChild(chooser)
		if m != nil && len(m) == 1 {
			base.Log().Printf("Chose: %v", m)
			switch m[0] {
			case "Select House":
				ui.AddChild(MakeGamePanel("versus/basic.lua", nil, map[string]string{"map": "select"}, ""))
			case "Random House":
				ui.AddChild(MakeGamePanel("versus/basic.lua", nil, map[string]string{"map": "random"}, ""))
			case "Continue":
				ui.AddChild(MakeGamePanel("versus/basic.lua", nil, map[string]string{"map": "continue"}, ""))
			default:
				base.Error().Printf("Unknown meta choice '%s'", m[0])
				return
			}
		} else {
			err := replace(ui)
			if err != nil {
				base.Error().Printf("Error replacing menu: %v", err)
			}
		}
	}()
	return nil
}
コード例 #3
0
ファイル: aoe_attack.go プロジェクト: genbattle/haunts
func (a *AoeAttack) Maintain(dt int64, g *game.Game, ae game.ActionExec) game.MaintenanceStatus {
	if ae != nil {
		a.exec = ae.(*aoeExec)
		a.targets = a.getTargetsAt(g, a.exec.X, a.exec.Y)
		if a.Current_ammo > 0 {
			a.Current_ammo--
		}
		a.ent = g.EntityById(ae.EntityId())
		if !a.ent.HasLos(a.exec.X, a.exec.Y, 1, 1) {
			base.Error().Printf("Entity %d tried to target position (%d, %d) with an aoe but doesn't have los to it: %v", a.ent.Id, a.exec.X, a.exec.Y, a.exec)
			return game.Complete
		}
		if a.Ap > a.ent.Stats.ApCur() {
			base.Error().Printf("Got an aoe attack that required more ap than available: %v", a.exec)
			return game.Complete
		}
		a.ent.Stats.ApplyDamage(-a.Ap, 0, status.Unspecified)

		// Track this information for the ais - the attacking ent will only
		// remember one ent that it hit, but that's ok
		for _, target := range a.targets {
			if target.Side() != a.ent.Side() {
				target.Info.LastEntThatAttackedMe = a.ent.Id
				a.ent.Info.LastEntThatIAttacked = target.Id
			}
		}
	}
	if a.ent.Sprite().State() != "ready" {
		return game.InProgress
	}
	for _, target := range a.targets {
		if target.Stats.HpCur() > 0 && target.Sprite().State() != "ready" {
			return game.InProgress
		}
	}
	a.ent.TurnToFace(a.exec.X, a.exec.Y)
	for _, target := range a.targets {
		target.TurnToFace(a.ent.Pos())
	}
	a.ent.Sprite().Command(a.Animation)
	for _, target := range a.targets {
		if g.DoAttack(a.ent, target, a.Strength, a.Kind) {
			for _, name := range a.Conditions {
				target.Stats.ApplyCondition(status.MakeCondition(name))
			}
			target.Stats.ApplyDamage(0, -a.Damage, a.Kind)
			if target.Stats.HpCur() <= 0 {
				target.Sprite().CommandN([]string{"defend", "killed"})
			} else {
				target.Sprite().CommandN([]string{"defend", "damaged"})
			}
		} else {
			target.Sprite().CommandN([]string{"defend", "undamaged"})
		}
	}
	return game.Complete
}
コード例 #4
0
ファイル: basic_attack.go プロジェクト: genbattle/haunts
func (a *BasicAttack) Maintain(dt int64, g *game.Game, ae game.ActionExec) game.MaintenanceStatus {
	if ae != nil {
		a.exec = ae.(*basicAttackExec)
		a.ent = g.EntityById(ae.EntityId())
		a.target = a.ent.Game().EntityById(a.exec.Target)

		// Track this information for the ais
		if a.ent.Side() != a.target.Side() {
			a.ent.Info.LastEntThatIAttacked = a.target.Id
			a.target.Info.LastEntThatAttackedMe = a.ent.Id
		}

		if a.Ap > a.ent.Stats.ApCur() {
			base.Error().Printf("Got a basic attack that required more ap than available: %v", a.exec)
			base.Error().Printf("Ent: %s, Ap: %d", a.ent.Name, a.ent.Stats.ApCur())
			return game.Complete
		}

		if !a.validTarget(a.ent, a.target) {
			base.Error().Printf("Got a basic attack that was invalid for some reason: %v", a.exec)
			return game.Complete
		}
	}
	if a.ent.Sprite().State() == "ready" && a.target.Sprite().State() == "ready" {
		a.target.TurnToFace(a.ent.Pos())
		a.ent.TurnToFace(a.target.Pos())
		if a.Current_ammo > 0 {
			a.Current_ammo--
		}
		a.ent.Stats.ApplyDamage(-a.Ap, 0, status.Unspecified)
		var defender_cmds []string
		if g.DoAttack(a.ent, a.target, a.Strength, a.Kind) {
			for _, name := range a.Conditions {
				a.target.Stats.ApplyCondition(status.MakeCondition(name))
			}
			a.target.Stats.ApplyDamage(0, -a.Damage, a.Kind)
			if a.target.Stats.HpCur() <= 0 {
				defender_cmds = []string{"defend", "killed"}
			} else {
				defender_cmds = []string{"defend", "damaged"}
			}
			results[a.exec.id] = BasicAttackResult{Hit: true}
		} else {
			defender_cmds = []string{"defend", "undamaged"}
			results[a.exec.id] = BasicAttackResult{Hit: false}
		}
		sprites := []*sprite.Sprite{a.ent.Sprite(), a.target.Sprite()}
		sprite.CommandSync(sprites, [][]string{[]string{a.Animation}, defender_cmds}, "hit")
		return game.Complete
	}
	return game.InProgress
}
コード例 #5
0
ファイル: ui_dialog.go プロジェクト: genbattle/haunts
func (mdb *MediumDialogBox) Draw(region gui.Region) {
	mdb.region = region
	if mdb.done {
		return
	}
	gl.Enable(gl.TEXTURE_2D)
	gl.Color4ub(255, 255, 255, 255)
	mdb.layout.Background.Data().RenderNatural(region.X, region.Y)
	for _, button := range mdb.buttons {
		button.RenderAt(region.X, region.Y)
	}

	for i := range mdb.format.Sections {
		section := mdb.format.Sections[i]
		data := mdb.data.Pages[mdb.data.cur_page].Sections[i]
		p := section.Paragraph
		d := base.GetDictionary(p.Size)
		var just gui.Justification
		switch p.Halign {
		case "left":
			just = gui.Left
		case "right":
			just = gui.Right
		case "center":
			just = gui.Center
		default:
			base.Error().Printf("Unknown justification '%s'", p.Halign)
			p.Halign = "left"
		}
		var valign gui.Justification
		switch p.Valign {
		case "top":
			valign = gui.Top
		case "bottom":
			valign = gui.Bottom
		case "center":
			valign = gui.Center
		default:
			base.Error().Printf("Unknown justification '%s'", p.Valign)
			p.Valign = "top"
		}
		gl.Color4ub(255, 255, 255, 255)

		d.RenderParagraph(data.Text, float64(p.X+region.X), float64(p.Y+region.Y)-d.MaxHeight()/2, 0, float64(p.Dx), d.MaxHeight(), just, valign)

		gl.Color4ub(255, 255, 255, byte(data.shading*255))
		tex := data.Image.Data()
		tex.RenderNatural(region.X+section.X-tex.Dx()/2, region.Y+section.Y-tex.Dy()/2)
	}
}
コード例 #6
0
ファイル: summon.go プロジェクト: genbattle/haunts
func (a *SummonAction) Maintain(dt int64, g *game.Game, ae game.ActionExec) game.MaintenanceStatus {
	if ae != nil {
		exec := ae.(*summonExec)
		ent := g.EntityById(exec.Ent)
		if ent == nil {
			base.Error().Printf("Got a summon action without a valid entity.")
			return game.Complete
		}
		a.ent = ent
		_, a.cx, a.cy = a.ent.Game().FromVertex(exec.Pos)
		a.ent.Stats.ApplyDamage(-a.Ap, 0, status.Unspecified)
		a.spawn = game.MakeEntity(a.Ent_name, a.ent.Game())
		if a.Current_ammo > 0 {
			a.Current_ammo--
		}
	}
	if a.ent.Sprite().State() == "ready" {
		a.ent.TurnToFace(a.cx, a.cy)
		a.ent.Sprite().Command(a.Animation)
		a.spawn.Stats.OnBegin()
		a.ent.Game().SpawnEntity(a.spawn, a.cx, a.cy)
		return game.Complete
	}
	return game.InProgress
}
コード例 #7
0
ファイル: spawn.go プロジェクト: genbattle/haunts
func PopSpawnRegexp() {
	if len(spawn_regex) == 0 {
		base.Error().Printf("Tried to pop an empty stack.")
		return
	}
	spawn_regex = spawn_regex[0 : len(spawn_regex)-1]
}
コード例 #8
0
ファイル: script_utils.go プロジェクト: genbattle/haunts
func LuaPushSmartFunctionTable(L *lua.State, ft FunctionTable) {
	// Copy it just in case - I can't imagine someone changing it after passing
	// it to this function, but I don't want to take any chances.
	myft := make(FunctionTable)
	for n, f := range ft {
		myft[n] = f
	}
	names := make([]string, len(myft))[0:0]
	for name := range myft {
		names = append(names, name)
	}
	sort.Strings(names)
	valid_selectors := "["
	for i, name := range names {
		if i > 0 {
			valid_selectors += ", "
		}
		valid_selectors += fmt.Sprintf("'%s'", name)
	}
	valid_selectors += "]."

	L.NewTable()
	L.PushString("__index")
	L.PushGoFunction(func(L *lua.State) int {
		name := L.ToString(-1)
		if f, ok := myft[name]; ok {
			f()
		} else {
			base.Error().Printf("'%s' is not a valid selector, valid seletors are %s", name, valid_selectors)
			L.PushNil()
		}
		return 1
	})
	L.SetTable(-3)
}
コード例 #9
0
ファイル: action.go プロジェクト: genbattle/haunts
func MakeAction(name string) Action {
	f, ok := action_map[name]
	if !ok {
		base.Error().Printf("Unable to find an Action named '%s'", name)
	}
	return f()
}
コード例 #10
0
ファイル: ai.go プロジェクト: genbattle/haunts
func makeAi(path string, g *game.Game, ent *game.Entity, dst_iface *game.Ai, kind game.AiKind) {
	ai_struct := new(Ai)
	ai_struct.path = path
	var err error
	ai_struct.watcher, err = fsnotify.NewWatcher()
	if err != nil {
		base.Warn().Printf("Unable to create a filewatcher - '%s' will not reload ai files dynamically: %v", path, err)
		ai_struct.watcher = nil
	}
	ai_struct.ent = ent
	ai_struct.game = g

	ai_struct.active_set = make(chan bool)
	ai_struct.active_query = make(chan bool)
	ai_struct.exec_query = make(chan struct{})
	ai_struct.pause = make(chan struct{})
	ai_struct.terminate = make(chan struct{})
	ai_struct.execs = make(chan game.ActionExec)
	ai_struct.kind = kind

	err = ai_struct.setupLuaState()
	if err != nil {
		base.Error().Printf("Unable to make ai: %v", err)
		if ai_struct.watcher != nil {
			ai_struct.watcher.Close()
		}
		dst_iface = nil
		return
	}
	go ai_struct.masterRoutine()

	*dst_iface = ai_struct
}
コード例 #11
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
}
コード例 #12
0
ファイル: conditions.go プロジェクト: genbattle/haunts
func MakeCondition(name string) Condition {
	maker, ok := condition_makers[name]
	if !ok {
		base.Error().Printf("Unable to find a Condition named '%s'", name)
		return condition_makers["Error"]()
	}
	return maker()
}
コード例 #13
0
ファイル: entity.go プロジェクト: genbattle/haunts
func (ei *entityDef) Dims() (int, int) {
	if ei.Dx <= 0 || ei.Dy <= 0 {
		base.Error().Printf("Entity '%s' didn't have its Dims set properly", ei.Name)
		ei.Dx = 1
		ei.Dy = 1
	}
	return ei.Dx, ei.Dy
}
コード例 #14
0
ファイル: action.go プロジェクト: genbattle/haunts
func encodeActionExec(ae ActionExec) []byte {
	b := bytes.NewBuffer(nil)
	enc := gob.NewEncoder(b)
	err := enc.Encode(ae)
	if err != nil {
		base.Error().Printf("Failed to gob an ActionExec: %v", err)
		return nil
	}
	return b.Bytes()
}
コード例 #15
0
ファイル: action.go プロジェクト: genbattle/haunts
func decodeActionExec(b []byte) ActionExec {
	var ae ActionExec
	dec := gob.NewDecoder(bytes.NewReader(b))
	err := dec.Decode(&ae)
	if err != nil {
		base.Error().Printf("Failed to ungob an ActionExec: %v", err)
		return nil
	}
	return ae
}
コード例 #16
0
ファイル: los.go プロジェクト: genbattle/haunts
func (g *Game) SetVisibility(side Side) {
	switch side {
	case SideHaunt:
		g.viewer.Los_tex = g.los.denizens.tex
	case SideExplorers:
		g.viewer.Los_tex = g.los.intruders.tex
	default:
		base.Error().Printf("Unable to SetVisibility for side == %d.", side)
		return
	}
}
コード例 #17
0
ファイル: spawn.go プロジェクト: genbattle/haunts
func PushSpawnRegexp(pattern string) {
	re, err := regexp.Compile(pattern)
	if err != nil {
		base.Error().Printf("Unable to compile regexp: '%s': %v", pattern, err)
		// Just duplicate the top one, since this will probably come with an
		// associated pop.
		spawn_regex = append(spawn_regex, topSpawnRegexp())
		return
	}
	spawn_regex = append(spawn_regex, re)
}
コード例 #18
0
ファイル: manager.go プロジェクト: genbattle/haunts
func PlaySound(name string, volume float64) {
	if system == nil {
		return
	}
	sound, err := system.GetEvent(name, fmod.MODE_DEFAULT)
	if err != nil {
		base.Error().Printf("Unable to get event '%s': %v", name, err)
		return
	}
	sound.SetVolume(volume)
	sound.Start()
}
コード例 #19
0
ファイル: action.go プロジェクト: genbattle/haunts
func (bae *BasicActionExec) SetBasicData(ent *Entity, action Action) {
	bae.Ent = ent.Id
	bae.Index = -1
	for i := range ent.Actions {
		if ent.Actions[i] == action {
			bae.Index = i
		}
	}
	if bae.Index == -1 {
		base.Error().Printf("Action '%v' was unable to find itself in Entity %v's Actions: %v", action, ent, ent.Actions)
	}
}
コード例 #20
0
ファイル: entity.go プロジェクト: genbattle/haunts
func (e *Entity) SetGear(gear_name string) bool {
	if e.ExplorerEnt == nil {
		base.Error().Printf("Tried to set gear on a non-explorer entity.")
		return false
	}
	if e.ExplorerEnt.Gear != nil && gear_name != "" {
		base.Error().Printf("Tried to set gear on an explorer that already had gear.")
		return false
	}
	if e.ExplorerEnt.Gear == nil && gear_name == "" {
		base.Error().Printf("Tried to remove gear from an explorer with no gear.")
		return false
	}
	if gear_name == "" {
		algorithm.Choose(&e.Actions, func(a Action) bool {
			return a.String() != e.ExplorerEnt.Gear.Action
		})
		if e.ExplorerEnt.Gear.Condition != "" {
			e.Stats.RemoveCondition(e.ExplorerEnt.Gear.Condition)
		}
		e.ExplorerEnt.Gear = nil
		return true
	}
	var g Gear
	g.Defname = gear_name
	base.GetObject("gear", &g)
	if g.Name == "" {
		base.Error().Printf("Tried to load gear '%s' that doesn't exist.", gear_name)
		return false
	}
	e.ExplorerEnt.Gear = &g
	if g.Action != "" {
		e.Actions = append(e.Actions, MakeAction(g.Action))
	}
	if g.Condition != "" {
		e.Stats.ApplyCondition(status.MakeCondition(g.Condition))
	}
	return true
}
コード例 #21
0
ファイル: entity.go プロジェクト: genbattle/haunts
func (ei *entityDef) Side() Side {
	types := 0
	if ei.ExplorerEnt != nil {
		types++
	}
	if ei.HauntEnt != nil {
		types++
	}
	if ei.ObjectEnt != nil {
		types++
	}
	if types > 1 {
		base.Error().Printf("Entity '%s' must specify exactly zero or one ent type.", ei.Name)
		return SideNone
	}

	switch {
	case ei.ExplorerEnt != nil:
		return SideExplorers

	case ei.HauntEnt != nil:
		switch ei.HauntEnt.Level {
		case LevelMinion:
		case LevelMaster:
		case LevelServitor:
		default:
			base.Error().Printf("Entity '%s' speciied unknown level '%s'.", ei.Name, ei.HauntEnt.Level)
		}
		return SideHaunt

	case ei.ObjectEnt != nil:
		return SideObject

	default:
		return SideNpc
	}

	return SideNone
}
コード例 #22
0
ファイル: move.go プロジェクト: genbattle/haunts
func (a *Move) Maintain(dt int64, g *game.Game, ae game.ActionExec) game.MaintenanceStatus {
	if ae != nil {
		exec := ae.(*moveExec)
		a.ent = g.EntityById(ae.EntityId())
		if len(exec.Path) == 0 {
			base.Error().Printf("Got a move exec with a path length of 0: %v", exec)
			return game.Complete
		}
		a.cost = exec.measureCost(a.ent, g)
		if a.cost > a.ent.Stats.ApCur() {
			base.Error().Printf("Got a move that required more ap than available: %v", exec)
			base.Error().Printf("Path: %v", exec.Path)
			return game.Complete
		}
		if a.cost == -1 {
			base.Error().Printf("Got a move that followed an invalid path: %v", exec)
			base.Error().Printf("Path: %v", exec.Path)
			if a.ent == nil {
				base.Error().Printf("ENT was Nil!")
			} else {
				x, y := a.ent.Pos()
				v := g.ToVertex(x, y)
				base.Error().Printf("Ent pos: (%d, %d) -> (%d)", x, y, v)
			}
			return game.Complete
		}
		algorithm.Map2(exec.Path, &a.path, func(v int) [2]int {
			_, x, y := g.FromVertex(v)
			return [2]int{x, y}
		})
		base.Log().Printf("Path Validated: %v", exec)
		a.ent.Stats.ApplyDamage(-a.cost, 0, status.Unspecified)
		src := g.ToVertex(a.ent.Pos())
		graph := g.Graph(a.ent.Side(), true, nil)
		a.drawPath(a.ent, g, graph, src)
	}
	// Do stuff
	factor := float32(math.Pow(2, a.ent.Walking_speed))
	dist := a.ent.DoAdvance(factor*float32(dt)/200, a.path[0][0], a.path[0][1])
	for dist > 0 {
		if len(a.path) == 1 {
			a.ent.DoAdvance(0, 0, 0)
			a.ent.Info.RoomsExplored[a.ent.CurrentRoom()] = true
			a.ent = nil
			return game.Complete
		}
		a.path = a.path[1:]
		a.ent.Info.RoomsExplored[a.ent.CurrentRoom()] = true
		dist = a.ent.DoAdvance(dist, a.path[0][0], a.path[0][1])
	}
	return game.InProgress
}
コード例 #23
0
ファイル: los.go プロジェクト: genbattle/haunts
func (g *Game) mergeLos(side Side) {
	var pix [][]byte
	switch side {
	case SideHaunt:
		pix = g.los.denizens.tex.Pix()
	case SideExplorers:
		pix = g.los.intruders.tex.Pix()
	default:
		base.Error().Printf("Unable to mergeLos on side %d.", side)
		return
	}
	for i := range g.los.full_merger {
		g.los.full_merger[i] = false
	}
	for _, ent := range g.Ents {
		if ent.Side() != side && !ent.Enemy_los {
			continue
		}
		if ent.los == nil {
			continue
		}
		for i := ent.los.minx; i <= ent.los.maxx; i++ {
			for j := ent.los.miny; j <= ent.los.maxy; j++ {
				if ent.los.grid[i][j] {
					g.los.merger[i][j] = true
				}
			}
		}
	}
	for i := 0; i < len(pix); i++ {
		for j := 0; j < len(pix); j++ {
			if g.los.merger[i][j] {
				continue
			}
			if pix[i][j] >= house.LosVisibilityThreshold {
				pix[i][j] = house.LosVisibilityThreshold - 1
			}
		}
	}
	for i := range g.los.merger {
		for j := range g.los.merger[i] {
			if g.los.merger[i][j] {
				if pix[i][j] < house.LosVisibilityThreshold {
					pix[i][j] = house.LosVisibilityThreshold
				}
			}
		}
	}
}
コード例 #24
0
ファイル: ui_versus.go プロジェクト: genbattle/haunts
func doChooserMenu(ui gui.WidgetParent, cm chooserMaker, r replacer, i inserter) error {
	chooser, done, err := cm()
	if err != nil {
		return err
	}
	ui.AddChild(chooser)
	go func() {
		m := <-done
		ui.RemoveChild(chooser)
		if m != nil {
			base.Log().Printf("Chose: %v", m)
			err = i(ui, r)
			if err != nil {
				base.Error().Printf("Error making menu: %v", err)
			}
		} else {
			err := r(ui)
			if err != nil {
				base.Error().Printf("Error replacing menu: %v", err)
			}
		}
	}()
	return nil
}
コード例 #25
0
ファイル: ui_versus.go プロジェクト: genbattle/haunts
func insertGoalMenu(ui gui.WidgetParent, replace replacer) error {
	chooser, done, err := makeChooseGoalMenu()
	if err != nil {
		return err
	}
	ui.AddChild(chooser)
	go func() {
		m := <-done
		ui.RemoveChild(chooser)
		if m != nil {
			base.Log().Printf("Chose: %v", m)
			err = insertGoalMenu(ui, replace)
			if err != nil {
				base.Error().Printf("Error making goal menu: %v", err)
			}
		} else {
			err := replace(ui)
			if err != nil {
				base.Error().Printf("Error replacing menu: %v", err)
			}
		}
	}()
	return nil
}
コード例 #26
0
ファイル: action.go プロジェクト: genbattle/haunts
func (bae BasicActionExec) Push(L *lua.State, g *Game) {
	ent := g.EntityById(bae.Ent)
	if bae.Index < 0 || bae.Index >= len(ent.Actions) {
		base.Error().Printf("Tried to push an exec for an invalid action index: '%s' %d.", ent.Name)
		L.PushNil()
		return
	}
	L.NewTable()
	L.PushString("Action")
	ent.Actions[bae.Index].Push(L)
	L.SetTable(-3)
	L.PushString("Ent")
	LuaPushEntity(L, ent)
	L.SetTable(-3)
}
コード例 #27
0
ファイル: manager.go プロジェクト: genbattle/haunts
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()
}
コード例 #28
0
ファイル: entity.go プロジェクト: genbattle/haunts
// Tries to place new_ent in the game at its current position.  Returns true
// on success, false otherwise.
// pattern is a regexp that matches only the names of all valid spawn points.
func (g *Game) placeEntity(pattern string) bool {
	if g.new_ent == nil {
		base.Log().Printf("No new ent")
		return false
	}
	re, err := regexp.Compile(pattern)
	if err != nil {
		base.Error().Printf("Failed to compile regexp: '%s': %v", pattern, err)
		return false
	}
	g.new_ent.Info.RoomsExplored[g.new_ent.CurrentRoom()] = true
	ix, iy := int(g.new_ent.X), int(g.new_ent.Y)
	idx, idy := g.new_ent.Dims()
	r, f, _ := g.House.Floors[0].RoomFurnSpawnAtPos(ix, iy)

	if r == nil || f != nil {
		return false
	}
	for _, e := range g.Ents {
		x, y := e.Pos()
		dx, dy := e.Dims()
		r1 := image.Rect(x, y, x+dx, y+dy)
		r2 := image.Rect(ix, iy, ix+idx, iy+idy)
		if r1.Overlaps(r2) {
			return false
		}
	}

	// Check for spawn points
	for _, spawn := range g.House.Floors[0].Spawns {
		if !re.MatchString(spawn.Name) {
			continue
		}
		x, y := spawn.Pos()
		dx, dy := spawn.Dims()
		if ix < x || ix+idx > x+dx {
			continue
		}
		if iy < y || iy+idy > y+dy {
			continue
		}
		g.Ents = append(g.Ents, g.new_ent)
		g.new_ent = nil
		return true
	}
	return false
}
コード例 #29
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
}
コード例 #30
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
}