public SplashSmokes(City city, RenderSystem rs) { this.parent = city; emitSmokes = new Smoke[SmokeCount]; FileLocation fl = FileSystem.Instance.Locate("smoke_light.mesh", GameFileLocs.Model); smokeModel = new Model(ModelManager.Instance.CreateInstance(rs, fl)); }
public BallPathFinderManager(City[] terr) { this.cityList = terr; units = new AStarNodeBall[terr.Length]; for (int i = 0; i < terr.Length; i++) { units[i] = new AStarNodeBall(terr[i]); nodeTable.Add(terr[i], units[i]); } }
public Smokes(City city, RenderSystem rs) { this.parent = city; int smokeCount = MinSmokeCount + (int)((MaxSmokeCount - MinSmokeCount) * Randomizer.GetRandomSingle()); emitSmokes = new Smoke[smokeCount]; FileLocation fl = FileSystem.Instance.Locate("smoke.mesh", GameFileLocs.Model); smokeModel = new Model(ModelManager.Instance.CreateInstance(rs, fl)); UpdateDirection(); }
/// <summary> /// 自动续传球 /// Automatically passing balls when the city has received balls from other city to pass on /// </summary> /// <param name="next"></param> /// <param name="follow"></param> void ThrowContinued(City next, List<City> follow, List<RBall> balls) { //if (!CanHandleCommand()) //{ // // 重设延时,到时候重新尝试 // reThrowDelay = 0.5f; // return; //} // 重新寻路,考虑断路可能 // Do the path finding again, considering if the path could no longer exist due to // loss of city battleField.BallPathFinder.Reset(); BallPathFinderResult result = battleField.BallPathFinder.FindPath(this, follow[follow.Count - 1]); if (result != null) { throwPathCont = new List<City>(result.NodeCount); for (int i = 0; i < result.NodeCount; i++) { throwPathCont.Add(result[i]); } ballsToThrowCont = balls; Quaternion targetRot = GetOrientation(follow[0].Position); RotateTo(targetRot, 0.5f); SetRotationPurpose(CityRotationPurpose.ThrowContinued); } }
internal void City_Visible(City obj) { visibleList.Add(obj); }
public BallPathFinderResult FindPath(City start, City target) { if (start == target) { return new BallPathFinderResult(new FastList<City>()); } //int ofsX = Math.Min(sx, tx); //int ofsY = Math.Min(sy, ty); FastList<AStarNodeBall> enQueueBuffer = new FastList<AStarNodeBall>(10); AStarNodeBall startNode = nodeTable[start]; startNode.parent = null; startNode.h = 0; startNode.g = 0; startNode.f = 0; startNode.depth = 0; queue.Enqueue(startNode); inQueueTable.Add(startNode.GetHashCode(), startNode); bool found = false; AStarNodeBall finalNode = null; // this is just a ordinary BFS with a sorting while (queue.Count > 0 && !(found)) { AStarNodeBall curPos = queue.Dequeue(); int curHash = curPos.GetHashCode(); inQueueTable.Remove(curHash); passedTable.Add(curHash, curPos); City cc = curPos.City; // BFS展开新节点 // expand sub nodes in the searching for (int i = 0; i < cc.LinkableCityCount; i++) { City nc = cc.GetLinkableCity(i); AStarNodeBall np = nodeTable[nc]; if (np.City == target) { // found the way to the destination found = true; //找到路径了 finalNode = np; np.depth = curPos.depth + 1; np.parent = curPos; //当前格坐标为终点的父方格坐标 break; } else if (np.City.Owner == start.Owner) { int npHash = np.GetHashCode(); float cost = Vector3.Distance(cc.Position, nc.Position) / 1000.0f; bool isNPInQueue = false; AStarNodeBall temp; if (inQueueTable.TryGetValue(npHash, out temp) && temp == np) { if (np.g > curPos.g + cost) { np.g = curPos.g + cost; np.f = np.g + np.h; } isNPInQueue = true; } // check if the expanded node is allowable // Is the grid node is node in passedTable and inQueueTable? if (!isNPInQueue && (!passedTable.TryGetValue(npHash, out temp) && temp != np)) //如果此方格不在即将展开的节点表 和 已遍历过的节点表 { np.parent = curPos; //当前格为此格的父方格 np.g = curPos.g + cost; np.h = Vector3.Distance(target.Position, nc.Position); np.f = np.g + np.h; np.depth = curPos.depth + 1; enQueueBuffer.Add(np); inQueueTable.Add(npHash, np); } } } // A* //enQueueBuffer.Sort(Comparision); if (enQueueBuffer.Count > 0) { QuickSort(enQueueBuffer, 0, enQueueBuffer.Count - 1); for (int i = 0; i < enQueueBuffer.Count; i++) { queue.Enqueue(enQueueBuffer[i]); } enQueueBuffer.Clear(); } } if (found) { AStarNodeBall curNode = finalNode; for (int i = 0; i < curNode.depth; i++) { result.Add((City)null); } do { //result.Add(curNode); result[curNode.depth - 1] = curNode.City; curNode = curNode.parent; } while (curNode.parent != null); return new BallPathFinderResult(result); } return null; }
public void CreateResourceBall(Player owner, City city, RBallType type) { RBall ball = new RBall(owner, city, type); resBalls.Add(ball); if (ResourceBallChanged != null) { ResourceBallChanged(this, new ResourceBallEventArg(true, ball)); } }
/// <summary> /// 初始化城市 /// </summary> private void LoadCities() { List<City> cityList = new List<City>(MaxCities); FileLocation fl = FileSystem.Instance.Locate("cities.xml", GameFileLocs.Config); GameConfiguration resCon = new GameConfiguration(fl); GameConfiguration.ValueCollection resVals = resCon.Values; Dictionary<string, City> resolveTable = new Dictionary<string, City>(MaxCities); foreach (GameConfigurationSection sect in resVals) { City city; string typestr = sect.GetString("Type", string.Empty).ToLowerInvariant(); CityType type = City.ParseType(typestr); switch (type) { case CityType.Neutral: city = new City(this, null, type); break; case CityType.Oil: case CityType.Green: city = new GatherCity(this, null, type); break; case CityType.Disease: case CityType.Education: case CityType.Health: case CityType.Volience: city = new ProductionCity(this, null, type); break; default: city = new City(this, null, type); break; } city.Parse(sect); resolveTable.Add(sect.Name, city); cityList.Add(city); } for (int i = 0; i < cityList.Count; i++) { cityList[i].ResolveCities(resolveTable); } cities = cityList.ToArray(); }
private void SetNodes(City[] nodes) { this.nodes = nodes; if (nodes != null) { for (int i = 0; i < nodes.Length - 1; i++) { City a = nodes[i]; City b = nodes[i + 1]; Matrix ori = GetCityLinkTransform(a, b); nodeLinks[i].CurrentAnimation.Clear(); nodeLinks[i].CurrentAnimation.Add(new NoAnimaionPlayer(ori)); } } }
public RBall(Player owner, City city, RBallType type) : base(owner) { this.Owner = owner; this.Type = type; switch (type) { case RBallType.Oil: { props.BaseMaxHealth = RulesTable.OilBallBaseHealth; props.MaxHealth = props.BaseMaxHealth * (city.Level / 10.0f + 1); props.Contribution = RulesTable.OilBallContribution; props.Heal = RulesTable.OilBallBaseHeal; props.Damage = RulesTable.OilBallBaseDamage; break; } case RBallType.Green: { props.BaseMaxHealth = RulesTable.GreenBallBaseHealth; props.MaxHealth = props.BaseMaxHealth * (city.Level / 10.0f + 1); props.Contribution = RulesTable.GreenBallContribution; props.Heal = RulesTable.GreenBallBaseHeal; props.Damage = RulesTable.GreenBallBaseDamage; break; } case RBallType.Disease: { props.BaseMaxHealth = RulesTable.DiseaseBallBaseHealth; props.MaxHealth = props.BaseMaxHealth * (city.Level / 10.0f + 1); props.Contribution = RulesTable.DiseaseBallContribution; props.Heal = RulesTable.DiseaseBallBaseHeal; props.Damage = RulesTable.DiseaseBallBaseDamage; props.HealthIncr = 0.0015f; break; } case RBallType.Health: { props.BaseMaxHealth = RulesTable.DiseaseBallBaseHealth; props.MaxHealth = props.BaseMaxHealth * (city.Level / 10.0f + 1); props.Contribution = RulesTable.HealthBallContribution; props.Heal = RulesTable.HealthBallBaseHeal; props.Damage = RulesTable.HealthBallBaseDamage; props.HealthIncr = 0.0015f; break; } case RBallType.Education: { props.BaseMaxHealth = RulesTable.EducationBallBaseHealth; props.MaxHealth = props.BaseMaxHealth * (city.Level / 10.0f + 1); props.Contribution = RulesTable.EducationBallContribution; props.Heal = RulesTable.EducationBallBaseHeal; props.Damage = RulesTable.EducationBallBaseDamage; break; } case RBallType.Volience: { props.BaseMaxHealth = RulesTable.VolienceBallBaseHealth; props.MaxHealth = props.BaseMaxHealth + city.Development * RulesTable.CityDevRBallHealthRate; props.Contribution = RulesTable.VolienceBallContribution; props.Heal = RulesTable.VolienceBallBaseHeal; props.Damage = RulesTable.VolienceBallBaseDamage; break; } } Health = props.MaxHealth; SetDockCity(city); currentRadius = NextRadius(); currentHeight = NextHeight(); refrenceLinSpeed = Randomizer.GetRandomSingle() * (MaxLinSpeed - MinLinSpeed) + MinLinSpeed; BoundingSphere.Radius = 15; }
public void SetDockCity(City c) { if (c != dockCity) { if (c != null) { c.NotifyResourceBallMoveIn(this); } if (dockCity != null) { dockCity.NotifyResourceBallMoveOut(this); } dockCity = c; } }
void ChangeState(State newState) { if (newState == State.Flying) { for (int i = 0; i < subBalls.Count; i++) { subBalls[i].SetDockCity(null); } srcPosition = position; City dstCity = goPath[0]; this.destCity = dstCity; Quaternion newDstOri = dstCity.GetOrientation(srcPosition); normal = sourceCity.Transformation.Up + dstCity.Transformation.Up; normal.Normalize(); dstPosition = GetRGBallPosition(dstCity, newDstOri); notifyedDest = false; flyProgress = 0; throwSound.Fire(); } else if (newState == State.Finished) { ReleaseBalls(); } state = newState; }
public RGatheredBall(List<RBall> balls, City dockCity, List<City> path) { state = State.WaitingGathering; subBalls = balls; goPath = path; sourceCity = dockCity; position = GetRGBallPosition(dockCity, dockCity.CurrentFacing); float lineCount = (float)Math.Sqrt(balls.Count); float span = (MathEx.PIf * 2) / lineCount; ballOffsets = new List<Vector3>(balls.Count); for (int i = 0; i < balls.Count; i++) { float row = (float)i / lineCount; float col = (float)Math.IEEERemainder(i, lineCount); float radLng = col * span; float radLat = (2 * row - lineCount) * span; Vector3 positionInGBall = PlanetEarth.GetPosition(radLng, radLat, GBallRadius); Quaternion oriInGBall = Quaternion.RotationMatrix(PlanetEarth.GetOrientation(radLng, radLat)); ballOffsets.Add(positionInGBall); balls[i].Gather(this, positionInGBall + position, oriInGBall); } throwSound = (Normal3DSoundObject)SoundManager.Instance.MakeSoundObjcet("throw", null, 1500); catchSound = (Normal3DSoundObject)SoundManager.Instance.MakeSoundObjcet("catch", null, 1500); }
/// <summary> /// Calculate the position of the RBall in the city's hand at the given direction /// </summary> /// <param name="city"></param> /// <param name="ori"></param> /// <returns></returns> static Vector3 GetRGBallPosition(City city, Quaternion ori) { Vector4 dir = Vector3.Transform(Vector3.UnitZ, ori); Vector3 offset = new Vector3(dir.X, dir.Y, dir.Z); offset *= GatherPositionRadius; offset.Y += GatherPositionHeight; offset = Vector3.TransformNormal(offset, city.Transformation); return city.Position + offset; }
/// <summary> /// Called when the ball has arrived a different city than its previous one. /// Changes the state to Free, making the ball back to their stand by position. /// </summary> public void Free(City city) { gatheredParent = null; SetDockCity(city); Vector3 targetPos; Quaternion dockOri; CalculateRoundTransform(currentRadius, false, out targetPos, out dockOri); NewMove(targetPos); ChangeState(RBallState.Free); enemyCheckTime = EnemyCheckTime; }
/// <summary> /// Flee from a city to a given target city /// </summary> public void Float(City target) { floatingTarget = target; NewMove(target.Position); ChangeState(RBallState.Float); }
Matrix GetCityLinkTransform(City start, City end) { //City end = targets[i]; Vector3 dir = end.Position - start.Position; dir.Normalize(); Vector3 pa = start.Position + dir * (City.CityOutterRadius); Vector3 pb = end.Position - dir * (City.CityOutterRadius); Vector3 center = 0.5f * (pa + pb); Vector3 normal = start.Transformation.Up + end.Transformation.Up; normal *= 0.5f; float dist = Vector3.Distance(pa, pb); float scale = dist; Matrix ori = Matrix.Identity; ori.Right = Vector3.Normalize(pa - pb); ori.Up = normal; ori.Forward = Vector3.Normalize(Vector3.Cross(ori.Up, ori.Right)); ori.TranslationValue = center + normal * 150; return Matrix.RotationX(-MathEx.PiOver2) * Matrix.RotationY(-MathEx.PiOver2) * Matrix.Scaling(dist / LinkBaseLength, 1 + LinkHeightScale, LinkWidthScale) * ori; }
///// <summary> ///// 获取此玩家所有的城市中离目标城市最近的一个 ///// </summary> ///// <param name="city">目标城市</param> ///// <returns></returns> //public City GetNearestCity(City city) //{ // float dist = float.MaxValue; // City minCity = null; // for (int i = 0; i < cities.Count; i++) // { // if (city != cities[i]) // { // float cdist = new Vector2(cities[i].Longitude - city.Longitude, cities[i].Latitude - city.Latitude).Length(); // if (cdist < dist) // { // dist = cdist; // minCity = cities[i]; // } // } // } // return minCity; //} ///// <summary> ///// 计算一个城市是否可以被占据 ///// 只有离玩家最近的城市才能占领,太远的,中间隔有更近的城市的无法占领 ///// </summary> ///// <returns></returns> //[Obsolete] //public bool CanCapture(City city) //{ // if (cities.Count == 0) // return false; // City minCity = GetNearestCity(city); // if (minCity != null) // { // // 检查是否在两个城市之间还有城市 // City midCity = null; // float minDist = float.MaxValue; // for (int i = 0; i < simulator.CityCount; i++) // { // City cc = simulator.GetCity(i); // bool flag1 = !object.ReferenceEquals(cc, minCity); // bool flag2 = !object.ReferenceEquals(cc.Owner, minCity.Owner); // if (flag1 && flag2) // { // float cdist = new Vector2(cc.Longitude - minCity.Longitude, cc.Latitude - minCity.Latitude).Length(); // if (cdist < minDist) // { // minDist = cdist; // midCity = cc; // } // } // } // Vector2 d = new Vector2(city.Longitude - minCity.Longitude, city.Latitude - minCity.Latitude); // return (object.ReferenceEquals(midCity, null) || object.ReferenceEquals(city, midCity)) || d.Length() < CaptureDistanceThreshold; // } // return false; //} /// <summary> /// 告知玩家控制了一个新的城市 /// </summary> /// <param name="city"></param> public void NotifyNewCity(City city) { if (rootCity == null) { rootCity = city; } //if (cities.Count > 0) //{ // // 加入城市网络 // City minCty = GetNearestCity(city); // if (minCty != null) // { // city.AddNearbyCity(minCty); // minCty.AddNearbyCity(city); // } //} cities.Add(city); if (NewCity != null) { NewCity(city); } }
private void SetCity(City start, City[] targets) { this.selectedCity = start; this.targets = targets; this.nodes = null; for (int i = 0; i < targets.Length; i++) { Matrix ori = GetCityLinkTransform(start, targets[i]); linkArrow[i].CurrentAnimation.Clear(); linkArrow[i].CurrentAnimation.Add(new NoAnimaionPlayer(ori)); } { float s = 0.8f * CitySelScale * City.CityOutterRadius / RingRadius; Matrix scale = Matrix.Scaling(s, 1, s); inner_marker.CurrentAnimation.Clear(); inner_marker.CurrentAnimation.Add(new NoAnimaionPlayer(scale * start.Transformation)); } }
public void NotifyLostCity(City city) { if (object.ReferenceEquals(rootCity, city)) { rootCity = null; } cities.Remove(city); if (LostCity != null) { LostCity(city); } }
public RGatheredBall CreateRGatherBall(List<RBall> balls, City dockCity, List<City> result) { RGatheredBall ball = new RGatheredBall(balls, dockCity, result); gatherBalls.Add(ball); return ball; }
int GetCityDangerIndex(City a) { int result = 0; for (int j = 0; j < a.LinkableCityCount; j++) { City cc = a.GetLinkableCity(j); if (cc.Owner == null) { result++; } else if (cc.Owner != player) { result += 5; } } return result; }
//readonly static int[][] stateEnum = new int[8][] //{ // new int[2] { 0, -1 }, new int[2] { 0, 1 }, // new int[2] { -1, 0 }, new int[2] { 1, 0 }, // new int[2] { -1, -1 }, new int[2] { 1, 1 }, // new int[2] { -1, 1 }, new int[2] { 1, -1 }, //}; //readonly static float[] stateEnumCost = new float[8] //{ // 1, 1, // 1, 1, // MathEx.Root2, MathEx.Root2, // MathEx.Root2, MathEx.Root2, //}; public BallPathFinder(City[] terr, AStarNodeBall[] units, Dictionary<City, AStarNodeBall> nodeTable) { this.terrain = terr; this.units = units; this.nodeTable = nodeTable; }
void PlayerArea_NewCity(City cc) { UpdateCityWeights(); }
public AStarNodeBall(City c) { this.City = c; }
void PlayerArea_RemoveCity(City cc) { UpdateCityWeights(); }
public float GetCityMark(City cc, float a, float b, float c) { CityData data; if (cityDataTable.TryGetValue(cc, out data)) { return a * data.ResourceCount + b * data.city.Level + c * data.city.NearbyOwnedBallCount; } return float.MinValue; }
public float GetWeightedOilRequirements(City c) { float ratio = (c.NearbyEnemyBallCount + 1) / (c.NearbyOwnedBallCount + 1); return OilBallRequirements * ratio; }
public void Open(City souceCity, City targetCity) { isAllSelected = false; isCancelled = true; isOpeningClicked = false; isCountedThrow = false; this.sourceCity = souceCity; this.targetCity = targetCity; StatisticRBall(true); ChangeState(State.Opening); }
/// <summary> /// 人类直接命令发球 /// Throw a ball. Just call method when the player asks a city. /// </summary> /// <param name="target"></param> public bool Throw(City target, RBallType type) { //if (!CanHandleCommand()) //return false; for (int i = 0; i < throwQueue.Count; i++) { ThrowTask tt = throwQueue.GetElement(i); if (tt.isTypedThrow && tt.typeToThrow == type && tt.throwPath[tt.throwPath.Count - 1] == target) { return false; } } //CancelCurrentCommand(); //reThrowDelay = 0; //throwRgball = null; battleField.BallPathFinder.Reset(); BallPathFinderResult result = battleField.BallPathFinder.FindPath(this, target); if (result != null) { List<City> throwPath = new List<City>(result.NodeCount); for (int i = 0; i < result.NodeCount; i++) { throwPath.Add(result[i]); } //Quaternion targetRot = GetOrientation(result[0].Position); //RotateTo(targetRot, 0.5f); //SetRotationPurpose(CityRotationPurpose.Throw); ThrowTask tt; tt.isTypedThrow = true; tt.throwPath = throwPath; tt.throwCount = 0; tt.isCountedThrow = false; tt.typeToThrow = type; throwQueue.Enqueue(tt); return true; } return false; }