public WRot QuantizeOrientation(Actor self, WRot orientation) { // Quantization disabled if (QuantizedFacings == 0) return orientation; // Map yaw to the closest facing var facing = Util.QuantizeFacing(orientation.Yaw.Angle / 4, QuantizedFacings) * (256 / QuantizedFacings); // Roll and pitch are always zero if yaw is quantized return new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facing)); }
public WDist DistanceFromEdge(WPos pos, WPos origin, WRot orientation) { if (pos.Z > origin.Z + VerticalTopOffset) { return(DistanceFromEdge(pos - (origin + new WVec(0, 0, VerticalTopOffset)))); } if (pos.Z < origin.Z + VerticalBottomOffset) { return(DistanceFromEdge(pos - (origin + new WVec(0, 0, VerticalBottomOffset)))); } return(DistanceFromEdge(pos - new WPos(origin.X, origin.Y, pos.Z))); }
public WRot QuantizeOrientation(WRot orientation, int facings) { //Quantization disabled if (facings == 0) { return(orientation); } //Map yaw to the closest facing. var facing = QuantizeFacing(orientation.Yaw.Angle / 4, facings); //Roll and pitch are always zero if yaw is quantized. return(new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facings))); }
IEnumerable <IRenderable> IHitShape.RenderDebugOverlay(WorldRenderer wr, Actor actor) { var actorPos = actor.CenterPosition; var orientation = actor.Orientation + WRot.FromYaw(LocalYaw); var vertsTop = combatOverlayVertsTop.Select(v => actorPos + v.Rotate(orientation)).ToArray(); var vertsBottom = combatOverlayVertsBottom.Select(v => actorPos + v.Rotate(orientation)).ToArray(); yield return(new PolygonAnnotationRenderable(vertsTop, actorPos, 1, Color.Yellow)); yield return(new PolygonAnnotationRenderable(vertsBottom, actorPos, 1, Color.Yellow)); yield return(new CircleAnnotationRenderable(actorPos, OuterRadius, 1, Color.LimeGreen)); }
public IEnumerable <VoxelAnimation> RenderPreviewVoxels(ActorPreviewInitializer init, RenderVoxelsInfo rv, string image, WRot orientation, int facings, PaletteReference p) { var body = init.Actor.Traits.Get <BodyOrientationInfo>(); var t = init.Actor.Traits.WithInterface <TurretedInfo>() .First(tt => tt.Turret == Turret); var voxel = VoxelProvider.GetVoxel(image, Sequence); var turretOffset = body.LocalToWorld(t.Offset.Rotate(orientation)); var turretBodyOrientation = new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(t.InitialFacing) - orientation.Yaw); var turretOrientation = new[] { turretBodyOrientation, body.QuantizeOrientation(orientation, facings) }; yield return(new VoxelAnimation(voxel, () => turretOffset, () => turretOrientation, () => false, () => 0)); }
// Orientation in world-space public WRot WorldOrientation(Actor self) { // Hack: turretFacing is relative to the world, so subtract the body yaw var world = WRot.FromYaw(WAngle.FromFacing(TurretFacing)); if (QuantizedFacings == 0) { return(world); } // Quantize orientation to match a rendered sprite // Implies no pitch or yaw return(WRot.FromYaw(body.QuantizeFacing(world.Yaw, QuantizedFacings))); }
public WRot QuantizeOrientation(Actor self, WRot orientation) { // Quantization disabled if (QuantizedFacings == 0) { return(orientation); } // Map yaw to the closest facing var facing = Util.QuantizeFacing(orientation.Yaw.Angle / 4, QuantizedFacings) * (256 / QuantizedFacings); // Roll and pitch are always zero if yaw is quantized return(new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facing))); }
void SpawnCrate(Actor self) { var inWater = self.World.SharedRandom.Next(100) < info.WaterChance; var pp = ChooseDropCell(self, inWater, 100); if (pp == null) { return; } var p = pp.Value; var crateActor = ChooseCrateActor(); self.World.AddFrameEndTask(w => { if (info.DeliveryAircraft != null) { var crate = w.CreateActor(false, crateActor, new TypeDictionary { new OwnerInit(w.WorldActor.Owner) }); var dropFacing = 256 * self.World.SharedRandom.Next(info.QuantizedFacings) / info.QuantizedFacings; var delta = new WVec(0, -1024, 0).Rotate(WRot.FromFacing(dropFacing)); var altitude = self.World.Map.Rules.Actors[info.DeliveryAircraft].TraitInfo <AircraftInfo>().CruiseAltitude.Length; var target = self.World.Map.CenterOfCell(p) + new WVec(0, 0, altitude); var startEdge = target - (self.World.Map.DistanceToEdge(target, -delta) + info.Cordon).Length * delta / 1024; var finishEdge = target + (self.World.Map.DistanceToEdge(target, delta) + info.Cordon).Length * delta / 1024; var plane = w.CreateActor(info.DeliveryAircraft, new TypeDictionary { new CenterPositionInit(startEdge), new OwnerInit(self.Owner), new FacingInit(dropFacing), }); var drop = plane.Trait <ParaDrop>(); drop.SetLZ(p, true); plane.Trait <Cargo>().Load(plane, crate); plane.QueueActivity(false, new Fly(plane, Target.FromPos(finishEdge))); plane.QueueActivity(new RemoveSelf()); } else { w.CreateActor(crateActor, new TypeDictionary { new OwnerInit(w.WorldActor.Owner), new LocationInit(p) }); } }); }
public WRot QuantizeOrientation(WRot orientation, int facings) { // Quantization disabled if (facings == 0) { return(orientation); } // Map yaw to the closest facing var facing = QuantizeFacing(orientation.Yaw, facings); // Roll and pitch are always zero if yaw is quantized return(WRot.FromYaw(facing)); }
public void Killed(Actor self, AttackInfo attack) { foreach (var wep in info.WeaponInfos) { var pieces = self.World.SharedRandom.Next(info.Pieces[0], info.Pieces[1]); var range = self.World.SharedRandom.Next(info.Range[0].Length, info.Range[1].Length); for (var i = 0; pieces > i; i++) { var rotation = WRot.FromFacing(self.World.SharedRandom.Next(1024)); var args = new ProjectileArgs { Weapon = wep, Facing = self.World.SharedRandom.Next(-1, 255), DamageModifiers = self.TraitsImplementing <IFirepowerModifier>() .Select(a => a.GetFirepowerModifier()).ToArray(), InaccuracyModifiers = self.TraitsImplementing <IInaccuracyModifier>() .Select(a => a.GetInaccuracyModifier()).ToArray(), RangeModifiers = self.TraitsImplementing <IRangeModifier>() .Select(a => a.GetRangeModifier()).ToArray(), Source = self.CenterPosition, CurrentSource = () => self.CenterPosition, SourceActor = self, PassiveTarget = self.CenterPosition + new WVec(range, 0, 0).Rotate(rotation) }; self.World.AddFrameEndTask(x => { if (args.Weapon.Projectile != null) { var projectile = args.Weapon.Projectile.Create(args); if (projectile != null) { self.World.Add(projectile); } if (args.Weapon.Report != null && args.Weapon.Report.Any()) { Game.Sound.Play(SoundType.World, args.Weapon.Report.Random(self.World.SharedRandom), self.CenterPosition); } } }); } } }
//Orientation in world-space. public WRot WorldOrientation(Actor self) { var world = WRot.FromYaw(WAngle.FromFacing(TurretFacing)); if (QuantizedFacings == 0) { return(world); } //Quantize orientation to match q rendered sprite //Implies no pitch or yaw var facing = body.QuantizeFacing(world.Yaw.Angle / 4, QuantizedFacings); return(new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facing))); }
public void Tick(World world) { lastPos = pos; if (--lifetime < 0) { world.AddFrameEndTask(w => { w.Remove(this); w.ScreenMap.Remove(this); }); return; } anim.Tick(); var forward = speed.Length == 2 ? world.SharedRandom.Next(speed[0].Length, speed[1].Length) : speed[0].Length; var height = gravity.Length == 2 ? world.SharedRandom.Next(gravity[0].Length, gravity[1].Length) : gravity[0].Length; var offset = new WVec(forward, 0, height); if (turnRate > 0) { facing = (facing + world.SharedRandom.Next(-turnRate, turnRate)) & 0xFF; } offset = offset.Rotate(WRot.FromFacing(facing)); pos += offset; world.ScreenMap.Update(this, pos, anim.Image); if (canDamage && --explosionInterval < 0) { var args = new WarheadArgs { Weapon = smoke.Weapon, Source = pos, SourceActor = invoker, WeaponTarget = Target.FromPos(pos), ImpactOrientation = new WRot(WAngle.Zero, Common.Util.GetVerticalAngle(lastPos, pos), WAngle.FromFacing(facing)), ImpactPosition = pos }; smoke.Weapon.Impact(Target.FromPos(pos), args); explosionInterval = smoke.Weapon.ReloadDelay; } }
// Orientation in unit-space public WRot LocalOrientation(Actor self) { // Hack: turretFacing is relative to the world, so subtract the body yaw var local = WRot.FromYaw(WAngle.FromFacing(TurretFacing) - self.Orientation.Yaw); if (QuantizedFacings == 0) { return(local); } // Quantize orientation to match a rendered sprite // Implies no pitch or yaw var facing = Util.QuantizeFacing(local.Yaw.Angle / 4, QuantizedFacings) * (256 / QuantizedFacings); return(new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facing))); }
public WDist DistanceFromEdge(WPos pos, WPos origin, WRot orientation) { orientation += WRot.FromYaw(LocalYaw); if (pos.Z > origin.Z + VerticalTopOffset) { return(DistanceFromEdge((pos - (origin + new WVec(0, 0, VerticalTopOffset))).Rotate(-orientation))); } if (pos.Z < origin.Z + VerticalBottomOffset) { return(DistanceFromEdge((pos - (origin + new WVec(0, 0, VerticalBottomOffset))).Rotate(-orientation))); } return(DistanceFromEdge((pos - new WPos(origin.X, origin.Y, pos.Z)).Rotate(-orientation))); }
// Orientation in world-space public Func <WRot> PreviewOrientation(ActorPreviewInitializer init, Func <WRot> orientation, int facings) { var body = init.Actor.TraitInfo <BodyOrientationInfo>(); var turretFacing = LocalFacingFromInit(init); Func <WRot> world = () => WRot.FromYaw(turretFacing()).Rotate(orientation()); if (facings == 0) { return(world); } // Quantize orientation to match a rendered sprite // Implies no pitch or roll return(() => WRot.FromYaw(body.QuantizeFacing(world().Yaw, facings))); }
public new IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p) { if (!EnabledByDefault) { yield break; } var body = init.Actor.TraitInfo <BodyOrientationInfo>(); var t = init.Actor.TraitInfos <TurretedInfo>() .First(tt => tt.Turret == Turret); var bodyAnim = new Animation(init.World, image, init.GetFacing()); bodyAnim.PlayRepeating(RenderSprites.NormalizeSequence(bodyAnim, init.GetDamageState(), "idle")); var bodySequence = bodyAnim.CurrentSequence as OffsetsSpriteSequence; Func <WVec> offset = null; if (bodySequence != null && bodySequence.EmbeddedOffsets.ContainsKey(bodyAnim.Image) && bodySequence.EmbeddedOffsets[bodyAnim.Image] != null) { var point = bodySequence.EmbeddedOffsets[bodyAnim.Image].FirstOrDefault(p1 => p1.Id == 0); if (point != null) { offset = () => new WVec(point.X * 32, point.Y * 32, 0); } } var turretFacing = Turreted.TurretFacingFromInit(init, t.InitialFacing, Turret); var anim = new Animation(init.World, image, turretFacing); anim.Play(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence)); if (offset == null) { Func <int> facing = init.GetFacing(); Func <WRot> orientation = () => body.QuantizeOrientation(WRot.FromFacing(facing()), facings); offset = () => body.LocalToWorld(t.Offset.Rotate(orientation())); } Func <int> zOffset = () => { var tmpOffset = offset(); return(-(tmpOffset.Y + tmpOffset.Z) + 1); }; yield return(new SpriteActorPreview(anim, offset, zOffset, p, rs.Scale)); }
void Nudge(Actor self) { // Disable nudging if the aircraft is outside the map if (!self.World.Map.Contains(self.Location)) { return; } var offset = new WVec(0, -self.World.SharedRandom.Next(512, 2048), 0) .Rotate(WRot.FromFacing(self.World.SharedRandom.Next(256))); var target = Target.FromPos(self.CenterPosition + offset); self.CancelActivity(); self.SetTargetLine(target, Color.Green, false); self.QueueActivity(new Fly(self, target)); UnReserve(); }
public VoxelRenderable( IEnumerable<VoxelAnimation> voxels, WPos pos, int zOffset, WRot camera, float scale, WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor, PaletteReference color, PaletteReference normals, PaletteReference shadow) { this.voxels = voxels; this.pos = pos; this.zOffset = zOffset; this.scale = scale; this.camera = camera; this.lightSource = lightSource; this.lightAmbientColor = lightAmbientColor; this.lightDiffuseColor = lightDiffuseColor; this.palette = color; this.normalsPalette = normals; this.shadowPalette = shadow; }
void SpawnCloud(Actor self) { var position = self.World.Map.ChooseRandomCell(self.World.SharedRandom); var facing = 256 * info.WindDirection / 32; var delta = new WVec(0, -1024, 0).Rotate(WRot.FromFacing(facing)); var target = self.World.Map.CenterOfCell(position) + new WVec(0, 0, info.CruiseAltitude.Length); var startEdge = target - (self.World.Map.DistanceToEdge(target, -delta) + info.Cordon).Length * delta / 1024; var finishEdge = target + (self.World.Map.DistanceToEdge(target, delta) + info.Cordon).Length * delta / 1024; var animation = new Animation(self.World, info.Image, () => WAngle.FromFacing(facing)); animation.PlayRepeating(info.Sequences.Random(self.World.SharedRandom)); self.World.AddFrameEndTask(w => w.Add(new Cloud(self.World, animation, startEdge, finishEdge, facing, info))); }
public WDist DistanceFromEdge(WPos pos, Actor actor) { var actorPos = actor.CenterPosition; var orientation = actor.Orientation + WRot.FromYaw(LocalYaw); if (pos.Z > actorPos.Z + VerticalTopOffset) { return(DistanceFromEdge((pos - (actorPos + new WVec(0, 0, VerticalTopOffset))).Rotate(-orientation))); } if (pos.Z < actorPos.Z + VerticalBottomOffset) { return(DistanceFromEdge((pos - (actorPos + new WVec(0, 0, VerticalBottomOffset))).Rotate(-orientation))); } return(DistanceFromEdge((pos - new WPos(actorPos.X, actorPos.Y, pos.Z)).Rotate(-orientation))); }
public VoxelRenderable( IEnumerable <VoxelAnimation> voxels, WPos pos, int zOffset, WRot camera, float scale, WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor, PaletteReference color, PaletteReference normals, PaletteReference shadow) { this.voxels = voxels; this.pos = pos; this.zOffset = zOffset; this.scale = scale; this.camera = camera; this.lightSource = lightSource; this.lightAmbientColor = lightAmbientColor; this.lightDiffuseColor = lightDiffuseColor; this.palette = color; this.normalsPalette = normals; this.shadowPalette = shadow; }
public IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, string image, int facings, PaletteReference p) { if (!EnabledByDefault) { yield break; } if (image == null) { yield break; } // For this, image must not be null if (Palette != null) { p = init.WorldRenderer.Palette(Palette); } Func <WAngle> facing; var dynamicfacingInit = init.GetOrDefault <DynamicFacingInit>(); if (dynamicfacingInit != null) { facing = dynamicfacingInit.Value; } else { var f = init.GetValue <FacingInit, WAngle>(WAngle.Zero); facing = () => f; } var anim = new Animation(init.World, image); anim.PlayThen(OpeningSequence, () => anim.PlayRepeating(Sequence)); var body = init.Actor.TraitInfo <BodyOrientationInfo>(); Func <WRot> orientation = () => body.QuantizeOrientation(WRot.FromYaw(facing()), facings); Func <WVec> offset = () => body.LocalToWorld(Offset.Rotate(orientation())); Func <int> zOffset = () => { var tmpOffset = offset(); return(tmpOffset.Y + tmpOffset.Z + 1); }; yield return(new SpriteActorPreview(anim, offset, zOffset, p)); }
void DrawArmaments(Actor self, AttackBase attack, WorldRenderer wr, RgbaColorRenderer wcr, float iz) { var c = Color.White; // Fire ports on garrisonable structures var garrison = attack as AttackGarrisoned; if (garrison != null) { var bodyOrientation = coords.Value.QuantizeOrientation(self, self.Orientation); foreach (var p in garrison.Info.Ports) { var pos = self.CenterPosition + coords.Value.LocalToWorld(p.Offset.Rotate(bodyOrientation)); var da = coords.Value.LocalToWorld(new WVec(224, 0, 0).Rotate(WRot.FromYaw(p.Yaw + p.Cone)).Rotate(bodyOrientation)); var db = coords.Value.LocalToWorld(new WVec(224, 0, 0).Rotate(WRot.FromYaw(p.Yaw - p.Cone)).Rotate(bodyOrientation)); var o = wr.Screen3DPosition(pos); var a = wr.Screen3DPosition(pos + da * 224 / da.Length); var b = wr.Screen3DPosition(pos + db * 224 / db.Length); wcr.DrawLine(o, a, iz, c); wcr.DrawLine(o, b, iz, c); } return; } foreach (var a in attack.Armaments) { if (a.IsTraitDisabled) { continue; } foreach (var b in a.Barrels) { var muzzle = self.CenterPosition + a.MuzzleOffset(self, b); var dirOffset = new WVec(0, -224, 0).Rotate(a.MuzzleOrientation(self, b)); var sm = wr.Screen3DPosition(muzzle); var sd = wr.Screen3DPosition(muzzle + dirOffset); wcr.DrawLine(sm, sd, iz, c); TargetLineRenderable.DrawTargetMarker(wr, c, sm); } } }
public IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, RenderSpritesInfo rs, string image, int facings, PaletteReference p) { if (UpgradeMinEnabledLevel > 0) { yield break; } if (image == null) { yield break; } // For this, image must not be null if (Palette != null) { p = init.WorldRenderer.Palette(Palette); } Func <int> facing; if (init.Contains <DynamicFacingInit>()) { facing = init.Get <DynamicFacingInit, Func <int> >(); } else { var f = init.Contains <FacingInit>() ? init.Get <FacingInit, int>() : 0; facing = () => f; } var anim = new Animation(init.World, image); anim.PlayThen(OpeningSequence, () => anim.PlayRepeating(Sequence)); var body = init.Actor.TraitInfo <BodyOrientationInfo>(); Func <WRot> orientation = () => body.QuantizeOrientation(WRot.FromFacing(facing()), facings); Func <WVec> offset = () => body.LocalToWorld(Offset.Rotate(orientation())); Func <int> zOffset = () => { var tmpOffset = offset(); return(tmpOffset.Y + tmpOffset.Z + 1); }; yield return(new SpriteActorPreview(anim, offset, zOffset, p, rs.Scale)); }
public VoxelPreview(VoxelAnimation[] components, WVec offset, int zOffset, float scale, WAngle lightPitch, WAngle lightYaw, float[] lightAmbientColor, float[] lightDiffuseColor, WAngle cameraPitch, PaletteReference colorPalette, PaletteReference normalsPalette, PaletteReference shadowPalette) { this.components = components; this.scale = scale; this.lightAmbientColor = lightAmbientColor; this.lightDiffuseColor = lightDiffuseColor; lightSource = new WRot(WAngle.Zero, new WAngle(256) - lightPitch, lightYaw); camera = new WRot(WAngle.Zero, cameraPitch - new WAngle(256), new WAngle(256)); this.colorPalette = colorPalette; this.normalsPalette = normalsPalette; this.shadowPalette = shadowPalette; this.offset = offset; this.zOffset = zOffset; }
public UIModelRenderable( IEnumerable <ModelAnimation> models, WPos effectiveWorldPos, int2 screenPos, int zOffset, WRot camera, float scale, WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor, PaletteReference color, PaletteReference normals, PaletteReference shadow) { this.models = models; this.effectiveWorldPos = effectiveWorldPos; this.screenPos = screenPos; this.zOffset = zOffset; this.scale = scale; this.camera = camera; this.lightSource = lightSource; this.lightAmbientColor = lightAmbientColor; this.lightDiffuseColor = lightDiffuseColor; palette = color; normalsPalette = normals; shadowPalette = shadow; }
public virtual IEnumerable <IActorPreview> RenderPreview(ActorPreviewInitializer init) { var body = init.Actor.Traits.Get <BodyOrientationInfo>(); var sequenceProvider = init.World.Map.SequenceProvider; var image = Image ?? init.Actor.Name; var facings = body.QuantizedFacings == -1 ? init.Actor.Traits.Get <IQuantizeBodyOrientationInfo>().QuantizedBodyFacings(sequenceProvider, init.Actor) : body.QuantizedFacings; var palette = init.WorldRenderer.Palette(Palette ?? (init.Owner != null ? PlayerPalette + init.Owner.InternalName : null)); var facing = init.Contains <FacingInit>() ? init.Get <FacingInit, int>() : 0; var orientation = WRot.FromFacing(facing); var components = init.Actor.Traits.WithInterface <IRenderActorPreviewVoxelsInfo>() .SelectMany(rvpi => rvpi.RenderPreviewVoxels(init, this, image, orientation, facings, palette)) .ToArray(); yield return(new VoxelPreview(components, WVec.Zero, 0, this.Scale, this.LightPitch, this.LightYaw, this.LightAmbientColor, this.LightDiffuseColor, body.CameraPitch, palette, init.WorldRenderer.Palette(NormalsPalette), init.WorldRenderer.Palette("shadow"))); }
public IEnumerable <IActorPreview> RenderPreviewSprites(ActorPreviewInitializer init, string image, int facings, PaletteReference p) { if (!EnabledByDefault) { yield break; } if (Palette != null) { var ownerName = init.Get <OwnerInit>().InternalName; p = init.WorldRenderer.Palette(IsPlayerPalette ? Palette + ownerName : Palette); } Func <WAngle> facing; var dynamicfacingInit = init.GetOrDefault <DynamicFacingInit>(); if (dynamicfacingInit != null) { facing = dynamicfacingInit.Value; } else { var f = init.GetValue <FacingInit, WAngle>(WAngle.Zero); facing = () => f; } var anim = new Animation(init.World, Image ?? image, facing) { IsDecoration = IsDecoration }; anim.PlayRepeating(RenderSprites.NormalizeSequence(anim, init.GetDamageState(), Sequence)); var body = init.Actor.TraitInfo <BodyOrientationInfo>(); Func <WRot> orientation = () => body.QuantizeOrientation(WRot.FromYaw(facing()), facings); Func <WVec> offset = () => body.LocalToWorld(Offset.Rotate(orientation())); Func <int> zOffset = () => { var tmpOffset = offset(); return(tmpOffset.Y + tmpOffset.Z + 1); }; yield return(new SpriteActorPreview(anim, offset, zOffset, p)); }
public WVec GetRepulseForce(Actor self, Actor other) { if (self == other || other.CenterPosition.Z < self.CenterPosition.Z) return WVec.Zero; var d = self.CenterPosition - other.CenterPosition; var distSq = d.HorizontalLengthSquared; if (distSq > Info.IdealSeparation.Range * Info.IdealSeparation.Range) return WVec.Zero; if (distSq < 1) { var yaw = self.World.SharedRandom.Next(0, 1023); var rot = new WRot(WAngle.Zero, WAngle.Zero, new WAngle(yaw)); return new WVec(1024, 0, 0).Rotate(rot); } return (d * 1024 * 8) / (int)distSq; }
void INotifyIdle.TickIdle(Actor self) { if (state == PopupState.Open && idleTicks++ > info.CloseDelay) { var facingOffset = new WVec(0, -1024, 0).Rotate(WRot.FromYaw(info.DefaultFacing)); turret.FaceTarget(self, Target.FromPos(self.CenterPosition + facingOffset)); state = PopupState.Rotating; } else if (state == PopupState.Rotating && turret.HasAchievedDesiredFacing) { state = PopupState.Transitioning; wsb.PlayCustomAnimation(self, info.ClosingSequence, () => { state = PopupState.Closed; wsb.PlayCustomAnimationRepeating(self, info.ClosedIdleSequence); turret.FaceTarget(self, Target.Invalid); }); } }
IEnumerable <IRenderable> IHitShape.RenderDebugOverlay(WorldRenderer wr, WPos origin, WRot orientation) { orientation += WRot.FromYaw(LocalYaw); var vertsTop = combatOverlayVertsTop.Select(v => origin + v.Rotate(orientation)).ToArray(); var vertsBottom = combatOverlayVertsBottom.Select(v => origin + v.Rotate(orientation)).ToArray(); var side1 = combatOverlayVertsSide1.Select(v => origin + v.Rotate(orientation)).ToArray(); var side2 = combatOverlayVertsSide2.Select(v => origin + v.Rotate(orientation)).ToArray(); yield return(new PolygonAnnotationRenderable(vertsTop, origin, 1, Color.Yellow)); yield return(new PolygonAnnotationRenderable(vertsBottom, origin, 1, Color.Yellow)); yield return(new PolygonAnnotationRenderable(side1, origin, 1, Color.Yellow)); yield return(new PolygonAnnotationRenderable(side2, origin, 1, Color.Yellow)); yield return(new CircleAnnotationRenderable(origin, OuterRadius, 1, Color.LimeGreen)); }
public ModelRenderable( IEnumerable <ModelAnimation> models, WPos pos, int zOffset, WRot camera, float scale, WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor, PaletteReference color, PaletteReference normals, PaletteReference shadow, float3 tint) { this.models = models; this.pos = pos; this.zOffset = zOffset; this.scale = scale; this.camera = camera; this.lightSource = lightSource; this.lightAmbientColor = lightAmbientColor; this.lightDiffuseColor = lightDiffuseColor; palette = color; normalsPalette = normals; shadowPalette = shadow; this.tint = tint; }
public void Killed(Actor self, AttackInfo attack) { foreach (var name in info.Weapons) { var wep = self.World.Map.Rules.Weapons[name]; var pieces = self.World.SharedRandom.Next(info.Pieces[0], info.Pieces[1]); var range = self.World.SharedRandom.Next(info.Range[0].Range, info.Range[1].Range); for (var i = 0; pieces > i; i++) { var rotation = WRot.FromFacing(self.World.SharedRandom.Next(1024)); var args = new ProjectileArgs { Weapon = wep, Facing = self.World.SharedRandom.Next(-1, 255), FirepowerModifier = self.TraitsImplementing <IFirepowerModifier>() .Select(a => a.GetFirepowerModifier()) .Product(), Source = self.CenterPosition, SourceActor = self, PassiveTarget = self.CenterPosition + new WVec(range, 0, 0).Rotate(rotation) }; self.World.AddFrameEndTask(x => { if (args.Weapon.Projectile != null) { var projectile = args.Weapon.Projectile.Create(args); if (projectile != null) { self.World.Add(projectile); } if (args.Weapon.Report != null && args.Weapon.Report.Any()) { Sound.Play(args.Weapon.Report.Random(self.World.SharedRandom), self.CenterPosition); } } }); } } }
public WDist DistanceFromEdge(WPos pos, Actor actor) { var actorPos = actor.CenterPosition; var orientation = new WRot(actor.Orientation.Roll, actor.Orientation.Pitch, new WAngle(actor.Orientation.Yaw.Angle + (RotateToIsometry ? 128 : 0))); var targetablePositions = actor.TraitsImplementing<ITargetablePositions>(); if (ApplyToAllTargetablePositions && targetablePositions.Any()) { var positions = targetablePositions.SelectMany(tp => tp.TargetablePositions(actor)); actorPos = positions.PositionClosestTo(pos); } if (pos.Z > actorPos.Z + VerticalTopOffset) return DistanceFromEdge((pos - (actorPos + new WVec(0, 0, VerticalTopOffset))).Rotate(-orientation)); if (pos.Z < actorPos.Z + VerticalBottomOffset) return DistanceFromEdge((pos - (actorPos + new WVec(0, 0, VerticalBottomOffset))).Rotate(-orientation)); return DistanceFromEdge((pos - new WPos(actorPos.X, actorPos.Y, pos.Z)).Rotate(-orientation)); }
public WRot QuantizeOrientation(WRot orientation, int facings) { // Quantization disabled if (facings == 0) return orientation; // Map yaw to the closest facing var facing = QuantizeFacing(orientation.Yaw.Angle / 4, facings); // Roll and pitch are always zero if yaw is quantized return new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facing)); }
public void DrawCombatOverlay(WorldRenderer wr, RgbaColorRenderer wcr, Actor actor) { var actorPos = actor.CenterPosition; var orientation = new WRot(actor.Orientation.Roll, actor.Orientation.Pitch, new WAngle(actor.Orientation.Yaw.Angle + (RotateToIsometry ? 128 : 0))); var targetablePositions = actor.TraitsImplementing<ITargetablePositions>(); if (ApplyToAllTargetablePositions && targetablePositions.Any()) { var positions = targetablePositions.SelectMany(tp => tp.TargetablePositions(actor)); foreach (var pos in positions) { var vertsTop = combatOverlayVertsTop.Select(v => wr.Screen3DPosition(pos + v.Rotate(orientation))); var vertsBottom = combatOverlayVertsBottom.Select(v => wr.Screen3DPosition(pos + v.Rotate(orientation))); wcr.DrawPolygon(vertsTop.ToArray(), 1, Color.Yellow); wcr.DrawPolygon(vertsBottom.ToArray(), 1, Color.Yellow); } } else { var vertsTop = combatOverlayVertsTop.Select(v => wr.Screen3DPosition(actorPos + v.Rotate(orientation))); var vertsBottom = combatOverlayVertsBottom.Select(v => wr.Screen3DPosition(actorPos + v.Rotate(orientation))); wcr.DrawPolygon(vertsTop.ToArray(), 1, Color.Yellow); wcr.DrawPolygon(vertsBottom.ToArray(), 1, Color.Yellow); } }
public VoxelRenderProxy RenderAsync( WorldRenderer wr, IEnumerable<VoxelAnimation> voxels, WRot camera, float scale, float[] groundNormal, WRot lightSource, float[] lightAmbientColor, float[] lightDiffuseColor, PaletteReference color, PaletteReference normals, PaletteReference shadowPalette) { // Correct for inverted y-axis var scaleTransform = Util.ScaleMatrix(scale, scale, scale); // Correct for bogus light source definition var lightYaw = Util.MakeFloatMatrix(new WRot(WAngle.Zero, WAngle.Zero, -lightSource.Yaw).AsMatrix()); var lightPitch = Util.MakeFloatMatrix(new WRot(WAngle.Zero, -lightSource.Pitch, WAngle.Zero).AsMatrix()); var shadowTransform = Util.MatrixMultiply(lightPitch, lightYaw); var invShadowTransform = Util.MatrixInverse(shadowTransform); var cameraTransform = Util.MakeFloatMatrix(camera.AsMatrix()); var invCameraTransform = Util.MatrixInverse(cameraTransform); if (invCameraTransform == null) throw new InvalidOperationException("Failed to invert the cameraTransform matrix during RenderAsync."); // Sprite rectangle var tl = new float2(float.MaxValue, float.MaxValue); var br = new float2(float.MinValue, float.MinValue); // Shadow sprite rectangle var stl = new float2(float.MaxValue, float.MaxValue); var sbr = new float2(float.MinValue, float.MinValue); foreach (var v in voxels) { // Convert screen offset back to world coords var offsetVec = Util.MatrixVectorMultiply(invCameraTransform, wr.ScreenVector(v.OffsetFunc())); var offsetTransform = Util.TranslationMatrix(offsetVec[0], offsetVec[1], offsetVec[2]); var worldTransform = v.RotationFunc().Aggregate(Util.IdentityMatrix(), (x, y) => Util.MatrixMultiply(Util.MakeFloatMatrix(y.AsMatrix()), x)); worldTransform = Util.MatrixMultiply(scaleTransform, worldTransform); worldTransform = Util.MatrixMultiply(offsetTransform, worldTransform); var bounds = v.Voxel.Bounds(v.FrameFunc()); var worldBounds = Util.MatrixAABBMultiply(worldTransform, bounds); var screenBounds = Util.MatrixAABBMultiply(cameraTransform, worldBounds); var shadowBounds = Util.MatrixAABBMultiply(shadowTransform, worldBounds); // Aggregate bounds rects tl = float2.Min(tl, new float2(screenBounds[0], screenBounds[1])); br = float2.Max(br, new float2(screenBounds[3], screenBounds[4])); stl = float2.Min(stl, new float2(shadowBounds[0], shadowBounds[1])); sbr = float2.Max(sbr, new float2(shadowBounds[3], shadowBounds[4])); } // Inflate rects to ensure rendering is within bounds tl -= SpritePadding; br += SpritePadding; stl -= SpritePadding; sbr += SpritePadding; // Corners of the shadow quad, in shadow-space var corners = new float[][] { new[] { stl.X, stl.Y, 0, 1 }, new[] { sbr.X, sbr.Y, 0, 1 }, new[] { sbr.X, stl.Y, 0, 1 }, new[] { stl.X, sbr.Y, 0, 1 } }; var shadowScreenTransform = Util.MatrixMultiply(cameraTransform, invShadowTransform); var shadowGroundNormal = Util.MatrixVectorMultiply(shadowTransform, groundNormal); var screenCorners = new float3[4]; for (var j = 0; j < 4; j++) { // Project to ground plane corners[j][2] = -(corners[j][1] * shadowGroundNormal[1] / shadowGroundNormal[2] + corners[j][0] * shadowGroundNormal[0] / shadowGroundNormal[2]); // Rotate to camera-space corners[j] = Util.MatrixVectorMultiply(shadowScreenTransform, corners[j]); screenCorners[j] = new float3(corners[j][0], corners[j][1], 0); } // Shadows are rendered at twice the resolution to reduce artifacts Size spriteSize, shadowSpriteSize; int2 spriteOffset, shadowSpriteOffset; CalculateSpriteGeometry(tl, br, 1, out spriteSize, out spriteOffset); CalculateSpriteGeometry(stl, sbr, 2, out shadowSpriteSize, out shadowSpriteOffset); var sprite = sheetBuilder.Allocate(spriteSize, 0, spriteOffset); var shadowSprite = sheetBuilder.Allocate(shadowSpriteSize, 0, shadowSpriteOffset); var sb = sprite.Bounds; var ssb = shadowSprite.Bounds; var spriteCenter = new float2(sb.Left + sb.Width / 2, sb.Top + sb.Height / 2); var shadowCenter = new float2(ssb.Left + ssb.Width / 2, ssb.Top + ssb.Height / 2); var translateMtx = Util.TranslationMatrix(spriteCenter.X - spriteOffset.X, renderer.SheetSize - (spriteCenter.Y - spriteOffset.Y), 0); var shadowTranslateMtx = Util.TranslationMatrix(shadowCenter.X - shadowSpriteOffset.X, renderer.SheetSize - (shadowCenter.Y - shadowSpriteOffset.Y), 0); var correctionTransform = Util.MatrixMultiply(translateMtx, FlipMtx); var shadowCorrectionTransform = Util.MatrixMultiply(shadowTranslateMtx, ShadowScaleFlipMtx); doRender.Add(Pair.New<Sheet, Action>(sprite.Sheet, () => { foreach (var v in voxels) { // Convert screen offset to world offset var offsetVec = Util.MatrixVectorMultiply(invCameraTransform, wr.ScreenVector(v.OffsetFunc())); var offsetTransform = Util.TranslationMatrix(offsetVec[0], offsetVec[1], offsetVec[2]); var rotations = v.RotationFunc().Aggregate(Util.IdentityMatrix(), (x, y) => Util.MatrixMultiply(Util.MakeFloatMatrix(y.AsMatrix()), x)); var worldTransform = Util.MatrixMultiply(scaleTransform, rotations); worldTransform = Util.MatrixMultiply(offsetTransform, worldTransform); var transform = Util.MatrixMultiply(cameraTransform, worldTransform); transform = Util.MatrixMultiply(correctionTransform, transform); var shadow = Util.MatrixMultiply(shadowTransform, worldTransform); shadow = Util.MatrixMultiply(shadowCorrectionTransform, shadow); var lightTransform = Util.MatrixMultiply(Util.MatrixInverse(rotations), invShadowTransform); var frame = v.FrameFunc(); for (uint i = 0; i < v.Voxel.Limbs; i++) { var rd = v.Voxel.RenderData(i); var t = v.Voxel.TransformationMatrix(i, frame); var it = Util.MatrixInverse(t); if (it == null) throw new InvalidOperationException("Failed to invert the transformed matrix of frame {0} during RenderAsync.".F(i)); // Transform light vector from shadow -> world -> limb coords var lightDirection = ExtractRotationVector(Util.MatrixMultiply(it, lightTransform)); Render(rd, Util.MatrixMultiply(transform, t), lightDirection, lightAmbientColor, lightDiffuseColor, color.TextureMidIndex, normals.TextureMidIndex); // Disable shadow normals by forcing zero diffuse and identity ambient light if (v.ShowShadow) Render(rd, Util.MatrixMultiply(shadow, t), lightDirection, ShadowAmbient, ShadowDiffuse, shadowPalette.TextureMidIndex, normals.TextureMidIndex); } } })); var screenLightVector = Util.MatrixVectorMultiply(invShadowTransform, ZVector); screenLightVector = Util.MatrixVectorMultiply(cameraTransform, screenLightVector); return new VoxelRenderProxy(sprite, shadowSprite, screenCorners, -screenLightVector[2] / screenLightVector[1]); }
public WRot QuantizeOrientation(Actor self, WRot orientation) { // Map yaw to the closest facing var numDirs = Info.QuantizedFacings == -1 ? anim.CurrentSequence.Facings : Info.QuantizedFacings; var facing = Util.QuantizeFacing(orientation.Yaw.Angle / 4, numDirs) * (256 / numDirs); // Roll and pitch are always zero return new WRot(WAngle.Zero, WAngle.Zero, WAngle.FromFacing(facing)); }
public WRot QuantizeOrientation(Actor self, WRot orientation) { return info.QuantizeOrientation(orientation, quantizedFacings.Value); }