init commit. I should have done it a while ago though

This commit is contained in:
2025-06-23 20:49:20 +10:00
commit b0e5e89126
25 changed files with 910 additions and 0 deletions

58
src/controller.cpp Normal file
View File

@@ -0,0 +1,58 @@
#include "controller.h"
using namespace godot;
void Controller::_bind_methods()
{
ClassDB::bind_method(D_METHOD("get_flags"), &Controller::get_flags);
ClassDB::bind_method(D_METHOD("set_flags","p_flags"), &Controller::set_flags);
ADD_PROPERTY(PropertyInfo(Variant::INT, "flags"), "set_flags", "get_flags");
ClassDB::bind_method(D_METHOD("get_target"), &Controller::get_target);
ClassDB::bind_method(D_METHOD("set_target","p_target"), &Controller::set_target);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "target", PROPERTY_HINT_RESOURCE_TYPE, "Vector2"), "set_target", "get_target");
}
Controller::Controller()
{
flags=0;
target=Vector2(0,0);
}
Controller::~Controller(){}
void Controller::_process(double delta)
{
if (get_multiplayer()->get_unique_id()!=get_multiplayer_authority()) return;
// Kinda janky but this might come in handy later
target=parent->get_global_mouse_position();
}
void Controller::_enter_tree()
{
set_root_path(NodePath("."));
Ref<SceneReplicationConfig> conf=memnew(SceneReplicationConfig);
set_replication_config(conf);
conf->add_property(":flags");
conf->add_property(":target");
}
void Controller::_unhandled_key_input(const Ref<InputEvent> &p_event)
{
if (get_multiplayer()->get_unique_id()!=get_multiplayer_authority()) return;
UtilityFunctions::print("pre ",flags);
//これ嫌い
if (p_event->is_action_pressed("move_up",false,true)) flags|=1;
if (p_event->is_action_released("move_up",true)) flags&=-2;
if (p_event->is_action_pressed("move_down",false,true)) flags|=2;
if (p_event->is_action_released("move_down",true)) flags&=-3;
if (p_event->is_action_pressed("move_left",false,true)) flags|=4;
if (p_event->is_action_released("move_left",true)) flags&=-5;
if (p_event->is_action_pressed("move_right",false,true)) flags|=8;
if (p_event->is_action_released("move_right",true)) flags&=-9;
//Viewport.set_input_as_handled(); // I have no idea how this figures out which input to flag as handled.
}
void Controller::set_flags(const int p_flags) { flags=p_flags; }
int Controller::get_flags() const { return flags; }
void Controller::set_target(const Vector2 p_target) { target=p_target; }
Vector2 Controller::get_target() const { return target; }

34
src/controller.h Normal file
View File

@@ -0,0 +1,34 @@
#ifndef GDCONTROLLER_H
#define GDCONTROLLER_H
#include <godot_cpp/classes/multiplayer_synchronizer.hpp>
// YOU MAY GET MYSTERIOUS "INVALID USE OF INCOMPLETE TYPE" ERRORS IF YOU DO NOT INCLUDE THE THINGS YOU NEED, BECAUSE THEY MIGHT BE BRIEFLY DEFINED IN OTHER THINGS.
#include <godot_cpp/classes/scene_replication_config.hpp>
#include <godot_cpp/classes/multiplayer_api.hpp>
#include <godot_cpp/classes/input_event.hpp>
#include <godot_cpp/classes/canvas_item.hpp>
namespace godot
{
class Controller : public MultiplayerSynchronizer
{
GDCLASS(Controller,MultiplayerSynchronizer)
protected:
static void _bind_methods();
public:
int flags;
Vector2 target;
CanvasItem *parent;
Controller();
~Controller();
void _process(double delta) override;
void _enter_tree() override;
void _unhandled_key_input(const Ref<InputEvent> &p_event);
// Garbage
void set_flags(const int p_flags);
int get_flags() const;
void set_target(const Vector2 p_target);
Vector2 get_target() const;
};
}
#endif

35
src/example.cpp.no Normal file
View File

@@ -0,0 +1,35 @@
#include "example.h"
#include <godot_cpp/core/class_db.hpp>
using namespace godot;
void Example::_bind_methods()
{
ClassDB::bind_method(D_METHOD("get_amplitude"), &Example::get_amplitude);
ClassDB::bind_method(D_METHOD("set_amplitude","p_amplitude"), &Example::set_amplitude);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "amplitude"), "set_amplitude", "get_amplitude");
ClassDB::bind_method(D_METHOD("get_speed"), &Example::get_speed);
ClassDB::bind_method(D_METHOD("set_speed","p_speed"), &Example::set_speed);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed", PROPERTY_HINT_RANGE,"0,20,0.01"), "set_speed", "get_speed");
}
Example::Example()
{
time_passed=0.0;
amplitude=10.0;
speed=1.0;
}
Example::~Example(){}
void Example::_process(double delta)
{
time_passed+=speed*delta;
Vector2 new_position=Vector2(amplitude+(amplitude*sin(time_passed*2.0)),amplitude+(amplitude*cos(time_passed*1.5)));
set_position(new_position);
}
void Example::set_amplitude(const double p_amplitude) { amplitude=p_amplitude; }
double Example::get_amplitude() const { return amplitude; }
void Example::set_speed(const double p_speed) { speed=p_speed; }
double Example::get_speed() const { return speed; }

28
src/example.h.no Normal file
View File

@@ -0,0 +1,28 @@
#ifndef GDEXAMPLE_H
#define GDEXAMPLE_H
#include <godot_cpp/classes/sprite2d.hpp>
namespace godot
{
class Example : public Sprite2D
{
GDCLASS(Example, Sprite2D)
private:
double time_passed;
double amplitude;
double speed;
protected:
static void _bind_methods();
public:
Example();
~Example();
void _process(double delta) override;
void set_amplitude(const double p_amplitude);
double get_amplitude() const;
void set_speed(const double p_speed);
double get_speed() const;
};
}
#endif

45
src/game.cpp Normal file
View File

@@ -0,0 +1,45 @@
#include "game.h"
#include <godot_cpp/core/class_db.hpp>
using namespace godot;
void Game::_bind_methods()
{
ClassDB::bind_method(D_METHOD("start","players"),&Game::start);
ClassDB::bind_method(D_METHOD("kyaraspawn","data"),&Game::kyaraspawn);
}
Game::Game()
{
spawn=memnew(MultiplayerSpawner);
spawn->set_name("_spawn");
spawn->set_spawn_function(callable_mp(this, &Game::kyaraspawn));
spawn->set_spawn_path("..");
add_child(spawn,false,INTERNAL_MODE_BACK);
}
Game::~Game(){}
void Game::start(const Dictionary &players)
{
show();
if (get_multiplayer()->get_unique_id()!=1) return;
Array keys=players.keys();
for (int i=0; i<keys.size(); i++)
{
static_cast<Dictionary>(players[keys[i]])["pid"]=keys[i];
UtilityFunctions::print(get_multiplayer()->get_unique_id()," ",keys[i]," ",players[keys[i]]," ",static_cast<Dictionary>(players[keys[i]])["name"]);
spawn->spawn(players[keys[i]]);
}
}
Node* Game::kyaraspawn(const Variant &data)
{
Dictionary dat=static_cast<Dictionary>(data);
UtilityFunctions::print(get_multiplayer()->get_unique_id()," ",data);
Character* kya=memnew(Character);
kya->set_name(dat["name"]);
kya->multiplayerowner=dat["pid"];
kya->set_position(Vector2(50,50));
kya->set_texture(ImageTexture::create_from_image(Image::load_from_file("res://icon.svg")));
return kya;
}

29
src/game.h Normal file
View File

@@ -0,0 +1,29 @@
#ifndef GDGAME_H
#define GDGAME_H
#include <godot_cpp/classes/node2d.hpp>
#include "kyara.h"
#include <godot_cpp/classes/multiplayer_api.hpp>
#include <godot_cpp/classes/multiplayer_spawner.hpp>
#include <godot_cpp/classes/image_texture.hpp>
#include <godot_cpp/classes/image.hpp>
namespace godot
{
class Game : public Node2D
{
GDCLASS(Game, Node2D)
private:
MultiplayerSpawner *spawn;
protected:
static void _bind_methods();
public:
Game();
~Game();
void start(const Dictionary &players);
Node* kyaraspawn(const Variant &data);
};
}
#endif

81
src/kyara.cpp Normal file
View File

@@ -0,0 +1,81 @@
#include "kyara.h"
#include <godot_cpp/core/class_db.hpp>
using namespace godot;
void Character::_bind_methods()
{
ClassDB::bind_method(D_METHOD("get_balance_radius"), &Character::get_balance_radius);
ClassDB::bind_method(D_METHOD("set_balance_radius","p_balance_radius"), &Character::set_balance_radius);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "balance_radius"), "set_balance_radius", "get_balance_radius");
ClassDB::bind_method(D_METHOD("get_speed"), &Character::get_speed);
ClassDB::bind_method(D_METHOD("set_speed","p_speed"), &Character::set_speed);
ADD_PROPERTY(PropertyInfo(Variant::FLOAT, "speed", PROPERTY_HINT_RANGE,"0,20,0.01"), "set_speed", "get_speed");
ClassDB::bind_method(D_METHOD("get_texture"), &Character::get_texture);
ClassDB::bind_method(D_METHOD("set_texture","p_texture"), &Character::set_texture);
ADD_PROPERTY(PropertyInfo(Variant::OBJECT, "texture", PROPERTY_HINT_RESOURCE_TYPE, "Texture2D"), "set_texture", "get_texture");
}
Character::Character()
{
set_motion_mode(MOTION_MODE_FLOATING);
speed=1.0;
balance_radius=64.0;
face=memnew(Sprite2D);
face->set_name("_face");
add_child(face,false,INTERNAL_MODE_BACK);
input=memnew(Controller);
input->set_name("_input");
input->parent=this;
add_child(input,false,INTERNAL_MODE_BACK);
sync=memnew(MultiplayerSynchronizer);
sync->set_name("_sync");
add_child(sync,false,INTERNAL_MODE_BACK);
shape=memnew(CollisionShape2D);
shape->set_name("_shape");
add_child(shape,false,INTERNAL_MODE_BACK);
}
Character::~Character(){}
void Character::_process(double delta)
{
// これも嫌い
if (input->flags&1) move(0.0,-speed);
if (input->flags&2) move(0.0,speed);
if (input->flags&4) move(-speed,0.0);
if (input->flags&8) move(speed,0.0);
look_at(input->target);
// Not sure if I should do this. Issues could occur if I'm wrong either side.
//CharacterBody2D::_process(delta);
}
void Character::_ready()
{
set_motion_mode(MOTION_MODE_FLOATING);
}
void Character::_enter_tree()
{
Ref<SceneReplicationConfig> conf=memnew(SceneReplicationConfig);
conf->add_property(":rotation");
conf->add_property(":position");
sync->set_replication_config(conf);
input->set_multiplayer_authority(multiplayerowner);
}
void Character::move(double x,double y)
{
// Collision detection needs to go in here, as well as adjusting and displaying balance radius, buncha shit
set_position(get_position()+Vector2(x,y));
}
void Character::set_balance_radius(const double p_balance_radius) { balance_radius=p_balance_radius; }
double Character::get_balance_radius() const { return balance_radius; }
void Character::set_speed(const double p_speed) { speed=p_speed; }
double Character::get_speed() const { return speed; }
void Character::set_texture(const Ref<Texture2D> &p_texture) { face->set_texture(p_texture); }
Ref<Texture2D> Character::get_texture() const { return face->get_texture(); }

51
src/kyara.h Normal file
View File

@@ -0,0 +1,51 @@
#ifndef GDKYARA_H
#define GDKYARA_H
#include <godot_cpp/classes/character_body2d.hpp>
// Children:
#include "controller.h"
#include <godot_cpp/classes/collision_shape2d.hpp>
#include <godot_cpp/classes/sprite2d.hpp>
#include <godot_cpp/classes/multiplayer_synchronizer.hpp>
// Grandchildren:
#include <godot_cpp/classes/circle_shape2d.hpp>
// YOU MAY GET MYSTERIOUS "INVALID USE OF INCOMPLETE TYPE" ERRORS IF YOU DO NOT INCLUDE THE THINGS YOU NEED, BECAUSE THEY MIGHT BE BRIEFLY DEFINED IN OTHER THINGS.
#include <godot_cpp/classes/scene_replication_config.hpp>
namespace godot
{
class Character : public CharacterBody2D
{
GDCLASS(Character, CharacterBody2D)
private:
double speed;
double balance_radius;
void move(double x,double y);
Sprite2D *face;
Controller *input;
MultiplayerSynchronizer *sync;
CollisionShape2D *shape;
protected:
static void _bind_methods();
public:
Character();
~Character();
void _process(double delta) override;
void _ready() override;
void _enter_tree() override;
int multiplayerowner;
// Garbage
void set_balance_radius(const double p_balance_radius);
double get_balance_radius() const;
void set_speed(const double p_speed);
double get_speed() const;
// This garbage ripped straight from sprite2d because I basically just want to pass it through.
// I don't really need to (I can just make the sprite public) but it's good practice
// (By good practice I mean this cost me at least an hour of debugging const Ref<>)
void set_texture(const Ref<Texture2D> &p_texture);
Ref<Texture2D> get_texture() const;
};
}
#endif

9
src/nodespawner.cpp Normal file
View File

@@ -0,0 +1,9 @@
#include "nodespawner.h"
#include <godot_cpp/core/class_db.hpp>
using namespace godot;
void NodeSpawner::_bind_methods()
{
}

21
src/nodespawner.h Normal file
View File

@@ -0,0 +1,21 @@
#ifndef GDNODESPAWNER_H
#define GDNODESPAWNER_H
#include <godot_cpp/classes/multiplayer_spawner.hpp>
// Probably won't need this.
//#include <godot_cpp/classes/multiplayer_api.hpp>
namespace godot
{
class NodeSpawner : public MultiplayerSpawner
{
GDCLASS(NodeSpawner,MultiplayerSpawner)
private:
String *spawnable_nodes;
protected:
static void _bind_methods();
public:
};
}
#endif

37
src/register_types.cpp Normal file
View File

@@ -0,0 +1,37 @@
#include "register_types.h"
#include "kyara.h"
#include "controller.h"
#include "game.h"
#include "nodespawner.h"
#include <gdextension_interface.h>
#include <godot_cpp/core/defs.hpp>
#include <godot_cpp/godot.hpp>
using namespace godot;
void initialize_character_module(ModuleInitializationLevel p_level)
{
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { return; }
GDREGISTER_RUNTIME_CLASS(Character);
GDREGISTER_RUNTIME_CLASS(Controller);
GDREGISTER_RUNTIME_CLASS(Game);
GDREGISTER_RUNTIME_CLASS(NodeSpawner);
}
void uninitialize_character_module(ModuleInitializationLevel p_level) {
if (p_level != MODULE_INITIALIZATION_LEVEL_SCENE) { return; }
}
extern "C"
{
GDExtensionBool GDE_EXPORT character_library_init(GDExtensionInterfaceGetProcAddress p_get_proc_address, const GDExtensionClassLibraryPtr p_library, GDExtensionInitialization *r_initialization)
{
godot::GDExtensionBinding::InitObject init_obj(p_get_proc_address, p_library, r_initialization);
init_obj.register_initializer(initialize_character_module);
init_obj.register_terminator(uninitialize_character_module);
init_obj.set_minimum_library_initialization_level(MODULE_INITIALIZATION_LEVEL_SCENE);
return init_obj.init();
}
}

10
src/register_types.h Normal file
View File

@@ -0,0 +1,10 @@
#ifndef CHARACTER_REGISTER_TYPES_H
#define CHARACTER_REGISTER_TYPES_H
#include <godot_cpp/core/class_db.hpp>
using namespace godot;
void initialize_character_module(ModuleInitializationLevel p_level);
void uninitialize_character_module(ModuleInitializationLevel p_level);
#endif