public override void AffectOther(Node other) { if (!active) { return; } float dist = Vector2R.Distance(parent.body.pos, other.body.pos); //if (dist > radius) return; if (springMode == mode.PullOnly && dist < restdist) { return; } if (springMode == mode.PushOnly && dist > restdist) { return; } //if (dist > restdist * 2) return; if (deadzone.enabled && dist < deadzone.value) { dist = deadzone.value; } float stretch = dist - restdist; float strength = -stretch * multiplier / 10000f; Vector2R force = other.body.pos - parent.body.pos; VMath.NormalizeSafe(ref force); force *= strength; other.body.ApplyForce(force); }
public override void AIControl(AIMode aiMode) { //if (aiMode == AIMode.) tempTurretTimer += OrbIt.Game.Time.ElapsedGameTime.Milliseconds; if (tempTurretTimer > TurretTimerSeconds * 1000) { float nearest = float.MaxValue; Node nearNode = null; foreach (Node n in room.Groups.Player.entities) { float dist = Vector2R.Distance(parent.body.pos, n.body.pos); if (dist < nearest) { nearNode = n; nearest = dist; } } if (nearNode != null) { Vector2R dir = nearNode.body.pos - parent.body.pos; VMath.NormalizeSafe(ref dir); dir.Y *= -1; FireNode(dir); tempTurretTimer = 0; } } }
public override void AffectOther(Node other) { if (onlyObstructors && !other.HasActiveComponent <Obstructor>()) { return; } if (onlyAvailableObs && other.HasActiveComponent <Obstructor>() && !other.Comp <Obstructor>().Available) { return; } float dist = Vector2R.Distance(other.body.pos, parent.body.pos); if (dist < radius) { if (nodeDistances.Count < maxWalls) { nodeDistances.Add(new KeyValuePair <float, Node>(dist, other)); nodeDistances.Sort((a, b) => a.Key.CompareTo(b.Key)); } else if (nodeDistances.Count > 0 && dist < nodeDistances.Last().Key) { nodeDistances.Add(new KeyValuePair <float, Node>(dist, other)); nodeDistances.Sort((a, b) => a.Key.CompareTo(b.Key)); nodeDistances.RemoveAt(nodeDistances.Count - 1); } } }
public override void AffectOther(Node other) { if (!active) { return; } if (exclusions.Contains(other)) { return; } float distVects = Vector2R.Distance(other.body.pos, parent.body.pos); if (distVects < radius) { if (distVects < lowerbound) { distVects = lowerbound; } double aa = Math.Atan2((parent.body.pos.Y - other.body.pos.Y), (parent.body.pos.X - other.body.pos.X)); //float counterforce = 100 / distVects; //float gravForce = multiplier / (distVects * distVects * counterforce); //Console.WriteLine(angle); //float gravForce = (multiplier * parent.transform.mass * other.transform.mass) / (distVects * distVects * counterforce); float gravForce; if (!ConstantPush) { gravForce = multiplier / 10f; // * 10; } else { gravForce = (multiplier / 10f * parent.body.mass * other.body.mass) / (distVects); } if (angle != 0) { aa = (aa + Math.PI + (Math.PI * (float)(angle / 180.0f)) % (Math.PI * 2)) - Math.PI; } //float gravForce = gnode1.GravMultiplier; float velX = (float)Math.Cos(aa) * gravForce; float velY = (float)Math.Sin(aa) * gravForce; Vector2R delta = new Vector2R(velX, velY); if (!ConstantPush) { delta *= other.body.invmass; } other.body.pos -= delta; } }
// half width and half height public void SetBox(float hw, float hh, bool fill = false) { vertexCount = 4; VMath.Set(ref vertices[0], -hw, -hh); //vertices[0].Set(-hw, -hh); VMath.Set(ref vertices[1], hw, -hh); //vertices[1].Set(hw, -hh); VMath.Set(ref vertices[2], hw, hh); //vertices[2].Set(hw, hh); VMath.Set(ref vertices[3], -hw, hh); //vertices[3].Set(-hw, hh); VMath.Set(ref normals[0], 0, -1); //normals[0].Set(0, -1); VMath.Set(ref normals[1], 1, 0); //normals[1].Set(1, 0); VMath.Set(ref normals[2], 0, 1); //normals[2].Set(0, 1); VMath.Set(ref normals[3], -1, 0); //normals[3].Set(-1, 0); polyReach = Vector2R.Distance(Vector2R.Zero, new Vector2R(hw, hh)) * 2; if (fill) { testTexture = CreateClippedTexture(body.texture, vertices, vertexCount, out this.offset); this.trueOffset = this.offset * -1f; } }
public void PlayerControlOld(Controller controller) { if (controller is FullController) { FullController fc = (FullController)controller; //fistNode.movement.active = false; //fistNode.body.velocity = fistNode.body.effvelocity * nodeKnockback; bool atReach = Vector2R.Distance(fistNode.body.pos, parent.body.pos) > fistReach; if (fc.newGamePadState.ThumbSticks.Right.LengthSquared() > 0.2 * 0.2) { if (!atReach) { movingStick = true; target = fc.newGamePadState.ThumbSticks.Right.toV2R() * fistReach; target.Y *= -1; target = parent.body.pos + target; Vector2R force = target - fistNode.body.pos; fistNode.body.ApplyForce(force / 10); //fistNode.body.velocity += force; //Console.WriteLine(force.X + " : " + force.Y); } } else { target = parent.body.pos; //movingStick = false; //Vector2 restPos = new Vector2(parent.body.radius, 0).Rotate(parent.body.orient) + parent.body.pos; //fistNode.body.pos = Vector2.Lerp(fistNode.body.pos, restPos, 0.1f); //fistNode.body.orient = Utils.AngleLerp(fistNode.body.orient, parent.body.orient, 0.1f); } if (atReach) { Vector2R direction = fistNode.body.pos - parent.body.pos; VMath.NormalizeSafe(ref direction); direction *= fistReach; fistNode.body.pos = parent.body.pos + direction; } } }
public override void AffectSelf() { if (useMsInterval && !schedulerModerated) { return; } bool black, white; if (colormode == ColorMode.angle) { float angle = (float)((Math.Atan2(parent.body.effvelocity.Y, parent.body.effvelocity.X) + Math.PI) * (180 / Math.PI)); parent.body.color = getColorFromHSV(angle, saturation, value); } else if (colormode == ColorMode.position) { float r = parent.body.pos.X / (float)room.WorldWidth; float g = parent.body.pos.Y / (float)room.WorldHeight; float b = (parent.body.pos.X / parent.body.pos.Y) / ((float)room.WorldWidth / (float)room.WorldHeight); parent.body.color = new Color(r, g, b); } else if (colormode == ColorMode.velocity) { float len = Vector2R.Distance(parent.body.velocity, Vector2R.Zero) / 25; parent.body.color = new Color((parent.body.permaColor.R / 255f) * len, (parent.body.permaColor.G / 255f) * len, (parent.body.permaColor.B / 255f) * len); //parent.body.color = getColorFromHSV((float)Math.Min(1.0, len / 20) * 360f, (float)Math.Min(1.0, len / 20), (float)Math.Min(1.0, len / 20)); } else if (colormode == ColorMode.hueShifter) { float range = 20; float tempinc = inc; if (hue % 120 > 60 - range && hue % 120 < 60 + range) { tempinc /= 2f; } parent.body.color = getColorFromHSV(hue, saturation, value); hue = (hue + tempinc) % 360; } else if ((black = colormode == ColorMode.phaseBlack) || (white = colormode == ColorMode.phaseWhite)) { Vector3 perma = parent.body.permaColor.ToVector3(); Vector3 dest = Vector3.Zero; if (black) { dest = Vector3.Zero; } else { dest = Vector3.One; } dest = Vector3.Lerp(perma, dest, phasePercent / 100f); currentLerpPos += (phaseSpeed / 1000f) * lerpSign; if (currentLerpPos > 1) { currentLerpPos = 1f; lerpSign *= -1; } else if (currentLerpPos < 0) { currentLerpPos = 0; lerpSign *= -1; } parent.body.color = Vector3.Lerp(perma, dest, currentLerpPos).ToColor(parent.body.color.A); } else if (colormode == ColorMode.phaseAround) { Vector3 perma = parent.body.permaColor.ToVector3(); Vector3 down = Vector3.Zero; Vector3 up = Vector3.One; down = Vector3.Lerp(perma, down, phasePercent / 100f); up = Vector3.Lerp(perma, up, phasePercent / 100f); currentLerpPos += (phaseSpeed / 1000f) * lerpSign; if (currentLerpPos > 1) { currentLerpPos = 1f; lerpSign *= -1; } else if (currentLerpPos < 0) { currentLerpPos = 0; lerpSign *= -1; } parent.body.color = Vector3.Lerp(down, up, currentLerpPos).ToColor(parent.body.color.A); } else if (colormode == ColorMode.phaseHue) { huedest = permaHue - (phasePercent / 100f * 90 * huesign); huedest = GMath.Sawtooth(huedest, 360); float range = 20; float tempinc = inc / 10f; if (hue % 120 > 60 - range && hue % 120 < 60 + range) { tempinc /= 2f; } float dist = GMath.CircularDistance(hue, huedest, 360); tempinc *= Math.Sign(dist); hue = GMath.Sawtooth(hue + tempinc, 360); if (Math.Abs(hue - huedest) < Math.Abs(tempinc)) { huesign *= -1; } //Console.WriteLine(dist + " " + huesign); parent.body.color = getColorFromHSV(hue, saturation, value); } }
public override void AffectOther(Node other) { if (mode == Mode.hue) { if (!other.HasComp <ColorGravity>()) { return; } float dist = 1f; if (distancemod == DistanceMod.color) { dist = hue - other.Comp <ColorGravity>().hue; if (dist == 0) { return; } float force = multiplier * other.body.mass * parent.body.mass / (dist * dist); if (dist < 0) { force *= -1; } float diff = hue - other.Comp <ColorGravity>().hue; if (Math.Abs(diff) > 180) { force *= -1; } if (force > maxhuevel) { force = maxhuevel; } else if (force < -maxhuevel) { force = -maxhuevel; } other.Comp <ColorGravity>().huevelocity += force; huevelocity += force; //float otherhue = other.Comp<ColorGravity>().hue; //dist = Utils.CircularDistance(hue, otherhue); //if (dist < 1) return; //float force = multiplier / (dist * dist) / divisor; //huevelocity += force; //Console.WriteLine("dist: {0} force: {1}", dist, force); } else if (distancemod == DistanceMod.spatial) { dist = Vector2R.Distance(parent.body.pos, other.body.pos) / divisor; if (dist == 0) { return; } float force = multiplier * other.body.mass * parent.body.mass / (dist * dist); float diff = hue - other.Comp <ColorGravity>().hue; //int wrap = Math.Abs(diff) > 180 ? -1 : 1; if (Math.Abs(diff) > 180) { force *= -1; } if (diff < 0) { force *= -1; } if (force > maxhuevel) { force = maxhuevel; } else if (force < -maxhuevel) { force = -maxhuevel; } other.Comp <ColorGravity>().huevelocity += force; huevelocity -= force; } } else if (mode == Mode.rgb) { Vector3 parentCol = parent.body.color.ToVector3(); Vector3 otherCol = other.body.color.ToVector3(); float dist = 1f; if (distancemod == DistanceMod.color) { dist = Vector3.Distance(parentCol, otherCol) / 100f; } else if (distancemod == DistanceMod.spatial) { dist = Vector2R.Distance(parent.body.pos, other.body.pos) / divisor / divisor; } Vector3 direction = otherCol - parentCol; if (dist < 1) { dist = 1; } if (direction != Vector3.Zero) { direction.Normalize(); } float mag = multiplier * parent.body.mass * other.body.mass / (dist * dist); Vector3 impulse = mag * direction; impulse /= 10000f; if (other.HasActiveComponent <ColorGravity>()) { other.Comp <ColorGravity>().colvelocity += impulse; } colvelocity -= impulse; } }
public override void OnSpawn() { collisionAction = (s, t) => { if (t.IsPlayer) { if (damageMode == DamageMode.Players || damageMode == DamageMode.Both) { t.meta.CalculateDamage(s, damageMultiplier); } if (pushBack.enabled) { Vector2R f = (t.body.pos - s.body.pos); VMath.NormalizeSafe(ref f); f *= pushBack.value; t.body.velocity += f; } if (stunSeconds.enabled) { if (t.movement.active) { t.movement.active = false; Action <Node> ad = (n) => { t.movement.active = true; }; room.Scheduler.AddAppointment(new Appointment(ad, (int)(stunSeconds.value * 1000))); } } } else { if (damageMode == DamageMode.Nodes || damageMode == DamageMode.Both) { t.meta.CalculateDamage(s, damageMultiplier); } if (pushBack.enabled) { Vector2R f = (t.body.pos - s.body.pos); VMath.NormalizeSafe(ref f); f *= pushBack.value; t.body.velocity += f; } if (stunSeconds.enabled) { if (t.movement.active) { t.movement.active = false; Action <Node> ad = (n) => t.movement.active = true; t.scheduler.AddAppointment(new Appointment(ad, (int)(stunSeconds.value * 1000))); } } } }; Polygon poly = new Polygon(); poly.body = parent.body; float dist = parent.body.radius * 1.3f; Vector2R[] verts = new Vector2R[3]; for (int i = 0; i < 3; i++) { verts[i] = VMath.AngleToVector(GMath.TwoPI / 3f * i) * dist; } parent.body.shape = poly; poly.Set(verts, 3); parent.body.DrawPolygonCenter = true; parent.body.orient = parent.body.orient; //todo:set this every init of polys parent.body.OnCollisionEnter += collisionAction; parent.body.ExclusionCheck += (s, t) => { return(Vector2R.Distance(s.pos, t.pos) > dist); }; }
public override void PlayerControl(Input input) { //fistNode.movement.active = false; //fistNode.body.velocity = fistNode.body.effvelocity * nodeKnockback; Vector2R newstickpos = input.GetRightStick().toV2R(); Vector2R relVel = newstickpos - oldstickpos; if (state == fistmode.ready) { fistNode.body.pos = parent.body.pos; fistNode.body.orient = parent.body.orient; //if stick is moving away from center of stick if (newstickpos.LengthSquared() > oldstickpos.LengthSquared()) { //if stick is moving fast enough float len = relVel.Length(); if (relVel.Length() > 0.2f) //deadzone { state = fistmode.punching; float power = (float)Math.Log((double)len + 2.0, 2.0) / 2f; //Console.WriteLine(power); VMath.NormalizeSafe(ref relVel); relVel *= power; //Console.WriteLine(relVel.X + " : " + relVel.Y); //fistNode.body.ApplyForce(relVel); fistNode.body.velocity = relVel * 10f; fistNode.body.orient = VMath.VectorToAngle(relVel); } } } else if (state == fistmode.punching) { //check if fully punched. if (Vector2R.Distance(fistNode.body.pos, parent.body.pos) > fistReach) { state = fistmode.retracting; } } else if (state == fistmode.retracting) { //fistNode.body.pos = Vector2.Lerp(fistNode.body.pos, parent.body.pos, 0.1f); //Vector2 vel = (parent.body.pos - fistNode.body.pos); //VMath.NormalizeSafe(ref vel); //vel *= 1; //fistNode.body.velocity = vel; Vector2R vel = (parent.body.pos - fistNode.body.pos); //if (vel.Length() < 5) //{ VMath.NormalizeSafe(ref vel); vel *= 20; //} fistNode.body.velocity = vel; if (Vector2R.DistanceSquared(fistNode.body.pos, parent.body.pos) < 50 * 50) { state = fistmode.ready; } } //if (state != fistmode.ready) // Console.WriteLine(state); oldstickpos = newstickpos; }
public void Set(Vector2R[] verts, int count) { //no hulls with less than 3 verticies (ensure actual polygon) //Debug.Assert(count > 2 && count < MaxPolyVertexCount); count = Math.Min(count, MaxPolyVertexCount); //find the right most point in the hull int rightMost = 0; double highestXCoord = verts[0].X; for (int i = 1; i < count; i++) { double x = verts[0].X; if (x > highestXCoord) { highestXCoord = x; rightMost = i; } //if matching x then take farthest negative y else if (x == highestXCoord && verts[i].Y < verts[rightMost].Y) { rightMost = i; } } int[] hull = new int[MaxPolyVertexCount]; int outCount = 0; int indexHull = rightMost; for (;;) { hull[outCount] = indexHull; // search for next index that wraps around the hull // by computing cross products to find the most counter-clockwise // vertex in the set, given the previous hull index int nextHullIndex = 0; for (int i = 1; i < count; i++) { //skip if same coordinate as we need three unique //points in the set to perform a cross product if (nextHullIndex == indexHull) { nextHullIndex = i; continue; } // cross every set of three unquie verticies // record each counter clockwise third vertex and add // to the output hull Vector2R e1 = verts[nextHullIndex] - verts[hull[outCount]]; Vector2R e2 = verts[i] - verts[hull[outCount]]; double c = VMath.Cross(e1, e2); if (c < 0.0f) { nextHullIndex = i; } // Cross product is zero then e vectors are on same line // therefor want to record vertex farthest along that line if (c == 0.0f && e2.LengthSquared() > e1.LengthSquared()) { nextHullIndex = i; } } outCount++; indexHull = nextHullIndex; //conclude algorithm upon wraparound if (nextHullIndex == rightMost) { vertexCount = outCount; break; } } float maxDist = 0; // Copy vertices into shape's vertices for (int i = 0; i < vertexCount; ++i) { vertices[i] = verts[hull[i]]; float dist = Vector2R.Distance(Vector2R.Zero, vertices[i]); if (dist > maxDist) { maxDist = dist; } } polyReach = maxDist * 2; ComputeNormals(); }
public override void PlayerControl(Input input) { Vector2R newstickpos = input.GetRightStick(shovelReach, true).toV2R(); //input.GetRightStick(); Vector2R pos = newstickpos * shovelReach; Vector2R worldStickPos = parent.body.pos + pos; Vector2R diff = worldStickPos - shovelNode.body.pos; //float angle = Utils.VectorToAngle(shovelNode.body.pos - parent.body.pos) + VMath.PIbyTwo % VMath.twoPI; Vector2R shovelDir = shovelNode.body.pos - parent.body.pos; shovelDir = new Vector2R(shovelDir.Y, -shovelDir.X); shovelNode.body.SetOrientV2(shovelDir); if (modeShovelPosition == ModeShovelPosition.AbsoluteStickPos) { shovelNode.body.pos = worldStickPos; } else if (modeShovelPosition == ModeShovelPosition.PhysicsBased) { float len = diff.Length(); if (len < 1) { shovelNode.body.velocity = Vector2R.Zero; } else { float velLen = shovelNode.body.velocity.Length(); Vector2R diffcopy = diff; VMath.NormalizeSafe(ref diffcopy); Vector2R normalizedVel = shovelNode.body.velocity; VMath.NormalizeSafe(ref normalizedVel); float result = 0; Vector2R.Dot(ref diffcopy, ref normalizedVel, out result); diffcopy *= result; Vector2R force = (diff / physicsDivisor); if (shovelling && compoundedMass >= 1) { force /= compoundedMass * 1; } shovelNode.body.velocity = diffcopy + force; //shovelNode.body.ApplyForce(force); } } if (shovelling) { //if (fc.newGamePadState.Triggers.Right < deadzone && fc.oldGamePadState.Triggers.Right > deadzone) if (input.BtnReleased(InputButtons.RightTrigger_Mouse1)) { shovelling = false; foreach (Node n in shovelLink.targets.ToList()) { if (physicsThrow) { n.body.velocity = n.body.effvelocity; } else { Vector2R stickdirection = newstickpos; VMath.NormalizeSafe(ref stickdirection); n.body.velocity = stickdirection * throwSpeed; } n.collision.active = true; shovelLink.targets.Remove(n); n.body.ClearExclusionChecks(); n.body.color = n.body.permaColor; } shovelLink.formation.UpdateFormation(); shovelLink.active = false; shovelNode.room.AllActiveLinks.Remove(shovelLink); compoundedMass = 0f; } } else { if (input.BtnClicked(InputButtons.RightTrigger_Mouse1)) { shovelling = true; ObservableHashSet <Node> capturedNodes = new ObservableHashSet <Node>(); int count = 0; Action <Collider, Collider> del = delegate(Collider c1, Collider c2) { if (count >= maxShovelCapacity) { return; } if (c2.parent.dataStore.ContainsKey("shovelnodeparent")) { return; } if (c2.parent.HasComp <Diode>()) { return; } if (modePlayers != ModePlayers.GrabBoth && c2.parent.IsPlayer) { if (modePlayers == ModePlayers.GrabNone) { return; } if (modePlayers == ModePlayers.GrabSelf && c2.parent != parent) { return; } if (modePlayers == ModePlayers.GrabOtherPlayers && c2.parent == parent) { return; } } float dist = Vector2R.Distance(c1.pos, c2.pos); if (dist <= scoopReach) { count++; capturedNodes.Add(c2.parent); c2.parent.body.color = parent.body.color; } }; shovelNode.room.GridsystemAffect.retrieveOffsetArraysAffect(shovelNode.body, del, scoopReach * 2); shovelLink.targets = capturedNodes; shovelLink.formation.UpdateFormation(); shovelLink.active = true; shovelNode.room.AllActiveLinks.Add(shovelLink); compoundedMass = 0f; foreach (Node n in capturedNodes) { n.collision.active = false; compoundedMass += n.body.mass; } } } }