mirror of
https://github.com/Fluorohydride/ygopro.git
synced 2026-10-18 22:51:17 +08:00
251 lines
6.5 KiB
C++
251 lines
6.5 KiB
C++
#include <algorithm>
|
|
#include "client_card.h"
|
|
#include "client_field.h"
|
|
#include "game.h"
|
|
|
|
namespace ygo {
|
|
|
|
ClientCard::~ClientCard() {
|
|
ClearTarget();
|
|
if (equipTarget) {
|
|
equipTarget->is_showequip = false;
|
|
equipTarget->equipped.erase(this);
|
|
equipTarget = nullptr;
|
|
}
|
|
for (auto& card : equipped) {
|
|
card->is_showequip = false;
|
|
card->equipTarget = nullptr;
|
|
}
|
|
equipped.clear();
|
|
if (overlayTarget) {
|
|
for (auto it = overlayTarget->overlayed.begin(); it != overlayTarget->overlayed.end(); ) {
|
|
if (*it == this) {
|
|
it = overlayTarget->overlayed.erase(it);
|
|
}
|
|
else
|
|
++it;
|
|
}
|
|
overlayTarget = nullptr;
|
|
}
|
|
for (auto& card : overlayed) {
|
|
card->overlayTarget = nullptr;
|
|
}
|
|
overlayed.clear();
|
|
}
|
|
void ClientCard::SetCode(unsigned int x) {
|
|
if (code == x) {
|
|
return;
|
|
}
|
|
if (x == 0) {
|
|
chain_code = code;
|
|
}
|
|
code = x;
|
|
if (location == LOCATION_HAND) {
|
|
mainGame->dField.MoveCard(this, 5);
|
|
}
|
|
}
|
|
void ClientCard::UpdateInfo(unsigned char* buf) {
|
|
int flag = BufferIO::Read<int32_t>(buf);
|
|
if (flag == 0) {
|
|
ClearData();
|
|
return;
|
|
}
|
|
if(flag & QUERY_CODE) {
|
|
int pdata = BufferIO::Read<int32_t>(buf);
|
|
if (!pdata)
|
|
ClearData();
|
|
SetCode(pdata);
|
|
}
|
|
if(flag & QUERY_POSITION) {
|
|
int pdata = (BufferIO::Read<int32_t>(buf) >> 24) & 0xff;
|
|
if((location & (LOCATION_EXTRA | LOCATION_REMOVED)) && pdata != position) {
|
|
position = pdata;
|
|
mainGame->dField.MoveCard(this, 1);
|
|
} else
|
|
position = pdata;
|
|
}
|
|
if(flag & QUERY_ALIAS)
|
|
alias = BufferIO::Read<int32_t>(buf);
|
|
if(flag & QUERY_TYPE)
|
|
type = BufferIO::Read<int32_t>(buf);
|
|
if(flag & QUERY_LEVEL) {
|
|
int pdata = BufferIO::Read<int32_t>(buf);
|
|
if(level != (unsigned int)pdata) {
|
|
level = pdata;
|
|
myswprintf(lvstring, L"L%d", level);
|
|
}
|
|
}
|
|
if(flag & QUERY_RANK) {
|
|
int pdata = BufferIO::Read<int32_t>(buf);
|
|
if(pdata && rank != (unsigned int)pdata) {
|
|
rank = pdata;
|
|
myswprintf(lvstring, L"R%d", rank);
|
|
}
|
|
}
|
|
if(flag & QUERY_ATTRIBUTE)
|
|
attribute = BufferIO::Read<int32_t>(buf);
|
|
if(flag & QUERY_RACE)
|
|
race = BufferIO::Read<int32_t>(buf);
|
|
if(flag & QUERY_ATTACK) {
|
|
attack = BufferIO::Read<int32_t>(buf);
|
|
if(attack < 0) {
|
|
atkstring[0] = '?';
|
|
atkstring[1] = 0;
|
|
} else
|
|
myswprintf(atkstring, L"%d", attack);
|
|
}
|
|
if(flag & QUERY_DEFENSE) {
|
|
defense = BufferIO::Read<int32_t>(buf);
|
|
if(type & TYPE_LINK) {
|
|
defstring[0] = '-';
|
|
defstring[1] = 0;
|
|
} else if(defense < 0) {
|
|
defstring[0] = '?';
|
|
defstring[1] = 0;
|
|
} else
|
|
myswprintf(defstring, L"%d", defense);
|
|
}
|
|
if(flag & QUERY_BASE_ATTACK)
|
|
base_attack = BufferIO::Read<int32_t>(buf);
|
|
if(flag & QUERY_BASE_DEFENSE)
|
|
base_defense = BufferIO::Read<int32_t>(buf);
|
|
if(flag & QUERY_REASON)
|
|
reason = BufferIO::Read<int32_t>(buf);
|
|
if(flag & QUERY_REASON_CARD)
|
|
buf += 4;
|
|
if(flag & QUERY_EQUIP_CARD) {
|
|
int c = BufferIO::Read<uint8_t>(buf);
|
|
unsigned int l = BufferIO::Read<uint8_t>(buf);
|
|
int s = BufferIO::Read<uint8_t>(buf);
|
|
BufferIO::Read<uint8_t>(buf);
|
|
ClientCard* ecard = mainGame->dField.GetCard(mainGame->LocalPlayer(c), l, s);
|
|
if (ecard) {
|
|
equipTarget = ecard;
|
|
ecard->equipped.insert(this);
|
|
}
|
|
}
|
|
if(flag & QUERY_TARGET_CARD) {
|
|
int count = BufferIO::Read<int32_t>(buf);
|
|
for(int i = 0; i < count; ++i) {
|
|
int c = BufferIO::Read<uint8_t>(buf);
|
|
unsigned int l = BufferIO::Read<uint8_t>(buf);
|
|
int s = BufferIO::Read<uint8_t>(buf);
|
|
BufferIO::Read<uint8_t>(buf);
|
|
ClientCard* tcard = mainGame->dField.GetCard(mainGame->LocalPlayer(c), l, s);
|
|
if (tcard) {
|
|
cardTarget.insert(tcard);
|
|
tcard->ownerTarget.insert(this);
|
|
}
|
|
}
|
|
}
|
|
if(flag & QUERY_OVERLAY_CARD) {
|
|
int count = BufferIO::Read<int32_t>(buf);
|
|
for(int i = 0; i < count; ++i) {
|
|
overlayed[i]->SetCode(BufferIO::Read<int32_t>(buf));
|
|
}
|
|
}
|
|
if(flag & QUERY_COUNTERS) {
|
|
int count = BufferIO::Read<int32_t>(buf);
|
|
for(int i = 0; i < count; ++i) {
|
|
int ctype = BufferIO::Read<uint16_t>(buf);
|
|
int ccount = BufferIO::Read<uint16_t>(buf);
|
|
counters[ctype] = ccount;
|
|
}
|
|
}
|
|
if(flag & QUERY_OWNER)
|
|
owner = BufferIO::Read<int32_t>(buf);
|
|
if(flag & QUERY_STATUS)
|
|
status = BufferIO::Read<int32_t>(buf);
|
|
if(flag & QUERY_LSCALE) {
|
|
lscale = BufferIO::Read<int32_t>(buf);
|
|
myswprintf(lscstring, L"%d", lscale);
|
|
}
|
|
if(flag & QUERY_RSCALE) {
|
|
rscale = BufferIO::Read<int32_t>(buf);
|
|
myswprintf(rscstring, L"%d", rscale);
|
|
}
|
|
if(flag & QUERY_LINK) {
|
|
int pdata = BufferIO::Read<int32_t>(buf);
|
|
if (link != (unsigned int)pdata) {
|
|
link = pdata;
|
|
}
|
|
myswprintf(linkstring, L"L\x2012%d", link);
|
|
pdata = BufferIO::Read<int32_t>(buf);
|
|
if (link_marker != (unsigned int)pdata) {
|
|
link_marker = pdata;
|
|
}
|
|
}
|
|
}
|
|
void ClientCard::ClearTarget() {
|
|
for (auto& pcard : cardTarget) {
|
|
pcard->is_showtarget = false;
|
|
pcard->ownerTarget.erase(this);
|
|
}
|
|
for (auto& pcard : ownerTarget) {
|
|
pcard->is_showtarget = false;
|
|
pcard->cardTarget.erase(this);
|
|
}
|
|
cardTarget.clear();
|
|
ownerTarget.clear();
|
|
}
|
|
void ClientCard::ClearData() {
|
|
alias = 0;
|
|
type = 0;
|
|
level = 0;
|
|
rank = 0;
|
|
race = 0;
|
|
attribute = 0;
|
|
attack = 0;
|
|
defense = 0;
|
|
base_attack = 0;
|
|
base_defense = 0;
|
|
lscale = 0;
|
|
rscale = 0;
|
|
link = 0;
|
|
link_marker = 0;
|
|
status = 0;
|
|
|
|
atkstring[0] = 0;
|
|
defstring[0] = 0;
|
|
lvstring[0] = 0;
|
|
linkstring[0] = 0;
|
|
rscstring[0] = 0;
|
|
lscstring[0] = 0;
|
|
counters.clear();
|
|
}
|
|
bool ClientCard::client_card_sort(ClientCard* c1, ClientCard* c2) {
|
|
if(c1->is_selected != c2->is_selected)
|
|
return c1->is_selected < c2->is_selected;
|
|
int cp1 = c1->overlayTarget ? c1->overlayTarget->controler : c1->controler;
|
|
int cp2 = c2->overlayTarget ? c2->overlayTarget->controler : c2->controler;
|
|
if(cp1 != cp2)
|
|
return cp1 < cp2;
|
|
if(c1->location != c2->location)
|
|
return c1->location < c2->location;
|
|
if (c1->location == LOCATION_OVERLAY) {
|
|
if (c1->overlayTarget != c2->overlayTarget)
|
|
return c1->overlayTarget->sequence < c2->overlayTarget->sequence;
|
|
else
|
|
return c1->sequence < c2->sequence;
|
|
}
|
|
else if (c1->location == LOCATION_DECK) {
|
|
return c1->sequence > c2->sequence;
|
|
}
|
|
else if (c1->location & (LOCATION_GRAVE | LOCATION_REMOVED | LOCATION_EXTRA)) {
|
|
auto it1 = std::find_if(mainGame->dField.chains.rbegin(), mainGame->dField.chains.rend(), [c1](const ChainInfo& ch) {
|
|
return c1 == ch.chain_card || ch.target.find(c1) != ch.target.end();
|
|
});
|
|
auto it2 = std::find_if(mainGame->dField.chains.rbegin(), mainGame->dField.chains.rend(), [c2](const ChainInfo& ch) {
|
|
return c2 == ch.chain_card || ch.target.find(c2) != ch.target.end();
|
|
});
|
|
if (it1 != mainGame->dField.chains.rend() || it2 != mainGame->dField.chains.rend()) {
|
|
return it1 < it2;
|
|
}
|
|
return c1->sequence > c2->sequence;
|
|
}
|
|
else {
|
|
return c1->sequence < c2->sequence;
|
|
}
|
|
}
|
|
}
|