Skip to content

Commit

Permalink
Create objects from scripting
Browse files Browse the repository at this point in the history
Fixes #366
Fixes #2445
  • Loading branch information
tobbi committed Jul 31, 2023
1 parent d08fbc6 commit d3ee694
Show file tree
Hide file tree
Showing 4 changed files with 105 additions and 1 deletion.
8 changes: 7 additions & 1 deletion data/scripts/default.nut
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,11 @@
* and variables you define here can be used in all threads
*/

function add_object(class_name, name, posX, posY, direction = "left", data = "")
{
Level_add_object(class_name, name, posX, posY, direction, data);
}

//Create Level table
Level <- {
finish=Level_finish,
Expand All @@ -13,7 +18,8 @@ Level <- {
set_respawn_pos=Level_set_respawn_pos,
flip_vertically=Level_flip_vertically,
toggle_pause=Level_toggle_pause,
edit=Level_edit
edit=Level_edit,
add_object=add_object
};


Expand Down
29 changes: 29 additions & 0 deletions src/scripting/level.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@
#include "scripting/level.hpp"

#include "supertux/flip_level_transformer.hpp"
#include "supertux/game_object_factory.hpp"
#include "supertux/game_session.hpp"
#include "supertux/sector.hpp"
#include "util/log.hpp"

namespace scripting {

Expand Down Expand Up @@ -79,6 +82,32 @@ Level_toggle_pause()
game_session.toggle_pause();
}

void
Level_add_object(const std::string& class_name, const std::string& name,
int posX, int posY, const std::string& direction,
const std::string& data)
{
SCRIPT_GUARD_GAMESESSION;
auto& sector = game_session.get_current_sector();

if(name.length() == 0)
{
log_fatal << "Object name cannot be empty" << std::endl;
return;
}

if(sector.get_object_by_name<GameObject>(name) != nullptr)
{
log_fatal << "Object with name " << name << " already exists in sector" << std::endl;
return;
}

std::unique_ptr<GameObject> obj =
GameObjectFactory::instance().create(class_name, Vector(posX, posY), string_to_dir(direction), data);
obj->set_name(name);
sector.add_object(std::move(obj));
}

void
Level_edit(bool edit_mode)
{
Expand Down
14 changes: 14 additions & 0 deletions src/scripting/level.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,20 @@ void Level_toggle_pause();
*/
void Level_edit(bool edit_mode);

/**
* Adds a game object to the game
*
* @param class_name GameObject's class
* @param name Name of the created object
* @param posX X position inside the current sector
* @param posY Y position inside the current sector
* @param direction Direction
* @param data Additional data
*/
void Level_add_object(const std::string& class_name, const std::string& name,
int posX, int posY, const std::string& direction,
const std::string& data);

#ifdef DOXYGEN_SCRIPTING
}
#endif
Expand Down
55 changes: 55 additions & 0 deletions src/scripting/wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12471,6 +12471,54 @@ static SQInteger Level_edit_wrapper(HSQUIRRELVM vm)

}

static SQInteger Level_add_object_wrapper(HSQUIRRELVM vm)
{
const SQChar* arg0;
if(SQ_FAILED(sq_getstring(vm, 2, &arg0))) {
sq_throwerror(vm, _SC("Argument 1 not a string"));
return SQ_ERROR;
}
const SQChar* arg1;
if(SQ_FAILED(sq_getstring(vm, 3, &arg1))) {
sq_throwerror(vm, _SC("Argument 2 not a string"));
return SQ_ERROR;
}
SQInteger arg2;
if(SQ_FAILED(sq_getinteger(vm, 4, &arg2))) {
sq_throwerror(vm, _SC("Argument 3 not an integer"));
return SQ_ERROR;
}
SQInteger arg3;
if(SQ_FAILED(sq_getinteger(vm, 5, &arg3))) {
sq_throwerror(vm, _SC("Argument 4 not an integer"));
return SQ_ERROR;
}
const SQChar* arg4;
if(SQ_FAILED(sq_getstring(vm, 6, &arg4))) {
sq_throwerror(vm, _SC("Argument 5 not a string"));
return SQ_ERROR;
}
const SQChar* arg5;
if(SQ_FAILED(sq_getstring(vm, 7, &arg5))) {
sq_throwerror(vm, _SC("Argument 6 not a string"));
return SQ_ERROR;
}

try {
scripting::Level_add_object(arg0, arg1, static_cast<int> (arg2), static_cast<int> (arg3), arg4, arg5);

return 0;

} catch(std::exception& e) {
sq_throwerror(vm, e.what());
return SQ_ERROR;
} catch(...) {
sq_throwerror(vm, _SC("Unexpected exception while executing function 'Level_add_object'"));
return SQ_ERROR;
}

}

} // namespace wrapper
void create_squirrel_instance(HSQUIRRELVM v, scripting::AmbientSound* object, bool setup_releasehook)
{
Expand Down Expand Up @@ -13747,6 +13795,13 @@ void register_supertux_wrapper(HSQUIRRELVM v)
throw SquirrelError(v, "Couldn't register function 'Level_edit'");
}

sq_pushstring(v, "Level_add_object", -1);
sq_newclosure(v, &Level_add_object_wrapper, 0);
sq_setparamscheck(v, SQ_MATCHTYPEMASKSTRING, ".ssb|nb|nss");
if(SQ_FAILED(sq_createslot(v, -3))) {
throw SquirrelError(v, "Couldn't register function 'Level_add_object'");
}

// Register class AmbientSound
sq_pushstring(v, "AmbientSound", -1);
if(sq_newclass(v, SQFalse) < 0) {
Expand Down

0 comments on commit d3ee694

Please sign in to comment.