Пример #1
0
func setWaypoint(gp *GamePanel) lua.GoFunction {
	return func(L *lua.State) int {
		if !LuaCheckParamsOk(L, "SetWaypoint", LuaString, LuaString, LuaPoint, LuaFloat) {
			return 0
		}
		gp.script.syncStart()
		defer gp.script.syncEnd()

		var wp waypoint
		side_str := L.ToString(-3)
		switch side_str {
		case "intruders":
			wp.Side = SideExplorers
		case "denizens":
			wp.Side = SideHaunt
		default:
			base.Error().Printf("Specified '%s' for the side parameter in SetWaypoint, must be 'intruders' or 'denizens'.", side_str)
			return 0
		}
		wp.Name = L.ToString(-4)
		// Remove any existing waypoint by the same name
		algorithm.Choose2(&gp.game.Waypoints, func(w waypoint) bool {
			return w.Name != wp.Name
		})
		px, py := LuaToPoint(L, -2)
		wp.X = float64(px)
		wp.Y = float64(py)
		wp.Radius = L.ToNumber(-1)
		gp.game.Waypoints = append(gp.game.Waypoints, wp)
		return 0
	}
}
Пример #2
0
func (a *AoeAttack) getTargetsAt(g *game.Game, tx, ty int) []*game.Entity {
	x := tx - (a.Diameter+1)/2
	y := ty - (a.Diameter+1)/2
	x2 := tx + a.Diameter/2
	y2 := ty + a.Diameter/2

	// If the diameter is even we need to run los from all four positions
	// around the center of the aoe.
	num_centers := 1
	if a.Diameter%2 == 0 {
		num_centers = 4
	}

	var targets []*game.Entity
	for i := 0; i < num_centers; i++ {
		// If num_centers is 4 then this will calculate the los for all four
		// positions around the center
		g.DetermineLos(tx+i%2, ty+i/2, a.Diameter, grid[i])
	}
	for _, ent := range g.Ents {
		entx, enty := ent.Pos()
		has_los := false
		for i := 0; i < num_centers; i++ {
			has_los = has_los || grid[i][entx][enty]
		}
		if has_los && entx >= x && entx < x2 && enty >= y && enty < y2 {
			targets = append(targets, ent)
		}
	}
	algorithm.Choose2(&targets, func(e *game.Entity) bool {
		return e.Stats != nil
	})

	return targets
}
Пример #3
0
func (w *WallPanel) onEscape() {
	if w.wall_texture != nil {
		if w.prev_wall_texture != nil {
			*w.wall_texture = *w.prev_wall_texture
		} else {
			algorithm.Choose2(&w.room.WallTextures, func(wt *WallTexture) bool {
				return wt != w.wall_texture
			})
		}
	}
	w.wall_texture = nil
	w.prev_wall_texture = nil
}
Пример #4
0
func (w *FurniturePanel) onEscape() {
	if w.furniture != nil {
		if w.prev_object != nil {
			*w.furniture = *w.prev_object
			w.prev_object = nil
		} else {
			algorithm.Choose2(&w.Room.Furniture, func(f *Furniture) bool {
				return f != w.furniture
			})
		}
		w.furniture = nil
	}
}
Пример #5
0
func (hdt *houseRelicsTab) onEscape() {
	if hdt.temp_relic != nil {
		if hdt.prev_relic != nil {
			*hdt.temp_relic = *hdt.prev_relic
			hdt.prev_relic = nil
		} else {
			algorithm.Choose2(&hdt.house.Floors[0].Spawns, func(s *SpawnPoint) bool {
				return s != hdt.temp_relic
			})
		}
		hdt.temp_relic = nil
	}
}
Пример #6
0
func (w *WallPanel) Respond(ui *gui.Gui, group gui.EventGroup) bool {
	if w.VerticalTable.Respond(ui, group) {
		return true
	}

	if found, event := group.FindEvent(gin.DeleteOrBackspace); found && event.Type == gin.Press {
		algorithm.Choose2(&w.room.WallTextures, func(wt *WallTexture) bool {
			return wt != w.wall_texture
		})
		w.wall_texture = nil
		w.prev_wall_texture = nil
		return true
	}

	if found, event := group.FindEvent(gin.Escape); found && event.Type == gin.Press {
		w.onEscape()
		return true
	}

	if found, event := group.FindEvent(base.GetDefaultKeyMap()["flip"].Id()); found && event.Type == gin.Press {
		if w.wall_texture != nil {
			w.wall_texture.Flip = !w.wall_texture.Flip
		}
		return true
	}
	if found, event := group.FindEvent(gin.MouseWheelVertical); found {
		if w.wall_texture != nil && gin.In().GetKey(gin.Space).CurPressAmt() == 0 {
			w.wall_texture.Rot += float32(event.Key.CurPressAmt() / 100)
		}
	}
	if found, event := group.FindEvent(gin.MouseLButton); found && event.Type == gin.Press {
		if w.wall_texture != nil {
			w.wall_texture.temporary = false
			w.wall_texture = nil
		} else if w.wall_texture == nil {
			w.wall_texture = w.textureNear(event.Key.Cursor().Point())
			if w.wall_texture != nil {
				w.prev_wall_texture = new(WallTexture)
				*w.prev_wall_texture = *w.wall_texture
				w.wall_texture.temporary = true

				wx, wy := w.viewer.BoardToWindowf(w.wall_texture.X, w.wall_texture.Y)
				px, py := event.Key.Cursor().Point()
				w.drag_anchor.X = float32(px) - wx
				w.drag_anchor.Y = float32(py) - wy
			}
		}
		return true
	}
	return false
}
Пример #7
0
func Chooser2Spec(c gospec.Context) {
	c.Specify("Choose on []int", func() {
		a := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
		b := make([]int, len(a))
		copy(b, a)
		algorithm.Choose2(&b, func(v int) bool { return v%2 == 0 })
		c.Expect(b, ContainsInOrder, []int{0, 2, 4, 6, 8})

		b = make([]int, len(a))
		copy(b, a)
		algorithm.Choose2(&b, func(v int) bool { return v%2 == 1 })
		c.Expect(b, ContainsInOrder, []int{1, 3, 5, 7, 9})

		b = make([]int, len(a))
		copy(b, a)
		algorithm.Choose2(&b, func(v int) bool { return true })
		c.Expect(b, ContainsInOrder, a)

		b = make([]int, len(a))
		copy(b, a)
		algorithm.Choose2(&b, func(v int) bool { return false })
		c.Expect(b, ContainsInOrder, []int{})

		b = b[0:0]
		algorithm.Choose2(&b, func(v int) bool { return false })
		c.Expect(b, ContainsInOrder, []int{})
	})

	c.Specify("Choose on []string", func() {
		a := []string{"foo", "bar", "wing", "ding", "monkey", "machine"}
		b := make([]string, len(a))
		copy(b, a)
		algorithm.Choose2(&b, func(v string) bool { return v > "foo" })
		c.Expect(b, ContainsInOrder, []string{"wing", "monkey", "machine"})

		b = make([]string, len(a))
		copy(b, a)
		algorithm.Choose2(&b, func(v string) bool { return v < "foo" })
		c.Expect(b, ContainsInOrder, []string{"bar", "ding"})

		b = make([]string, len(a))
		copy(b, a)
		algorithm.Choose2(&b, func(v string) bool { return true })
		c.Expect(b, ContainsInOrder, a)
	})
}
Пример #8
0
func (hdt *houseRelicsTab) Respond(ui *gui.Gui, group gui.EventGroup) bool {
	if hdt.VerticalTable.Respond(ui, group) {
		return true
	}

	if found, event := group.FindEvent(gin.Escape); found && event.Type == gin.Press {
		hdt.onEscape()
		return true
	}

	if found, event := group.FindEvent(gin.DeleteOrBackspace); found && event.Type == gin.Press {
		algorithm.Choose2(&hdt.house.Floors[0].Spawns, func(s *SpawnPoint) bool {
			return s != hdt.temp_relic
		})
		hdt.temp_relic = nil
		hdt.prev_relic = nil
		return true
	}

	cursor := group.Events[0].Key.Cursor()
	floor := hdt.house.Floors[hdt.current_floor]
	if found, event := group.FindEvent(gin.MouseLButton); found && event.Type == gin.Press {
		if hdt.temp_relic != nil {
			if !hdt.temp_relic.invalid {
				hdt.temp_relic.temporary = false
				hdt.temp_relic = nil
			}
		} else {
			for _, sp := range floor.Spawns {
				fbx, fby := hdt.viewer.WindowToBoard(cursor.Point())
				bx, by := roundDown(fbx), roundDown(fby)
				x, y := sp.Pos()
				dx, dy := sp.Dims()
				if bx >= x && bx < x+dx && by >= y && by < y+dy {
					hdt.temp_relic = sp
					hdt.prev_relic = new(SpawnPoint)
					*hdt.prev_relic = *hdt.temp_relic
					hdt.temp_relic.temporary = true
					hdt.drag_anchor.x = fbx - float32(hdt.temp_relic.X)
					hdt.drag_anchor.y = fby - float32(hdt.temp_relic.Y)
					break
				}
			}
		}
	}
	return false
}
Пример #9
0
func (hdt *houseDoorTab) onEscape() {
	if hdt.temp_door != nil {
		if hdt.temp_room != nil {
			algorithm.Choose2(&hdt.temp_room.Doors, func(d *Door) bool {
				return d != hdt.temp_door
			})
		}
		if hdt.prev_door != nil {
			hdt.prev_room.Doors = append(hdt.prev_room.Doors, hdt.prev_door)
			hdt.prev_door.state.pos = -1 // forces it to redo its gl data
			hdt.prev_door = nil
			hdt.prev_room = nil
		}
		hdt.temp_door = nil
		hdt.temp_room = nil
	}
}
Пример #10
0
func (hdt *houseDataTab) onEscape() {
	if hdt.prev_room != nil {
		dx := hdt.prev_room.X - hdt.temp_room.X
		dy := hdt.prev_room.Y - hdt.temp_room.Y
		for i := range hdt.temp_spawns {
			hdt.temp_spawns[i].X += dx
			hdt.temp_spawns[i].Y += dy
		}
		*hdt.temp_room = *hdt.prev_room
		hdt.prev_room = nil
	} else {
		algorithm.Choose2(&hdt.house.Floors[0].Rooms, func(r *Room) bool {
			return r != hdt.temp_room
		})
	}
	hdt.temp_room = nil
}
Пример #11
0
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.Choose2(&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
}
Пример #12
0
func (hv *HouseViewer) RemoveDrawable(d Drawable) {
	algorithm.Choose2(&hv.drawables, func(t Drawable) bool {
		return t != d
	})
}
Пример #13
0
func (hdt *houseDoorTab) Respond(ui *gui.Gui, group gui.EventGroup) bool {
	if hdt.VerticalTable.Respond(ui, group) {
		return true
	}

	if found, event := group.FindEvent(gin.Escape); found && event.Type == gin.Press {
		hdt.onEscape()
		return true
	}

	if found, event := group.FindEvent(gin.DeleteOrBackspace); found && event.Type == gin.Press {
		algorithm.Choose2(&hdt.temp_room.Doors, func(d *Door) bool {
			return d != hdt.temp_door
		})
		hdt.temp_room = nil
		hdt.temp_door = nil
		hdt.prev_room = nil
		hdt.prev_door = nil
		return true
	}

	cursor := group.Events[0].Key.Cursor()
	var bx, by float32
	if cursor != nil {
		bx, by = hdt.viewer.WindowToBoard(cursor.Point())
	}
	if cursor != nil && hdt.temp_door != nil {
		room := hdt.viewer.FindClosestDoorPos(hdt.temp_door, bx, by)
		if room != hdt.temp_room {
			algorithm.Choose2(&hdt.temp_room.Doors, func(d *Door) bool {
				return d != hdt.temp_door
			})
			hdt.temp_room = room
			hdt.temp_door.invalid = (hdt.temp_room == nil)
			hdt.temp_room.Doors = append(hdt.temp_room.Doors, hdt.temp_door)
		}
		if hdt.temp_room == nil {
			hdt.temp_door.invalid = true
		} else {
			other_room, _ := hdt.house.Floors[0].findRoomForDoor(hdt.temp_room, hdt.temp_door)
			hdt.temp_door.invalid = (other_room == nil)
		}
	}

	floor := hdt.house.Floors[hdt.current_floor]
	if found, event := group.FindEvent(gin.MouseLButton); found && event.Type == gin.Press {
		if hdt.temp_door != nil {
			other_room, other_door := floor.findRoomForDoor(hdt.temp_room, hdt.temp_door)
			if other_room != nil {
				other_room.Doors = append(other_room.Doors, other_door)
				hdt.temp_door.temporary = false
				hdt.temp_door = nil
				hdt.prev_door = nil
			}
		} else {
			hdt.temp_room, hdt.temp_door = hdt.viewer.FindClosestExistingDoor(bx, by)
			if hdt.temp_door != nil {
				hdt.prev_door = new(Door)
				*hdt.prev_door = *hdt.temp_door
				hdt.prev_room = hdt.temp_room
				hdt.temp_door.temporary = true
				room, door := hdt.house.Floors[0].FindMatchingDoor(hdt.temp_room, hdt.temp_door)
				if room != nil {
					algorithm.Choose2(&room.Doors, func(d *Door) bool {
						return d != door
					})
				}
			}
		}
		return true
	}

	return false
}
Пример #14
0
func (hdt *houseDataTab) Respond(ui *gui.Gui, group gui.EventGroup) bool {
	if hdt.VerticalTable.Respond(ui, group) {
		return true
	}

	if found, event := group.FindEvent(gin.Escape); found && event.Type == gin.Press {
		hdt.onEscape()
		return true
	}

	if found, event := group.FindEvent(gin.DeleteOrBackspace); found && event.Type == gin.Press {
		if hdt.temp_room != nil {
			spawns := make(map[*SpawnPoint]bool)
			for i := range hdt.temp_spawns {
				spawns[hdt.temp_spawns[i]] = true
			}
			algorithm.Choose2(&hdt.house.Floors[0].Spawns, func(s *SpawnPoint) bool {
				return !spawns[s]
			})
			algorithm.Choose2(&hdt.house.Floors[0].Rooms, func(r *Room) bool {
				return r != hdt.temp_room
			})
			hdt.temp_room = nil
			hdt.prev_room = nil
			hdt.viewer.SetBounds()
		}
		return true
	}

	floor := hdt.house.Floors[hdt.current_floor]
	if found, event := group.FindEvent(gin.MouseLButton); found && event.Type == gin.Press {
		if hdt.temp_room != nil {
			if !hdt.temp_room.invalid {
				hdt.temp_room.temporary = false
				floor.removeInvalidDoors()
				hdt.temp_room = nil
				hdt.prev_room = nil
				hdt.viewer.SetBounds()
			}
		} else {
			cx, cy := event.Key.Cursor().Point()
			bx, by := hdt.viewer.WindowToBoard(cx, cy)
			for i := range floor.Rooms {
				x, y := floor.Rooms[i].Pos()
				dx, dy := floor.Rooms[i].Dims()
				if int(bx) >= x && int(bx) < x+dx && int(by) >= y && int(by) < y+dy {
					hdt.temp_room = floor.Rooms[i]
					hdt.prev_room = new(Room)
					*hdt.prev_room = *hdt.temp_room
					hdt.temp_room.temporary = true
					hdt.drag_anchor.x = bx - float32(x)
					hdt.drag_anchor.y = by - float32(y)
					break
				}
			}
			if hdt.temp_room != nil {
				hdt.temp_spawns = hdt.temp_spawns[0:0]
				for _, sp := range hdt.house.Floors[0].Spawns {
					x, y := sp.Pos()
					rx, ry := hdt.temp_room.Pos()
					rdx, rdy := hdt.temp_room.Dims()
					if x >= rx && x < rx+rdx && y >= ry && y < ry+rdy {
						hdt.temp_spawns = append(hdt.temp_spawns, sp)
					}
				}
			}
		}
		return true
	}

	return false
}
Пример #15
0
// This is called if the player is ready to end the turn, if the turn ends
// then the following things happen:
// 1. The game script gets to run its OnRound() function
// 2. Entities with stats and HpCur() <= 0 are removed.
// 3. Entities all have their OnRound() function called.
func (g *Game) OnRound() {
	// Don't end the round if any of the following are true
	// An action is currently executing
	if g.Action_state != noAction {
		return
	}
	// Any master ai is still active
	if g.Side == SideHaunt && (g.Ai.minions.Active() || g.Ai.denizens.Active()) {
		return
	}

	g.Turn++
	if g.Side == SideExplorers {
		g.Side = SideHaunt
	} else {
		g.Side = SideExplorers
	}
	g.viewer.Los_tex.Remap()

	for i := range g.Ents {
		if g.Ents[i].Side() == g.Side {
			g.Ents[i].OnRound()
		}
	}

	// The entity ais must be activated before the master ais, otherwise the
	// masters might be running with stale data if one of the entities has been
	// reloaded.
	for i := range g.Ents {
		g.Ents[i].Ai.Activate()
		base.Log().Printf("EntityActive '%s': %t", g.Ents[i].Name, g.Ents[i].Ai.Active())
	}

	if g.Side == SideHaunt {
		g.Ai.minions.Activate()
		g.Ai.denizens.Activate()
		g.player_inactive = g.Ai.denizens.Active()
	} else {
		g.Ai.intruders.Activate()
		g.player_inactive = g.Ai.intruders.Active()
	}

	for i := range g.Ents {
		if g.Ents[i].Stats != nil && g.Ents[i].Stats.HpCur() <= 0 {
			g.viewer.RemoveDrawable(g.Ents[i])
		}
	}
	algorithm.Choose2(&g.Ents, func(ent *Entity) bool {
		return ent.Stats == nil || ent.Stats.HpCur() > 0
	})

	g.script.OnRound(g)

	if g.selected_ent != nil {
		g.selected_ent.hovered = false
		g.selected_ent.selected = false
	}
	if g.hovered_ent != nil {
		g.hovered_ent.hovered = false
		g.hovered_ent.selected = false
	}
	g.hovered_ent = nil
}
Пример #16
0
func (hv *HouseViewer) RemoveFloorDrawable(fd FloorDrawer) {
	algorithm.Choose2(&hv.floor_drawers, func(t FloorDrawer) bool {
		return t != fd
	})
}
Пример #17
0
func (sm *OnlineMenu) Think(g *gui.Gui, t int64) {
	if sm.last_t == 0 {
		sm.last_t = t
		return
	}
	dt := t - sm.last_t
	sm.last_t = t
	if sm.mx == 0 && sm.my == 0 {
		sm.mx, sm.my = gin.In().GetCursor("Mouse").Point()
	}

	done := false
	for !done {
		select {
		case sm.control.in <- struct{}{}:
			<-sm.control.out
		default:
			done = true
		}
	}

	var net_id mrgnet.NetId
	fmt.Sscanf(base.GetStoreVal("netid"), "%d", &net_id)
	for i := range []*gameListBox{&sm.layout.Active, &sm.layout.Unstarted} {
		glb := []*gameListBox{&sm.layout.Active, &sm.layout.Unstarted}[i]
		select {
		case list := <-glb.update:
			glb.games = glb.games[0:0]
			for j := range list.Games {
				var b Button
				var name string
				base.Log().Printf("Adding button: %s", list.Games[j].Name)
				b.Text.Justification = sm.layout.Text.Justification
				b.Text.Size = sm.layout.Text.Size
				if net_id == list.Games[j].Denizens_id {
					name = list.Games[j].Name
				} else {
					name = list.Games[j].Name
				}
				b.Text.String = "Join!"
				game_key := list.Game_keys[j]
				active := (glb == &sm.layout.Active)
				in_joingame := false
				b.f = func(interface{}) {
					if in_joingame {
						return
					}
					in_joingame = true
					if active {
						go func() {
							var req mrgnet.StatusRequest
							req.Id = net_id
							req.Game_key = game_key
							var resp mrgnet.StatusResponse
							done := make(chan bool, 1)
							go func() {
								mrgnet.DoAction("status", 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_joingame = false
								sm.control.out <- struct{}{}
							}()
							if resp.Err != "" || resp.Game == nil {
								sm.layout.Error.err = resp.Err
								base.Error().Printf("Couldn't join game: %v", resp.Err)
								return
							}
							sm.ui.RemoveChild(sm)
							sm.ui.AddChild(MakeGamePanel("", nil, nil, game_key))
						}()
					} else {
						go func() {
							var req mrgnet.JoinGameRequest
							req.Id = net_id
							req.Game_key = game_key
							var resp mrgnet.JoinGameResponse
							done := make(chan bool, 1)
							go func() {
								mrgnet.DoAction("join", 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_joingame = false
								sm.control.out <- struct{}{}
							}()
							if resp.Err != "" || !resp.Successful {
								sm.layout.Error.err = resp.Err
								base.Error().Printf("Couldn't join game: %v", resp.Err)
								return
							}
							sm.ui.RemoveChild(sm)
							sm.ui.AddChild(MakeGamePanel("", nil, nil, game_key))
						}()
					}
				}
				if active {
					d := Button{}
					d.Text.String = "Delete!"
					d.Text.Justification = "right"
					d.Text.Size = sm.layout.Text.Size
					d.f = func(interface{}) {
						go func() {
							var req mrgnet.KillRequest
							req.Id = net_id
							req.Game_key = game_key
							var resp mrgnet.KillResponse
							done := make(chan bool, 1)
							go func() {
								mrgnet.DoAction("kill", req, &resp)
								done <- true
							}()
							select {
							case <-done:
							case <-time.After(5 * time.Second):
								resp.Err = "Couldn't connect to server."
							}
							<-sm.control.in
							if resp.Err != "" {
								sm.layout.Error.err = resp.Err
								base.Error().Printf("Couldn't kill game: %v", resp.Err)
							} else {
								algorithm.Choose2(&glb.games, func(gf gameField) bool {
									return gf.key != req.Game_key
								})
							}
							sm.control.out <- struct{}{}
						}()
					}
					glb.games = append(glb.games, gameField{&b, &d, name, list.Game_keys[j], list.Games[j]})
				} else {
					glb.games = append(glb.games, gameField{&b, nil, name, list.Game_keys[j], list.Games[j]})
				}
			}
			glb.Scroll.Height = int(base.GetDictionary(sm.layout.Text.Size).MaxHeight() * float64(len(list.Games)))

		default:
		}

		sm.hover_game = nil
		if (gui.Point{sm.mx, sm.my}.Inside(glb.Scroll.Region())) {
			for i := range glb.games {
				game := &glb.games[i]
				var region gui.Region
				region.X = game.join.(*Button).bounds.x
				region.Y = game.join.(*Button).bounds.y
				region.Dx = glb.Scroll.Dx
				region.Dy = int(base.GetDictionary(sm.layout.Text.Size).MaxHeight())
				if (gui.Point{sm.mx, sm.my}.Inside(region)) {
					sm.hover_game = game
				}
				game.join.Think(sm.region.X, sm.region.Y, sm.mx, sm.my, dt)
				if game.delete != nil {
					game.delete.Think(sm.region.X, sm.region.Y, sm.mx, sm.my, dt)
				}
			}
		} else {
			for _, game := range glb.games {
				game.join.Think(sm.region.X, sm.region.Y, 0, 0, dt)
				if game.delete != nil {
					game.delete.Think(sm.region.X, sm.region.Y, 0, 0, dt)
				}
			}
		}
		glb.Scroll.Think(dt)
	}

	if sm.update_alpha > 0.0 && time.Now().Sub(sm.update_time).Seconds() >= 2 {
		sm.update_alpha = doApproach(sm.update_alpha, 0.0, dt)
	}

	for _, button := range sm.buttons {
		button.Think(sm.region.X, sm.region.Y, sm.mx, sm.my, dt)
	}
}
Пример #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
}
Пример #19
0
func (w *FurniturePanel) Respond(ui *gui.Gui, group gui.EventGroup) bool {
	if w.VerticalTable.Respond(ui, group) {
		return true
	}

	// On escape we want to revert the furniture we're moving back to where it was
	// and what state it was in before we selected it.  If we don't have any
	// furniture selected then we don't do anything.
	if found, event := group.FindEvent(gin.Escape); found && event.Type == gin.Press {
		w.onEscape()
		return true
	}

	// If we hit delete then we want to remove the furniture we're moving around
	// from the room.  If we're not moving anything around then nothing happens.
	if found, event := group.FindEvent(gin.DeleteOrBackspace); found && event.Type == gin.Press {
		algorithm.Choose2(&w.Room.Furniture, func(f *Furniture) bool {
			return f != w.furniture
		})
		w.furniture = nil
		w.prev_object = nil
		return true
	}

	if found, event := group.FindEvent(w.key_map["rotate left"].Id()); found && event.Type == gin.Press {
		if w.furniture != nil {
			w.furniture.RotateLeft()
		}
	}
	if found, event := group.FindEvent(w.key_map["rotate right"].Id()); found && event.Type == gin.Press {
		if w.furniture != nil {
			w.furniture.RotateRight()
		}
	}
	if found, event := group.FindEvent(w.key_map["flip"].Id()); found && event.Type == gin.Press {
		if w.furniture != nil {
			w.furniture.Flip = !w.furniture.Flip
		}
	}
	if found, event := group.FindEvent(gin.MouseLButton); found && event.Type == gin.Press {
		if w.furniture != nil {
			if !w.furniture.invalid {
				w.furniture.temporary = false
				w.furniture = nil
			}
		} else if w.furniture == nil {
			bx, by := w.RoomViewer.WindowToBoard(event.Key.Cursor().Point())
			for i := range w.Room.Furniture {
				x, y := w.Room.Furniture[i].Pos()
				dx, dy := w.Room.Furniture[i].Dims()
				if int(bx) >= x && int(bx) < x+dx && int(by) >= y && int(by) < y+dy {
					w.furniture = w.Room.Furniture[i]
					w.prev_object = new(Furniture)
					*w.prev_object = *w.furniture
					w.furniture.temporary = true
					px, py := w.furniture.Pos()
					w.drag_anchor.x = bx - float32(px)
					w.drag_anchor.y = by - float32(py)
					break
				}
			}
		}
		return true
	}
	return false
}