Updated display of Maximum Summon#300
Conversation
8c6ff87 to
a2b65e7
Compare
| if(mcenter) { | ||
| driver->setMaterial(matManager.mSelField); | ||
| int seq = mcenter->sequence; | ||
| if(seq > 0) { | ||
| Materials::QuadVertex side; | ||
| for(int i = 0; i < 4; ++i) side[i] = matManager.vFieldMzone[dField.hovered_controler][seq - 1][i]; | ||
| side[0].Pos = side[0].Pos.getInterpolated(side[1].Pos, 0.5f); | ||
| side[2].Pos = side[2].Pos.getInterpolated(side[3].Pos, 0.5f); | ||
| driver->drawVertexPrimitiveList(side, 4, matManager.iRectangle, 2); | ||
| } | ||
| driver->drawVertexPrimitiveList(matManager.vFieldMzone[dField.hovered_controler][seq], 4, matManager.iRectangle, 2); | ||
| if(seq < 4) { | ||
| Materials::QuadVertex side; | ||
| for(int i = 0; i < 4; ++i) side[i] = matManager.vFieldMzone[dField.hovered_controler][seq + 1][i]; | ||
| side[1].Pos = side[1].Pos.getInterpolated(side[0].Pos, 0.5f); | ||
| side[3].Pos = side[3].Pos.getInterpolated(side[2].Pos, 0.5f); | ||
| driver->drawVertexPrimitiveList(side, 4, matManager.iRectangle, 2); | ||
| } | ||
| return; |
There was a problem hiding this comment.
here all the drawing should be doable with a single vertex drawing (since you're drawing 3 rectangles that in the end are forming a single rect)
| for(size_t i = 0; i < rects.size() - 1; ++i) { | ||
| rects[i].LowerRightCorner.X = rects[i + 1].UpperLeftCorner.X; | ||
| } } else { |
There was a problem hiding this comment.
the code is not properly indented
| for(size_t i = 0; i < codes.size(); ++i) { | ||
| auto cardtxt = imageManager.GetTextureCard(codes[i], imgType::ART); | ||
| auto cardrect = irr::core::rect<irr::s32>(irr::core::vector2di(0, 0), irr::core::dimension2di(cardtxt->getOriginalSize())); | ||
| driver->draw2DImage(cardtxt, rects[i], cardrect, 0, matManager.c2d, true); | ||
| } |
There was a problem hiding this comment.
this is more of a note for myself that in case this could be made a single call to draw2DImageBatch
| if(pcard->IsMaximumSide()) { | ||
| float offset = 0.4f; | ||
| if(controler == 0) { | ||
| if(sequence == 1) t->X += offset; | ||
| else if(sequence == 3) t->X -= offset; | ||
| } else { | ||
| if(sequence == 1) t->X -= offset; | ||
| else if(sequence == 3) t->X += offset; | ||
| } | ||
| } |
There was a problem hiding this comment.
currently IsMaximumSide doesn't enforce a maximum side piece to be sequence 1/3. In case either that has to be checked there, or this piece of code needs to be made sequence agnostic and check if the card is the left or right piece and act accordingly
There was a problem hiding this comment.
I'm not really sure how to proceed here because even though the client doesn't enforce the sequence of the maximum side pieces, it is handled script-wise in the proc_maximum. And because of this, a monster in Maximum Mode will always have its side pieces in the same sequence.
| ClientCard* mcenter = nullptr; | ||
| for(int p = 0; p < 2; ++p) { | ||
| for(auto pcard : dField.mzone[p]) { | ||
| if(pcard && pcard->code == showcardcode && pcard->IsMaximumCenter()) { |
There was a problem hiding this comment.
this isn't technically right, since both players could have the same card on the field, and for some reasons they might have different side pieces, leading to wrong popup image being displayed. But this is due to a limitation of how the client does things atm, so it's something to be addressed at a later time in case
There was a problem hiding this comment.
I don't understand this part. In all my testing, the correct popup image has always been displayed correctly, even with different side pieces. Could you give me an example of this ?
There was a problem hiding this comment.
- player 0 has a maximum monster in play with a center piece x and 2 side pieces
- player 1 summons a maximum with same center piece but another pair of side pieces
- this logic would show player 0's maximum pieces
| #include <unordered_map> | ||
| #include <IrrlichtDevice.h> | ||
| #include <ISceneManager.h> | ||
| #include <IFileSystem.h> | ||
| #include <IReadFile.h> |
| else clicked_card = 0; | ||
| if(clicked_card && clicked_card->IsMaximumSide()) { | ||
| ClientCard* center = clicked_card->GetMaximumCenter(); | ||
| if(center && center->is_selectable) |
There was a problem hiding this comment.
checking for is_selectable will prevent the side pieces to be used for general actions like attacking or using effects. Is it intentional? i don't remember atm if side pieces can have individual effects requiring that piece specifically to be selected to be activated
There was a problem hiding this comment.
This is intentional. Side pieces are not considered monsters on the field so they cannot attack or use effects, or do anything at all. You have to think that when in Maximum Mode, it become essentially just the center piece, who gains the effects of the side pieces.
There was a problem hiding this comment.
Then removing the is_selectable check should be the way to go, since it'll consider clicking a side piece as clicking the center piece under any circumstance (currently it won't let you declare an attack by clicking on the side piece for example)
| ClientCard* ClientCard::GetMaximumCenter() { | ||
| if(IsMaximumCenter()) | ||
| return this; | ||
| if(!(type & TYPE_MAXIMUM) || location != LOCATION_MZONE || !(position & POS_FACEUP)) | ||
| return nullptr; | ||
| const auto& zone = mainGame->dField.mzone[controler]; | ||
| if(sequence > 0 && sequence - 1 < zone.size()) { | ||
| ClientCard* neighbor = zone[sequence - 1]; | ||
| if(neighbor && neighbor->IsMaximumCenter()) | ||
| return neighbor; | ||
| } | ||
| if(sequence + 1 < zone.size()) { | ||
| ClientCard* neighbor = zone[sequence + 1]; | ||
| if(neighbor && neighbor->IsMaximumCenter()) | ||
| return neighbor; | ||
| } | ||
| return nullptr; | ||
| } | ||
| bool ClientCard::IsMaximumCenter() const { | ||
| return (status & STATUS_MAXIMUM_CENTER) != 0; | ||
| } | ||
| bool ClientCard::IsMaximumSide() const { | ||
| if(!(type & TYPE_MAXIMUM) || location != LOCATION_MZONE || !(position & POS_FACEUP)) | ||
| return false; | ||
| const auto& zone = mainGame->dField.mzone[controler]; | ||
| if(sequence > 0 && sequence - 1 < zone.size()) { | ||
| ClientCard* neighbor = zone[sequence - 1]; | ||
| if(neighbor && neighbor->IsMaximumCenter()) | ||
| return true; | ||
| } | ||
| if(sequence + 1 < zone.size()) { | ||
| ClientCard* neighbor = zone[sequence + 1]; | ||
| if(neighbor && neighbor->IsMaximumCenter()) | ||
| return true; | ||
| } | ||
| return false; | ||
| } |
There was a problem hiding this comment.
some extra sanity checks might be added to these functions, like checking that a center piece is a center only if it has 2 sides, and all the 3 pieces are in the main monster zones. In case any of these conditions fail, then none of them should be considered part of a maximum monster
The list of features included in this PR is the following: