// ensure Loc exist public Panel_unit() { Loc = new iVec2( 0 , 0 ); TarPos = new iVec2( 0 , 0 ); CharID = 0; // nActionTime = 1; bOnSelected = true; bIsDead = false; TarIdent = 0; }
public iVec2 FindEmptyPos( iVec2 st , int len = 999 ) { if (CheckIsEmptyPos (st)) { return st; } // get a empty pos that can pop for (int i=1; i < len; i++) { List<iVec2> pool = Grids.GetRangePool( st , i , i-1 ); if( pool == null ) continue; foreach( iVec2 pos in pool ) { if( CheckIsEmptyPos(pos) ){ return pos; } } } Debug.Log ( " Error ! can't find a Empty Pos"); return null; }
public void MoveTo( int x , int y ) { TarPos = new iVec2 (x, y); //TarPos.X = x; //TarPos.Y = y; if (TarPos.Collision (Loc)) { // this case won't trig move end event. return; } if (pathfind != null) { PathList = pathfind; pathfind = null; } else { PathList = Panel_StageUI.Instance.PathFinding( this , Loc , TarPos ); // ensure we can reach if( PathList == null ) // move direct if no path can find { PathList = GameScene.Instance.Grids.GetPathList (Loc, TarPos); } } MoveNextPoint(); }
public int Dist( iVec2 vec2 ) { int dist = Math.Abs(vec2.X - X) + Math.Abs(vec2.Y - Y); return dist; }
// Get Path list public List<iVec2> GetPathList( iVec2 st , iVec2 ed ) { List<iVec2> lst = new List<iVec2>(); int Diffx = ed.X- st.X; int Diffy = ed.Y- st.Y; iVec2 p1 = new iVec2(); if( Diffy == 0 ) { p1.X = ed.X; p1.Y = st.Y; } else{ p1.X = st.X; p1.Y = ed.Y; } lst.Add( p1 ); lst.Add( ed ); return lst; }
public bool SetValue( iVec2 v , _TILE value ) { return Layer.SetValue(v.X + hW, v.Y + hH, value ); }
public iVec2( iVec2 v ) { X = v.X; Y = v.Y; }
public cMyCell(int x, int y) { Loc = new iVec2( x , y ); Value = 0; }
public double GetAngleFromTwoPoint(iVec2 p1, iVec2 p2) { return AngleBetween( (this-p1) , (this-p2) ); }
// 比對 座標。看是否同一點 public bool Collision(iVec2 v2) { return ( X==v2.X && Y==v2.Y); }
public List<iVec2> MoveAbleCell( iVec2 st , int nDist ) { List<iVec2> pool = new List<iVec2> (); //InitializePathFindMap (); // maybe move out later var startLocation = new Point(st.X+hW, st.Y+hH); // convert srw to path find PathFinder pathFinder = GetPathFinder(); // new method to get path // check if need refresh if( pathFinder.bIsDirty == true ) { pathFinder.ApplyMap (map); // need apply every time for new find pathFinder.ApplyMaskPoint (IgnorePool); // need apply every time. pathFinder.bIsDirty = false; } //pathFinder.nMaxStep = nDist; // max dist List<Point> path = pathFinder.MoveAble(startLocation , nDist ); foreach( Point pt in path) { iVec2 pos = new iVec2( pt.X-hW , pt.Y -hH ); pool.Add( pos ); } return pool; }
public void AddIgnorePos( iVec2 v ) { if(IgnorePool == null ) IgnorePool = new List<Point>(); IgnorePool.Add (new Point( v.X+hW , v.Y+hH )); GetPathFinder().bIsDirty = true; }
// Check if pos in grid public bool Contain( iVec2 v ) { if( v.X < -hW || v.X > hW ) { return false; } if( v.Y < -hH || v.Y > hH ) { return false; } return true; }
// tool func to get aoe affect pool public List < iVec2 > GetAOEPool( int nX , int nY , int nAoe ) { iVec2 st = new iVec2 ( nX , nY ); Dictionary< string , iVec2 > tmp = new Dictionary< string , iVec2 >(); tmp.Add ( st.GetKey() , st ); // pool.Add ( st ); AOE aoe = ConstDataManager.Instance.GetRow<AOE> ( nAoe ) ; if (aoe != null) { // add extra first cTextArray TA = new cTextArray(); TA.SetText ( aoe.s_EXTRA ); for( int i = 0 ; i < TA.GetMaxCol(); i++ ) { CTextLine line = TA.GetTextLine( i ); for( int j = 0 ; j < line.GetRowNum() ; j++ ) { string s = line.m_kTextPool[ j ]; string [] arg = s.Split( ",".ToCharArray() ); if( arg.Length < 2 ) continue; if( arg[0] != null && arg[1] != null ) { int x = int.Parse( arg[0] ); int y = int.Parse( arg[1] ); iVec2 v = st.MoveXY( x , y ); if( Grids.Contain( v ) == false ) continue; string key = v.GetKey(); if( tmp.ContainsKey( key ) == false ){ tmp.Add( key , v ); } } } } // get range pool List<iVec2> r = Grids.GetRangePool( st , aoe.n_MAX , aoe.n_MIN ); } List < iVec2 > pool = new List < iVec2 > (); return pool; }
// public List< iVec2> GetTarPosPKPosPool( Panel_unit unit , bool bCanPK , int nTarX , int nTarY , int nDist = 0 ) // { // List< iVec2> lst = new List< iVec2> (); // foreach (KeyValuePair < int , Panel_unit > pair in IdentToUnit) { // if( unit.CanPK( pair.Value ) == bCanPK ) // { // lst.Add( pair.Value.Loc ); // } // } // return lst; // // } public List< iVec2 > PathFinding( Panel_unit unit , iVec2 st , iVec2 ed , int nStep = 999) { // nStep = 999; // debug List< iVec2 > path = null; //List< iVec2 > unitList = GetUnitPosList(); // try the short path //this.GetUnitPKPosPool (unit, true); Grids.ClearIgnorePool(); Grids.AddIgnorePool ( GetUnitPKPosPool( unit , true ) ); // all is block in first find // List< iVec2 > nearList = Grids.GetRangePool( ed , 1 ); // the 4 pos can't stand ally // foreach( iVec2 pos in nearList ){ // if( CheckIsEmptyPos( pos ) == false ){ // Grids.AddIgnorePos( pos ); // } // } // avoid the end node have ally //List< iVec2 > nearList = GetUnitPKPosPool( unit , ); path = Grids.PathFinding( st , ed , nStep ); // if (path == null) { // Grids.ClearIgnorePool(); // //Grids.AddIgnorePool ( GetUnitPosList() ); // only enemy is block in second find // Grids.AddIgnorePool( GetUnitPKPosPool( unit , true ) ); // // path = Grids.PathFinding( st , ed , nStep ); // } if (Config.GOD == true) { CreatePathOverEffect (path); // draw path } return path; }
public static iVec2 operator /(iVec2 v1, float f) { if (f == 0.0f) return v1; iVec2 v3 = new iVec2(); v3.X = (int)(v1.X / f); v3.Y = (int)(v1.Y / f); return v3; }
public IntPtr Ptr { set; get; } // 自訂指標 public cMyCell() { Loc = new iVec2(); Value = 0; }
public static double AngleBetween(iVec2 vector1, iVec2 vector2) { double sin = vector1.X * vector2.Y - vector2.X * vector1.Y; double cos = vector1.X * vector2.X + vector1.Y * vector2.Y; return Math.Atan2(sin, cos) * (180 / Math.PI); }
public cMyCell( int x , int y , int value ) { Loc = new iVec2(x, y); Value = value; }
// v = 目的座標, E 的敵方座標 public bool ZocCheck(iVec2 C, iVec2 E ) { // it wont zoc if the same point if( Collision( C ) || Collision( E ) || C.Collision(E)) return false; //距離短的的絕不會是 ZOC int distc = Dist (C); int diste = Dist (E); if ( distc <= diste ) return false; // 座標在相對45度以上 不會是ZOC double ang1 = GetAngleFromTwoPoint(C, E); ; if ( Math.Abs( ang1 ) > 26 ) // 45 is too large ... return false; // 由目標點夾角判斷。這邊不知道對不對 // double ang = C.GetAngleFromTwoPoint(this, E); // Math.Atan2(sin, cos) * (180 / Math.PI); // // // ang = Math.Abs( ang ); // // if (ang > 180) // { // ang = 360 - ang; // } // return ang < 40; return true; }
public _TILE GetValue( iVec2 v) { return Layer.GetValue(v.X + hW, v.Y + hH); }
// 移動座標 public iVec2 MoveX ( int nX ) { iVec2 v = new iVec2( this ); v.X += nX; return v; }
public void GetRealXY( ref float fX , ref float fY , iVec2 v ) { fX = GetRealX( v.X ); fY = GetRealY( v.Y ); }
public iVec2 MoveY(int nY) { iVec2 v = new iVec2(this); v.Y += nY; return v; }
// Math utility func public List<iVec2> GetRangePool( iVec2 v , int max , int min=0 ) { // 取得指定座標 對應距離內的 pool List<iVec2> lst = new List<iVec2>(); // 正向 for (int i = 0; i <= max; i++) // 0 不用計算 { int x1 = v.X + i; // 正 if (x1 <= hW) { for (int j = 0; j <= max; j++) // 0 不用計算 { int tmp = i + j; if ( tmp > max || tmp < min ) continue; int y1 = v.Y + j; // 正 if (y1 <= hH) { lst.Add(new iVec2(x1, y1)); } if( j == 0 ) // avoid 0 duplic continue; int y2 = v.Y - j; // 反 if (y2 >= -hH) { lst.Add(new iVec2(x1, y2)); } } } if( i == 0) // avoid 0 duplic continue; int x2 = v.X - i; // 反 if (x2 >= -hW) { for (int j = 0; j <= max; j++) // 0 不用計算 { int tmp = i + j; if ( tmp > max || tmp < min ) continue ; // over dist int y1 = v.Y + j; // 正 if (y1 <= hH) { lst.Add(new iVec2(x2, y1)); } if( j == 0 ) // avoid 0 duplic continue; int y2 = v.Y - j; // 反 if (y2 >= -hH) { lst.Add(new iVec2(x2, y2)); } } } } // return lst; }
public iVec2 MoveXY(int nX , int nY) { iVec2 v = new iVec2(this); v.X += nX; v.Y += nY; return v; }
// 凡是被 ZOC影響到的 都移除 , S = 自己, E 的敵人, 0=可行走, Z= ZOC // ZOC: 敵人身後 不可行走 // Ex1: // 0 0 0 S 0 0 0 // 0 0 0 0 0 0 0 // 0 0 0 E 0 0 0 // 0 0 Z Z Z 0 0 // Ex2: // 0 0 0 S 0 0 0 // 0 0 0 0 0 0 0 // 0 0 0 0 E Z Z // 0 0 0 0 Z Z Z // 0 0 0 0 Z Z Z // remove Zoc Block public List<iVec2> FilterZocPool( iVec2 self , ref List<iVec2> pool, ref List<iVec2> enemy ) { List<iVec2> lst = new List<iVec2>(); foreach (iVec2 v in pool) { bool bCol = false; foreach (iVec2 v2 in enemy ) { if (self.ZocCheck( v, v2 )) { bCol = true; break; } } if (bCol){ continue; //continue; // 重複的過濾掉 } lst.Add(v); // } return lst; }
public static iVec2 operator -(iVec2 v1, iVec2 v2) { iVec2 v3 = new iVec2(); v3.X = v1.X - v2.X; v3.Y = v1.Y - v2.Y; return v3; }
public static iVec2 operator *(iVec2 v1, float f) { iVec2 v3 = new iVec2(); v3.X = (int)(v1.X *f); v3.Y = (int)(v1.Y *f) ; return v3; }
public bool CheckIsEmptyPos( iVec2 pos ) { if (Grids.Contain (pos) == false) return false; // check tile if( cMyGrids.IsWalkAbleTile( Grids.GetValue( pos ) ) == false ) return false; // check thiing // check unit foreach( KeyValuePair< int , Panel_unit > pair in IdentToUnit ) { if( pair.Value.Loc.Collision( pos ) ){ return false; } } return true; }