forked from townforge/townforge
make if in scripts more generic, and allow an else branch too
This commit is contained in:
parent
867e9b359f
commit
5474600c6a
@ -187,14 +187,6 @@ static void print_action_string(const Action &a, std::string &source, const std:
|
||||
{
|
||||
std::string I(base_indent);
|
||||
std::string s;
|
||||
if (!a.conditions.empty())
|
||||
{
|
||||
source += I + "if (";
|
||||
for (const Expression &e: a.conditions)
|
||||
source += get_expression_string(e);
|
||||
source += ")\n";
|
||||
I += base_indent;
|
||||
}
|
||||
switch (a.type)
|
||||
{
|
||||
case action_none:
|
||||
@ -251,6 +243,42 @@ static void print_action_string(const Action &a, std::string &source, const std:
|
||||
CHECK_AND_ASSERT_THROW_MES(!a.str.empty(), "Expected a string for action_storyline_event");
|
||||
source += I + "storyline event \"" + escape(a.str) + "\"\n";
|
||||
break;
|
||||
case action_if:
|
||||
{
|
||||
source += I + "if (";
|
||||
for (const Expression &e: a.conditions)
|
||||
source += get_expression_string(e);
|
||||
source += ") {\n";
|
||||
bool has_else = false;
|
||||
for (const auto &e: a.actions)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(e.weight.type == op_unsigned, "Unexpected type in if action weight");
|
||||
if (e.weight.data != 1)
|
||||
{
|
||||
has_else = true;
|
||||
continue;
|
||||
}
|
||||
std::string s;
|
||||
print_action_string(e.action, s, base_indent, indent);
|
||||
source += I + s;
|
||||
}
|
||||
source += I + "}\n";
|
||||
if (has_else)
|
||||
{
|
||||
source += I + "else {\n";
|
||||
for (const auto &e: a.actions)
|
||||
{
|
||||
CHECK_AND_ASSERT_THROW_MES(e.weight.type == op_unsigned, "Unexpected type in if action weight");
|
||||
if (e.weight.data != 0)
|
||||
continue;
|
||||
std::string s;
|
||||
print_action_string(e.action, s, base_indent, indent);
|
||||
source += I + s;
|
||||
}
|
||||
source += I + "}\n";
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1223,12 +1251,6 @@ static bool execute(cryptonote::cc_command_t cmd, BlockchainStateProxy &proxy, g
|
||||
if (action.type == action_none)
|
||||
return true;
|
||||
|
||||
for (const Expression &e: action.conditions)
|
||||
{
|
||||
if (!is_condition_true(proxy, e, account, owner, city, seed, salt))
|
||||
return true;
|
||||
}
|
||||
|
||||
cryptonote::cc_account_data_t ad;
|
||||
const auto value_signed = action.ops.empty() || action.ops[0].type == op_none ? std::make_pair<uint64_t, bool>(0, false) : get_attribute(proxy, action.ops[0], account, owner, city, seed, salt);
|
||||
const uint64_t value = value_signed.first;
|
||||
@ -1367,6 +1389,19 @@ static bool execute(cryptonote::cc_command_t cmd, BlockchainStateProxy &proxy, g
|
||||
case action_storyline_event:
|
||||
events.add(cmd, account) << "Storyline event: " << action.str;
|
||||
break;
|
||||
case action_if:
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(action.conditions.size() == 1, false, "If action should have one condition");
|
||||
CHECK_AND_ASSERT_MES(!action.actions.empty(), false, "If action should not be empty");
|
||||
const uint64_t branch = is_condition_true(proxy, action.conditions[0], account, owner, city, seed, salt) ? 1 : 0;
|
||||
for (const auto &a: action.actions)
|
||||
{
|
||||
CHECK_AND_ASSERT_MES(a.weight.type == op_unsigned, false, "Unexpected type in if action");
|
||||
if (a.weight.data == branch && !execute(cmd, proxy, events, script, account, owner, city, a.action, seed, salt))
|
||||
return false;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -159,6 +159,7 @@ typedef enum ActionType
|
||||
action_set_player_variable,
|
||||
action_set_local_variable,
|
||||
action_storyline_event,
|
||||
action_if,
|
||||
} ActionType;
|
||||
static const struct
|
||||
{
|
||||
@ -178,6 +179,7 @@ static const struct
|
||||
{ "set player variable", action_set_player_variable },
|
||||
{ "set local variable", action_set_local_variable },
|
||||
{ "storyline_event", action_storyline_event },
|
||||
{ "if", action_if },
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
@ -381,16 +383,16 @@ typedef cc::script::Script Script;
|
||||
struct script_partial_state_t
|
||||
{
|
||||
std::vector<Operand> operands;
|
||||
std::vector<Expression> expressions;
|
||||
std::vector<std::vector<Expression>> expressions;
|
||||
std::vector<WeightedAction> actions;
|
||||
uint32_t pick;
|
||||
std::vector<uint32_t> action_group_count;
|
||||
State state;
|
||||
Choice choice;
|
||||
bool use_choice_reserves;
|
||||
|
||||
Script *script;
|
||||
|
||||
script_partial_state_t(): pick(0), use_choice_reserves(false), script(new Script()) { }
|
||||
script_partial_state_t(): use_choice_reserves(false), script(new Script()) { expressions.push_back({}); }
|
||||
~script_partial_state_t() { delete script; }
|
||||
};
|
||||
|
||||
@ -423,9 +425,12 @@ void set_partial_state_public(script_partial_state_t *state);
|
||||
void set_partial_state_override_string(script_partial_state_t *state, uint32_t n, const char *text);
|
||||
void set_partial_state_override_local(script_partial_state_t *state, const char *text, uint32_t n);
|
||||
void set_partial_state_action(script_partial_state_t *state, ActionType type, const char *str, unsigned num_ops);
|
||||
void set_partial_state_action_pick_count_up(script_partial_state_t *state);
|
||||
void set_partial_state_action_add_action_group_count(script_partial_state_t *state);
|
||||
void set_partial_state_action_inc_action_group_count(script_partial_state_t *state);
|
||||
void set_partial_state_action_set_weight(script_partial_state_t *state);
|
||||
void set_partial_state_action_pick(script_partial_state_t *state);
|
||||
void set_partial_state_action_if(script_partial_state_t *state);
|
||||
void set_partial_state_action_else(script_partial_state_t *state);
|
||||
void set_partial_state_action_percent(script_partial_state_t *state);
|
||||
void set_partial_state_state_init_actions(script_partial_state_t *state);
|
||||
void set_partial_state_state_text(script_partial_state_t *state, const char *str);
|
||||
|
@ -171,13 +171,13 @@ void set_partial_state_binary_expression(script_partial_state_t *state, Function
|
||||
e.op1 = state->operands[n_ops - 1];
|
||||
state->operands.pop_back();
|
||||
state->operands.pop_back();
|
||||
state->expressions.push_back(std::move(e));
|
||||
state->expressions.back().push_back(std::move(e));
|
||||
}
|
||||
|
||||
void set_partial_state_binary_compound_expression(script_partial_state_t *state, FunctionType type)
|
||||
{
|
||||
MDEBUG("compound expression: " << get_function_name(type));
|
||||
if (state->expressions.size() < 2)
|
||||
if (state->expressions.back().size() < 2)
|
||||
{
|
||||
tfscript_error("Binary compound expression needs at least two expressions");
|
||||
return;
|
||||
@ -185,18 +185,18 @@ void set_partial_state_binary_compound_expression(script_partial_state_t *state,
|
||||
Expression e;
|
||||
e.function = type;
|
||||
|
||||
const size_t n_ops = state->expressions.size();
|
||||
e.expressions.push_back(state->expressions[n_ops - 2]);
|
||||
e.expressions.push_back(state->expressions[n_ops - 1]);
|
||||
state->expressions.pop_back();
|
||||
state->expressions.pop_back();
|
||||
state->expressions.push_back(std::move(e));
|
||||
const size_t n_ops = state->expressions.back().size();
|
||||
e.expressions.push_back(state->expressions.back()[n_ops - 2]);
|
||||
e.expressions.push_back(state->expressions.back()[n_ops - 1]);
|
||||
state->expressions.back().pop_back();
|
||||
state->expressions.back().pop_back();
|
||||
state->expressions.back().push_back(std::move(e));
|
||||
}
|
||||
|
||||
void set_partial_state_unary_expression(script_partial_state_t *state, FunctionType type)
|
||||
{
|
||||
MDEBUG("expression: " << get_function_name(type));
|
||||
if (state->expressions.size() < 1)
|
||||
if (state->expressions.back().size() < 1)
|
||||
{
|
||||
tfscript_error("Unary expression needs at least one expression");
|
||||
return;
|
||||
@ -204,9 +204,9 @@ void set_partial_state_unary_expression(script_partial_state_t *state, FunctionT
|
||||
Expression e;
|
||||
e.function = type;
|
||||
|
||||
e.expressions.push_back(std::move(state->expressions.back()));
|
||||
state->expressions.pop_back();
|
||||
state->expressions.push_back(std::move(e));
|
||||
e.expressions.push_back(std::move(state->expressions.back().back()));
|
||||
state->expressions.back().pop_back();
|
||||
state->expressions.back().push_back(std::move(e));
|
||||
}
|
||||
|
||||
void set_partial_state_unary_predicate(script_partial_state_t *state, FunctionType type)
|
||||
@ -222,13 +222,13 @@ void set_partial_state_unary_predicate(script_partial_state_t *state, FunctionTy
|
||||
|
||||
e.op0 = state->operands.back();
|
||||
state->operands.pop_back();
|
||||
state->expressions.push_back(std::move(e));
|
||||
state->expressions.back().push_back(std::move(e));
|
||||
}
|
||||
|
||||
void set_partial_state_ternary(script_partial_state_t *state)
|
||||
{
|
||||
MDEBUG("ternary");
|
||||
if (state->expressions.size() < 1)
|
||||
if (state->expressions.back().size() < 1)
|
||||
{
|
||||
tfscript_error("Ternary expression needs at least one expression");
|
||||
return;
|
||||
@ -240,8 +240,8 @@ void set_partial_state_ternary(script_partial_state_t *state)
|
||||
}
|
||||
Operand op;
|
||||
op.type = op_cond;
|
||||
op.expr.push_back(state->expressions[state->expressions.size() - 1]);
|
||||
state->expressions.pop_back();
|
||||
op.expr.push_back(state->expressions.back()[state->expressions.back().size() - 1]);
|
||||
state->expressions.back().pop_back();
|
||||
op.ops.push_back(state->operands[state->operands.size() - 2]);
|
||||
op.ops.push_back(state->operands[state->operands.size() - 1]);
|
||||
state->operands.pop_back();
|
||||
@ -252,15 +252,15 @@ void set_partial_state_ternary(script_partial_state_t *state)
|
||||
void set_partial_state_precondition(script_partial_state_t *state, const char *text)
|
||||
{
|
||||
MDEBUG("precondition");
|
||||
if (state->expressions.size() < 1)
|
||||
if (state->expressions.back().size() < 1)
|
||||
{
|
||||
tfscript_error("Precondition needs at least one condition");
|
||||
return;
|
||||
}
|
||||
state->script->preconditions.push_back(std::move(state->expressions.back()));
|
||||
state->script->preconditions.push_back(std::move(state->expressions.back().back()));
|
||||
if (text)
|
||||
state->script->preconditions.back().text = text;
|
||||
state->expressions.pop_back();
|
||||
state->expressions.back().pop_back();
|
||||
}
|
||||
|
||||
void set_partial_state_name(script_partial_state_t *state, const char *s)
|
||||
@ -367,14 +367,19 @@ void set_partial_state_action(script_partial_state_t *state, ActionType type, co
|
||||
a.ops.push_back(std::move(state->operands[state->operands.size() - num_ops + i]));
|
||||
for (unsigned int i = 0; i < num_ops; ++i)
|
||||
state->operands.pop_back();
|
||||
a.conditions = std::move(state->expressions);
|
||||
state->expressions.clear();
|
||||
}
|
||||
|
||||
void set_partial_state_action_pick_count_up(script_partial_state_t *state)
|
||||
void set_partial_state_action_add_action_group_count(script_partial_state_t *state)
|
||||
{
|
||||
MDEBUG("pick one");
|
||||
++state->pick;
|
||||
MDEBUG("add action group count");
|
||||
state->action_group_count.push_back(0);
|
||||
state->expressions.push_back({});
|
||||
}
|
||||
|
||||
void set_partial_state_action_inc_action_group_count(script_partial_state_t *state)
|
||||
{
|
||||
MDEBUG("inc action group count");
|
||||
++state->action_group_count.back();
|
||||
}
|
||||
|
||||
void set_partial_state_action_set_weight(script_partial_state_t *state)
|
||||
@ -397,27 +402,99 @@ void set_partial_state_action_set_weight(script_partial_state_t *state)
|
||||
void set_partial_state_action_pick(script_partial_state_t *state)
|
||||
{
|
||||
MDEBUG("pick");
|
||||
if (state->pick == 0)
|
||||
if (state->actions.empty())
|
||||
{
|
||||
tfscript_error("Pick action requires at least one action");
|
||||
tfscript_error("Pick actions is empty");
|
||||
return;
|
||||
}
|
||||
if (state->actions.size() < state->pick)
|
||||
const uint32_t group_count = state->action_group_count.back();
|
||||
state->action_group_count.pop_back();
|
||||
if (state->actions.size() < group_count)
|
||||
{
|
||||
tfscript_error("Pick action found fewer actions than needed");
|
||||
return;
|
||||
}
|
||||
state->actions.insert(state->actions.begin() + state->actions.size() - state->pick, WeightedAction{});
|
||||
Action &pick = state->actions[state->actions.size() - 1 - state->pick].action;
|
||||
for (uint32_t i = 0; i < state->pick; ++i)
|
||||
{
|
||||
pick.actions.push_back(std::move(state->actions.back()));
|
||||
state->actions.insert(state->actions.begin() + state->actions.size() - group_count, WeightedAction{});
|
||||
Action &pick = state->actions[state->actions.size() - 1 - group_count].action;
|
||||
for (uint32_t i = 0; i < group_count; ++i)
|
||||
pick.actions.push_back(std::move(state->actions[state->actions.size() - group_count + i]));
|
||||
for (uint32_t i = 0; i < group_count; ++i)
|
||||
state->actions.pop_back();
|
||||
}
|
||||
pick.type = action_pick;
|
||||
state->pick = 0;
|
||||
pick.conditions = std::move(state->expressions);
|
||||
state->expressions.clear();
|
||||
if (!state->expressions.back().empty())
|
||||
pick.conditions.push_back(std::move(state->expressions.back().back()));
|
||||
state->expressions.pop_back();
|
||||
}
|
||||
|
||||
void set_partial_state_action_if(script_partial_state_t *state)
|
||||
{
|
||||
MDEBUG("if");
|
||||
if (state->actions.empty())
|
||||
{
|
||||
tfscript_error("If action is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t group_count = state->action_group_count.back();
|
||||
state->action_group_count.pop_back();
|
||||
if (state->actions.size() < group_count)
|
||||
{
|
||||
tfscript_error("If action found fewer actions than needed");
|
||||
return;
|
||||
}
|
||||
|
||||
state->actions.insert(state->actions.begin() + state->actions.size() - group_count, WeightedAction{});
|
||||
Action &a = state->actions[state->actions.size() - 1 - group_count].action;
|
||||
for (uint32_t i = 0; i < group_count; ++i)
|
||||
{
|
||||
a.actions.push_back(std::move(state->actions[state->actions.size() - group_count + i]));
|
||||
a.actions.back().weight.type = op_unsigned;
|
||||
a.actions.back().weight.data = 1;
|
||||
}
|
||||
for (uint32_t i = 0; i < group_count; ++i)
|
||||
state->actions.pop_back();
|
||||
a.type = action_if;
|
||||
if (state->expressions.back().empty())
|
||||
{
|
||||
tfscript_error("If action has no expression");
|
||||
return;
|
||||
}
|
||||
a.conditions.push_back(std::move(state->expressions.back().back()));
|
||||
state->expressions.pop_back();
|
||||
}
|
||||
|
||||
void set_partial_state_action_else(script_partial_state_t *state)
|
||||
{
|
||||
MDEBUG("else");
|
||||
if (state->actions.empty())
|
||||
{
|
||||
tfscript_error("Else action is empty");
|
||||
return;
|
||||
}
|
||||
|
||||
const uint32_t group_count = state->action_group_count.back();
|
||||
state->action_group_count.pop_back();
|
||||
if (state->actions.size() < group_count)
|
||||
{
|
||||
tfscript_error("Else action found fewer actions than needed");
|
||||
return;
|
||||
}
|
||||
|
||||
Action &a = state->actions[state->actions.size() - 1 - group_count].action;
|
||||
if (a.type != action_if)
|
||||
{
|
||||
tfscript_error("Else does not match the expected if");
|
||||
return;
|
||||
}
|
||||
for (uint32_t i = 0; i < group_count; ++i)
|
||||
{
|
||||
a.actions.push_back(std::move(state->actions[state->actions.size() - group_count + i]));
|
||||
a.actions.back().weight.type = op_unsigned;
|
||||
a.actions.back().weight.data = 0;
|
||||
}
|
||||
for (uint32_t i = 0; i < group_count; ++i)
|
||||
state->actions.pop_back();
|
||||
state->expressions.pop_back();
|
||||
}
|
||||
|
||||
void set_partial_state_action_percent(script_partial_state_t *state)
|
||||
@ -440,8 +517,6 @@ void set_partial_state_action_percent(script_partial_state_t *state)
|
||||
percent.actions[0].weight = std::move(state->operands.back());
|
||||
state->actions.pop_back();
|
||||
state->operands.pop_back();
|
||||
percent.conditions = std::move(state->expressions);
|
||||
state->expressions.clear();
|
||||
}
|
||||
|
||||
void set_partial_state_state_init_actions(script_partial_state_t *state)
|
||||
@ -502,14 +577,14 @@ void set_partial_state_choice_selected_text(script_partial_state_t *state, const
|
||||
void set_partial_state_choice_enabled(script_partial_state_t *state)
|
||||
{
|
||||
MDEBUG("choice condition");
|
||||
if (state->expressions.size() < 1)
|
||||
if (state->expressions.back().size() < 1)
|
||||
{
|
||||
tfscript_error("Choice condition requires at least one condition");
|
||||
return;
|
||||
}
|
||||
auto &c = state->expressions.back();
|
||||
auto &c = state->expressions.back().back();
|
||||
state->choice.enabled.push_back(std::move(c));
|
||||
state->expressions.pop_back();
|
||||
state->expressions.back().pop_back();
|
||||
}
|
||||
|
||||
void set_partial_state_choice_actions(script_partial_state_t *state)
|
||||
@ -557,7 +632,9 @@ void finalize_partial_state(script_partial_state_t **state)
|
||||
{
|
||||
MDEBUG("finalizing state");
|
||||
if (!(*state)->operands.empty()) tfscript_error("Not all operands were used up: " + std::to_string((*state)->operands.size()) + " leftover");
|
||||
if (!(*state)->expressions.empty()) tfscript_error("Not all expressions were used up: " + std::to_string((*state)->expressions.size()) + " leftover");
|
||||
if (!(*state)->expressions.back().empty()) tfscript_error("Not all expressions were used up: " + std::to_string((*state)->expressions.back().size()) + " leftover");
|
||||
(*state)->expressions.pop_back();
|
||||
if (!(*state)->expressions.empty()) tfscript_error("Not all expressions levels were popped: " + std::to_string((*state)->expressions.size()) + " leftover");
|
||||
if (!(*state)->actions.empty()) tfscript_error("Not all actions were used up: " + std::to_string((*state)->actions.size()) + " leftover");
|
||||
|
||||
MDEBUG("clearing state");
|
||||
|
@ -107,6 +107,7 @@ coin { return COIN; }
|
||||
food { return FOOD; }
|
||||
custom { return CUSTOM; }
|
||||
if { return IF; }
|
||||
else { return ELSE; }
|
||||
storyline { return STORYLINE; }
|
||||
restricted { return RESTRICTED; }
|
||||
|
||||
|
@ -36,7 +36,7 @@ static script_partial_state_t *state = NULL;
|
||||
%token <number> ADD SUB MUL MIN MAX NOT DIV MOD SQRT
|
||||
%token <number> PERCENT PAY CONSUME TEMPERATURE_NUMBER TEMPERATURE RANDOM
|
||||
%token <number> IMAGE UI CHOICES CHOICE NEXT SELECTED ENABLED ACTIONS PUBLIC IS BLOCKCHAIN BY OVERRIDES ID
|
||||
%token <number> GEMSTONE BLOCK LABOUR COIN FOOD CUSTOM IF STORYLINE RESTRICTED
|
||||
%token <number> GEMSTONE BLOCK LABOUR COIN FOOD CUSTOM IF ELSE STORYLINE RESTRICTED
|
||||
|
||||
%type <number> script script_contents script_content choice_contents choice_content
|
||||
%type <number> name owner description icon precondition reserves state public
|
||||
@ -48,6 +48,7 @@ static script_partial_state_t *state = NULL;
|
||||
%type <number> reserves_contents reserves_content state_contents state_content
|
||||
%type <number> comparison overrides overrides_contents overrides_content
|
||||
%type <number> selected_text
|
||||
%type <number> action_if if_actions
|
||||
|
||||
%left ADD SUB MUL AND OR DIV MOD
|
||||
%left BADGE ATTRIBUTE DISCOVERER HEIGHT ITEM RANDOM
|
||||
@ -122,7 +123,7 @@ action: action_percent
|
||||
| action_set_global_variable
|
||||
| action_storyline_event
|
||||
| action_none
|
||||
| IF '(' expression ')' action
|
||||
| action_if
|
||||
;
|
||||
|
||||
action_percent: PERCENT operand action { set_partial_state_action_percent(state); }
|
||||
@ -152,10 +153,10 @@ action_set_global_variable: SET GLOBAL STRING operand { set_partial_state_action
|
||||
action_set_local_variable: SET LOCAL STRING operand { set_partial_state_action(state, action_set_local_variable, $3, 1); }
|
||||
;
|
||||
|
||||
action_pick: PICK '{' pick_actions '}' { set_partial_state_action_pick(state); }
|
||||
action_pick: PICK '{' { set_partial_state_action_add_action_group_count(state); } pick_actions '}' { set_partial_state_action_pick(state); }
|
||||
;
|
||||
|
||||
pick_actions: pick_actions pick_action { set_partial_state_action_pick_count_up(state); }
|
||||
pick_actions: pick_actions pick_action { set_partial_state_action_inc_action_group_count(state); }
|
||||
| {}
|
||||
;
|
||||
|
||||
@ -165,6 +166,17 @@ pick_action: WEIGHT operand action { set_partial_state_action_set_weight(state);
|
||||
action_storyline_event: STORYLINE EVENT STRING { set_partial_state_action(state, action_storyline_event, $3, 0); }
|
||||
;
|
||||
|
||||
action_if: IF { set_partial_state_action_add_action_group_count(state); } '(' expression ')' '{' if_actions '}' { set_partial_state_action_if(state); } optional_else
|
||||
;
|
||||
|
||||
if_actions: if_actions action { set_partial_state_action_inc_action_group_count(state); }
|
||||
| {}
|
||||
;
|
||||
|
||||
optional_else: ELSE { set_partial_state_action_add_action_group_count(state); } '{' if_actions '}' { set_partial_state_action_else(state); }
|
||||
| {}
|
||||
;
|
||||
|
||||
action_none: NONE { set_partial_state_action(state, action_none, NULL, 0); }
|
||||
;
|
||||
|
||||
|
@ -6291,6 +6291,59 @@ script {
|
||||
assert 'reserve' not in res
|
||||
assert game_256 == [x.amount for x in res.item_balances if x.type == 256][0]
|
||||
|
||||
print('Testing if/else in scripts')
|
||||
script = """
|
||||
script {
|
||||
name "if/else test"
|
||||
state "0" {
|
||||
choice { text "end" }
|
||||
choice { text "1" actions { if (local "x" == 1) { set local "z" 1 } else { set local "z" 2 } } next state "0" }
|
||||
choice { text "2" actions { set local "x" 1 } next state "0" }
|
||||
choice { text "3" actions { set local "x" 2 } next state "0" }
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
self.wallet[3].cc_create_script(source = script)
|
||||
res = self.generate_blocks('TF1MMBg4zx18SnZC6oswCRB7DzdVeUKce5NdCMSWUHNY4wNvNhzmFj4WqZY2bFj8R1REAWR3qAH5zD7sjXyHz3tVayzHSswqymx', 1)
|
||||
res = daemon.cc_get_scripts()
|
||||
assert len(res.scripts) > 1
|
||||
script_id = res.scripts[-1].index
|
||||
|
||||
# start the script
|
||||
res = self.wallet[2].cc_start_script(script_id, city = 0)
|
||||
res = self.generate_blocks('TF1MMBg4zx18SnZC6oswCRB7DzdVeUKce5NdCMSWUHNY4wNvNhzmFj4WqZY2bFj8R1REAWR3qAH5zD7sjXyHz3tVayzHSswqymx', 1)
|
||||
|
||||
res = daemon.cc_get_account(account2_id)
|
||||
assert res.script == script_id
|
||||
assert res.script_city == 0
|
||||
assert res.script_owner == GAME_ACCOUNT
|
||||
assert res.script_state == 0
|
||||
assert 'script_local_variables' not in res or len(res.script_local_variables) == 0
|
||||
|
||||
res = self.wallet[2].cc_script_choice(script_id, state = 0, city = 0, owner = GAME_ACCOUNT, choice = 1)
|
||||
res = self.generate_blocks('TF1MMBg4zx18SnZC6oswCRB7DzdVeUKce5NdCMSWUHNY4wNvNhzmFj4WqZY2bFj8R1REAWR3qAH5zD7sjXyHz3tVayzHSswqymx', 1)
|
||||
res = daemon.cc_get_account(account2_id)
|
||||
assert res.script_local_variables[0] == { 'name': 'z', 'value': 2}
|
||||
|
||||
res = self.wallet[2].cc_script_choice(script_id, state = 0, city = 0, owner = GAME_ACCOUNT, choice = 2)
|
||||
res = self.generate_blocks('TF1MMBg4zx18SnZC6oswCRB7DzdVeUKce5NdCMSWUHNY4wNvNhzmFj4WqZY2bFj8R1REAWR3qAH5zD7sjXyHz3tVayzHSswqymx', 1)
|
||||
res = self.wallet[2].cc_script_choice(script_id, state = 0, city = 0, owner = GAME_ACCOUNT, choice = 1)
|
||||
res = self.generate_blocks('TF1MMBg4zx18SnZC6oswCRB7DzdVeUKce5NdCMSWUHNY4wNvNhzmFj4WqZY2bFj8R1REAWR3qAH5zD7sjXyHz3tVayzHSswqymx', 1)
|
||||
res = daemon.cc_get_account(account2_id)
|
||||
assert res.script_local_variables[0] == { 'name': 'z', 'value': 1} or res.script_local_variables[1] == { 'name': 'z', 'value': 1}
|
||||
|
||||
res = self.wallet[2].cc_script_choice(script_id, state = 0, city = 0, owner = GAME_ACCOUNT, choice = 3)
|
||||
res = self.generate_blocks('TF1MMBg4zx18SnZC6oswCRB7DzdVeUKce5NdCMSWUHNY4wNvNhzmFj4WqZY2bFj8R1REAWR3qAH5zD7sjXyHz3tVayzHSswqymx', 1)
|
||||
res = self.wallet[2].cc_script_choice(script_id, state = 0, city = 0, owner = GAME_ACCOUNT, choice = 1)
|
||||
res = self.generate_blocks('TF1MMBg4zx18SnZC6oswCRB7DzdVeUKce5NdCMSWUHNY4wNvNhzmFj4WqZY2bFj8R1REAWR3qAH5zD7sjXyHz3tVayzHSswqymx', 1)
|
||||
res = daemon.cc_get_account(account2_id)
|
||||
assert res.script_local_variables[0] == { 'name': 'z', 'value': 2} or res.script_local_variables[1] == { 'name': 'z', 'value': 2}
|
||||
|
||||
# end the script
|
||||
res = self.wallet[2].cc_script_choice(script_id, state = 0, city = 0, owner = GAME_ACCOUNT, choice = 0)
|
||||
res = self.generate_blocks('TF1MMBg4zx18SnZC6oswCRB7DzdVeUKce5NdCMSWUHNY4wNvNhzmFj4WqZY2bFj8R1REAWR3qAH5zD7sjXyHz3tVayzHSswqymx', 1)
|
||||
|
||||
def check_gold_consistency(self):
|
||||
daemon = self.daemon
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user