|
@@ -1244,7 +1244,8 @@ const char* JSpecificBlockBoolExpressionFactory::getTypeToken() const
|
|
|
|
|
|
|
|
JFirstBlockAboveBoolExpression::JFirstBlockAboveBoolExpression()
|
|
JFirstBlockAboveBoolExpression::JFirstBlockAboveBoolExpression()
|
|
|
: JBoolExpression(),
|
|
: JBoolExpression(),
|
|
|
- filter(0)
|
|
|
|
|
|
|
+ filter(0),
|
|
|
|
|
+ maxDistance(0)
|
|
|
{}
|
|
{}
|
|
|
|
|
|
|
|
JFirstBlockAboveBoolExpression::~JFirstBlockAboveBoolExpression()
|
|
JFirstBlockAboveBoolExpression::~JFirstBlockAboveBoolExpression()
|
|
@@ -1282,18 +1283,44 @@ JFirstBlockAboveBoolExpression::buildAssembly(JExpressionMemory* zMemory)
|
|
|
// load current chunk into R15
|
|
// load current chunk into R15
|
|
|
codeBlock.addLoadValue(
|
|
codeBlock.addLoadValue(
|
|
|
(__int64*)zMemory->zzCurrentChunk(), Framework::Assembly::R15);
|
|
(__int64*)zMemory->zzCurrentChunk(), Framework::Assembly::R15);
|
|
|
|
|
+ if (maxDistance)
|
|
|
|
|
+ {
|
|
|
|
|
+ // calculate loop end
|
|
|
|
|
+ codeBlock.addMoveValue(
|
|
|
|
|
+ Framework::Assembly::RBX, Framework::Assembly::R14);
|
|
|
|
|
+ codeBlock.addAddition(Framework::Assembly::RBX, maxDistance + 1);
|
|
|
|
|
+ codeBlock.addCompare(Framework::Assembly::RBX, WORLD_HEIGHT);
|
|
|
|
|
+ codeBlock.addJump(Framework::Assembly::JL, "continue");
|
|
|
|
|
+ codeBlock.addMoveValue(Framework::Assembly::RBX, WORLD_HEIGHT);
|
|
|
|
|
+ codeBlock.defineJumpTarget("continue");
|
|
|
|
|
+ }
|
|
|
// begin loop to check above blocks
|
|
// begin loop to check above blocks
|
|
|
codeBlock.defineJumpTarget("loop_start");
|
|
codeBlock.defineJumpTarget("loop_start");
|
|
|
// increment height
|
|
// increment height
|
|
|
- codeBlock.addAddition(Framework::Assembly::R14, (char)1);
|
|
|
|
|
- // check if height is above world height
|
|
|
|
|
- codeBlock.addCompare(Framework::Assembly::R14, WORLD_HEIGHT);
|
|
|
|
|
|
|
+ codeBlock.addAddition(
|
|
|
|
|
+ Framework::Assembly::R14, (char)1, Framework::Assembly::LOWER32);
|
|
|
|
|
+ // check if height is above loop end
|
|
|
|
|
+ if (maxDistance)
|
|
|
|
|
+ {
|
|
|
|
|
+ codeBlock.addCompare(Framework::Assembly::R14,
|
|
|
|
|
+ Framework::Assembly::RBX,
|
|
|
|
|
+ Framework::Assembly::LOWER32);
|
|
|
|
|
+ }
|
|
|
|
|
+ else
|
|
|
|
|
+ {
|
|
|
|
|
+ codeBlock.addCompare(Framework::Assembly::R14, WORLD_HEIGHT);
|
|
|
|
|
+ }
|
|
|
codeBlock.addJump(Framework::Assembly::JGE, "end_false");
|
|
codeBlock.addJump(Framework::Assembly::JGE, "end_false");
|
|
|
// load block type at current position into RAX
|
|
// load block type at current position into RAX
|
|
|
codeBlock.addMoveValue(Framework::Assembly::RCX, Framework::Assembly::R15);
|
|
codeBlock.addMoveValue(Framework::Assembly::RCX, Framework::Assembly::R15);
|
|
|
codeBlock.addMoveValue(Framework::Assembly::RDX, Framework::Assembly::R12);
|
|
codeBlock.addMoveValue(Framework::Assembly::RDX, Framework::Assembly::R12);
|
|
|
codeBlock.addMoveValue(Framework::Assembly::R8, Framework::Assembly::R13);
|
|
codeBlock.addMoveValue(Framework::Assembly::R8, Framework::Assembly::R13);
|
|
|
codeBlock.addMoveValue(Framework::Assembly::R9, Framework::Assembly::R14);
|
|
codeBlock.addMoveValue(Framework::Assembly::R9, Framework::Assembly::R14);
|
|
|
|
|
+ if (maxDistance)
|
|
|
|
|
+ { // save loop end in RBX for later comparison
|
|
|
|
|
+ codeBlock.addPush(
|
|
|
|
|
+ Framework::Assembly::RBX, Framework::Assembly::LOWER32);
|
|
|
|
|
+ }
|
|
|
codeBlock.addMemberCall<int (Chunk::*)(int, int, int) const>(
|
|
codeBlock.addMemberCall<int (Chunk::*)(int, int, int) const>(
|
|
|
&Chunk::getBlockTypeAtWC,
|
|
&Chunk::getBlockTypeAtWC,
|
|
|
Framework::Assembly::INT_VALUE,
|
|
Framework::Assembly::INT_VALUE,
|
|
@@ -1302,6 +1329,12 @@ JFirstBlockAboveBoolExpression::buildAssembly(JExpressionMemory* zMemory)
|
|
|
Framework::Assembly::R8,
|
|
Framework::Assembly::R8,
|
|
|
Framework::Assembly::R9},
|
|
Framework::Assembly::R9},
|
|
|
{});
|
|
{});
|
|
|
|
|
+ if (maxDistance)
|
|
|
|
|
+ {
|
|
|
|
|
+ // restore loop end from stack
|
|
|
|
|
+ codeBlock.addPop(
|
|
|
|
|
+ Framework::Assembly::RBX, Framework::Assembly::LOWER32);
|
|
|
|
|
+ }
|
|
|
// check if block type is 0 (NO_BLOCK) or 1 (AIR)
|
|
// check if block type is 0 (NO_BLOCK) or 1 (AIR)
|
|
|
codeBlock.addCompare(Framework::Assembly::RAX, 1);
|
|
codeBlock.addCompare(Framework::Assembly::RAX, 1);
|
|
|
codeBlock.addJump(Framework::Assembly::JLE, "loop_start");
|
|
codeBlock.addJump(Framework::Assembly::JLE, "loop_start");
|
|
@@ -1349,6 +1382,16 @@ BlockFilter* JFirstBlockAboveBoolExpression::zFilter() const
|
|
|
return filter;
|
|
return filter;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+void JFirstBlockAboveBoolExpression::setMaxDistance(short maxDistance)
|
|
|
|
|
+{
|
|
|
|
|
+ this->maxDistance = maxDistance;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+short JFirstBlockAboveBoolExpression::getMaxDistance() const
|
|
|
|
|
+{
|
|
|
|
|
+ return maxDistance;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
JFirstBlockAboveBoolExpressionFactory::JFirstBlockAboveBoolExpressionFactory()
|
|
JFirstBlockAboveBoolExpressionFactory::JFirstBlockAboveBoolExpressionFactory()
|
|
|
: SubTypeFactory()
|
|
: SubTypeFactory()
|
|
|
{}
|
|
{}
|
|
@@ -1360,6 +1403,11 @@ JFirstBlockAboveBoolExpression* JFirstBlockAboveBoolExpressionFactory::fromJson(
|
|
|
= new JFirstBlockAboveBoolExpression();
|
|
= new JFirstBlockAboveBoolExpression();
|
|
|
result->setFilter(Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
|
|
result->setFilter(Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
|
|
|
zJson->zValue("condition")));
|
|
zJson->zValue("condition")));
|
|
|
|
|
+ if (zJson->hasValue("maxDistance"))
|
|
|
|
|
+ {
|
|
|
|
|
+ result->setMaxDistance(
|
|
|
|
|
+ (short)zJson->zValue("maxDistance")->asNumber()->getNumber());
|
|
|
|
|
+ }
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1370,6 +1418,11 @@ JFirstBlockAboveBoolExpressionFactory::toJsonObject(
|
|
|
Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
|
|
Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
|
|
|
result->addValue("condition",
|
|
result->addValue("condition",
|
|
|
Game::INSTANCE->zTypeRegistry()->toJson(zObject->zFilter()));
|
|
Game::INSTANCE->zTypeRegistry()->toJson(zObject->zFilter()));
|
|
|
|
|
+ if (zObject->getMaxDistance())
|
|
|
|
|
+ {
|
|
|
|
|
+ result->addValue("maxDistance",
|
|
|
|
|
+ new Framework::JSON::JSONNumber(zObject->getMaxDistance()));
|
|
|
|
|
+ }
|
|
|
return result;
|
|
return result;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -1377,8 +1430,13 @@ JSONObjectValidationBuilder*
|
|
|
JFirstBlockAboveBoolExpressionFactory::addToValidator(
|
|
JFirstBlockAboveBoolExpressionFactory::addToValidator(
|
|
|
JSONObjectValidationBuilder* builder) const
|
|
JSONObjectValidationBuilder* builder) const
|
|
|
{
|
|
{
|
|
|
- return builder->withRequiredAttribute("condition",
|
|
|
|
|
- Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>());
|
|
|
|
|
|
|
+ return builder
|
|
|
|
|
+ ->withRequiredAttribute("condition",
|
|
|
|
|
+ Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>())
|
|
|
|
|
+ ->withOptionalNumber("maxDistance")
|
|
|
|
|
+ ->whichIsGreaterThen(0)
|
|
|
|
|
+ ->whichIsLessThen(WORLD_HEIGHT)
|
|
|
|
|
+ ->finishNumber();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const char* JFirstBlockAboveBoolExpressionFactory::getTypeToken() const
|
|
const char* JFirstBlockAboveBoolExpressionFactory::getTypeToken() const
|