object RetrieveObjectDataExt(ushort[,] map, BitArray walls, int x, int y) { int id = GetMapInfoData(map, x + 1, y); int offset = 0; while (true) { ushort tile = TileAtOffset(map, offset); while ((tile & 0x3FF) != OBJ_OBJECT_INFO) { offset++; tile = TileAtOffset(map, offset); } offset++; if (id == GetMapInfoData(map, ref offset)) { tile = TileAtOffset(map, offset); offset++; int type = tile & 0x3FF; int direction, startTime, period, speed; switch (type) { case OBJ_PISTON: direction = GetMapInfoData(map, ref offset); startTime = GetMapInfoData(map, ref offset); period = GetMapInfoData(map, ref offset); speed = 0x10000 / GetMapInfoData(map, ref offset); return(new Piston(x, y, direction, startTime, period, speed)); case OBJ_ROLLER: direction = GetMapInfoData(map, ref offset); startTime = GetMapInfoData(map, ref offset); period = GetMapInfoData(map, ref offset); speed = GetMapInfoData(map, ref offset); return(Roller.Create(walls, WidthPx, x, y, direction, startTime, period, speed)); default: // Unsupported object (shooter?) break; } return(null); } } }
List <Roller> RetrieveRollerData(ushort[,] map, BitArray walls, int x, int y) { return(Roller.Create(walls, WidthPx, x, y, GetMapInfoData(map, x + 1, y), // direction GetMapInfoData(map, x, y + 1), // start time GetMapInfoData(map, x, y + 2))); // period }
public static List <Roller> Create(BitArray walls, int mapWidth, int x, int y, int dir, int startTime, int period, int speed = 0xC0) { Roller roller = new Roller(); dir *= 0x2000; roller.vx = KuruMath.instance.sin(speed * 0x100, (short)dir); roller.vy = -KuruMath.instance.cos(speed * 0x100, (short)dir); roller.x = (short)(x * 8 + 16); if ((dir & 0x2000) != 0) { roller.x -= 8; } roller.y = (short)(y * 8 + 16); roller.startTime = (ushort)startTime; // Roll through the level until it collides with something int colxoffs = KuruMath.instance.sin(15, (short)dir); int colyoffs = -KuruMath.instance.cos(15, (short)dir); int xpos = roller.x << 16; int ypos = roller.y << 16; int t = 0; bool isPixelInCollision(int xm, int ym) { int addr = xm + ym * mapWidth; return(walls[addr]); } while (true) { xpos += roller.vx; ypos += roller.vy; if (isPixelInCollision((xpos >> 16) + colxoffs, (ypos >> 16) + colyoffs)) { break; } t++; } int minx = Math.Min(roller.x, xpos >> 16) - 14; int miny = Math.Min(roller.y, ypos >> 16) - 14; int maxx = Math.Max(roller.x, xpos >> 16) + 14; int maxy = Math.Max(roller.y, ypos >> 16) + 14; roller.dangerArea = Rectangle.FromLTRB(minx, miny, maxx + 1, maxy + 1); roller.endTime = (ushort)t; period++; int remainder = t % period; if (remainder != 0) { t += period - remainder; } roller.period = (ushort)t; List <Roller> res = new List <Roller>(); for (; t > 0; t -= period) { res.Add(roller); roller = (Roller)roller.MemberwiseClone(); roller.startTime += (ushort)period; //roller.endTime += (ushort)period; } return(res); }