aozhiwei 0768c890a0 1
2023-03-14 10:41:37 +08:00

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);
}