diff --git a/src/vm_builtins.c b/src/vm_builtins.c index 8c6b7db46..d04c4d960 100644 --- a/src/vm_builtins.c +++ b/src/vm_builtins.c @@ -12454,6 +12454,22 @@ static RValue builtin_tile_layer_find(VMContext* ctx, RValue* args, MAYBE_UNUSED return RValue_makeReal(-1.0); } +// tile_layer_depth(depth, newdepth) - changes the depth of all tiles at the given depth to the new depth. +static RValue builtin_tile_layer_depth(VMContext* ctx, RValue* args, MAYBE_UNUSED int32_t argCount) { + Runner* runner = ctx->runner; + Room* room = runner->currentRoom; + if (room == nullptr) return RValue_makeUndefined(); + int32_t depth = RValue_toInt32(args[0]); + int32_t newdepth = RValue_toInt32(args[1]); + for (int32_t i = 0; i < (int32_t) room->tileCount; i++) { + RoomTile* tile = &room->tiles[i]; + if (tile->tileDepth != depth) continue; + tile->tileDepth = newdepth; + runner->drawableListSortDirty = true; + } + return RValue_makeUndefined(); +} + // tile_layer_delete(depth) - removes every tile at the given depth from the current room. static RValue builtin_tile_layer_delete(VMContext* ctx, RValue* args, MAYBE_UNUSED int32_t argCount) { Runner* runner = ctx->runner; @@ -12472,6 +12488,34 @@ static RValue builtin_tile_layer_delete(VMContext* ctx, RValue* args, MAYBE_UNUS return RValue_makeUndefined(); } +// tile_layer_delete_at(depth, x, y) - removes every tile at the given depth and position from the current room. +static RValue builtin_tile_layer_delete_at(VMContext* ctx, RValue* args, MAYBE_UNUSED int32_t argCount) { + Runner* runner = ctx->runner; + Room* room = runner->currentRoom; + if (room == nullptr) return RValue_makeUndefined(); + int32_t depth = RValue_toInt32(args[0]); + GMLReal qx = RValue_toReal(args[1]); + GMLReal qy = RValue_toReal(args[2]); + uint32_t write = 0; + bool removedAny = false; + repeat(room->tileCount, i) { + RoomTile* tile = &room->tiles[i]; + if (tile->tileDepth == depth) { + GMLReal w = (GMLReal) tile->width * (GMLReal) tile->scaleX; + GMLReal h = (GMLReal) tile->height * (GMLReal) tile->scaleY; + if (qx >= (GMLReal) tile->x && qx < (GMLReal) tile->x + w && qy >= (GMLReal) tile->y && qy < (GMLReal) tile->y + h) { + removedAny = true; + continue; + } + } + if (write != i) room->tiles[write] = room->tiles[i]; + write++; + } + room->tileCount = write; + if (removedAny) runner->drawableListStructureDirty = true; + return RValue_makeUndefined(); +} + // tile_delete(id) - removes the tile with the given id from the current room. static RValue builtin_tile_delete(VMContext* ctx, RValue* args, MAYBE_UNUSED int32_t argCount) { Runner* runner = ctx->runner; @@ -16499,7 +16543,9 @@ void VMBuiltins_registerAll(VMContext* ctx) { VM_registerBuiltin(ctx, "tile_add", builtin_tile_add); VM_registerBuiltin(ctx, "tile_exists", builtin_tile_exists); VM_registerBuiltin(ctx, "tile_layer_find", builtin_tile_layer_find); + VM_registerBuiltin(ctx, "tile_layer_depth", builtin_tile_layer_depth); VM_registerBuiltin(ctx, "tile_layer_delete", builtin_tile_layer_delete); + VM_registerBuiltin(ctx, "tile_layer_delete_at", builtin_tile_layer_delete_at); VM_registerBuiltin(ctx, "tile_delete", builtin_tile_delete); VM_registerBuiltin(ctx, "tile_get_ids_at_depth", builtin_tile_get_ids_at_depth); VM_registerBuiltin(ctx, "tile_set_alpha", builtin_tile_set_alpha);