public void AddStripToTriangleList2(Edge e, float depth, List<VertexPositionColorNormalTexture> triangleList) { float edgeLength = (e.end.position - e.start.position).Length(); if (e.start.normal != e.end.normal) { Vector3 fullEdge = e.end.position - e.start.position; Vector3 currentComponent = Vector3.Dot(e.end.normal, fullEdge) * e.end.normal; Vector3 nextComponent = Vector3.Dot(e.start.normal, fullEdge) * e.start.normal; Vector3 constantComponent = Vector3.Dot(Vector3.Cross(e.end.normal, e.start.normal), fullEdge) * Vector3.Cross(e.end.normal, e.start.normal); float currentPercent = currentComponent.Length() / (currentComponent.Length() + nextComponent.Length()); Vector3 midPoint = e.start.position + currentComponent + currentPercent * constantComponent; edgeLength = (e.end.position - midPoint).Length() + (e.start.position - midPoint).Length(); } int width = (int)(edgeLength+.5f); float blockWidth = edgeLength / width; List<Vertex> fullPointList = new List<Vertex>(); for (int i = 0; i < width+1; i++) { Vector3 up = Vector3.Cross(e.start.normal, e.start.direction); fullPointList.Add(new Vertex(e.start, e.start.direction * i + up)); fullPointList.Add(new Vertex(e.start, e.start.direction * i)); } for (int i = 0; i < (width+1) * 2; i++) { fullPointList[i].Update(this, 0); } for (int i = 0; i < width; i++) { List<Vertex> subList = new List<Vertex>(); List<Vertex> mirrorSubList = new List<Vertex>(); Vector3 up = Vector3.Cross(fullPointList[(i * 2)].direction, fullPointList[i * 2].normal); mirrorSubList.Add(new Vertex(fullPointList[(i) * 2 + 1], .01f * up)); mirrorSubList.Add(new Vertex(fullPointList[(i + 1) * 2 + 1], .01f * up)); mirrorSubList.Add(fullPointList[(i + 1) * 2]); mirrorSubList.Add(fullPointList[i * 2]); subList.Add(new Vertex(fullPointList[(i+1) * 2 + 1], .01f*up)); subList.Add(new Vertex(fullPointList[(i) * 2 + 1], .01f*up)); subList.Add(fullPointList[(i) * 2]); subList.Add(fullPointList[(i+1) * 2]); /*foreach (Vertex v in mirrorSubList) v.Update(this, 0); foreach (Vertex v in subList) v.Update(this, 0);*/ if (e.properties.type == VL.EdgeType.Ice) { #region ice if (i == width - 1) { AddBlockFrontToTriangleList(mirrorSubList, Color.White, depth + .01f, edgeSideEndTexCoords, triangleList, true); AddTopStrip(fullPointList[(i + 1) * 2 + 1], fullPointList[i * 2 + 1], depth + .01f, .01f, true, edgeTopEndTexCoords, triangleList); } else if (i == 0) { AddBlockFrontToTriangleList(subList, Color.White, depth + .01f, edgeSideEndTexCoords, triangleList, true); AddTopStrip(fullPointList[i * 2 + 1], fullPointList[(i + 1) * 2 + 1], depth + .01f, .01f, false, edgeTopEndTexCoords, triangleList); } else { AddBlockFrontToTriangleList(subList, Color.White, depth + .01f, edgeSideTexCoords, triangleList, true); AddTopStrip(fullPointList[i * 2 + 1], fullPointList[(i + 1) * 2 + 1], depth + .01f, .01f, false, edgeTopTexCoords, triangleList); } #endregion } else if (e.properties.type == VL.EdgeType.Bounce) { #region bounce float treadRise = .1f; float treadFraction = .75f; if (i == width - 1) { Vertex v1t = new Vertex(fullPointList[i * 2 + 1], treadRise * up); Vertex v3t = fullPointList[(i + 1) * 2 + 1]; Vertex v2t = new Vertex(fullPointList[i * 2 + 1], treadRise * up + treadFraction * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position)); v1t.Update(this, 0); v2t.Update(this, 0); v3t.Update(this, 0); List<Vertex> subListA = new List<Vertex>(); subListA.Add(new Vertex(subList[0], Vector3.Zero)); // Left subListA.Add(new Vertex(subList[1], treadRise * up + treadFraction * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position))); subListA.Add(new Vertex(subList[2], treadFraction * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position))); subListA.Add(new Vertex(subList[3], Vector3.Zero)); // Left foreach (Vertex v in subListA) v.Update(this, 0); List<Vertex> subListB = new List<Vertex>(); subListB.Add(new Vertex(subList[1], treadRise * up + treadFraction * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position))); subListB.Add(new Vertex(subList[1], treadRise * up)); subListB.Add(new Vertex(subList[2], Vector3.Zero)); subListB.Add(new Vertex(subList[2], treadFraction * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position))); foreach (Vertex v in subListB) v.Update(this, 0); AddTopStrip(v1t, v2t, depth + .011f, .00f, false, edgeTopTexCoords, triangleList); AddTopStrip(v2t, v3t, depth + .011f, .00f, false, edgeTopTexCoords, triangleList); AddBlockFrontToTriangleList(mirrorSubList, Color.White, depth + .01f, edgeSideEndTexCoords, triangleList, true); AddBlockFrontToTriangleList(subListA, Color.White, depth + .011f, rubberSideSmallTexCoords, triangleList, true); AddBlockFrontToTriangleList(subListB, Color.White, depth + .011f, rubberSideSmallTexCoords, triangleList, true); } else if (i == 0) { Vertex v1 = fullPointList[i * 2 + 1]; Vertex v3 = new Vertex(fullPointList[(i + 1) * 2 + 1], treadRise * up); Vertex v2 = new Vertex(fullPointList[i * 2 + 1], treadRise * up + (1 - treadFraction) * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position)); v1.Update(this, 0); v2.Update(this, 0); v3.Update(this, 0); List<Vertex> subListA = new List<Vertex>(); subListA.Add(new Vertex(subList[0], treadRise * up)); // Left subListA.Add(new Vertex(subList[1], treadRise * up + (1 - treadFraction) * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position))); subListA.Add(new Vertex(subList[2], (1 - treadFraction) * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position))); subListA.Add(new Vertex(subList[3], Vector3.Zero)); // Left List<Vertex> subListB = new List<Vertex>(); subListB.Add(new Vertex(subList[1], treadRise * up + (1 - treadFraction) * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position))); subListB.Add(new Vertex(subList[1], Vector3.Zero)); subListB.Add(new Vertex(subList[2], Vector3.Zero)); subListB.Add(new Vertex(subList[2], (1 - treadFraction) * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position))); AddBlockFrontToTriangleList(subList, Color.White, depth + .01f, edgeSideEndTexCoords, triangleList, true); AddBlockFrontToTriangleList(subListA, Color.White, depth + .011f, rubberSideSmallTexCoords, triangleList, true); AddBlockFrontToTriangleList(subListB, Color.White, depth + .011f, rubberSideSmallTexCoords, triangleList, true); AddTopStrip(v1, v2, depth + .011f, .00f, false, edgeTopTexCoords, triangleList); AddTopStrip(v2, v3, depth + .011f, .00f, false, edgeTopTexCoords, triangleList); } else { Vertex v1 = new Vertex(fullPointList[i * 2 + 1], treadRise * up); Vertex v2 = new Vertex(fullPointList[(i + 1) * 2 + 1], treadRise * up); v1.Update(this, 0); v2.Update(this, 0); List<Vertex> subListA = new List<Vertex>(); subListA.Add(new Vertex(subList[0], treadRise * up)); subListA.Add(new Vertex(subList[1], treadRise * up)); subListA.Add(new Vertex(subList[2], Vector3.Zero)); subListA.Add(new Vertex(subList[3], Vector3.Zero)); AddBlockFrontToTriangleList(subList, Color.White, depth + .01f, edgeSideTexCoords, triangleList, true); AddBlockFrontToTriangleList(subListA, Color.White, depth + .01f, rubberSideSmallTexCoords, triangleList, true); AddTopStrip(v1, v2, depth + .01f, .00f, false, edgeTopTexCoords, triangleList); } #endregion } else if (e.properties.type == VL.EdgeType.ConveyorBelt) { #region conveyorbelt float beltOffset = .0000125f * beltAnimation * e.properties.primaryValue; beltOffset %= .125f; if (beltOffset < 0) beltOffset += .125f; List<Vector2> activeBeltTopTexCoords = new List<Vector2>(); activeBeltTopTexCoords.Add(edgeTopTexCoords[0] + beltOffset * Vector2.UnitX); activeBeltTopTexCoords.Add(edgeTopTexCoords[1] + beltOffset * Vector2.UnitX); activeBeltTopTexCoords.Add(edgeTopTexCoords[2] + beltOffset * Vector2.UnitX); activeBeltTopTexCoords.Add(edgeTopTexCoords[3] + beltOffset * Vector2.UnitX); List<Vector2> activeBeltSideTexCoords = new List<Vector2>(); activeBeltSideTexCoords.Add(beltSideSmallTexCoords[0] + beltOffset * Vector2.UnitX); activeBeltSideTexCoords.Add(beltSideSmallTexCoords[1] + beltOffset * Vector2.UnitX); activeBeltSideTexCoords.Add(beltSideSmallTexCoords[2] + beltOffset * Vector2.UnitX); activeBeltSideTexCoords.Add(beltSideSmallTexCoords[3] + beltOffset * Vector2.UnitX); float treadRise = .08f; float treadFraction = .8f; if (i == width - 1) { Vertex v1t = new Vertex(fullPointList[i * 2 + 1], treadRise * up); Vertex v3t = fullPointList[(i + 1) * 2 + 1]; Vertex v2t = new Vertex(fullPointList[i * 2 + 1], treadRise * up + treadFraction * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position)); List<Vertex> subListA = new List<Vertex>(); subListA.Add(new Vertex(subList[0], Vector3.Zero)); // Left subListA.Add(new Vertex(subList[1], treadRise * up + treadFraction * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position))); subListA.Add(new Vertex(subList[2], treadFraction * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position))); subListA.Add(new Vertex(subList[3], Vector3.Zero)); // Left List<Vertex> subListB = new List<Vertex>(); subListB.Add(new Vertex(subList[1], treadRise * up + treadFraction * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position))); subListB.Add(new Vertex(subList[1], treadRise * up)); subListB.Add(new Vertex(subList[2], Vector3.Zero)); subListB.Add(new Vertex(subList[2], treadFraction * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position))); AddTopStrip(v1t, v2t, depth + .011f, .00f, false, activeBeltTopTexCoords, triangleList); AddTopStrip(v2t, v3t, depth + .011f, .00f, false, activeBeltTopTexCoords, triangleList); AddBlockFrontToTriangleList(mirrorSubList, Color.White, depth + .01f, edgeSideEndTexCoords, triangleList, true); AddBlockFrontToTriangleList(subListA, Color.White, depth + .011f, activeBeltSideTexCoords, triangleList, true); AddBlockFrontToTriangleList(subListB, Color.White, depth + .011f, activeBeltSideTexCoords, triangleList, true); } else if (i == 0) { Vertex v1 = fullPointList[i * 2 + 1]; Vertex v3 = new Vertex(fullPointList[(i + 1) * 2 + 1], treadRise * up); Vertex v2 = new Vertex(fullPointList[i * 2 + 1], treadRise * up + (1-treadFraction) * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position)); v1.Update(this, 0); v2.Update(this, 0); v3.Update(this, 0); List<Vertex> subListA = new List<Vertex>(); subListA.Add(new Vertex(subList[0], treadRise * up)); // Left subListA.Add(new Vertex(subList[1], treadRise * up+(1 - treadFraction) * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position))); subListA.Add(new Vertex(subList[2], (1-treadFraction) * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position))); subListA.Add(new Vertex(subList[3], Vector3.Zero)); // Left List<Vertex> subListB = new List<Vertex>(); subListB.Add(new Vertex(subList[1], treadRise * up + (1-treadFraction) * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position))); subListB.Add(new Vertex(subList[1], Vector3.Zero)); subListB.Add(new Vertex(subList[2], Vector3.Zero)); subListB.Add(new Vertex(subList[2], (1 - treadFraction) * (fullPointList[(i + 1) * 2 + 1].position - fullPointList[i * 2 + 1].position))); AddTopStrip(v1, v2, depth + .011f, .00f, false, activeBeltTopTexCoords, triangleList); AddTopStrip(v2, v3, depth + .011f, .00f, false, activeBeltTopTexCoords, triangleList); AddBlockFrontToTriangleList(subList, Color.White, depth + .01f, edgeSideEndTexCoords, triangleList, true); AddBlockFrontToTriangleList(subListA, Color.White, depth + .011f, activeBeltSideTexCoords, triangleList, true); AddBlockFrontToTriangleList(subListB, Color.White, depth + .011f, activeBeltSideTexCoords, triangleList, true); } else { Vertex v1 = new Vertex(fullPointList[i * 2 + 1], treadRise * up); Vertex v2 = new Vertex(fullPointList[(i + 1) * 2 + 1], treadRise * up); v1.Update(this, 0); v2.Update(this, 0); List<Vertex> subListA = new List<Vertex>(); subListA.Add(new Vertex(subList[0], treadRise * up)); subListA.Add(new Vertex(subList[1], treadRise * up)); subListA.Add(new Vertex(subList[2], Vector3.Zero)); subListA.Add(new Vertex(subList[3], Vector3.Zero)); AddTopStrip(v1, v2, depth + .011f, .00f, false, activeBeltTopTexCoords, triangleList); AddBlockFrontToTriangleList(subList, Color.White, depth + .01f, edgeSideTexCoords, triangleList, true); AddBlockFrontToTriangleList(subListA, Color.White, depth + .011f, activeBeltSideTexCoords, triangleList, true); } #endregion } else if (e.properties.type == VL.EdgeType.Electric && e.properties.primaryValue == 0) { #region electric off if (i == width - 1) { AddBlockFrontToTriangleList(mirrorSubList, Color.White, depth + .01f, edgeSideEndTexCoords, triangleList, true); AddTopStrip(fullPointList[(i + 1) * 2 + 1], fullPointList[i * 2 + 1], depth + .01f, .01f, true, edgeTopEndTexCoords, triangleList); } else if (i == 0) { AddBlockFrontToTriangleList(subList, Color.White, depth + .01f, edgeSideEndTexCoords, triangleList, true); AddTopStrip(fullPointList[i * 2 + 1], fullPointList[(i + 1) * 2 + 1], depth + .01f, .01f, false, edgeTopEndTexCoords, triangleList); } else { AddBlockFrontToTriangleList(subList, Color.White, depth + .01f, edgeSideTexCoords, triangleList, true); AddTopStrip(fullPointList[i * 2 + 1], fullPointList[(i + 1) * 2 + 1], depth + .01f, .01f, false, edgeTopTexCoords, triangleList); } #endregion } else if (e.properties.type == VL.EdgeType.Electric && e.properties.primaryValue != 0) { #region electric on if (i == width - 1) { AddBlockFrontToTriangleList(mirrorSubList, Color.White, depth + .01f, edgeSideEndTexCoords, triangleList, true); AddTopStrip(fullPointList[(i + 1) * 2 + 1], fullPointList[i * 2 + 1], depth + .01f, .01f, true, edgeTopEndTexCoords, triangleList); } else if (i == 0) { AddBlockFrontToTriangleList(subList, Color.White, depth + .01f, edgeSideEndTexCoords, triangleList, true); AddTopStrip(fullPointList[i * 2 + 1], fullPointList[(i + 1) * 2 + 1], depth + .01f, .01f, false, edgeTopEndTexCoords, triangleList); } else { AddBlockFrontToTriangleList(subList, Color.White, depth + .01f, edgeSideTexCoords, triangleList, true); AddTopStrip(fullPointList[i * 2 + 1], fullPointList[(i + 1) * 2 + 1], depth + .01f, .01f, false, edgeTopTexCoords, triangleList); } #endregion } else if (e.properties.type == VL.EdgeType.Fire && e.properties.primaryValue == 0) { #region lava off if (i == width - 1) { AddBlockFrontToTriangleList(mirrorSubList, Color.White, depth + .01f, edgeSideEndTexCoords, triangleList, true); AddTopStrip(fullPointList[(i + 1) * 2 + 1], fullPointList[i * 2 + 1], depth + .01f, .01f, true, edgeTopEndTexCoords, triangleList); } else if (i == 0) { AddBlockFrontToTriangleList(subList, Color.White, depth + .01f, edgeSideEndTexCoords, triangleList, true); AddTopStrip(fullPointList[i * 2 + 1], fullPointList[(i + 1) * 2 + 1], depth + .01f, .01f, false, edgeTopEndTexCoords, triangleList); } else { AddBlockFrontToTriangleList(subList, Color.White, depth + .01f, edgeSideTexCoords, triangleList, true); AddTopStrip(fullPointList[i * 2 + 1], fullPointList[(i + 1) * 2 + 1], depth + .01f, .01f, false, edgeTopTexCoords, triangleList); } #endregion } else if (e.properties.type == VL.EdgeType.Fire && e.properties.primaryValue != 0) { #region lava on if (i == width - 1) { AddBlockFrontToTriangleList(mirrorSubList, Color.White, depth + .01f, edgeSideEndTexCoords, triangleList, true); AddTopStrip(fullPointList[(i + 1) * 2 + 1], fullPointList[i * 2 + 1], depth + .01f, .01f, true, edgeTopEndTexCoords, triangleList); } else if (i == 0) { AddBlockFrontToTriangleList(subList, Color.White, depth + .01f, edgeSideEndTexCoords, triangleList, true); AddTopStrip(fullPointList[i * 2 + 1], fullPointList[(i + 1) * 2 + 1], depth + .01f, .01f, false, edgeTopEndTexCoords, triangleList); } else { AddBlockFrontToTriangleList(subList, Color.White, depth + .01f, edgeSideTexCoords, triangleList, true); AddTopStrip(fullPointList[i * 2 + 1], fullPointList[(i + 1) * 2 + 1], depth + .01f, .01f, false, edgeTopTexCoords, triangleList); } #endregion } else { #region magnet if (i == width - 1) AddBlockFrontToTriangleList(mirrorSubList, Color.White, depth + .01f, edgeSideEndTexCoords, triangleList, true); else if (i == 0) AddBlockFrontToTriangleList(subList, Color.White, depth + .01f, edgeSideEndTexCoords, triangleList, true); else AddBlockFrontToTriangleList(subList, Color.White, depth + .01f, edgeSideTexCoords, triangleList, true); AddTopStrip(fullPointList[i * 2 + 1], fullPointList[(i + 1) * 2 + 1], depth + .01f, .01f, false, edgeTopTexCoords, triangleList); #endregion } } }
public void Upgate(int gameTime, Monster srcMonster) { position = new Vertex(srcMonster.position); position.velocity = positionOffset.X * srcMonster.rightUnit - positionOffset.Y * srcMonster.upUnit; position.Update(Engine.player.currentRoom, 1); position.velocity = srcMonster.position.velocity; if ((Engine.player.center.position - position.position).Length() < weaponRange) fireCooldown -= gameTime; if (fireCooldown < 0) fireCooldown = 0; float cosTheta = 0f; float sinTheta = 0f; if (angleRotateSpeed != 0) { Vector3 aimTarget = Engine.player.center.position - position.position; aimTarget.Normalize(); cosTheta = Vector3.Dot(srcMonster.upUnit, aimTarget); sinTheta = Vector3.Dot(srcMonster.rightUnit, aimTarget); float targetAngle = 0; if (sinTheta > 0) targetAngle = (float)Math.Acos(cosTheta); else targetAngle = (float)(2 * Math.PI) - (float)Math.Acos(cosTheta); float posGap = targetAngle - currentAngle; if (posGap < 0) posGap += (float)Math.PI * 2; if (posGap < .1f) { } else if (posGap < Math.PI) currentAngle += angleRotateSpeed; else if (posGap > Math.PI) currentAngle -= angleRotateSpeed; if (currentAngle > 2 * Math.PI) currentAngle -= (float)Math.PI * 2; if (currentAngle < 0) currentAngle += (float)Math.PI * 2; if (!(srcMonster.moveType == VL.MovementType.Hover || srcMonster.moveType == VL.MovementType.ArmorBoss || srcMonster.moveType == VL.MovementType.RockBoss || srcMonster.moveType == VL.MovementType.SnakeBoss || srcMonster.moveType == VL.MovementType.BattleBoss)) { if (currentAngle > Math.PI / 2 && currentAngle < Math.PI) currentAngle = (float)(Math.PI / 2 - .05f); if (currentAngle > Math.PI && currentAngle < 3 * Math.PI / 2) currentAngle = (float)(3 * Math.PI / 2 + .05f); } } else if (trackType == VL.TrackType.Up) { currentAngle = 0f; } else if (trackType == VL.TrackType.UpLeft) { currentAngle = (float)(7 * Math.PI / 4); } else if (trackType == VL.TrackType.UpRight) { currentAngle = (float)(Math.PI / 4); } else if (trackType == VL.TrackType.Left) { currentAngle = (float)(3 * Math.PI / 2); } else if (trackType == VL.TrackType.Right) { currentAngle = (float)(Math.PI / 2); } cosTheta = (float)Math.Cos(currentAngle); sinTheta = (float)Math.Sin(currentAngle); gunLine = srcMonster.right * sinTheta + srcMonster.up * cosTheta; gunNormal = Vector3.Cross(gunLine, position.normal); gunLine.Normalize(); gunNormal.Normalize(); if (srcMonster.moveType == VL.MovementType.RockBoss && (srcMonster.rockBoss.state == RockBossState.Snow_Flee1)) return; if (fireCooldown == 0) { Vector3 projectileVelocity = gunLine; projectileVelocity.Normalize(); fireCooldown = fireTime; if (srcMonster != null) { fireCooldown += (ArmorBoss.r.Next(fireCooldown / 5) - fireCooldown / 10); } if (gunType == VL.GunType.Blaster || gunType == VL.GunType.Repeater) { SoundFX.FireBlaster(position.position); Engine.player.currentRoom.projectiles.Add(new Projectile(srcMonster, ProjectileType.Plasma, position.position + radius * gunLine, Vector3.Zero, position.normal, projectileVelocity)); if (gunType == VL.GunType.Repeater) { repeaterCount++; repeaterCount %= 4; } } if (gunType == VL.GunType.Beam) { SoundFX.FireLaser(position.position); Engine.player.currentRoom.projectiles.Add(new Projectile(srcMonster, ProjectileType.Laser, position.position + radius * gunLine, Vector3.Zero, position.normal, projectileVelocity)); } if (gunType == VL.GunType.Missile) { SoundFX.FireMissile(position.position); Engine.player.currentRoom.projectiles.Add(new Projectile(srcMonster, ProjectileType.Missile, position.position + radius * gunLine, position.velocity, position.normal, projectileVelocity)); } if (gunType == VL.GunType.Spread) { SoundFX.FireBlaster(position.position); SoundFX.FireBlaster(position.position); SoundFX.FireBlaster(position.position); Engine.player.currentRoom.projectiles.Add(new Projectile(srcMonster, ProjectileType.Plasma, position.position + radius * gunLine, Vector3.Zero, position.normal, projectileVelocity + .5f * gunNormal)); Engine.player.currentRoom.projectiles.Add(new Projectile(srcMonster, ProjectileType.Plasma, position.position + radius * gunLine, Vector3.Zero, position.normal, projectileVelocity - .5f * gunNormal)); Engine.player.currentRoom.projectiles.Add(new Projectile(srcMonster, ProjectileType.Plasma, position.position + radius * gunLine, Vector3.Zero, position.normal, projectileVelocity)); } } }