public static IEnumerable<Actor> FindUnitsInCircle(this World world, float2 a, float r) { using (new PerfSample("FindUnitsInCircle")) { var min = a - new float2(r, r); var max = a + new float2(r, r); var actors = world.FindUnits(min, max); var rect = new RectangleF(min.X, min.Y, max.X - min.X, max.Y - min.Y); var inBox = actors.Where(x => x.GetBounds(false).IntersectsWith(rect)); return inBox.Where(x => (x.CenterLocation - a).LengthSquared < r * r); } }
public Actor( World world, string name, int2 location, Player owner ) { World = world; ActorID = world.NextAID(); Location = location; CenterLocation = Traits.Util.CenterOfCell(Location); Owner = owner; if (name != null) { Info = Rules.Info[name.ToLowerInvariant()]; Health = this.GetMaxHP(); foreach (var trait in Info.TraitsInConstructOrder()) traits.Add(trait.Create(this)); } }
public float2 Constrain(float2 min, float2 max) { return new float2( Constrain(X, min.X, max.X), Constrain(Y, min.Y, max.Y)); }
public static float2 Min(float2 a, float2 b) { return new float2(Math.Min(a.X, b.X), Math.Min(a.Y, b.Y)); }
public static float Dot(float2 a, float2 b) { return a.X * b.X + a.Y * b.Y; }
public static ISound PlayToPlayer(Player player, string name, float2 pos) { return Play(player, name, false, pos, 1); }
public static ISound Play(string name, float2 pos) { return Play(null, name, false, pos, 1); }
public RectangleF GetBounds(bool useAltitude) { var si = Info.Traits.GetOrDefault<SelectableInfo>(); var size = SelectedSize; var loc = CenterLocation - 0.5f * size; if (si != null && si.Bounds != null && si.Bounds.Length > 2) loc += new float2(si.Bounds[2], si.Bounds[3]); if (useAltitude) { var unit = traits.GetOrDefault<Unit>(); if (unit != null) loc -= new float2(0, unit.Altitude); } return new RectangleF(loc.X, loc.Y, size.X, size.Y); }
public ISound Play2D(ISoundSource sound, bool loop, bool relative, float2 pos, float volume) { int source = GetSourceFromPool(); return new OpenAlSound(source, (sound as OpenAlSoundSource).buffer, loop, relative, pos, volume); }
public void SetListenerPosition(float2 position) { }
public static void SetListenerPosition(float2 position) { soundEngine.SetListenerPosition(position); }
public ISound Play2D(ISoundSource sound, bool loop, bool relative, float2 pos, float volume) { return(new NullSound()); }
public ISound Play2D(ISoundSource sound, bool loop, bool relative, float2 pos, float volume) { int source = GetSourceFromPool(); return(new OpenAlSound(source, (sound as OpenAlSoundSource).buffer, loop, relative, pos, volume)); }
public static ISound PlayToPlayer(Player player, string name, float2 pos) { return(Play(player, name, false, pos, 1)); }
public static ISound Play(string name, float2 pos, float volumeModifier) { return(Play(null, name, false, pos, volumeModifier)); }
public static ISound Play(string name, float2 pos) { return(Play(null, name, false, pos, 1)); }
public static void PlayToPlayer(Player player, string name, float2 pos) { if (player == player.World.LocalPlayer) Play(name, pos); }
public static IEnumerable<Actor> SelectActorsInBox(this World world, float2 a, float2 b) { return world.FindUnits(a, b) .Where( x => x.traits.Contains<Selectable>() && x.IsVisible() ) .GroupBy(x => (x.Owner == world.LocalPlayer) ? x.Info.Traits.Get<SelectableInfo>().Priority : 0) .OrderByDescending(g => g.Key) .Select( g => g.AsEnumerable() ) .DefaultIfEmpty( new Actor[] {} ) .FirstOrDefault(); }
public static IEnumerable<Actor> FindUnits(this World world, float2 a, float2 b) { var u = float2.Min(a, b).ToInt2(); var v = float2.Max(a, b).ToInt2(); return world.WorldActor.traits.Get<SpatialBins>().ActorsInBox(u,v); }
void DrawSupportPowers( World world ) { var powers = world.LocalPlayer.PlayerActor.traits.WithInterface<SupportPower>(); var numPowers = powers.Count(p => p.IsAvailable); if (numPowers == 0) return; rgbaRenderer.DrawSprite(ChromeProvider.GetImage(renderer, chromeCollection, "specialbin-top"), new float2(0, 14), "chrome"); for (var i = 1; i < numPowers; i++) rgbaRenderer.DrawSprite(ChromeProvider.GetImage(renderer, chromeCollection, "specialbin-middle"), new float2(0, 14 + i * 51), "chrome"); rgbaRenderer.DrawSprite(ChromeProvider.GetImage(renderer, chromeCollection, "specialbin-bottom"), new float2(0, 14 + numPowers * 51), "chrome"); rgbaRenderer.Flush(); var y = 24; SupportPower tooltipItem = null; int2 tooltipPos = int2.Zero; foreach (var sp in powers) { var image = spsprites[sp.Info.Image]; if (sp.IsAvailable) { var drawPos = new float2(5, y); shpRenderer.DrawSprite(image, drawPos, "chrome"); clock.PlayFetchIndex("idle", () => (sp.TotalTime - sp.RemainingTime) * (clock.CurrentSequence.Length - 1) / sp.TotalTime); clock.Tick(); shpRenderer.DrawSprite(clock.Image, drawPos, "chrome"); var rect = new Rectangle(5, y, 64, 48); if (sp.IsReady) { ready.Play("ready"); shpRenderer.DrawSprite(ready.Image, drawPos + new float2((64 - ready.Image.size.X) / 2, 2), "chrome"); } AddButton(rect, HandleSupportPower(sp)); if (rect.Contains(lastMousePos.ToPoint())) { tooltipItem = sp; tooltipPos = drawPos.ToInt2() + new int2(72, 0); } y += 51; } } shpRenderer.Flush(); if (tooltipItem != null) DrawSupportPowerTooltip(world, tooltipItem, tooltipPos); }
public static ISound Play(string name, float2 pos, float volumeModifier) { return Play(null, name, false, pos, volumeModifier); }
public void TickRadarAnimation() { if (!radarAnimating) return; // Increment frame if (hasRadar) radarAnimationFrame++; else radarAnimationFrame--; // Calculate radar bin position if (radarAnimationFrame <= radarSlideAnimationLength) radarOrigin = float2.Lerp(radarClosedOrigin, radarOpenOrigin, radarAnimationFrame * 1.0f / radarSlideAnimationLength); var eva = Game.world.WorldActor.Info.Traits.Get<EvaAlertsInfo>(); // Play radar-on sound at the start of the activate anim (open) if (radarAnimationFrame == radarSlideAnimationLength && hasRadar) Sound.Play(eva.RadarUp); // Play radar-on sound at the start of the activate anim (close) if (radarAnimationFrame == radarSlideAnimationLength + radarActivateAnimationLength - 1 && !hasRadar) Sound.Play(eva.RadarDown); // Minimap height if (radarAnimationFrame >= radarSlideAnimationLength) radarMinimapHeight = float2.Lerp(0, 192, (radarAnimationFrame - radarSlideAnimationLength) * 1.0f / radarActivateAnimationLength); // Animation is complete if ((radarAnimationFrame == 0 && !hasRadar) || (radarAnimationFrame == radarSlideAnimationLength + radarActivateAnimationLength && hasRadar)) { radarAnimating = false; } }
static ISound Play(Player player, string name, bool headRelative, float2 pos, float volumeModifier) { if (player != null && player != player.World.LocalPlayer) return null; if (name == "" || name == null) return null; return soundEngine.Play2D(sounds[name], false, headRelative, pos, InternalSoundVolume * volumeModifier); }
void DrawPower( World world ) { // Nothing to draw if (world.LocalPlayer.PowerProvided == 0 && world.LocalPlayer.PowerDrained == 0) return; // Draw bar horizontally var barStart = powerOrigin + radarOrigin; var barEnd = barStart + new float2(powerSize.Width, 0); float powerScaleBy = 100; var maxPower = Math.Max(world.LocalPlayer.PowerProvided, world.LocalPlayer.PowerDrained); while (maxPower >= powerScaleBy) powerScaleBy *= 2; // Current power supply var powerLevelTemp = barStart.X + (barEnd.X - barStart.X) * (world.LocalPlayer.PowerProvided / powerScaleBy); lastPowerProvidedPos = float2.Lerp(lastPowerProvidedPos.GetValueOrDefault(powerLevelTemp), powerLevelTemp, .3f); float2 powerLevel = new float2(lastPowerProvidedPos.Value, barStart.Y); var color = Color.LimeGreen; if (world.LocalPlayer.GetPowerState() == PowerState.Low) color = Color.Orange; if (world.LocalPlayer.GetPowerState() == PowerState.Critical) color = Color.Red; var colorDark = Graphics.Util.Lerp(0.25f, color, Color.Black); for (int i = 0; i < powerSize.Height; i++) { color = (i-1 < powerSize.Height/2) ? color : colorDark; float2 leftOffset = new float2(0,i); float2 rightOffset = new float2(0,i); // Indent corners if ((i == 0 || i == powerSize.Height - 1) && powerLevel.X - barStart.X > 1) { leftOffset.X += 1; rightOffset.X -= 1; } lineRenderer.DrawLine(Game.viewport.Location + barStart + leftOffset, Game.viewport.Location + powerLevel + rightOffset, color, color); } lineRenderer.Flush(); // Power usage indicator var indicator = ChromeProvider.GetImage(renderer, radarCollection, "power-indicator"); var powerDrainedTemp = barStart.X + (barEnd.X - barStart.X) * (world.LocalPlayer.PowerDrained / powerScaleBy); lastPowerDrainedPos = float2.Lerp(lastPowerDrainedPos.GetValueOrDefault(powerDrainedTemp), powerDrainedTemp, .3f); float2 powerDrainLevel = new float2(lastPowerDrainedPos.Value-indicator.size.X/2, barStart.Y-1); rgbaRenderer.DrawSprite(indicator, powerDrainLevel, "chrome"); rgbaRenderer.Flush(); }
public static float2 Lerp(float2 a, float2 b, float2 t) { return new float2( Lerp(a.X, b.X, t.X), Lerp(a.Y, b.Y, t.Y)); }
void DrawButtons( World world ) { var origin = new int2(Game.viewport.Width - 200, 2); foreach (var cb in world.WorldActor.traits.WithInterface<IChromeButton>()) { var state = cb.Enabled ? cb.Pressed ? "pressed" : "normal" : "disabled"; var image = ChromeProvider.GetImage(renderer, cb.Image + "-button", state); origin.X -= (int)image.size.X + chromeButtonGap; rgbaRenderer.DrawSprite(image, origin, "chrome"); var button = cb; AddButton(new RectangleF(origin.X, origin.Y, image.size.X, image.size.Y), _ => { if (button.Enabled) button.OnClick(); }); } //Options Rectangle optionsRect = new Rectangle(0,0, optionsButton.Image.bounds.Width, optionsButton.Image.bounds.Height); var optionsDrawPos = new float2(optionsRect.Location); optionsButton.ReplaceAnim(optionsPressed ? "left-pressed" : "left-normal"); AddButton(optionsRect, isLmb => optionsPressed = !optionsPressed); shpRenderer.DrawSprite(optionsButton.Image, optionsDrawPos, "chrome"); shpRenderer.Flush(); renderer.RegularFont.DrawText(rgbaRenderer, "Options", new int2((int)(optionsButton.Image.size.X - renderer.RegularFont.Measure("Options").X) / 2, -2), Color.White); }
public static bool WithinEpsilon(float2 a, float2 b, float e) { float2 d = a - b; return Math.Abs(d.X) < e && Math.Abs(d.Y) < e; }
void TickPaletteAnimation() { if (!paletteAnimating) return; // Increment frame if (paletteOpen) paletteAnimationFrame++; else paletteAnimationFrame--; // Calculate palette position if (paletteAnimationFrame <= paletteAnimationLength) paletteOrigin = float2.Lerp(paletteClosedOrigin, paletteOpenOrigin, paletteAnimationFrame * 1.0f / paletteAnimationLength); var eva = Game.world.WorldActor.Info.Traits.Get<EvaAlertsInfo>(); // Play palette-open sound at the start of the activate anim (open) if (paletteAnimationFrame == 1 && paletteOpen) Sound.Play(eva.BuildPaletteOpen); // Play palette-close sound at the start of the activate anim (close) if (paletteAnimationFrame == paletteAnimationLength + -1 && !paletteOpen) Sound.Play(eva.BuildPaletteClose); // Animation is complete if ((paletteAnimationFrame == 0 && !paletteOpen) || (paletteAnimationFrame == paletteAnimationLength && paletteOpen)) { paletteAnimating = false; } }
public ISound Play2D(ISoundSource sound, bool loop, bool relative, float2 pos, float volume, bool attenuateVolume) { if (sound == null) { Log.Write("debug", "Attempt to Play2D a null `ISoundSource`"); return null; } var world = Game.orderManager.world; int currFrame = world != null ? world.FrameNumber : 0; float atten = 1f; // Check if max # of instances-per-location reached: if (attenuateVolume) { int instances = 0, activeCount = 0; foreach (var s in sourcePool.Values) { if (!s.isActive) continue; if (s.isRelative != relative) continue; ++activeCount; if (s.sound != sound) continue; if (currFrame - s.frameStarted >= 5) continue; // Too far away to count? var lensqr = (s.pos - pos).LengthSquared; if (lensqr >= groupDistanceSqr) continue; // If we are starting too many instances of the same sound within a short time then stop this one: if (++instances == maxInstancesPerFrame) return null; } // Attenuate a little bit based on number of active sounds: atten = 0.66f * ((POOL_SIZE - activeCount * 0.5f) / POOL_SIZE); } int source = GetSourceFromPool(); if (source == -1) return null; var slot = sourcePool[source]; slot.pos = pos; slot.frameStarted = currFrame; slot.sound = sound; slot.isRelative = relative; return new OpenAlSound(source, (sound as OpenAlSoundSource).buffer, loop, relative, pos, volume * atten); }
// Return an int telling us the y coordinate at the bottom of the palette int DrawBuildPalette( World world, string queueName ) { // Hack int columns = paletteColumns; float2 origin = new float2(paletteOrigin.X + 9, paletteOrigin.Y + 9); if (queueName == null) return 0; var x = 0; var y = 0; var buildableItems = Rules.TechTree.BuildableItems(world.LocalPlayer, queueName).ToArray(); var allBuildables = Rules.TechTree.AllBuildables(queueName) .Where(a => a.Traits.Get<BuildableInfo>().Owner.Contains(world.LocalPlayer.Country.Race)) .OrderBy(a => a.Traits.Get<BuildableInfo>().BuildPaletteOrder) .ThenBy(a => a.Traits.Get<BuildableInfo>().TechLevel).ToArray(); var queue = world.LocalPlayer.PlayerActor.traits.Get<ProductionQueue>(); var overlayBits = new List<Pair<Sprite, float2>>(); string tooltipItem = null; // Draw the top border rgbaRenderer.DrawSprite(ChromeProvider.GetImage(renderer, paletteCollection, "top"), new float2(origin.X - 9, origin.Y - 9), "chrome"); var numActualRows = Math.Max((allBuildables.Length + columns - 1) / columns, paletteRows); for (var w = 0; w < numActualRows; w++) rgbaRenderer.DrawSprite( ChromeProvider.GetImage(renderer, paletteCollection, "bg-" + (w % 4).ToString()), new float2(origin.X - 9, origin.Y + 48 * w), "chrome"); rgbaRenderer.DrawSprite(ChromeProvider.GetImage(renderer, paletteCollection, "bottom"), new float2(origin.X - 9, origin.Y - 1 + 48 * numActualRows), "chrome"); rgbaRenderer.Flush(); // Draw the icons foreach (var item in allBuildables) { var rect = new RectangleF(origin.X + x * 64, origin.Y + 48 * y, 64, 48); var drawPos = new float2(rect.Location); var isBuildingSomething = queue.CurrentItem(queueName) != null; shpRenderer.DrawSprite(tabSprites[item.Name], drawPos, "chrome"); var firstOfThis = queue.AllItems(queueName).FirstOrDefault(a => a.Item == item.Name); if (rect.Contains(lastMousePos.ToPoint())) tooltipItem = item.Name; var overlayPos = drawPos + new float2((64 - ready.Image.size.X) / 2, 2); if (firstOfThis != null) { clock.PlayFetchIndex( "idle", () => (firstOfThis.TotalTime - firstOfThis.RemainingTime) * (clock.CurrentSequence.Length - 1)/ firstOfThis.TotalTime); clock.Tick(); shpRenderer.DrawSprite(clock.Image, drawPos, "chrome"); if (firstOfThis.Done) { ready.Play("ready"); overlayBits.Add(Pair.New(ready.Image, overlayPos)); } else if (firstOfThis.Paused) { ready.Play("hold"); overlayBits.Add(Pair.New(ready.Image, overlayPos)); } var repeats = queue.AllItems(queueName).Count(a => a.Item == item.Name); if (repeats > 1 || queue.CurrentItem(queueName) != firstOfThis) { var offset = -22; var digits = repeats.ToString(); foreach (var d in digits) { ready.PlayFetchIndex("groups", () => d - '0'); ready.Tick(); overlayBits.Add(Pair.New(ready.Image, overlayPos + new float2(offset, 0))); offset += 6; } } } else if (!buildableItems.Contains(item.Name) || isBuildingSomething) overlayBits.Add(Pair.New(cantBuild.Image, drawPos)); var closureItemName = item.Name; var eva = world.WorldActor.Info.Traits.Get<EvaAlertsInfo>(); AddButton(rect, buildableItems.Contains(item.Name) ? isLmb => HandleBuildPalette(world, closureItemName, isLmb) : (Action<bool>)(_ => Sound.Play(eva.TabClick))); if (++x == columns) { x = 0; y++; } } if (x != 0) y++; foreach (var ob in overlayBits) shpRenderer.DrawSprite(ob.First, ob.Second, "chrome"); shpRenderer.Flush(); // Draw dock rgbaRenderer.DrawSprite(ChromeProvider.GetImage(renderer, paletteCollection, "dock-top"), new float2(Game.viewport.Width - 14, origin.Y - 23), "chrome"); for (int i = 0; i < numActualRows; i++) rgbaRenderer.DrawSprite(ChromeProvider.GetImage(renderer, paletteCollection, "dock-" + (i % 4).ToString()), new float2(Game.viewport.Width - 14, origin.Y + 48 * i), "chrome"); rgbaRenderer.DrawSprite(ChromeProvider.GetImage(renderer, paletteCollection, "dock-bottom"), new float2(Game.viewport.Width - 14, origin.Y - 1 + 48 * numActualRows), "chrome"); rgbaRenderer.Flush(); if (tooltipItem != null && paletteOpen) DrawProductionTooltip(world, tooltipItem, new float2(Game.viewport.Width, origin.Y + numActualRows * 48 + 9).ToInt2()); return y*48+9; }
public ISound Play2D(ISoundSource sound, bool loop, bool relative, float2 pos, float volume) { return new NullSound(); }
public void Draw(int frame, float2 pos) { sequence.GetSprite(frame).DrawAt(pos - sequence.Hotspot, Game.modData.Palette.GetPaletteIndex(sequence.Palette)); }
public OpenAlSound(int source, int buffer, bool looping, bool relative, float2 pos, float volume) { if (source == -1) return; this.source = source; Al.alSourcef(source, Al.AL_PITCH, 1f); Al.alSourcef(source, Al.AL_GAIN, 1f); Al.alSource3f(source, Al.AL_POSITION, pos.X, pos.Y, 0f); Al.alSource3f(source, Al.AL_VELOCITY, 0f, 0f, 0f); Al.alSourcei(source, Al.AL_BUFFER, buffer); Al.alSourcei(source, Al.AL_LOOPING, looping ? Al.AL_TRUE : Al.AL_FALSE); Al.alSourcei(source, Al.AL_SOURCE_RELATIVE, relative ? 1 : 0); Al.alSourcef(source, Al.AL_REFERENCE_DISTANCE, 200); Al.alSourcef(source, Al.AL_MAX_DISTANCE, 1500); Volume = volume; Al.alSourcePlay(source); }
public void Draw(int frame, float2 pos) { sequence.GetSprite(frame).DrawAt(pos - sequence.Hotspot, sequence.Palette); }
public void SetListenerPosition(float2 position) { var orientation = new[] { 0f, 0f, 1f, 0f, -1f, 0f }; Al.alListener3f(Al.AL_POSITION, position.X, position.Y, 50); Al.alListenerfv(Al.AL_ORIENTATION, ref orientation[0]); Al.alListenerf(Al.AL_METERS_PER_UNIT, .01f); }
public static void MoveViewport(float2 loc) { viewport.Center(loc); }