Beispiel #1
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.Choose(&targets, func(e *game.Entity) bool {
		return e.Stats != nil
	})

	return targets
}
Beispiel #2
0
func (f *Floor) removeInvalidDoors() {
	for _, room := range f.Rooms {
		algorithm.Choose(&room.Doors, func(a interface{}) bool {
			_, other_door := f.FindMatchingDoor(room, a.(*Door))
			return other_door != nil && !other_door.temporary
		})
	}
}
Beispiel #3
0
func ChooserSpec(c gospec.Context) {
	c.Specify("Choose on []int", func() {
		a := []int{0, 1, 2, 3, 4, 5, 6, 7, 8, 9}
		var b []int
		b = algorithm.Choose(a, func(v interface{}) bool { return v.(int)%2 == 0 }).([]int)
		c.Expect(b, ContainsInOrder, []int{0, 2, 4, 6, 8})

		b = algorithm.Choose(a, func(v interface{}) bool { return v.(int)%2 == 1 }).([]int)
		c.Expect(b, ContainsInOrder, []int{1, 3, 5, 7, 9})

		b = algorithm.Choose(a, func(v interface{}) bool { return true }).([]int)
		c.Expect(b, ContainsInOrder, a)

		b = algorithm.Choose(a, func(v interface{}) bool { return false }).([]int)
		c.Expect(b, ContainsInOrder, []int{})

		b = algorithm.Choose([]int{}, func(v interface{}) bool { return false }).([]int)
		c.Expect(b, ContainsInOrder, []int{})
	})

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

		b = algorithm.Choose(a, func(v interface{}) bool { return v.(string) < "foo" }).([]string)
		c.Expect(b, ContainsInOrder, []string{"bar", "ding"})
	})
}
Beispiel #4
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.Choose(&hdt.house.Floors[0].Spawns, func(s *SpawnPoint) bool {
				return s != hdt.temp_relic
			})
		}
		hdt.temp_relic = nil
	}
}
Beispiel #5
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.Choose(&w.room.WallTextures, func(wt *WallTexture) bool {
				return wt != w.wall_texture
			})
		}
	}
	w.wall_texture = nil
	w.prev_wall_texture = nil
}
Beispiel #6
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.Choose(&w.Room.Furniture, func(f *Furniture) bool {
				return f != w.furniture
			})
		}
		w.furniture = nil
	}
}
Beispiel #7
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.Choose(&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
}
Beispiel #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.Choose(&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
}
Beispiel #9
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.Choose(&hdt.house.Floors[0].Rooms, func(r *Room) bool {
			return r != hdt.temp_room
		})
	}
	hdt.temp_room = nil
}
Beispiel #10
0
func (hdt *houseDoorTab) onEscape() {
	if hdt.temp_door != nil {
		if hdt.temp_room != nil {
			algorithm.Choose(&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
	}
}
Beispiel #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.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
}
Beispiel #12
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.Choose(&hdt.house.Floors[0].Spawns, func(s *SpawnPoint) bool {
				return !spawns[s]
			})
			algorithm.Choose(&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
}
Beispiel #13
0
func (hv *HouseViewer) RemoveDrawable(d Drawable) {
	algorithm.Choose(&hv.drawables, func(t Drawable) bool {
		return t != d
	})
}
Beispiel #14
0
func (s *Sprite) Think(dt int64) {
	if s.thinks == 0 {
		s.shared.facings[0].Load()
		s.togo = s.shared.node_data[s.anim_node].time
	}
	s.thinks++
	if dt < 0 {
		return
		// panic("Can't have dt < 0")
	}

	// Check for waiters
	defer func() {
		if s.NumPendingCmds() > 0 {
			return
		}
		for i := range s.waiters {
			for _, state := range s.waiters[i].states {
				if state == s.AnimState() {
					s.waiters[i].c <- struct{}{}
					s.waiters[i].states = nil
				}
			}
			algorithm.Choose(&s.waiters, func(w *waiter) bool {
				return w.states != nil
			})
		}
	}()

	var path []*yed.Node
	if len(s.pending_cmds) > 0 && len(s.path) == 0 {
		if s.pending_cmds[0].group == nil {
			path = s.findPathForCmd(s.pending_cmds[0], s.anim_node)
		} else if s.pending_cmds[0].group.ready() {
			t := s.pending_cmds[0].group.eta[s]
			t -= dt
			if t <= 0 {
				path = s.pending_cmds[0].group.paths[s]
				s.anim_node = path[0]
				s.doTrigger()
				s.togo = s.shared.node_data[s.anim_node].time
				path = path[1:]
			}
			s.pending_cmds[0].group.eta[s] = t
		}
	}
	if path != nil {
		s.applyPath(path)
		s.pending_cmds = s.pending_cmds[1:]
	}

	if len(s.path) > 0 && s.anim_node.Group() != nil {
		// If the current node is in a group that has an edge to the next node
		// then we want to follow that edge immediately rather than waiting for
		// the time for this frame to elapse
		for i := 0; i < s.anim_node.NumGroupOutputs(); i++ {
			edge := s.anim_node.GroupOutput(i)
			if edge.Src() == s.anim_node {
				continue
			}
			if edge.Dst() == s.path[0] {
				s.togo = 0
			}
		}
	}
	if s.togo >= dt {
		s.togo -= dt
		if s.facing != s.prev_facing {
			s.shared.facings[s.prev_facing].Unload()
			s.shared.facings[s.facing].Load()
			s.prev_facing = s.facing
		}
		return
	}
	dt -= s.togo
	var next *yed.Node
	if len(s.path) > 0 {
		next = s.path[0]
		s.path = s.path[1:]
	} else {
		edge := selectAnEdge(s.anim_node, s.shared.edge_data, []string{""})
		if edge != nil {
			next = edge.Dst()
		} else {
			next = s.anim_node
		}
	}
	var edge *yed.Edge
	if next != nil {
		edge = edgeTo(s.anim_node, next)
		face := s.shared.edge_data[edge].facing
		if face != 0 {
			s.facing = (s.facing + face + len(s.shared.facings)) % len(s.shared.facings)
		}
	}
	s.anim_node = next
	s.doTrigger()
	s.togo = s.shared.node_data[s.anim_node].time
	s.Think(dt)
}
Beispiel #15
0
func (hv *HouseViewer) RemoveFloorDrawable(fd FloorDrawer) {
	algorithm.Choose(&hv.floor_drawers, func(t FloorDrawer) bool {
		return t != fd
	})
}
Beispiel #16
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.Choose(&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)
	}
}
Beispiel #17
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.Choose(&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.Choose(&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.Choose(&room.Doors, func(d *Door) bool {
						return d != door
					})
				}
			}
		}
		return true
	}

	return false
}
Beispiel #18
0
func (s *Inst) RemoveCondition(name string) {
	algorithm.Choose(&s.inst.Conditions, func(c Condition) bool {
		return c.Name() != name
	})
}
Beispiel #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.Choose(&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
}
Beispiel #20
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(do_scripts bool) {
	// Don't end the round if any of the following are true
	// An action is currently executing
	if g.Action_state != noAction {
		base.Log().Printf("No OnRound - have action")
		return
	}
	// Any master ai is still active
	if g.Side == SideHaunt && (g.Ai.minions.Active() || g.Ai.denizens.Active()) {
		base.Log().Printf("No OnRound - waiting on ais")
		return
	}

	if do_scripts {
		g.Turn++
		if g.Side == SideExplorers {
			base.Log().Printf("OnRound from %d Intruders to %d Denizens", g.Turn-1, g.Turn)
			g.Side = SideHaunt
		} else {
			base.Log().Printf("OnRound from %d Denizens to %d Intruders", g.Turn-1, g.Turn)
			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.
	if do_scripts {
		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.Choose(&g.Ents, func(ent *Entity) bool {
		return ent.Stats == nil || ent.Stats.HpCur() > 0
	})

	if do_scripts {
		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
}
Beispiel #21
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.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
}