public bool CanSee(PhysicalObject o) { if(o == this || p.Equals(o.p)){ //same object or same location return true; } if(HasAttr(AttrType.ASLEEP)){ return false; } Actor a = o as Actor; if(a != null){ if(HasAttr(AttrType.DETECTING_MONSTERS)){ if(this == player){ a.attrs[AttrType.DANGER_SENSED] = 1; } return true; } if(a.IsInvisibleHere() && !HasAttr(AttrType.BLINDSIGHT)){ return false; } } Tile t = o as Tile; if(t != null){ if(t.solid_rock){ return false; } } if(HasAttr(AttrType.BLIND) && !HasAttr(AttrType.BLINDSIGHT)){ return false; } if(type == ActorType.CLOUD_ELEMENTAL){ List<pos> cloud = M.tile.GetFloodFillPositions(p,false,x=>M.tile[x].features.Contains(FeatureType.FOG)); foreach(pos p2 in cloud){ if(o.DistanceFrom(p2) <= 12){ if(M.tile[p2].HasLOS(o.row,o.col)){ if(o is Actor){ if((o as Actor).IsHiddenFrom(this)){ return false; } return true; } else{ return true; } } } } return false; } else{ if(IsWithinSightRangeOf(o.row,o.col) || (M.tile[o.row,o.col].IsLit() && !HasAttr(AttrType.BLINDSIGHT))){ if(HasLOS(o.row,o.col)){ if(a != null && a.IsHiddenFrom(this)){ return false; } if(a != null && this == player){ a.attrs[AttrType.DANGER_SENSED] = 1; } return true; } } } return false; }
public bool GrabPreventsMovement(PhysicalObject o) { if (!HasAttr(AttrType.GRABBED) || DistanceFrom(o) > 1) { return false; } List<Actor> grabbers = new List<Actor>(); foreach (Actor a in ActorsAtDistance(1)) { if (a.attrs[Forays.AttrType.GRABBING] == a.DirectionOf(this)) { grabbers.Add(a); } } foreach (Actor a in grabbers) { if (o.DistanceFrom(a) > 1) { return true; } } return false; }
private static void AI_Step_Build_Direction_Lists(PhysicalObject start,PhysicalObject obj,bool flee,List<int> dirs,List<int> sideways_dirs) { int rowchange = 0; int colchange = 0; if(obj.row < start.row){ rowchange = -1; } if(obj.row > start.row){ rowchange = 1; } if(obj.col < start.col){ colchange = -1; } if(obj.col > start.col){ colchange = 1; } if(flee){ rowchange = -rowchange; colchange = -colchange; } if(rowchange == -1){ if(colchange == -1){ dirs.Add(7); } if(colchange == 0){ dirs.Add(8); } if(colchange == 1){ dirs.Add(9); } } if(rowchange == 0){ if(colchange == -1){ dirs.Add(4); } if(colchange == 1){ dirs.Add(6); } } if(rowchange == 1){ if(colchange == -1){ dirs.Add(1); } if(colchange == 0){ dirs.Add(2); } if(colchange == 1){ dirs.Add(3); } } if(dirs.Count == 0){ return; } bool clockwise = R.CoinFlip(); if(obj.DistanceFrom(start.TileInDirection(dirs[0].RotateDir(true))) < obj.DistanceFrom(start.TileInDirection(dirs[0].RotateDir(false)))){ clockwise = true; } else{ if(obj.DistanceFrom(start.TileInDirection(dirs[0].RotateDir(false))) < obj.DistanceFrom(start.TileInDirection(dirs[0].RotateDir(true)))){ clockwise = false; } } if(clockwise){ dirs.Add(dirs[0].RotateDir(true)); dirs.Add(dirs[0].RotateDir(false)); //building a list of directions to try: first the primary direction, } else{ dirs.Add(dirs[0].RotateDir(false)); dirs.Add(dirs[0].RotateDir(true)); } clockwise = R.CoinFlip(); //then the ones next to it, then the ones next to THOSE(in random order, unless one is closer) if(obj.DistanceFrom(start.TileInDirection(dirs[0].RotateDir(true,2))) < obj.DistanceFrom(start.TileInDirection(dirs[0].RotateDir(false,2)))){ clockwise = true; } else{ if(obj.DistanceFrom(start.TileInDirection(dirs[0].RotateDir(false,2))) < obj.DistanceFrom(start.TileInDirection(dirs[0].RotateDir(true,2)))){ clockwise = false; } } sideways_dirs.Add(dirs[0].RotateDir(clockwise,2)); //these 2 are considered last. sideways_dirs.Add(dirs[0].RotateDir(!clockwise,2)); //this completes the list of 5 directions. }