DeltaLoaderDocs
  1. Home
  2. API Wiki
  3. sw/trees.hpp

sw/trees.hpp

The kind of tree per tile or chunk.

Source: include/sw/trees.hpp

trees.hpp
#include <cstddef>
#include <cstdint>

namespace sw::trees {

enum class Kind : int { fir = 0, burnt = 1, snow = 2 };

inline constexpr std::uint32_t kRvaDrawFrame = 0x6d4de0;      // renderer_draw_frame
inline constexpr std::uint32_t kRvaSiteFoliage = 0x6d701c;    // the first place (shader object at renderer + 0x6c0)
inline constexpr std::uint32_t kRvaSiteSecond = 0x6d7848;     // the second place (+ 0x760)
inline constexpr std::size_t kSiteBytes = 35;                 // movsxd .. add rax, 0x1c0
inline constexpr std::uint32_t kRvaMeshLibraryLoader = 0x6b20c0;
inline constexpr std::size_t kOffElementKind = 0xf8;          // int
inline constexpr std::size_t kOffElementLod = 0xfc;           // int
inline constexpr std::size_t kOffElementChunkX = 0x08;        // int, taken to be the chunk index (500 m)
inline constexpr std::size_t kOffElementChunkZ = 0x0c;        // int
inline constexpr std::uintptr_t kLibrarySlotsOffset = 0x1c0;  // the nine mesh slots, 8 bytes each

// The slot of the game's formula, relative to the library: 0x1c0 + (kind * 3 + lod) * 8. lod 0..2.
constexpr std::uintptr_t slot_offset(Kind kind, int lod) {
    return kLibrarySlotsOffset + (static_cast<std::uintptr_t>(kind) * 3 + static_cast<std::uintptr_t>(lod)) * 8;
}

// The tile (grid cell) that holds a chunk index; floor((c + 1) / 2), also for negative numbers.
constexpr int tile_of_chunk(int chunk) {
    const int n = chunk + 1;
    return n >= 0 ? n / 2 : -((-n + 1) / 2);
}

// Sets the kind of a tile / a chunk. False for a kind that is not one of the three.
bool set_tile(int gx, int gz, Kind kind);
bool set_chunk(int cx, int cz, Kind kind);
// Removes a rule / all rules.
bool clear_tile(int gx, int gz);
bool clear_chunk(int cx, int cz);
void clear_rules();
std::size_t rule_count();

// The kind a chunk is drawn with, given the kind the game asks for. This is what the stub calls.
Kind resolve(Kind original, int cx, int cz);

// Checks the 35 bytes at both places (and the instruction after them), then patches both. False when the game
// does not match, the runtime is not attached, a stub cannot be placed within 2 GB of the image, or this is
// the 32 bit build. Calling it again after a success returns true.
bool watch();
// Puts the original bytes back. The stubs stay allocated, so a draw that is just inside one can finish.
void unwatch();
bool active();

struct ChunkSeen {
    int cx = 0, cz = 0;
    int kind = 0, lod = 0;     // as the game asked
    int drawn_kind = 0;        // as it was drawn
};
// Copies up to max of the first distinct chunks that were drawn (at most 64); returns how many.
std::size_t chunk_seen(ChunkSeen* out, std::size_t max);

// The first draw elements the stub saw (each element once, by address): the first 0x100 bytes as 32 quadwords. The ints at
// +0x08 / +0x0c turned out to be 0 for every element (a player's log), so they are NOT the chunk index; this is for finding where
// the position of the chunk is stored.
struct ElementSample {
    std::uintptr_t address = 0;
    std::int32_t kind = 0, lod = 0;
    std::uint64_t q[32] = {};
};
std::size_t element_samples(ElementSample* out, std::size_t max);   // at most 24

}  // namespace sw::trees

Documentation for game build 1.15.26. Found a mistake? Open an issue.