-
Notifications
You must be signed in to change notification settings - Fork 197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New Command: 2002 - Trigger Event At [x,y] #3183
New Command: 2002 - Trigger Event At [x,y] #3183
Conversation
`@raw 2002, "", UseVarX,x UseVarY,y` Activate an event in map remotely, based on its x and y coordinates. Command made by @MackValentine, I only refactored it to fit the player specifications.
ef8060f
to
006066c
Compare
I tried two days ago to patch the editor back to English. I didn't post about it so you can guess the result... The editor itself was mostly English again but the entire command window stayed Japanese. :/ So this relies on BingShan again to make it usable. Closed Source... Yeah...... The Ui is just Windows Forms. So they are just drag-and-dropped using the Visual Studio Designer. So they can contain anything you want. Though the question is if that is worth the time. Another solution which would be also useful for our editor later is our own open source TPC replacement. (2 commands of 154 done xD) Teaser |
Oh! that's cool! Another question: |
In needed two days to become used to the API and write wrappers so creating the binding code is not too ugly. The script language is chaiscript (https://chaiscript.com/) with some custom modifications by me to make the syntax nicer. The syntax is JavaScript like. But simpler. I will share some code when I found more event commands. Still figuring out some edge cases. Currently this will be a code generator like TPC but I don't see a reason why this shouldn't be executable by the player directly later. Code gen first is good for finding bugs :) |
Example how to add a command (Not too useful yet as code is not released but just so you can see it). Header: #pragma once
#include "event_command.h"
#include "types.h"
namespace EasyScript {
class TriggerEventAt {
public:
TriggerEventAt();
TriggerEventAt X(const chaiscript::Boxed_Value& value);
TriggerEventAt Y(const chaiscript::Boxed_Value& value);
static void Register(chaiscript::ChaiScript& chai, EventCommand::List& commands);
std::shared_ptr<EventCommand> cmd = std::make_shared<EventCommand>();
};
} Source: #include "trigger_event_at.h"
#include "chaiscript/chaiscript.hpp"
#include "dynamic_object.h"
#include "easyscript/event_command.h"
#include <lcf/rpg/eventcommand.h>
EasyScript::TriggerEventAt::TriggerEventAt() {
cmd->SetDefaults(static_cast<EventCommand::Code>(2002), "", { 0, 0, 0, 0 });
}
EasyScript::TriggerEventAt EasyScript::TriggerEventAt::X(const chaiscript::Boxed_Value& value) {
cmd->SetValueAndMode(0, 1, value);
return *this;
}
EasyScript::TriggerEventAt EasyScript::TriggerEventAt::Y(const chaiscript::Boxed_Value& value) {
cmd->SetValueAndMode(2, 3, value);
return *this;
}
void EasyScript::TriggerEventAt::Register(chaiscript::ChaiScript& chai, EventCommand::List& commands) {
chaiscript::ModulePtr m = std::make_shared<chaiscript::Module>();
chaiscript::utility::add_class<TriggerEventAt>(*m, "__cls_TriggerEventAt",
{
chaiscript::constructor<TriggerEventAt()>()
},
{
{chaiscript::fun(&TriggerEventAt::X), "x"},
{chaiscript::fun(&TriggerEventAt::Y), "y"}
}
);
chai.add(m);
chaiscript::dispatch::Dynamic_Object o;
o["trigger"] = chaiscript::var(chaiscript::fun([&](){
auto evt = TriggerEventAt();
commands.push_back(evt.cmd);
return evt;
}));
chai.set_global(chaiscript::var(o), "@map");
} Invocation in the script:
|
Looks interesting. |
yeah currently I'm not auto-generating it. But will do it for most of the simple commands. Still streamlining the syntax a bit. Before: void EasyScript::TriggerEventAt::Register(chaiscript::ChaiScript& chai, EventCommand::List& commands) {
chaiscript::ModulePtr m = std::make_shared<chaiscript::Module>();
chaiscript::utility::add_class<TriggerEventAt>(*m, "__cls_TriggerEventAt",
{
chaiscript::constructor<TriggerEventAt()>()
},
{
{chaiscript::fun(&TriggerEventAt::X), "x"},
{chaiscript::fun(&TriggerEventAt::Y), "y"}
}
);
chai.add(m);
chaiscript::dispatch::Dynamic_Object o;
o["trigger"] = chaiscript::var(chaiscript::fun([&](){
auto evt = TriggerEventAt();
commands.push_back(evt.cmd);
return evt;
}));
chai.set_global(chaiscript::var(o), "@map");
} After: void EasyScript::TriggerEventAt::Register(chaiscript::ChaiScript& chai, EventCommand::List& commands) {
Bind<TriggerEventAt, void, TriggerEventAt()>(
chai, commands,
"TriggerEventAt", "map", "trigger",
&TriggerEventAt::X, "x",
&TriggerEventAt::Y, "y"
);
} |
looking better! Probably the value from user input? 🤔 |
That's the argument passed in to the function
Function X receives number 1 and Function Y receives
|
Okay and I enhanced the API again: The binding API "introspects" now the class to bind everything. Of course will only work for events that are quite "simple" but this is the case for 90% of them ;). Example for TriggerEventAt: Header: #pragma once
#include "easyscript/forward.h"
#include "easyscript/parameter.h"
namespace EasyScript {
class TriggerEventAt {
public:
TriggerEventAt();
std::shared_ptr<EventCommand> cmd = std::make_shared<EventCommand>();
static void Register(chaiscript::ChaiScript& chai, EventCommandList& commands);
static constexpr std::array name = { "TriggerEventAt", "map", "trigger" };
static constexpr const std::array param = std::to_array<Parameter>({
{ "x", 0, 1, 0 },
{ "y", 0, 3, 2 },
});
};
} Source: #include "trigger_event_at.h"
#include "chaiscript/chaiscript.hpp"
#include "easyscript/binding.h"
#include "easyscript/event_command.h"
EasyScript::TriggerEventAt::TriggerEventAt() {
cmd->SetDefaults(static_cast<Code>(2002), "", { 0, 0, 0, 0 });
}
void EasyScript::TriggerEventAt::Register(chaiscript::ChaiScript& chai, EventCommandList& commands) {
BindAuto<TriggerEventAt, void, TriggerEventAt()>(chai, commands);
} More complex example: PlayBgm Header: #pragma once
#include "easyscript/forward.h"
#include "easyscript/parameter.h"
namespace EasyScript {
class PlayBgm {
public:
PlayBgm(StringArg value);
std::shared_ptr<EventCommand> cmd = std::make_shared<EventCommand>();
static void Register(chaiscript::ChaiScript& chai, EventCommandList& commands);
static constexpr std::array name = { "PlayBgm", "music", "play" };
static constexpr const std::array param = std::to_array<Parameter>({
{ "fadein", 0, 0, 4, 1 },
{ "volume", 100, 1, 4, 2 },
{ "tempo", 100, 2, 4, 3 },
{ "balance", 50, 3, 4, 4 }
});
static constexpr const StringParameter string_param = {nullptr, 5, 4, 0};
static std::string FromCommand(const EventCommand& command);
};
} Source: #include "play_bgm.h"
#include "chaiscript/chaiscript.hpp"
#include "easyscript/binding.h"
#include "easyscript/event_command.h"
#include "easyscript/forward.h"
EasyScript::PlayBgm::PlayBgm(StringArg value) {
cmd->SetDefaults(Code::PlayBGM, "", { 0, 100, 100, 50 });
string_param.Set(*cmd, value);
}
void EasyScript::PlayBgm::Register(chaiscript::ChaiScript& chai, EventCommandList& commands) {
BindAuto<PlayBgm, StringArg, PlayBgm(StringArg)>(chai, commands);
BindNamespaceFunctions(
chai, "music",
[&](){
auto evt = PlayBgm(chaiscript::Boxed_Value(std::make_shared<const std::string>("(OFF)")));
commands.push_back(evt.cmd);
return evt;
}, "stop"
);
}
std::string EasyScript::PlayBgm::FromCommand(const EventCommand& command) {
if (string_param.GetMode(command) == 0 && command.string == "(OFF)") {
return "@music.stop";
}
return {};
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is like call event but it checks if the event passes the start conditions and which page should be run so is imo a useful addition.
Not sure if it should be ActivateEventAt or TriggerEventAt but that is only nitpicking.
Btw I would prefer to keep this 2002 cast for now and then do the enum stuff in liblcf in one batch.
(My script stuff will take at least 2-3 months to be usable so is not worth to wait for it 🙈)
@Ghabry We have ways of activating commands right now, So it's no problem aproving those new commands. TriggerEventAt is also a good name! |
efe97d7
to
20b4215
Compare
Going to merge this when the build passed. Note that starting from Player 0.8.1 this command will be subject to "opt-in" for EasyRPG extensions. Please add this to your INI file to be future proof: [Patch]
EasyRPG=1 |
I'm prototyping some enhanced debugging flags and stumbled upon this. SaveEvent::triggered_by_decision_key is set to true, so any condition branch that checks for this, will evaluate to true. Is this wanted? And now for the reason why I looked at this command...: |
You are right, both of these behaviours should not happen (or at least make it possible to configure them). This shows that even simple commands need lots of testing. I'm currently creating a TestGame to test the new commands before doing further inclusion (next one is "Wait for Single Movement" so this doesn't happen again. Sorry :/ |
@raw 2002, "", UseVarX,x UseVarY,y
Activate an event in map remotely, based on its x and y coordinates.
![image](https://private-user-images.githubusercontent.com/45118493/294783464-5b6c4bea-d083-4441-bb3f-0ee023c979c1.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3Mzg4NzQzMjIsIm5iZiI6MTczODg3NDAyMiwicGF0aCI6Ii80NTExODQ5My8yOTQ3ODM0NjQtNWI2YzRiZWEtZDA4My00NDQxLWJiM2YtMGVlMDIzYzk3OWMxLnBuZz9YLUFtei1BbGdvcml0aG09QVdTNC1ITUFDLVNIQTI1NiZYLUFtei1DcmVkZW50aWFsPUFLSUFWQ09EWUxTQTUzUFFLNFpBJTJGMjAyNTAyMDYlMkZ1cy1lYXN0LTElMkZzMyUyRmF3czRfcmVxdWVzdCZYLUFtei1EYXRlPTIwMjUwMjA2VDIwMzM0MlomWC1BbXotRXhwaXJlcz0zMDAmWC1BbXotU2lnbmF0dXJlPWE1Zjc1ZWM1NzQ0MTk3YjU5YmU2Y2IxNDFjNWVhNmY3OThhN2Y5Y2Q0NzhlZjMzNzlhNmZlY2UwNDdmN2YwNjUmWC1BbXotU2lnbmVkSGVhZGVycz1ob3N0In0.yp_CQ7S6_VfHQPqS4ZLMPCGyCWBe0bfkawgGiM3m4uk)
Command made by @MackValentine,
I only refactored it to fit the player specifications.