2021-01-06 15:10:21 -05:00
|
|
|
|
2026-02-25 01:58:19 -05:00
|
|
|
#pragma once
|
2021-01-06 15:10:21 -05:00
|
|
|
|
2022-02-23 23:08:28 -05:00
|
|
|
#include "wrap-set.hpp"
|
|
|
|
|
#include "wrap-unordered-map.hpp"
|
|
|
|
|
#include "wrap-map.hpp"
|
|
|
|
|
|
2022-02-25 19:57:23 -05:00
|
|
|
#include <memory>
|
|
|
|
|
#include <utility>
|
|
|
|
|
|
2021-01-06 15:10:21 -05:00
|
|
|
#include "luastack.hpp"
|
2021-01-16 01:24:33 -05:00
|
|
|
#include "planemap.hpp"
|
|
|
|
|
#include "idalloc.hpp"
|
|
|
|
|
#include "animqueue.hpp"
|
2021-07-19 15:32:34 -04:00
|
|
|
#include "invocation.hpp"
|
2021-07-25 19:22:39 -04:00
|
|
|
#include "streambuffer.hpp"
|
2021-11-21 13:35:39 -05:00
|
|
|
#include "debugcollector.hpp"
|
2021-10-20 14:05:09 -04:00
|
|
|
#include "printbuffer.hpp"
|
2021-02-18 17:21:25 -05:00
|
|
|
#include "sched.hpp"
|
2022-05-03 00:36:11 -04:00
|
|
|
#include "http.hpp"
|
2021-01-16 01:24:33 -05:00
|
|
|
#include "source.hpp"
|
2021-02-09 17:15:54 -05:00
|
|
|
#include "luasnap.hpp"
|
2021-01-06 15:10:21 -05:00
|
|
|
|
2026-02-24 22:36:01 -05:00
|
|
|
struct EngineWrapper;
|
|
|
|
|
|
2026-02-21 21:42:53 -05:00
|
|
|
enum WorldType {
|
|
|
|
|
WORLD_TYPE_MASTER = 1,
|
|
|
|
|
WORLD_TYPE_PREDICTIVE = 2,
|
|
|
|
|
};
|
|
|
|
|
|
2021-01-16 01:24:33 -05:00
|
|
|
class World;
|
|
|
|
|
|
2022-03-02 14:52:51 -05:00
|
|
|
class Tangible : public eng::opnew {
|
2021-03-16 12:19:37 -04:00
|
|
|
private:
|
|
|
|
|
friend class World;
|
|
|
|
|
|
|
|
|
|
// Serialize and deserialize
|
|
|
|
|
//
|
|
|
|
|
// The tangible's ID is not serialized. When you serialize a tangible, you
|
|
|
|
|
// should probably serialize the ID separately.
|
|
|
|
|
//
|
|
|
|
|
// The Lua portion of the tangible is not serialized here. Instead, the lua
|
|
|
|
|
// portion is serialized when you serialize the lua state as a whole.
|
|
|
|
|
//
|
|
|
|
|
// PlaneItem is not serialized. The deserialize routine rebuilds the
|
|
|
|
|
// PlaneItem from the AnimQueue.
|
|
|
|
|
//
|
|
|
|
|
// World pointer is not serialized.
|
|
|
|
|
//
|
|
|
|
|
void serialize(StreamBuffer *sb);
|
|
|
|
|
void deserialize(StreamBuffer *sb);
|
|
|
|
|
|
2021-01-16 01:24:33 -05:00
|
|
|
public:
|
2021-01-22 17:35:23 -05:00
|
|
|
// Animation queue.
|
2021-01-16 01:24:33 -05:00
|
|
|
//
|
|
|
|
|
AnimQueue anim_queue_;
|
|
|
|
|
|
2021-01-22 17:35:23 -05:00
|
|
|
// Plane Item.
|
|
|
|
|
//
|
|
|
|
|
// The PlaneItem also contains this tangible's ID.
|
2021-03-14 18:17:34 -04:00
|
|
|
// To move this PlaneItem, update the anim_queue first, then call
|
|
|
|
|
// update_plane_item, which copies the data from the anim_queue.
|
|
|
|
|
//
|
2021-01-22 17:35:23 -05:00
|
|
|
PlaneItem plane_item_;
|
|
|
|
|
|
2021-01-16 01:24:33 -05:00
|
|
|
// Player ID pool
|
|
|
|
|
//
|
2021-03-14 18:17:34 -04:00
|
|
|
// This is present in every tangible, whether a player or not.
|
|
|
|
|
// However, the fifo is only enabled in logged-in players.
|
|
|
|
|
//
|
|
|
|
|
IdPlayerPool id_player_pool_;
|
|
|
|
|
|
2021-10-20 14:05:09 -04:00
|
|
|
// Print Buffer
|
|
|
|
|
//
|
2021-11-26 15:45:36 -05:00
|
|
|
// Stores the console output for this actor until it can be
|
|
|
|
|
// probed by the client. Most tangibles have empty printbuffers,
|
|
|
|
|
// which are stored as just a null pointer internally.
|
2021-10-20 14:05:09 -04:00
|
|
|
//
|
2021-11-14 15:57:18 -05:00
|
|
|
PrintBuffer print_buffer_;
|
2021-10-20 14:05:09 -04:00
|
|
|
|
2024-03-04 16:33:23 -05:00
|
|
|
// Can-Be-Controlled flag.
|
|
|
|
|
//
|
|
|
|
|
// This flag indicates whether the tangible can be controlled
|
|
|
|
|
// by a client. Clients will not be allowed to attach to tangibles
|
|
|
|
|
// who don't have this flag. If this flag is true, the
|
|
|
|
|
// tangible cannot be deleted using a mere 'tangible.delete', instead,
|
|
|
|
|
// you have to use 'tangible.deleteplayer'.
|
|
|
|
|
//
|
|
|
|
|
bool can_be_controlled_;
|
|
|
|
|
|
|
|
|
|
// Is Controlled Flag.
|
|
|
|
|
//
|
|
|
|
|
// This flag is set to true when a client is controlling this player.
|
|
|
|
|
// It gets set back to false when the client logs out or attaches
|
|
|
|
|
// to a different player. This can only be set in master models.
|
|
|
|
|
//
|
|
|
|
|
bool is_controlled_;
|
|
|
|
|
|
|
|
|
|
// Force disconnect flag.
|
|
|
|
|
//
|
|
|
|
|
// This flag is used to force the client to log out ASAP. This flag
|
|
|
|
|
// can only be set in master models.
|
|
|
|
|
//
|
|
|
|
|
bool force_disconnect_;
|
|
|
|
|
|
|
|
|
|
// Delete on Logout Flag.
|
|
|
|
|
//
|
|
|
|
|
// This flag can be set on a controlled player. When the player
|
|
|
|
|
// disconnects, their character will be deleted. This flag can only
|
|
|
|
|
// be set if the is_controlled_ flag is true.
|
|
|
|
|
//
|
|
|
|
|
bool delete_on_disconnect_;
|
|
|
|
|
|
2021-03-14 18:17:34 -04:00
|
|
|
// constructor.
|
|
|
|
|
//
|
|
|
|
|
Tangible(World *w, int64_t id);
|
2021-01-22 17:35:23 -05:00
|
|
|
|
2021-03-14 18:17:34 -04:00
|
|
|
// Get the ID
|
|
|
|
|
//
|
2021-07-26 13:12:44 -04:00
|
|
|
int64_t id() const { return plane_item_.id(); }
|
2021-03-19 13:41:41 -04:00
|
|
|
|
2021-02-25 15:43:05 -05:00
|
|
|
void update_plane_item();
|
2021-07-18 17:48:39 -04:00
|
|
|
bool is_an_actor() { return (id_player_pool_.get_fifo_capacity() > 0); }
|
2021-12-14 12:53:31 -05:00
|
|
|
void configure_id_pool_for_actor() { id_player_pool_.set_fifo_capacity(3); id_player_pool_.refill(); }
|
2021-01-16 01:24:33 -05:00
|
|
|
};
|
2021-01-06 15:10:21 -05:00
|
|
|
|
2022-02-25 19:57:23 -05:00
|
|
|
using UniqueTangible = std::unique_ptr<Tangible>;
|
2021-10-15 13:51:32 -04:00
|
|
|
|
2022-03-02 14:52:51 -05:00
|
|
|
class World : public eng::opnew {
|
2021-01-06 15:10:21 -05:00
|
|
|
public:
|
2021-07-25 19:22:39 -04:00
|
|
|
using IdVector = util::IdVector;
|
2022-02-24 02:17:41 -05:00
|
|
|
using TanVector = eng::vector<const Tangible*>;
|
|
|
|
|
using Redirects = eng::map<int64_t, int64_t>;
|
2024-02-28 15:35:47 -05:00
|
|
|
const float RadiusVisibility = 1000.0;
|
|
|
|
|
const float RadiusClose = 1000.0;
|
2021-03-30 18:35:08 -04:00
|
|
|
|
2021-01-16 01:24:33 -05:00
|
|
|
// Constructor.
|
|
|
|
|
//
|
|
|
|
|
// The constructor also calls 'lua_open' to create a new
|
2021-08-03 11:25:12 -04:00
|
|
|
// lua interpreter for this world model.
|
2021-01-16 01:24:33 -05:00
|
|
|
//
|
2023-03-01 16:07:13 -05:00
|
|
|
World(WorldType wt);
|
2021-01-16 01:24:33 -05:00
|
|
|
|
|
|
|
|
// Destructor.
|
|
|
|
|
//
|
|
|
|
|
// Not currently functional.
|
|
|
|
|
//
|
2021-01-06 15:10:21 -05:00
|
|
|
~World();
|
|
|
|
|
|
2021-01-16 01:24:33 -05:00
|
|
|
// get_lua_state
|
|
|
|
|
//
|
|
|
|
|
// Get the lua interpreter associated with this world model.
|
|
|
|
|
//
|
2021-03-30 18:35:08 -04:00
|
|
|
lua_State *state() const { return lua_snap_.state(); }
|
2021-01-16 01:24:33 -05:00
|
|
|
|
2021-02-07 13:38:29 -05:00
|
|
|
// get_near
|
2021-01-22 17:35:23 -05:00
|
|
|
//
|
2023-07-24 17:20:45 -04:00
|
|
|
// Get a list of tangibles in any arbitrary region.
|
2021-01-17 16:23:10 -05:00
|
|
|
//
|
2023-07-24 17:20:45 -04:00
|
|
|
void get_near(PlaneScan &sc, IdVector *into) const;
|
2023-07-24 17:19:25 -04:00
|
|
|
|
|
|
|
|
// get_near
|
|
|
|
|
//
|
2023-07-24 17:20:45 -04:00
|
|
|
// Get a list of the tangibles that are near the player. If
|
|
|
|
|
// 'exclude_nowhere' is true, exclude any tangibles on the nowhere plane
|
|
|
|
|
// (but still include the player himself). The unsorted version returns the
|
|
|
|
|
// tangibles in an unpredictable order. If sorted is false, return them in
|
|
|
|
|
// an unpredictable order. This is a thin wrapper around the more general
|
|
|
|
|
// form of 'get_near', above.
|
2023-07-24 17:19:25 -04:00
|
|
|
//
|
2023-07-24 17:20:45 -04:00
|
|
|
void get_near(int64_t player_id, float radius, bool exclude_nowhere, bool omit_player, bool sorted, IdVector *into) const;
|
|
|
|
|
|
2026-02-24 22:36:01 -05:00
|
|
|
// Get tangibles near the specified tangible.
|
|
|
|
|
//
|
|
|
|
|
// Returns a count and pointer to an array of tangible IDs. The
|
|
|
|
|
// returned pointer remains valid until the next call to
|
|
|
|
|
// get_tangibles_near.
|
|
|
|
|
//
|
|
|
|
|
void get_tangibles_near(uint64_t tanid, double rx, double ry, double rz, uint32_t *count, int64_t **ids);
|
|
|
|
|
|
|
|
|
|
// Get the animation queues for the specified tangibles.
|
2023-07-24 17:20:45 -04:00
|
|
|
//
|
2026-02-24 22:36:01 -05:00
|
|
|
// For each tangible ID, returns the animation queue as a serialized
|
|
|
|
|
// string via lengths/strings output arrays. The returned pointers
|
|
|
|
|
// remain valid until the next call to get_animation_queues.
|
2023-07-24 17:20:45 -04:00
|
|
|
//
|
2026-02-24 22:36:01 -05:00
|
|
|
void get_animation_queues(uint32_t count, const int64_t *ids, uint32_t *lengths, const char **strings);
|
2023-07-24 17:21:44 -04:00
|
|
|
|
2021-01-22 17:35:23 -05:00
|
|
|
// Make a tangible.
|
2021-01-17 16:23:10 -05:00
|
|
|
//
|
2023-04-14 15:33:58 -04:00
|
|
|
// You must provide a valid previously-unused ID. Otherwise, leaves the lua
|
|
|
|
|
// stack untouched. Returns a pointer to the C++ part of the tangible, and
|
|
|
|
|
// optionally stores the Lua part in a stack slot.
|
2021-01-22 17:35:23 -05:00
|
|
|
//
|
2023-07-24 17:19:25 -04:00
|
|
|
Tangible *tangible_make(const LuaCoreStack &LS0, LuaSlot tan, int64_t id);
|
|
|
|
|
Tangible *tangible_make(int64_t id);
|
2021-01-17 16:23:10 -05:00
|
|
|
|
2021-01-22 17:35:23 -05:00
|
|
|
// Get a pointer to the specified tangible.
|
|
|
|
|
//
|
2023-03-16 23:31:29 -04:00
|
|
|
// If there's no such tangible, or if the tangible is deleted,
|
|
|
|
|
// returns nullptr.
|
2021-08-03 12:40:12 -04:00
|
|
|
//
|
2021-01-22 17:35:23 -05:00
|
|
|
Tangible *tangible_get(int64_t id);
|
2021-07-26 13:12:44 -04:00
|
|
|
const Tangible *tangible_get(int64_t id) const;
|
2021-07-25 19:22:39 -04:00
|
|
|
|
2021-02-25 15:43:05 -05:00
|
|
|
// Get a pointer to the specified tangible.
|
|
|
|
|
//
|
2023-03-16 23:31:29 -04:00
|
|
|
// The value on the lua stack should be a lua tangible.
|
2021-02-25 15:43:05 -05:00
|
|
|
//
|
2023-03-16 23:31:29 -04:00
|
|
|
// If the 'allowdel' flag is true, then it is valid to pass in
|
|
|
|
|
// a deleted tangible. In that case, this function returns nullptr,
|
|
|
|
|
// but this is not a Lua error.
|
|
|
|
|
//
|
2023-04-06 20:12:03 -04:00
|
|
|
Tangible *tangible_get(const LuaCoreStack &LS, LuaSlot slot, bool allowdel);
|
2021-07-26 13:12:44 -04:00
|
|
|
|
|
|
|
|
// Get pointers to many tangibles.
|
|
|
|
|
//
|
|
|
|
|
TanVector tangible_get_all(const IdVector &ids) const;
|
2021-01-17 16:23:10 -05:00
|
|
|
|
2021-03-19 13:41:41 -04:00
|
|
|
// Delete the specified tangible.
|
|
|
|
|
//
|
2021-08-03 12:40:12 -04:00
|
|
|
// If there's no such tangible, this is a no-op.
|
|
|
|
|
//
|
|
|
|
|
void tangible_delete(int64_t id);
|
2021-08-03 11:25:12 -04:00
|
|
|
|
2021-03-30 18:35:08 -04:00
|
|
|
// Create a login actor.
|
|
|
|
|
//
|
|
|
|
|
// Creates a tangible of class 'login' and returns its ID.
|
|
|
|
|
// This is used to create a temporary actor which is used during
|
|
|
|
|
// the login process.
|
|
|
|
|
//
|
2025-06-16 19:58:26 -04:00
|
|
|
// If this is a master model, The function 'login.init'
|
2024-03-04 16:33:23 -05:00
|
|
|
// called. Then, the following login flags are set:
|
|
|
|
|
// can_be_controlled, is_controlled, and delete_on_disconnect.
|
|
|
|
|
//
|
2025-06-16 19:58:26 -04:00
|
|
|
// In a client model, 'login.init' is not called,
|
2024-03-04 16:33:23 -05:00
|
|
|
// and the login flags are not used in client models.
|
|
|
|
|
//
|
|
|
|
|
int64_t create_login_actor();
|
|
|
|
|
|
|
|
|
|
// Log out a connected player.
|
|
|
|
|
//
|
|
|
|
|
// This is to be called after a client disconnects.
|
2024-02-27 17:32:08 -05:00
|
|
|
//
|
2024-03-04 16:33:23 -05:00
|
|
|
void disconnected(int64_t actor_id);
|
2021-03-30 18:35:08 -04:00
|
|
|
|
|
|
|
|
// Fetch all redirects and clear the redirects table.
|
|
|
|
|
//
|
|
|
|
|
Redirects fetch_redirects();
|
|
|
|
|
|
2021-11-26 13:56:24 -05:00
|
|
|
// Probe an arbitrary lua expression.
|
|
|
|
|
//
|
|
|
|
|
// Any print-statements in the lua code are sent into
|
|
|
|
|
// a stringstream. The return value of probe_lua is the string
|
|
|
|
|
// from the stringstream. If the lua expression returns a
|
|
|
|
|
// value, that is also printed to the stringstream.
|
|
|
|
|
//
|
2024-09-01 19:43:00 -04:00
|
|
|
eng::string probe_lua_expr(int64_t actor_id, std::string_view lua);
|
|
|
|
|
|
|
|
|
|
// Probe that calls lua function, passing arguments.
|
|
|
|
|
//
|
|
|
|
|
// Print statements are discarded. The lua function may return a vector
|
|
|
|
|
// of values. If so, the values are packed into a StreamBuffer.
|
|
|
|
|
//
|
2025-04-07 16:48:27 -04:00
|
|
|
void probe_lua_call(int64_t actor_id, int64_t place_id, std::string_view datapack, StreamBuffer *retvals);
|
2021-11-26 13:56:24 -05:00
|
|
|
|
2021-07-19 15:32:34 -04:00
|
|
|
// Invoke an Invocation object.
|
2021-02-16 13:31:34 -05:00
|
|
|
//
|
2021-07-19 15:32:34 -04:00
|
|
|
// This is the primary dispatcher for all operations that mutate a world model.
|
|
|
|
|
// To mutate a world model, create an invocation, then invoke it.
|
|
|
|
|
//
|
2022-05-03 00:36:11 -04:00
|
|
|
// It is legal to mutate a world model without using 'Invoke', but
|
|
|
|
|
// only in authoritative world models.
|
|
|
|
|
//
|
2021-07-19 15:32:34 -04:00
|
|
|
void invoke(const Invocation &inv);
|
2021-10-15 14:47:12 -04:00
|
|
|
|
2021-10-21 13:15:04 -04:00
|
|
|
// Get the PrintBuffer of the actor.
|
|
|
|
|
//
|
|
|
|
|
const PrintBuffer *get_printbuffer(int64_t actor_id);
|
|
|
|
|
|
2026-01-12 13:45:04 -05:00
|
|
|
// Get the source database.
|
|
|
|
|
//
|
|
|
|
|
SourceDB &get_source() { return source_db_; }
|
|
|
|
|
|
2025-06-16 19:58:26 -04:00
|
|
|
// Rebuild the global environment from the source database.
|
2021-08-03 11:25:12 -04:00
|
|
|
//
|
2026-05-26 15:07:42 -04:00
|
|
|
// Error messages go to the specified actor.
|
|
|
|
|
//
|
2025-06-16 19:58:26 -04:00
|
|
|
// Returns true if the rebuild goes without errors.
|
2021-10-05 12:54:37 -04:00
|
|
|
//
|
2026-05-26 15:07:42 -04:00
|
|
|
bool rebuild_sourcedb(int64_t actor_id);
|
2021-12-15 14:18:19 -05:00
|
|
|
|
2025-06-16 19:58:26 -04:00
|
|
|
// Update the source database from disk, then rebuild the global environment.
|
|
|
|
|
//
|
2026-05-26 15:07:42 -04:00
|
|
|
// Error messages go to the specified actor.
|
2025-06-16 19:58:26 -04:00
|
|
|
//
|
|
|
|
|
// Returns true if the update goes without errors.
|
2023-04-10 17:58:44 -04:00
|
|
|
//
|
2026-05-26 15:07:42 -04:00
|
|
|
bool update_source(const util::LuaSourceVec &source, int64_t actor_id);
|
|
|
|
|
bool update_source(std::string_view sourcepk, int64_t actor_id);
|
2023-04-10 17:58:44 -04:00
|
|
|
|
2022-05-03 00:36:11 -04:00
|
|
|
// Supply an HTTP response to an outstanding HTTP request.
|
2022-05-20 17:12:58 -04:00
|
|
|
//
|
2022-05-16 17:16:42 -04:00
|
|
|
void http_response(const HttpParser &response);
|
|
|
|
|
void http_responses(const HttpParserVec &responses);
|
2022-05-06 13:16:27 -04:00
|
|
|
|
2022-05-03 00:36:11 -04:00
|
|
|
// Abort all HTTP requests. This is typically used after
|
|
|
|
|
// reloading a world from a save-game. The http requests that
|
|
|
|
|
// were in progress are long-since dead.
|
2022-05-20 17:12:58 -04:00
|
|
|
//
|
2022-05-03 00:36:11 -04:00
|
|
|
void abort_all_http_requests(int status_code, std::string_view error);
|
|
|
|
|
|
2022-05-20 17:12:58 -04:00
|
|
|
// Serve an HTTP query coming in from outside.
|
|
|
|
|
//
|
|
|
|
|
// Note: the lua code for the http_serve runs in a nonblocking
|
|
|
|
|
// context. It must produce a result instantly.
|
|
|
|
|
//
|
|
|
|
|
HttpServerResponse http_serve(const HttpParser &request);
|
|
|
|
|
|
2026-02-24 22:36:01 -05:00
|
|
|
// Install this world into an EngineWrapper's function pointers.
|
|
|
|
|
//
|
|
|
|
|
void expose_world_to_driver(EngineWrapper *w);
|
|
|
|
|
|
2021-03-19 13:41:41 -04:00
|
|
|
// fetch_global_pointer
|
2021-01-16 01:24:33 -05:00
|
|
|
//
|
|
|
|
|
// Given a lua state, fetch the world model associated with
|
|
|
|
|
// that lua state.
|
|
|
|
|
//
|
2021-02-25 14:09:16 -05:00
|
|
|
static World *fetch_global_pointer(lua_State *L);
|
2021-02-16 13:31:34 -05:00
|
|
|
|
2022-04-25 17:17:41 -04:00
|
|
|
// Check if the world is authoritative.
|
|
|
|
|
//
|
2026-02-21 21:42:53 -05:00
|
|
|
bool is_authoritative() const { return world_type_ == WORLD_TYPE_MASTER; }
|
2023-03-01 16:07:13 -05:00
|
|
|
|
2022-05-03 00:36:11 -04:00
|
|
|
// Get a table showing all outstanding HTTP requests.
|
|
|
|
|
//
|
2022-05-06 13:16:27 -04:00
|
|
|
const HttpClientRequestMap &http_requests() const { return http_requests_; }
|
2022-05-03 00:36:11 -04:00
|
|
|
|
2021-03-16 12:19:37 -04:00
|
|
|
// Serialize and deserialize.
|
|
|
|
|
//
|
|
|
|
|
void serialize(StreamBuffer *sb);
|
|
|
|
|
void deserialize(StreamBuffer *sb);
|
|
|
|
|
|
2021-06-03 13:29:19 -04:00
|
|
|
// Snapshot and rollback.
|
2021-02-16 13:31:34 -05:00
|
|
|
//
|
2023-03-01 16:07:13 -05:00
|
|
|
// These are used by the client to convert the synchronous model
|
|
|
|
|
// to an asynchronous model and back.
|
|
|
|
|
//
|
2021-03-16 12:19:37 -04:00
|
|
|
void snapshot();
|
|
|
|
|
void rollback();
|
2021-11-09 16:27:39 -05:00
|
|
|
bool snapshot_empty() { return snapshot_.empty(); }
|
|
|
|
|
|
2021-09-10 17:06:07 -04:00
|
|
|
// Run any threads which according to the scheduler queue are ready.
|
|
|
|
|
//
|
2021-11-26 15:45:36 -05:00
|
|
|
void run_scheduled_threads();
|
2021-09-10 17:06:07 -04:00
|
|
|
|
|
|
|
|
// Check that the main thread has nothing on the stack
|
|
|
|
|
//
|
|
|
|
|
bool stack_is_clear() const { return lua_gettop(state()) == 0; }
|
|
|
|
|
|
2021-10-14 11:43:16 -04:00
|
|
|
// Set the lthread state.
|
|
|
|
|
//
|
|
|
|
|
// Whenever lua code is running, and ONLY when lua code is running,
|
|
|
|
|
// we store the following information in the world model:
|
|
|
|
|
//
|
|
|
|
|
// * lthread_actor_id: current actor
|
|
|
|
|
// * lthread_place_id: current place
|
|
|
|
|
// * lthread_use_ppool: true if we should use the player ID pool.
|
2021-10-21 13:15:04 -04:00
|
|
|
// * lthread_prints_: a stringstream which will collect 'print' statements.
|
2021-10-14 11:43:16 -04:00
|
|
|
//
|
|
|
|
|
// As soon as the lua code stops executing, these variables are
|
|
|
|
|
// cleared.
|
|
|
|
|
//
|
2021-10-21 13:15:04 -04:00
|
|
|
void clear_lthread_state();
|
2026-02-09 17:03:22 -05:00
|
|
|
void open_lthread_state(int64_t actor_id, int64_t place_id, int64_t thread_id, bool ppool);
|
2021-10-21 13:15:04 -04:00
|
|
|
|
2026-02-09 17:03:22 -05:00
|
|
|
std::ostream *lthread_print_stream() { return <hread_prints_; }
|
|
|
|
|
|
2026-05-26 15:07:42 -04:00
|
|
|
// Send the lthread_prints output to the specified actor.
|
|
|
|
|
//
|
|
|
|
|
// If actor_id == (-1) prints are discarded.
|
|
|
|
|
// If actor_id == (0) prints go to dprint.
|
|
|
|
|
// Anything else, and the prints go to a specific actor.
|
|
|
|
|
//
|
|
|
|
|
void lthread_prints_to_actor(int64_t actor_id);
|
2021-10-14 11:43:16 -04:00
|
|
|
|
2025-01-14 18:37:31 -05:00
|
|
|
// Set a lua global variable.
|
2023-04-10 16:00:47 -04:00
|
|
|
//
|
2025-01-14 18:37:31 -05:00
|
|
|
// The table just stores strings, and the difference transmitter
|
|
|
|
|
// just difference transmits those strings. The strings are meant
|
|
|
|
|
// to be serialized lua data structures, but there is no enforcement
|
|
|
|
|
// of that here.
|
2023-04-10 16:00:47 -04:00
|
|
|
//
|
2025-01-14 18:37:31 -05:00
|
|
|
void set_global(const eng::string &var, std::string_view value);
|
2023-04-10 16:00:47 -04:00
|
|
|
|
2025-01-14 18:37:31 -05:00
|
|
|
// Get a lua global variable.
|
2023-04-10 16:00:47 -04:00
|
|
|
//
|
2025-01-14 18:37:31 -05:00
|
|
|
const eng::string &get_global(const eng::string &var);
|
2023-04-10 16:00:47 -04:00
|
|
|
|
2021-10-14 11:43:16 -04:00
|
|
|
// Allocate a single ID.
|
|
|
|
|
//
|
|
|
|
|
// The rules are as follows:
|
|
|
|
|
// * if lthread_use_ppool is false, uses the global pool.
|
|
|
|
|
// * if lthread_actor_id is not a valid actor id, uses the global pool.
|
|
|
|
|
// * otherwise, uses the player pool of lthread_actor_id.
|
|
|
|
|
//
|
|
|
|
|
int64_t alloc_id_predictable();
|
|
|
|
|
|
2022-05-03 00:36:11 -04:00
|
|
|
// If we're in a probe, generate an error.
|
|
|
|
|
// If we're in a nonauthoritative model, do a nopredict yield.
|
|
|
|
|
// Otherwise, return.
|
|
|
|
|
void guard_blockable(lua_State *L, const char *fn);
|
|
|
|
|
|
|
|
|
|
// If we're in a probe, return.
|
|
|
|
|
// If we're in a nonauthoritative model, do a nopredict yield.
|
|
|
|
|
// Otherwise, return.
|
|
|
|
|
void guard_nopredict(lua_State *L, const char *fn);
|
|
|
|
|
|
2021-10-13 19:41:59 -04:00
|
|
|
private:
|
2022-04-27 16:05:45 -04:00
|
|
|
// Add a thread to the scheduler queue.
|
|
|
|
|
//
|
|
|
|
|
void schedule(int64_t clk, int64_t thid, int64_t plid);
|
|
|
|
|
|
2021-10-13 19:41:59 -04:00
|
|
|
// Store a pointer to a world model into a lua registry.
|
|
|
|
|
//
|
|
|
|
|
static void store_global_pointer(lua_State *L, World *w);
|
|
|
|
|
|
2024-08-28 19:40:23 -04:00
|
|
|
// Invoke the lua_call operation.
|
|
|
|
|
//
|
|
|
|
|
void invoke_lua_call(int64_t actor_id, int64_t place_id, std::string_view datapack);
|
|
|
|
|
|
2021-10-15 14:47:12 -04:00
|
|
|
// Invoke a lua string.
|
|
|
|
|
//
|
2024-09-02 21:48:24 -04:00
|
|
|
void invoke_lua_expr(int64_t actor_id, int64_t place_id, std::string_view datapack);
|
2021-10-15 14:47:12 -04:00
|
|
|
|
2021-10-25 14:47:37 -04:00
|
|
|
// Invoke the flush-prints operation.
|
|
|
|
|
//
|
2023-10-19 19:42:33 -04:00
|
|
|
void invoke_flush_prints(int64_t actor_id, int64_t place_id, std::string_view datapack);
|
2021-11-26 15:45:36 -05:00
|
|
|
|
|
|
|
|
// Invoke the tick operation.
|
|
|
|
|
//
|
2023-10-19 19:42:33 -04:00
|
|
|
void invoke_tick(int64_t actor_id, int64_t place_id, std::string_view datapack);
|
2021-10-25 14:47:37 -04:00
|
|
|
|
2021-12-15 14:18:19 -05:00
|
|
|
// Invoke the lua_source operation.
|
|
|
|
|
//
|
2023-10-19 19:42:33 -04:00
|
|
|
void invoke_lua_source(int64_t actor_id, int64_t place_id, std::string_view datapack);
|
2024-02-27 17:01:26 -05:00
|
|
|
|
|
|
|
|
// Low level spawn thread function.
|
|
|
|
|
//
|
2025-02-26 15:58:12 -05:00
|
|
|
bool spawn(LuaCoreStack &LS0, int64_t actor_id, int64_t place_id, LuaSlot func, int nargs, bool print);
|
2024-02-27 17:01:26 -05:00
|
|
|
|
2021-08-03 11:25:12 -04:00
|
|
|
public:
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
//
|
|
|
|
|
// TESTING SUPPORT
|
|
|
|
|
//
|
|
|
|
|
// The following functions are not designed to be useful for production
|
|
|
|
|
// code, they're designed to be helpful for unit testing.
|
|
|
|
|
//
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
2023-07-24 17:19:25 -04:00
|
|
|
// Clear the animation queue and remove all persistent state.
|
|
|
|
|
//
|
|
|
|
|
void tangible_clear_anim_queue_to_empty(int64_t id);
|
|
|
|
|
|
|
|
|
|
// Clear the animation queue to a reasonable starting position.
|
|
|
|
|
//
|
|
|
|
|
void tangible_clear_plane_and_xyz(int64_t id, const eng::string &plane, const util::DXYZ &xyz);
|
|
|
|
|
|
2021-08-03 11:25:12 -04:00
|
|
|
// Add a 'walkto' animation to the specified tangible.
|
|
|
|
|
//
|
2023-07-24 17:19:25 -04:00
|
|
|
void tangible_walkto(int64_t id, float x, float y);
|
2021-08-03 11:25:12 -04:00
|
|
|
|
2021-08-03 12:40:12 -04:00
|
|
|
// Get the tangible's animation queue as a debug string.
|
|
|
|
|
//
|
2022-02-24 02:17:41 -05:00
|
|
|
eng::string tangible_anim_debug_string(int64_t id) const;
|
2021-08-03 12:40:12 -04:00
|
|
|
|
2021-12-14 12:53:31 -05:00
|
|
|
// Get the tangible's ID Pool as a debug string.
|
|
|
|
|
//
|
2022-02-24 02:17:41 -05:00
|
|
|
eng::string tangible_id_pool_debug_string(int64_t id) const;
|
2021-12-14 12:53:31 -05:00
|
|
|
|
2021-08-03 11:25:12 -04:00
|
|
|
// Get a list of all existing tangibles as a comma-separated string.
|
|
|
|
|
//
|
2022-02-24 02:17:41 -05:00
|
|
|
eng::string tangible_ids_debug_string() const;
|
2021-08-13 17:02:35 -04:00
|
|
|
|
2021-11-16 13:14:59 -05:00
|
|
|
// Get a list of all tangibles near the target as a string.
|
|
|
|
|
//
|
2022-02-24 02:17:41 -05:00
|
|
|
eng::string tangibles_near_debug_string(int64_t actor, int64_t distance);
|
2021-11-16 13:14:59 -05:00
|
|
|
|
2021-08-13 17:02:35 -04:00
|
|
|
// Shows the TID (table ID) of the tables that were numbered.
|
|
|
|
|
// TIDs are in alphabetical order. Any table without a TID
|
|
|
|
|
// shows up as "unknown"
|
|
|
|
|
//
|
2022-02-24 02:17:41 -05:00
|
|
|
eng::string numbered_tables_debug_string() const;
|
2021-08-13 17:02:35 -04:00
|
|
|
|
|
|
|
|
// Paired tables debug string. Shows TID=TID pairs, sorted alphabetically.
|
|
|
|
|
//
|
2022-02-24 02:17:41 -05:00
|
|
|
eng::string paired_tables_debug_string(lua_State *master) const;
|
2021-08-13 17:02:35 -04:00
|
|
|
|
|
|
|
|
// Store a string in the tangible's database.
|
|
|
|
|
//
|
2022-02-24 02:17:41 -05:00
|
|
|
void tangible_set_string(int64_t id, const eng::string &path, const eng::string &value);
|
2021-08-13 17:02:35 -04:00
|
|
|
|
2023-04-05 18:41:03 -04:00
|
|
|
// Copy a from the lua global environment into the tangible's database.
|
|
|
|
|
//
|
|
|
|
|
// This is for unit testing.
|
2021-08-13 17:02:35 -04:00
|
|
|
//
|
2022-02-24 02:17:41 -05:00
|
|
|
void tangible_copy_global(int64_t id, const eng::string &path, const eng::string &global);
|
2021-08-13 17:02:35 -04:00
|
|
|
|
2021-09-09 18:23:17 -04:00
|
|
|
// Pretty-print the entire tangible database and return it as a string.
|
|
|
|
|
//
|
2022-02-24 02:17:41 -05:00
|
|
|
eng::string tangible_pprint(int64_t id) const;
|
2021-07-25 19:22:39 -04:00
|
|
|
|
2021-09-10 17:06:07 -04:00
|
|
|
// Set the tangible's lua class.
|
2021-07-25 19:22:39 -04:00
|
|
|
//
|
2022-02-24 02:17:41 -05:00
|
|
|
void tangible_set_class(int64_t id, const eng::string &c) const;
|
2021-07-25 19:22:39 -04:00
|
|
|
|
2021-09-10 17:06:07 -04:00
|
|
|
// Get the tangible's lua class (returns empty string if none).
|
2021-07-25 19:22:39 -04:00
|
|
|
//
|
2022-02-24 02:17:41 -05:00
|
|
|
eng::string tangible_get_class(int64_t id) const;
|
2021-09-10 17:06:07 -04:00
|
|
|
|
|
|
|
|
public:
|
|
|
|
|
///////////////////////////////////////////////////////////
|
2021-07-25 19:22:39 -04:00
|
|
|
//
|
2025-12-02 18:06:23 -05:00
|
|
|
// difference transmission internals related to table comparison
|
2021-09-10 17:06:07 -04:00
|
|
|
//
|
|
|
|
|
// These routines compare tables in the master lua to the corresponding
|
|
|
|
|
// tables in the synchronous lua. This is a nonrecursive process, because
|
|
|
|
|
// the recursion has already been done during the table enumeration process.
|
|
|
|
|
//
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
2021-11-21 13:35:39 -05:00
|
|
|
void patch_numbered_tables(StreamBuffer *sb, DebugCollector *dbc);
|
2021-09-10 17:06:07 -04:00
|
|
|
void diff_numbered_tables(lua_State *master, StreamBuffer *sb);
|
|
|
|
|
|
2021-11-21 13:35:39 -05:00
|
|
|
void patch_tangible_databases(StreamBuffer *sb, DebugCollector *dbc);
|
2021-09-10 17:06:07 -04:00
|
|
|
void diff_tangible_databases(const IdVector &basis, lua_State *master, StreamBuffer *sb);
|
|
|
|
|
|
2021-11-21 13:35:39 -05:00
|
|
|
void patch_tangible_classes(StreamBuffer *sb, DebugCollector *dbc);
|
2021-09-10 17:06:07 -04:00
|
|
|
void diff_tangible_classes(const IdVector &basis, lua_State *master, StreamBuffer *sb);
|
2021-07-25 19:22:39 -04:00
|
|
|
|
2021-09-09 18:23:17 -04:00
|
|
|
///////////////////////////////////////////////////////////
|
2021-07-25 19:22:39 -04:00
|
|
|
//
|
2025-12-02 18:06:23 -05:00
|
|
|
// Difference transmission internals
|
2021-07-25 19:22:39 -04:00
|
|
|
//
|
2021-09-09 18:23:17 -04:00
|
|
|
///////////////////////////////////////////////////////////
|
2021-07-25 19:22:39 -04:00
|
|
|
|
2021-09-10 17:06:07 -04:00
|
|
|
util::IdVector get_visible_union(int64_t actor_id, World *master);
|
|
|
|
|
|
2021-11-21 13:35:39 -05:00
|
|
|
int64_t patch_actor(StreamBuffer *sb, DebugCollector *dbc);
|
2021-09-09 18:23:17 -04:00
|
|
|
void diff_actor(int64_t actor_id, World *master, StreamBuffer *sb);
|
|
|
|
|
|
2021-11-21 13:35:39 -05:00
|
|
|
void patch_visible(StreamBuffer *sb, DebugCollector *dbc);
|
2021-09-09 18:23:17 -04:00
|
|
|
void diff_visible(const util::IdVector &ids, World *master, StreamBuffer *sb);
|
|
|
|
|
|
2021-11-21 13:35:39 -05:00
|
|
|
void patch_luatabs(StreamBuffer *sb, DebugCollector *dbc);
|
2021-09-09 18:23:17 -04:00
|
|
|
void diff_luatabs(int64_t actor_id, World *master, StreamBuffer *sb);
|
|
|
|
|
|
2021-11-21 13:35:39 -05:00
|
|
|
void patch_tanclass(StreamBuffer *sb, DebugCollector *dbc);
|
2021-09-10 17:06:07 -04:00
|
|
|
void diff_tanclass(int64_t actor_id, World *master, StreamBuffer *sb);
|
|
|
|
|
|
2021-11-21 13:35:39 -05:00
|
|
|
void patch_source(StreamBuffer *sb, DebugCollector *dbc);
|
2021-09-23 12:40:21 -04:00
|
|
|
void diff_source(World *master, StreamBuffer *sb);
|
|
|
|
|
|
2023-04-10 16:00:47 -04:00
|
|
|
void patch_globals(StreamBuffer *sb, DebugCollector *dbc);
|
|
|
|
|
void diff_globals(World *master, StreamBuffer *sb);
|
2025-12-02 18:06:23 -05:00
|
|
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
2021-07-25 19:22:39 -04:00
|
|
|
//
|
2025-12-02 18:06:23 -05:00
|
|
|
// Difference transmission entry point.
|
|
|
|
|
//
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
|
|
int64_t patch(StreamBuffer *sb, DebugCollector *dbc);
|
|
|
|
|
void diff(int64_t actor, bool full, World *master, StreamBuffer *sb);
|
2021-07-25 19:22:39 -04:00
|
|
|
|
2021-08-13 17:02:35 -04:00
|
|
|
public:
|
2021-08-24 10:59:19 -04:00
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
//
|
2021-09-07 14:38:46 -04:00
|
|
|
// world-pairtab: Numbering and pairing of lua tables.
|
2021-08-13 17:02:35 -04:00
|
|
|
//
|
2021-08-31 20:03:33 -04:00
|
|
|
// The following routines pair up tables in the synchronous
|
|
|
|
|
// model with tables in the master model, by assigning matching
|
|
|
|
|
// table numbers. This is not one subroutine but several, because
|
|
|
|
|
// some of the steps happen on the server, some on the client,
|
|
|
|
|
// and so forth.
|
|
|
|
|
//
|
|
|
|
|
// The goal of these routines is to build these data structures:
|
|
|
|
|
//
|
2021-08-13 17:02:35 -04:00
|
|
|
// Table-to-number mapping is stored in registry.tnmap
|
|
|
|
|
// Number-to-table mapping is stored in registry.ntmap
|
2021-08-24 10:59:19 -04:00
|
|
|
//
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
|
|
|
|
2021-08-31 20:03:33 -04:00
|
|
|
// In the synchronous models, number tables recursively.
|
2021-08-24 10:59:19 -04:00
|
|
|
//
|
2021-08-31 20:03:33 -04:00
|
|
|
// This is a simple recursive traversal, which numbers tables.
|
|
|
|
|
// This creates the initial ntmap in the synchronous models.
|
2021-08-13 17:02:35 -04:00
|
|
|
//
|
|
|
|
|
int number_lua_tables(const IdVector &basis);
|
|
|
|
|
|
2021-08-31 20:03:33 -04:00
|
|
|
// Pair tables in the master model to tables in the synch model.
|
2021-08-13 17:02:35 -04:00
|
|
|
//
|
2021-08-31 20:03:33 -04:00
|
|
|
// Recursively walk the master and synchronous model in parallel,
|
|
|
|
|
// copying table numbers from the synchronous ntmap into the master's ntmap.
|
2021-08-13 17:02:35 -04:00
|
|
|
//
|
2021-08-23 23:34:30 -04:00
|
|
|
void pair_lua_tables(const IdVector &basis, lua_State *master);
|
2021-08-13 17:02:35 -04:00
|
|
|
|
2021-08-31 20:03:33 -04:00
|
|
|
// Number previously unpaired tables in the master model.
|
2021-08-13 17:02:35 -04:00
|
|
|
//
|
2021-08-31 20:03:33 -04:00
|
|
|
// This finds every not-yet-numbered table in the master model,
|
|
|
|
|
// and appends these tables to the master's ntmap. Once they're
|
|
|
|
|
// in the ntmap, they can be paired by simply creating new tables
|
|
|
|
|
// in the synchronous model.
|
2021-08-13 17:02:35 -04:00
|
|
|
//
|
2021-08-31 20:03:33 -04:00
|
|
|
int number_remaining_tables(const IdVector &basis, lua_State *master);
|
2021-08-13 17:02:35 -04:00
|
|
|
|
2021-08-31 20:03:33 -04:00
|
|
|
// Create new tables in the synchronous models.
|
|
|
|
|
//
|
|
|
|
|
// Creates new tables in the synchronous model and appends these
|
|
|
|
|
// new tables to the synchronous model's ntmap.
|
2021-08-13 17:02:35 -04:00
|
|
|
//
|
|
|
|
|
void create_new_tables(int n);
|
|
|
|
|
|
2021-08-31 20:03:33 -04:00
|
|
|
// Delete the table numbering.
|
|
|
|
|
//
|
|
|
|
|
// This simply removes registry.tnmap and registry.ntmap
|
|
|
|
|
//
|
|
|
|
|
void unnumber_lua_tables();
|
|
|
|
|
|
2021-07-25 19:22:39 -04:00
|
|
|
private:
|
|
|
|
|
// Type of model
|
2023-03-01 16:07:13 -05:00
|
|
|
WorldType world_type_;
|
2021-07-25 19:22:39 -04:00
|
|
|
|
|
|
|
|
// A lua intepreter with snapshot function.
|
|
|
|
|
//
|
|
|
|
|
LuaSnap lua_snap_;
|
|
|
|
|
|
|
|
|
|
// The Global ID Pool.
|
|
|
|
|
//
|
|
|
|
|
IdGlobalPool id_global_pool_;
|
|
|
|
|
|
|
|
|
|
// Source Database.
|
|
|
|
|
//
|
|
|
|
|
SourceDB source_db_;
|
|
|
|
|
PlaneMap plane_map_;
|
|
|
|
|
|
2023-04-10 16:00:47 -04:00
|
|
|
// Lua Global Variables
|
|
|
|
|
//
|
|
|
|
|
// assign_seqno: sequence number generator for global variable assignments (master and client)
|
|
|
|
|
// gvname_to_serial: global variable name to serialized data. (master and client)
|
|
|
|
|
// gvname_to_seqno: global variable name to sequence number. (master only)
|
|
|
|
|
// seqno_to_gvname: sequence number to global variable name. (master only)
|
|
|
|
|
// gvname_modified: set of global variables recently locally modified. (client only)
|
|
|
|
|
//
|
|
|
|
|
int64_t assign_seqno_;
|
|
|
|
|
eng::map<eng::string, eng::string> gvname_to_serial_;
|
|
|
|
|
eng::map<eng::string, int64_t> gvname_to_seqno_;
|
|
|
|
|
eng::map<int64_t, eng::string> seqno_to_gvname_;
|
|
|
|
|
eng::set<eng::string> gvname_modified_;
|
|
|
|
|
|
2021-07-25 19:22:39 -04:00
|
|
|
// Tangibles table.
|
|
|
|
|
//
|
2022-02-24 02:17:41 -05:00
|
|
|
eng::unordered_map<int64_t, UniqueTangible> tangibles_;
|
2021-07-25 19:22:39 -04:00
|
|
|
|
2021-11-26 15:45:36 -05:00
|
|
|
// Current time.
|
2022-05-03 00:36:11 -04:00
|
|
|
//
|
2021-11-26 15:45:36 -05:00
|
|
|
int64_t clock_;
|
|
|
|
|
|
2021-07-25 19:22:39 -04:00
|
|
|
// Thread schedule: must include every thread, except
|
|
|
|
|
// for the one currently-executing thread.
|
|
|
|
|
//
|
|
|
|
|
Schedule thread_sched_;
|
|
|
|
|
|
2022-05-03 00:36:11 -04:00
|
|
|
// Outstanding HTTP requests, indexed by request ID.
|
|
|
|
|
// Authoritative models only.
|
|
|
|
|
//
|
2022-05-06 13:16:27 -04:00
|
|
|
HttpClientRequestMap http_requests_;
|
2022-05-03 00:36:11 -04:00
|
|
|
|
2021-07-25 19:22:39 -04:00
|
|
|
// Serialized snapshot of world model.
|
2022-05-03 00:36:11 -04:00
|
|
|
//
|
2021-07-25 19:22:39 -04:00
|
|
|
StreamBuffer snapshot_;
|
|
|
|
|
|
|
|
|
|
// Redirects.
|
|
|
|
|
//
|
|
|
|
|
Redirects redirects_;
|
|
|
|
|
|
2026-02-24 22:36:01 -05:00
|
|
|
// Storage for wrapper_get_tangibles_near and wrapper_get_animation_queues.
|
|
|
|
|
// These hold results alive while the driver reads from the raw pointers.
|
|
|
|
|
//
|
|
|
|
|
util::IdVector wrapper_scan_result_;
|
|
|
|
|
util::SharedStdStringVec wrapper_anim_queues_;
|
|
|
|
|
|
2021-10-14 11:43:16 -04:00
|
|
|
// lthread variables: see set_lthread_state for explanation.
|
|
|
|
|
//
|
|
|
|
|
int64_t lthread_actor_id_;
|
|
|
|
|
int64_t lthread_place_id_;
|
2022-04-25 17:17:41 -04:00
|
|
|
int64_t lthread_thread_id_;
|
2021-10-14 11:43:16 -04:00
|
|
|
int64_t lthread_use_ppool_;
|
2026-02-09 17:03:22 -05:00
|
|
|
eng::ostringstream lthread_prints_;
|
2021-10-14 11:43:16 -04:00
|
|
|
|
2021-07-25 19:22:39 -04:00
|
|
|
friend class Tangible;
|
2021-09-07 17:37:23 -04:00
|
|
|
friend int lfn_tangible_animate(lua_State *L);
|
|
|
|
|
friend int lfn_tangible_build(lua_State *L);
|
|
|
|
|
friend int lfn_tangible_redirect(lua_State *L);
|
2021-10-14 11:43:16 -04:00
|
|
|
friend int lfn_tangible_actor(lua_State *L);
|
|
|
|
|
friend int lfn_tangible_place(lua_State *L);
|
2021-11-21 13:35:39 -05:00
|
|
|
friend int lfn_tangible_nopredict(lua_State *L);
|
2021-11-23 16:10:48 -05:00
|
|
|
friend int lfn_tangible_near(lua_State *L);
|
|
|
|
|
friend int lfn_tangible_scan(lua_State *L);
|
2022-07-14 00:57:11 -04:00
|
|
|
friend int lfn_tangible_find(lua_State *L);
|
2022-05-16 14:21:09 -04:00
|
|
|
friend int lfn_tangible_start(lua_State *L);
|
2022-03-31 17:15:15 -04:00
|
|
|
friend int lfn_math_random(lua_State *L);
|
|
|
|
|
friend int lfn_math_randomstate(lua_State *L);
|
2026-01-14 15:07:56 -05:00
|
|
|
friend int lfn_time(lua_State *L);
|
2022-04-25 17:17:41 -04:00
|
|
|
friend int lfn_wait(lua_State *L);
|
|
|
|
|
friend int lfn_nopredict(lua_State *L);
|
2022-06-07 01:54:08 -04:00
|
|
|
friend int lfn_http_request(lua_State *L, const char *method);
|
2023-04-05 18:41:03 -04:00
|
|
|
friend int lfn_global_set(lua_State *L);
|
2021-01-06 15:10:21 -05:00
|
|
|
};
|
|
|
|
|
|
2022-02-25 19:57:23 -05:00
|
|
|
using UniqueWorld = std::unique_ptr<World>;
|