Example #1
0
func (p *PlayerEnt) Supply(mana Mana) Mana {
	base.DoOrdered(p.Processes, func(a, b int) bool { return a < b }, func(id int, proc Process) {
		mana = proc.Supply(mana)
	})
	return mana
}
Example #2
0
func (cp *ControlPoint) Supply(mana Mana) Mana {
	base.DoOrdered(cp.Processes, func(a, b int) bool { return a < b }, func(id int, proc Process) {
		mana = proc.Supply(mana)
	})
	return mana
}
Example #3
0
func (g *Game) DoForEnts(f func(Gid, Ent)) {
	base.DoOrdered(g.Ents, lessGids, f)
}
Example #4
0
func (g *Game) ThinkGame() {
	// cache wall data
	if g.local.temp.AllWalls == nil || g.local.temp.AllWallsDirty {
		g.local.temp.AllWallsDirty = false
		g.local.temp.AllWalls = nil
		g.local.temp.WallCache = nil
		g.local.temp.VisibleWallCache = nil

		// Can't use a nil slice, otherwise we'll run this block every Think for levels
		// with no walls.
		allWalls := make([]linear.Seg2, 0)
		base.DoOrdered(g.Level.Room.Walls, func(a, b string) bool { return a < b }, func(_ string, walls linear.Poly) {
			for i := range walls {
				allWalls = append(allWalls, walls.Seg(i))
			}
		})
		g.local.temp.AllWalls = allWalls
		g.local.temp.WallCache = &wallCache{}
		g.local.temp.WallCache.SetWalls(g.Level.Room.Dx, g.Level.Room.Dy, allWalls, 100)
		g.local.temp.VisibleWallCache = &wallCache{}
		g.local.temp.VisibleWallCache.SetWalls(g.Level.Room.Dx, g.Level.Room.Dy, allWalls, stats.LosPlayerHorizon)
		g.local.pathingData = makePathingData(&g.Level.Room)
	}

	// cache ent data
	for _, ent := range g.local.temp.AllEnts {
		if ent.Dead() {
			if _, ok := ent.(*PlayerEnt); ok {
				var id int64
				_, err := fmt.Sscanf(string(ent.Id()), "Engine:%d", &id)
				if err != nil {
					_, err = fmt.Sscanf(string(ent.Id()), "Ai:%d", &id)
					id = -id // Ai's engine ids are negative
				}
				if err != nil {
					base.Error().Printf("Unable to parse player id '%v'", ent.Id())
				} else {
					if engineData, ok := g.Engines[id]; ok {
						if !ok {
							base.Error().Printf("Unable to find engine %d for player %v", id, ent.Id())
						} else {
							engineData.CountdownFrames = 60 * 10
							base.Log().Printf("%v died, counting down....", *engineData)
						}
					}
				}
			}
			ent.OnDeath(g)
			g.RemoveEnt(ent.Id())
		}
	}

	// Death countdown
	base.DoOrdered(g.Engines, func(a, b int64) bool { return a < b }, func(_ int64, engineData *PlayerData) {
		if engineData.CountdownFrames > 0 {
			engineData.CountdownFrames--
			if engineData.CountdownFrames == 0 {
				g.AddPlayers([]*PlayerData{engineData})
			}
		}
	})

	if g.local.temp.AllEnts == nil || g.local.temp.AllEntsDirty {
		g.local.temp.AllEnts = g.local.temp.AllEnts[0:0]
		g.DoForEnts(func(gid Gid, ent Ent) {
			g.local.temp.AllEnts = append(g.local.temp.AllEnts, ent)
		})
		g.local.temp.AllEntsDirty = false
	}
	if g.local.temp.EntGrid == nil {
		g.local.temp.EntGrid = MakeEntCache(g.Level.Room.Dx, g.Level.Room.Dy)
	}
	g.local.temp.EntGrid.SetEnts(g.local.temp.AllEnts)

	for _, proc := range g.Processes {
		proc.Think(g)
	}
	algorithm.Choose(&g.Processes, func(proc Process) bool { return !proc.Dead() })

	// Advance players, check for collisions, add segments
	eps := 1.0e-3
	for _, ent := range g.local.temp.AllEnts {
		ent.Think(g)
		for _, ab := range ent.Abilities() {
			ab.Think(ent, g)
		}
		pos := ent.Pos()
		pos.X = clamp(pos.X, eps, float64(g.Level.Room.Dx)-eps)
		pos.Y = clamp(pos.Y, eps, float64(g.Level.Room.Dy)-eps)
		ent.SetPos(pos)
	}

	var nearby []Ent
	for i := 0; i < len(g.local.temp.AllEnts); i++ {
		outerEnt := g.local.temp.AllEnts[i]
		outerSize := outerEnt.Stats().Size()
		if outerSize == 0 {
			continue
		}
		g.local.temp.EntGrid.EntsInRange(outerEnt.Pos(), 100, &nearby)
		for _, innerEnt := range nearby {
			innerSize := innerEnt.Stats().Size()
			if innerSize == 0 {
				continue
			}
			distSq := outerEnt.Pos().Sub(innerEnt.Pos()).Mag2()
			colDist := innerSize + outerSize
			if distSq > colDist*colDist {
				continue
			}
			if distSq < 0.015625 { // this means that dist < 0.125
				continue
			}
			dist := math.Sqrt(distSq)
			force := 50.0 * (colDist - dist)
			innerEnt.ApplyForce(innerEnt.Pos().Sub(outerEnt.Pos()).Scale(force / dist))
		}
	}

	g.Level.ManaSource.Think(g.Ents)
}
Example #5
0
func (u SetupComplete) Apply(_g interface{}) {
	g := _g.(*Game)
	if g.Setup == nil {
		return
	}
	sideCount := make(map[int]int)
	// Must have at least two sides
	sideCount[0] = 0
	sideCount[1] = 0
	for _, spd := range g.Setup.Players {
		sideCount[spd.Side]++
	}
	g.Engines = make(map[int64]*PlayerData)
	for id, player := range g.Setup.Players {
		var gid Gid
		if id < 0 {
			gid = Gid(fmt.Sprintf("Ai:%d", -id))
		} else {
			gid = Gid(fmt.Sprintf("Engine:%d", id))
		}
		g.Engines[id] = &PlayerData{
			PlayerGid:  Gid(gid),
			Side:       player.Side,
			ChampIndex: player.ChampIndex,
		}
	}

	// Now that we have the information we can set up a lot of the local data for
	// this engine's player.

	if g.IsPlaying() {
		g.local.Side = g.Engines[g.local.Engine.Id()].Side
		g.local.Gid = g.Engines[g.local.Engine.Id()].PlayerGid
		g.local.Data = g.Engines[g.local.Engine.Id()]
	}

	var room Room
	err := base.LoadJson(filepath.Join(base.GetDataDir(), "rooms/basic.json"), &room)
	if err != nil {
		base.Error().Fatalf("%v", err)
	}
	errs := room.Validate()
	for _, err := range errs {
		base.Error().Printf("%v", err)
	}
	if len(errs) > 0 {
		base.Error().Fatalf("Errors with the level, bailing...")
	}
	g.Level = &Level{}
	g.Level.Room = room
	g.Rng = cmwc.MakeGoodCmwc()
	g.Rng.Seed(u.Seed)
	g.Ents = make(map[Gid]Ent)
	g.Friction = 0.97
	g.losCache = makeLosCache(g.Level.Room.Dx, g.Level.Room.Dy)
	sides := make(map[int][]int64)
	var playerDatas []*PlayerData
	base.DoOrdered(g.Engines, func(a, b int64) bool { return a < b }, func(id int64, data *PlayerData) {
		sides[data.Side] = append(sides[data.Side], id)
		playerDatas = append(playerDatas, data)
	})
	for id, ed := range g.Engines {
		base.Log().Printf("%v -> %v", id, *ed)
	}
	g.AddPlayers(playerDatas)

	g.MakeControlPoints()
	g.Init()
	base.Log().Printf("Nillifying g.Setup()")
	g.Setup = nil
}