|
|
@@ -1012,29 +1012,30 @@ const char* JFloatOperatorBoolExpressionFactory::getTypeToken() const
|
|
|
return "comparsion";
|
|
|
}
|
|
|
|
|
|
-JBlockTypeBoolExpression::JBlockTypeBoolExpression()
|
|
|
+JSpecificBlockBoolExpression::JSpecificBlockBoolExpression()
|
|
|
: JBoolExpression(),
|
|
|
- typeId(0),
|
|
|
+ filter(0),
|
|
|
x(0),
|
|
|
y(0),
|
|
|
z(0)
|
|
|
{}
|
|
|
|
|
|
-JBlockTypeBoolExpression ::~JBlockTypeBoolExpression()
|
|
|
+JSpecificBlockBoolExpression::~JSpecificBlockBoolExpression()
|
|
|
{
|
|
|
+ if (filter) filter->release();
|
|
|
if (x) x->release();
|
|
|
if (y) y->release();
|
|
|
if (z) z->release();
|
|
|
}
|
|
|
|
|
|
-bool JBlockTypeBoolExpression::isValidPosition(
|
|
|
+bool JSpecificBlockBoolExpression::isValidPosition(
|
|
|
int x, int y, Chunk* currentChunk)
|
|
|
{
|
|
|
return currentChunk
|
|
|
&& Game::getChunkCenter(x, y) == currentChunk->getCenter();
|
|
|
}
|
|
|
|
|
|
-Framework::Assembly::AssemblyBlock& JBlockTypeBoolExpression::buildAssembly(
|
|
|
+Framework::Assembly::AssemblyBlock& JSpecificBlockBoolExpression::buildAssembly(
|
|
|
JExpressionMemory* zMemory)
|
|
|
{
|
|
|
Framework::Assembly::AssemblyBlock& xBlock = x->buildAssembly(zMemory);
|
|
|
@@ -1099,12 +1100,11 @@ Framework::Assembly::AssemblyBlock& JBlockTypeBoolExpression::buildAssembly(
|
|
|
codeBlock.addPush(Framework::Assembly::R9, Framework::Assembly::LOWER32);
|
|
|
codeBlock.addLoadValue(
|
|
|
(__int64*)zMemory->zzCurrentChunk(), Framework::Assembly::R9);
|
|
|
- codeBlock
|
|
|
- .addMemberCall<bool (JBlockTypeBoolExpression::*)(int, int, Chunk*)>(
|
|
|
- &JBlockTypeBoolExpression::isValidPosition,
|
|
|
- Framework::Assembly::INT_VALUE,
|
|
|
- {Framework::Assembly::R9},
|
|
|
- {});
|
|
|
+ codeBlock.addMemberCall<bool (JSpecificBlockBoolExpression::*)(
|
|
|
+ int, int, Chunk*)>(&JSpecificBlockBoolExpression::isValidPosition,
|
|
|
+ Framework::Assembly::INT_VALUE,
|
|
|
+ {Framework::Assembly::R9},
|
|
|
+ {});
|
|
|
codeBlock.addPop(Framework::Assembly::R9, Framework::Assembly::LOWER32);
|
|
|
codeBlock.addPop(Framework::Assembly::R8, Framework::Assembly::LOWER32);
|
|
|
codeBlock.addPop(Framework::Assembly::RDX, Framework::Assembly::LOWER32);
|
|
|
@@ -1114,19 +1114,25 @@ Framework::Assembly::AssemblyBlock& JBlockTypeBoolExpression::buildAssembly(
|
|
|
codeBlock.addJump(Framework::Assembly::JZ, "end");
|
|
|
codeBlock.addLoadValue(
|
|
|
(__int64*)zMemory->zzCurrentChunk(), Framework::Assembly::RCX);
|
|
|
- codeBlock.addMemberCall<int (Chunk::*)(int, int, int) const>(
|
|
|
- &Chunk::getBlockTypeAtWC,
|
|
|
+ codeBlock.addMemberCall<const Block* (Chunk::*)(int, int, int) const>(
|
|
|
+ &Chunk::zBlockConstWC,
|
|
|
Framework::Assembly::INT_VALUE,
|
|
|
{Framework::Assembly::RCX,
|
|
|
Framework::Assembly::RDX,
|
|
|
Framework::Assembly::R8,
|
|
|
Framework::Assembly::R9},
|
|
|
{});
|
|
|
- codeBlock.addLoadValue(&typeId, Framework::Assembly::RCX);
|
|
|
- codeBlock.addCompare(Framework::Assembly::RAX,
|
|
|
- Framework::Assembly::RCX,
|
|
|
- Framework::Assembly::LOWER32);
|
|
|
- codeBlock.addJump(Framework::Assembly::JNE, "end_false");
|
|
|
+ codeBlock.addMoveValue(Framework::Assembly::RDX, Framework::Assembly::RAX);
|
|
|
+ codeBlock.addLoadValue((__int64*)&filter, Framework::Assembly::RCX);
|
|
|
+ codeBlock.addMemberCall<bool (BlockFilter::*)(const Block*) const>(
|
|
|
+ &BlockFilter::test,
|
|
|
+ Framework::Assembly::INT_VALUE,
|
|
|
+ {Framework::Assembly::RCX, Framework::Assembly::RDX},
|
|
|
+ {});
|
|
|
+ codeBlock.addTest(Framework::Assembly::RAX,
|
|
|
+ Framework::Assembly::RAX,
|
|
|
+ Framework::Assembly::LOWER8);
|
|
|
+ codeBlock.addJump(Framework::Assembly::JZ, "end");
|
|
|
codeBlock.addMoveValue(Framework::Assembly::RAX, (char)1);
|
|
|
codeBlock.addJump(Framework::Assembly::JMP, "end");
|
|
|
codeBlock.defineJumpTarget("end_false");
|
|
|
@@ -1135,59 +1141,63 @@ Framework::Assembly::AssemblyBlock& JBlockTypeBoolExpression::buildAssembly(
|
|
|
return codeBlock;
|
|
|
}
|
|
|
|
|
|
-void JBlockTypeBoolExpression::setTypeId(int typeId)
|
|
|
+void JSpecificBlockBoolExpression::setFilter(BlockFilter* filter)
|
|
|
{
|
|
|
- this->typeId = typeId;
|
|
|
+ if (this->filter)
|
|
|
+ {
|
|
|
+ this->filter->release();
|
|
|
+ }
|
|
|
+ this->filter = filter;
|
|
|
}
|
|
|
|
|
|
-int JBlockTypeBoolExpression::getTypeId() const
|
|
|
+BlockFilter* JSpecificBlockBoolExpression::zFilter() const
|
|
|
{
|
|
|
- return typeId;
|
|
|
+ return filter;
|
|
|
}
|
|
|
|
|
|
-void JBlockTypeBoolExpression::setX(JFloatExpression* x)
|
|
|
+void JSpecificBlockBoolExpression::setX(JFloatExpression* x)
|
|
|
{
|
|
|
if (this->x) this->x->release();
|
|
|
this->x = x;
|
|
|
}
|
|
|
|
|
|
-JFloatExpression* JBlockTypeBoolExpression::zX() const
|
|
|
+JFloatExpression* JSpecificBlockBoolExpression::zX() const
|
|
|
{
|
|
|
return x;
|
|
|
}
|
|
|
|
|
|
-void JBlockTypeBoolExpression::setY(JFloatExpression* y)
|
|
|
+void JSpecificBlockBoolExpression::setY(JFloatExpression* y)
|
|
|
{
|
|
|
if (this->y) this->y->release();
|
|
|
this->y = y;
|
|
|
}
|
|
|
|
|
|
-JFloatExpression* JBlockTypeBoolExpression::zY() const
|
|
|
+JFloatExpression* JSpecificBlockBoolExpression::zY() const
|
|
|
{
|
|
|
return y;
|
|
|
}
|
|
|
|
|
|
-void JBlockTypeBoolExpression::setZ(JFloatExpression* z)
|
|
|
+void JSpecificBlockBoolExpression::setZ(JFloatExpression* z)
|
|
|
{
|
|
|
if (this->z) this->z->release();
|
|
|
this->z = z;
|
|
|
}
|
|
|
|
|
|
-JFloatExpression* JBlockTypeBoolExpression::zZ() const
|
|
|
+JFloatExpression* JSpecificBlockBoolExpression::zZ() const
|
|
|
{
|
|
|
return z;
|
|
|
}
|
|
|
|
|
|
-JBlockTypeBoolExpressionFactory::JBlockTypeBoolExpressionFactory()
|
|
|
+JSpecificBlockBoolExpressionFactory::JSpecificBlockBoolExpressionFactory()
|
|
|
: SubTypeFactory()
|
|
|
{}
|
|
|
|
|
|
-JBlockTypeBoolExpression* JBlockTypeBoolExpressionFactory::fromJson(
|
|
|
+JSpecificBlockBoolExpression* JSpecificBlockBoolExpressionFactory::fromJson(
|
|
|
Framework::JSON::JSONObject* zJson) const
|
|
|
{
|
|
|
- JBlockTypeBoolExpression* result = new JBlockTypeBoolExpression();
|
|
|
- result->setTypeId(Game::INSTANCE->getBlockTypeId(
|
|
|
- zJson->zValue("blockType")->asString()->getString()));
|
|
|
+ JSpecificBlockBoolExpression* result = new JSpecificBlockBoolExpression();
|
|
|
+ result->setFilter(Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
|
|
|
+ zJson->zValue("condition")));
|
|
|
result->setX(Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
|
|
|
zJson->zValue("x")));
|
|
|
result->setY(Game::INSTANCE->zTypeRegistry()->fromJson<JFloatExpression>(
|
|
|
@@ -1197,13 +1207,12 @@ JBlockTypeBoolExpression* JBlockTypeBoolExpressionFactory::fromJson(
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
-Framework::JSON::JSONObject* JBlockTypeBoolExpressionFactory::toJsonObject(
|
|
|
- JBlockTypeBoolExpression* zObject) const
|
|
|
+Framework::JSON::JSONObject* JSpecificBlockBoolExpressionFactory::toJsonObject(
|
|
|
+ JSpecificBlockBoolExpression* zObject) const
|
|
|
{
|
|
|
Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
|
|
|
- result->addValue("blockType",
|
|
|
- new Framework::JSON::JSONString(
|
|
|
- Game::INSTANCE->zBlockType(zObject->getTypeId())->getName()));
|
|
|
+ result->addValue("condition",
|
|
|
+ Game::INSTANCE->zTypeRegistry()->toJson(zObject->zFilter()));
|
|
|
result->addValue(
|
|
|
"x", Game::INSTANCE->zTypeRegistry()->toJson(zObject->zX()));
|
|
|
result->addValue(
|
|
|
@@ -1213,13 +1222,13 @@ Framework::JSON::JSONObject* JBlockTypeBoolExpressionFactory::toJsonObject(
|
|
|
return result;
|
|
|
}
|
|
|
|
|
|
-JSONObjectValidationBuilder* JBlockTypeBoolExpressionFactory::addToValidator(
|
|
|
+JSONObjectValidationBuilder*
|
|
|
+JSpecificBlockBoolExpressionFactory::addToValidator(
|
|
|
JSONObjectValidationBuilder* builder) const
|
|
|
{
|
|
|
return builder
|
|
|
- ->withRequiredAttribute("blockType",
|
|
|
- Game::INSTANCE->zTypeRegistry()->getValidator<Framework::Text>(
|
|
|
- BlockTypeNameFactory::TYPE_ID))
|
|
|
+ ->withRequiredAttribute("condition",
|
|
|
+ Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>())
|
|
|
->withRequiredAttribute("x",
|
|
|
Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>())
|
|
|
->withRequiredAttribute("y",
|
|
|
@@ -1228,7 +1237,151 @@ JSONObjectValidationBuilder* JBlockTypeBoolExpressionFactory::addToValidator(
|
|
|
Game::INSTANCE->zTypeRegistry()->getValidator<JFloatExpression>());
|
|
|
}
|
|
|
|
|
|
-const char* JBlockTypeBoolExpressionFactory::getTypeToken() const
|
|
|
+const char* JSpecificBlockBoolExpressionFactory::getTypeToken() const
|
|
|
+{
|
|
|
+ return "specificBlockMatches";
|
|
|
+}
|
|
|
+
|
|
|
+JFirstBlockAboveBoolExpression::JFirstBlockAboveBoolExpression()
|
|
|
+ : JBoolExpression(),
|
|
|
+ filter(0)
|
|
|
+{}
|
|
|
+
|
|
|
+JFirstBlockAboveBoolExpression::~JFirstBlockAboveBoolExpression()
|
|
|
+{
|
|
|
+ if (filter) filter->release();
|
|
|
+}
|
|
|
+
|
|
|
+Framework::Assembly::AssemblyBlock&
|
|
|
+JFirstBlockAboveBoolExpression::buildAssembly(JExpressionMemory* zMemory)
|
|
|
+{
|
|
|
+ // load x into R12
|
|
|
+ codeBlock.addLoadValue(
|
|
|
+ zMemory->getFloatVariableP("x"), Framework::Assembly::MM0);
|
|
|
+ codeBlock.addConversion(Framework::Assembly::R12,
|
|
|
+ Framework::Assembly::MM0,
|
|
|
+ Framework::Assembly::SINGLE_FLOAT,
|
|
|
+ Framework::Assembly::LOWER32,
|
|
|
+ 1);
|
|
|
+ // load y into R13
|
|
|
+ codeBlock.addLoadValue(
|
|
|
+ zMemory->getFloatVariableP("y"), Framework::Assembly::MM0);
|
|
|
+ codeBlock.addConversion(Framework::Assembly::R13,
|
|
|
+ Framework::Assembly::MM0,
|
|
|
+ Framework::Assembly::SINGLE_FLOAT,
|
|
|
+ Framework::Assembly::LOWER32,
|
|
|
+ 1);
|
|
|
+ // load z into R14
|
|
|
+ codeBlock.addLoadValue(
|
|
|
+ zMemory->getFloatVariableP("z"), Framework::Assembly::MM0);
|
|
|
+ codeBlock.addConversion(Framework::Assembly::R14,
|
|
|
+ Framework::Assembly::MM0,
|
|
|
+ Framework::Assembly::SINGLE_FLOAT,
|
|
|
+ Framework::Assembly::LOWER32,
|
|
|
+ 1);
|
|
|
+ // load current chunk into R15
|
|
|
+ codeBlock.addLoadValue(
|
|
|
+ (__int64*)zMemory->zzCurrentChunk(), Framework::Assembly::R15);
|
|
|
+ // begin loop to check above blocks
|
|
|
+ codeBlock.defineJumpTarget("loop_start");
|
|
|
+ // increment height
|
|
|
+ codeBlock.addAddition(Framework::Assembly::R14, (char)1);
|
|
|
+ // check if height is above world height
|
|
|
+ codeBlock.addCompare(Framework::Assembly::R14, WORLD_HEIGHT);
|
|
|
+ codeBlock.addJump(Framework::Assembly::JGE, "end_false");
|
|
|
+ // load block type at current position into RAX
|
|
|
+ codeBlock.addMoveValue(Framework::Assembly::RCX, Framework::Assembly::R15);
|
|
|
+ codeBlock.addMoveValue(Framework::Assembly::RDX, Framework::Assembly::R12);
|
|
|
+ codeBlock.addMoveValue(Framework::Assembly::R8, Framework::Assembly::R13);
|
|
|
+ codeBlock.addMoveValue(Framework::Assembly::R9, Framework::Assembly::R14);
|
|
|
+ codeBlock.addMemberCall<int (Chunk::*)(int, int, int) const>(
|
|
|
+ &Chunk::getBlockTypeAtWC,
|
|
|
+ Framework::Assembly::INT_VALUE,
|
|
|
+ {Framework::Assembly::RCX,
|
|
|
+ Framework::Assembly::RDX,
|
|
|
+ Framework::Assembly::R8,
|
|
|
+ Framework::Assembly::R9},
|
|
|
+ {});
|
|
|
+ // check if block type is 0 (NO_BLOCK) or 1 (AIR)
|
|
|
+ codeBlock.addCompare(Framework::Assembly::RAX, 1);
|
|
|
+ codeBlock.addJump(Framework::Assembly::JLE, "loop_start");
|
|
|
+ // end of loop
|
|
|
+ // load current block into RDX
|
|
|
+ codeBlock.addMoveValue(Framework::Assembly::RCX, Framework::Assembly::R15);
|
|
|
+ codeBlock.addMoveValue(Framework::Assembly::RDX, Framework::Assembly::R12);
|
|
|
+ codeBlock.addMoveValue(Framework::Assembly::R8, Framework::Assembly::R13);
|
|
|
+ codeBlock.addMoveValue(Framework::Assembly::R9, Framework::Assembly::R14);
|
|
|
+ codeBlock.addMemberCall<const Block* (Chunk::*)(int, int, int) const>(
|
|
|
+ &Chunk::zBlockConstWC,
|
|
|
+ Framework::Assembly::INT_VALUE,
|
|
|
+ {Framework::Assembly::RCX,
|
|
|
+ Framework::Assembly::RDX,
|
|
|
+ Framework::Assembly::R8,
|
|
|
+ Framework::Assembly::R9},
|
|
|
+ {});
|
|
|
+ codeBlock.addMoveValue(Framework::Assembly::RDX, Framework::Assembly::RAX);
|
|
|
+ // load filter into RCX
|
|
|
+ codeBlock.addLoadValue((__int64*)&filter, Framework::Assembly::RCX);
|
|
|
+ // check filter condition
|
|
|
+ codeBlock.addMemberCall<bool (BlockFilter::*)(const Block*) const>(
|
|
|
+ &BlockFilter::test,
|
|
|
+ Framework::Assembly::INT_VALUE,
|
|
|
+ {Framework::Assembly::RCX, Framework::Assembly::RDX},
|
|
|
+ {});
|
|
|
+ codeBlock.addJump(Framework::Assembly::JMP, "end");
|
|
|
+ codeBlock.defineJumpTarget("end_false");
|
|
|
+ codeBlock.addMoveValue(Framework::Assembly::RAX, (char)0);
|
|
|
+ codeBlock.defineJumpTarget("end");
|
|
|
+ return codeBlock;
|
|
|
+}
|
|
|
+
|
|
|
+void JFirstBlockAboveBoolExpression::setFilter(BlockFilter* filter)
|
|
|
+{
|
|
|
+ if (this->filter)
|
|
|
+ {
|
|
|
+ this->filter->release();
|
|
|
+ }
|
|
|
+ this->filter = filter;
|
|
|
+}
|
|
|
+
|
|
|
+BlockFilter* JFirstBlockAboveBoolExpression::zFilter() const
|
|
|
{
|
|
|
- return "blockType";
|
|
|
-}
|
|
|
+ return filter;
|
|
|
+}
|
|
|
+
|
|
|
+JFirstBlockAboveBoolExpressionFactory::JFirstBlockAboveBoolExpressionFactory()
|
|
|
+ : SubTypeFactory()
|
|
|
+{}
|
|
|
+
|
|
|
+JFirstBlockAboveBoolExpression* JFirstBlockAboveBoolExpressionFactory::fromJson(
|
|
|
+ Framework::JSON::JSONObject* zJson) const
|
|
|
+{
|
|
|
+ JFirstBlockAboveBoolExpression* result
|
|
|
+ = new JFirstBlockAboveBoolExpression();
|
|
|
+ result->setFilter(Game::INSTANCE->zTypeRegistry()->fromJson<BlockFilter>(
|
|
|
+ zJson->zValue("condition")));
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+Framework::JSON::JSONObject*
|
|
|
+JFirstBlockAboveBoolExpressionFactory::toJsonObject(
|
|
|
+ JFirstBlockAboveBoolExpression* zObject) const
|
|
|
+{
|
|
|
+ Framework::JSON::JSONObject* result = new Framework::JSON::JSONObject();
|
|
|
+ result->addValue("condition",
|
|
|
+ Game::INSTANCE->zTypeRegistry()->toJson(zObject->zFilter()));
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+JSONObjectValidationBuilder*
|
|
|
+JFirstBlockAboveBoolExpressionFactory::addToValidator(
|
|
|
+ JSONObjectValidationBuilder* builder) const
|
|
|
+{
|
|
|
+ return builder->withRequiredAttribute("condition",
|
|
|
+ Game::INSTANCE->zTypeRegistry()->getValidator<BlockFilter>());
|
|
|
+}
|
|
|
+
|
|
|
+const char* JFirstBlockAboveBoolExpressionFactory::getTypeToken() const
|
|
|
+{
|
|
|
+ return "firstBlockAboveMatches";
|
|
|
+}
|