218 lines
7.4 KiB
C++
218 lines
7.4 KiB
C++
#include "precompile.h"
|
|
|
|
#include "lispenv.h"
|
|
#include "buff.h"
|
|
#include "battledatacontext.h"
|
|
#include "creature.h"
|
|
#include "glmhelper.h"
|
|
|
|
#include "mt/Skill.h"
|
|
#include "mt/SkillNumber.h"
|
|
|
|
class SkillScope : public a8::lisp::GlobalScope
|
|
{
|
|
public:
|
|
|
|
void Init()
|
|
{
|
|
RegisterCProc
|
|
(
|
|
"!getSkillNumber",
|
|
[this] (const a8::lisp::List& params) -> std::shared_ptr<a8::lisp::Value>
|
|
{
|
|
double result = 0;
|
|
if (params->size() != 1) {
|
|
abort();
|
|
}
|
|
a8::lisp::Atom atom = std::any_cast<a8::lisp::Atom>(params->at(0)->value);
|
|
int idx = atom.val;
|
|
result = context_.buff->skill_meta->_number_meta->GetAttrByIdx(idx);
|
|
return std::make_shared<a8::lisp::Value>(a8::lisp::Atom(result));
|
|
});
|
|
RegisterCProc
|
|
(
|
|
"myself.get_hero_atk",
|
|
[this] (const a8::lisp::List& params) -> std::shared_ptr<a8::lisp::Value>
|
|
{
|
|
double result = context_.buff->owner->GetBattleContext()->GetHeroTotalAtk();
|
|
return std::make_shared<a8::lisp::Value>(a8::lisp::Atom(result));
|
|
});
|
|
RegisterCProc
|
|
(
|
|
"myself.get_max_hp",
|
|
[this] (const a8::lisp::List& params) -> std::shared_ptr<a8::lisp::Value>
|
|
{
|
|
double result = context_.buff->owner->GetMaxHP();
|
|
return std::make_shared<a8::lisp::Value>(a8::lisp::Atom(result));
|
|
});
|
|
RegisterCProc
|
|
(
|
|
"caster.get_hero_atk",
|
|
[this] (const a8::lisp::List& params) -> std::shared_ptr<a8::lisp::Value>
|
|
{
|
|
double result = 0.0f;
|
|
if (context_.buff->GetCaster().Get()) {
|
|
context_.buff->GetCaster().Get()->GetBattleContext()->GetHeroTotalAtk();
|
|
}
|
|
return std::make_shared<a8::lisp::Value>(a8::lisp::Atom(result));
|
|
});
|
|
RegisterCProc
|
|
(
|
|
"caster.get_skill_distance",
|
|
[this] (const a8::lisp::List& params) -> std::shared_ptr<a8::lisp::Value>
|
|
{
|
|
double result = 0.0f;
|
|
if (context_.buff->GetCaster().Get()) {
|
|
result = GlmHelper::Norm(context_.buff->owner->context_real_pos -
|
|
context_.buff->owner->GetPos().ToGlmVec3());
|
|
}
|
|
return std::make_shared<a8::lisp::Value>(a8::lisp::Atom(result));
|
|
});
|
|
RegisterCProc
|
|
(
|
|
"caster.get_skill_raycast_distance",
|
|
[this] (const a8::lisp::List& params) -> std::shared_ptr<a8::lisp::Value>
|
|
{
|
|
double result = 0.0f;
|
|
if (context_.buff->GetCaster().Get()) {
|
|
result = context_.buff->GetCaster().Get()->GetSkillRaycastDistance();
|
|
}
|
|
return std::make_shared<a8::lisp::Value>(a8::lisp::Atom(result));
|
|
});
|
|
RegisterCProc
|
|
(
|
|
"caster.get_skill_pos_x",
|
|
[this] (const a8::lisp::List& params) -> std::shared_ptr<a8::lisp::Value>
|
|
{
|
|
double result = 0.0f;
|
|
if (context_.buff->GetCaster().Get()) {
|
|
result = context_.buff->GetCaster().Get()->skill_pos.x;
|
|
}
|
|
return std::make_shared<a8::lisp::Value>(a8::lisp::Atom(result));
|
|
});
|
|
RegisterCProc
|
|
(
|
|
"caster.get_skill_pos_y",
|
|
[this] (const a8::lisp::List& params) -> std::shared_ptr<a8::lisp::Value>
|
|
{
|
|
double result = 0.0f;
|
|
if (context_.buff->GetCaster().Get()) {
|
|
result = context_.buff->GetCaster().Get()->skill_pos.y;
|
|
}
|
|
return std::make_shared<a8::lisp::Value>(a8::lisp::Atom(result));
|
|
});
|
|
RegisterCProc
|
|
(
|
|
"caster.get_skill_pos_z",
|
|
[this] (const a8::lisp::List& params) -> std::shared_ptr<a8::lisp::Value>
|
|
{
|
|
double result = 0.0f;
|
|
if (context_.buff->GetCaster().Get()) {
|
|
result = context_.buff->GetCaster().Get()->skill_pos.z;
|
|
}
|
|
return std::make_shared<a8::lisp::Value>(a8::lisp::Atom(result));
|
|
});
|
|
}
|
|
|
|
float Eval(std::shared_ptr<a8::lisp::Value> expr,
|
|
Buff* buff)
|
|
{
|
|
context_.buff = buff;
|
|
|
|
auto result = a8::lisp::Expr::Eval(expr, shared_from_this());
|
|
|
|
context_.buff = nullptr;
|
|
|
|
if (!result) {
|
|
abort();
|
|
}
|
|
if (!result->IsType(a8::lisp::ValueType::kAtom)) {
|
|
abort();
|
|
}
|
|
auto&& atom = std::any_cast<a8::lisp::Atom>(result->value);
|
|
return atom.val;
|
|
}
|
|
|
|
std::shared_ptr<a8::lisp::Value> Compile(const std::string& script)
|
|
{
|
|
auto expr = a8::lisp::Expr::Compile(script, shared_from_this());
|
|
if (!expr) {
|
|
abort();
|
|
}
|
|
if (!expr->IsType(a8::lisp::ValueType::kList)) {
|
|
abort();
|
|
}
|
|
Transform(nullptr, expr);
|
|
a8::XPrintf("script:%s ast:%s\n", {script, expr->ToXObject().ToJsonStr()});
|
|
return expr;
|
|
}
|
|
|
|
void Transform(std::shared_ptr<a8::lisp::Value> parent_node, std::shared_ptr<a8::lisp::Value> node)
|
|
{
|
|
if (node->IsType(a8::lisp::ValueType::kSymbol)) {
|
|
auto func_call_exprs = std::make_shared<a8::lisp::List::element_type>();
|
|
|
|
auto&& symbol = std::any_cast<a8::lisp::Symbol>(node->value);
|
|
int idx = mt::SkillNumber::GetAttrIdxByName(symbol.name);
|
|
if (idx < 0) {
|
|
abort();
|
|
} else {
|
|
{
|
|
auto cproc = Find("!getSkillNumber");
|
|
if (!cproc) {
|
|
abort();
|
|
}
|
|
if (!cproc->IsType(a8::lisp::ValueType::kCProc)) {
|
|
abort();
|
|
}
|
|
func_call_exprs->push_back(cproc);
|
|
func_call_exprs->push_back
|
|
(std::make_shared<a8::lisp::Value>(a8::lisp::Atom(idx)));
|
|
}
|
|
}
|
|
if (parent_node &&
|
|
parent_node->IsType(a8::lisp::ValueType::kList) &&
|
|
std::any_cast<a8::lisp::List>(parent_node->value)->size() == 1
|
|
) {
|
|
parent_node->Assign(func_call_exprs);
|
|
} else {
|
|
node->Assign(func_call_exprs);
|
|
}
|
|
} else if (node->IsType(a8::lisp::ValueType::kList)) {
|
|
auto list = std::any_cast<a8::lisp::List>(node->value);
|
|
for (auto child_node : *list) {
|
|
Transform(node, child_node);
|
|
}
|
|
}
|
|
}
|
|
|
|
private:
|
|
|
|
struct {
|
|
Buff* buff = nullptr;
|
|
} context_;
|
|
|
|
};
|
|
|
|
void LispEnv::Init()
|
|
{
|
|
skill_env_ = std::make_shared<SkillScope>();
|
|
skill_env_->Init();
|
|
}
|
|
|
|
void LispEnv::UnInit()
|
|
{
|
|
|
|
}
|
|
|
|
std::shared_ptr<a8::lisp::Value> LispEnv::CompileSkillNumberExpr(const std::string& script)
|
|
{
|
|
return skill_env_->Compile(script);
|
|
}
|
|
|
|
float LispEnv::EvalSkillNumberExpr(std::shared_ptr<a8::lisp::Value> expr,
|
|
Buff* buff)
|
|
{
|
|
return skill_env_->Eval(expr, buff);
|
|
}
|