Commit b73d8012 authored by mercury233's avatar mercury233

Merge branch 'master' of https://github.com/Fluorohydride/ygopro into server

parents 12f9e87c b824c77e
Pipeline #43048 passed with stages
in 2 minutes and 40 seconds
...@@ -32,14 +32,15 @@ ClientCard::~ClientCard() { ...@@ -32,14 +32,15 @@ ClientCard::~ClientCard() {
overlayed.clear(); overlayed.clear();
} }
void ClientCard::SetCode(unsigned int x) { void ClientCard::SetCode(unsigned int x) {
if((location == LOCATION_HAND) && (code != x)) { if (code == x) {
code = x; return;
}
if (x == 0) {
chain_code = code;
}
code = x;
if (location == LOCATION_HAND) {
mainGame->dField.MoveCard(this, 5); mainGame->dField.MoveCard(this, 5);
} else {
if (x == 0 && code != 0) {
chain_code = code;
}
code = x;
} }
} }
void ClientCard::UpdateInfo(unsigned char* buf) { void ClientCard::UpdateInfo(unsigned char* buf) {
......
...@@ -456,17 +456,15 @@ void ClientField::ShowSelectCard(bool buttonok, bool is_continuous) { ...@@ -456,17 +456,15 @@ void ClientField::ShowSelectCard(bool buttonok, bool is_continuous) {
if(mainGame->dInfo.curMsg != MSG_SORT_CARD) { if(mainGame->dInfo.curMsg != MSG_SORT_CARD) {
// text // text
wchar_t formatBuffer[2048]; wchar_t formatBuffer[2048];
if(select_continuous) if (select_continuous)
myswprintf(formatBuffer, L"%ls", dataManager.unknown_string); myswprintf(formatBuffer, L"%ls", dataManager.unknown_string);
else if(cant_check_grave && selectable_cards[i]->location == LOCATION_GRAVE) else if (cant_check_grave && selectable_cards[i]->location == LOCATION_GRAVE)
myswprintf(formatBuffer, L"%ls", dataManager.FormatLocation(selectable_cards[i]->location, 0)); myswprintf(formatBuffer, L"%ls", dataManager.FormatLocation(selectable_cards[i]->location, 0));
else if(selectable_cards[i]->location == LOCATION_OVERLAY) else if (selectable_cards[i]->location == LOCATION_OVERLAY)
myswprintf(formatBuffer, L"%ls[%d](%d)", myswprintf(formatBuffer, L"%ls[%d](%d)",
dataManager.FormatLocation(selectable_cards[i]->overlayTarget->location, selectable_cards[i]->overlayTarget->sequence), dataManager.FormatLocation(selectable_cards[i]->overlayTarget), selectable_cards[i]->overlayTarget->sequence + 1, selectable_cards[i]->sequence + 1);
selectable_cards[i]->overlayTarget->sequence + 1, selectable_cards[i]->sequence + 1);
else else
myswprintf(formatBuffer, L"%ls[%d]", dataManager.FormatLocation(selectable_cards[i]->location, selectable_cards[i]->sequence), myswprintf(formatBuffer, L"%ls[%d]", dataManager.FormatLocation(selectable_cards[i]), selectable_cards[i]->sequence + 1);
selectable_cards[i]->sequence + 1);
mainGame->stCardPos[i]->setText(formatBuffer); mainGame->stCardPos[i]->setText(formatBuffer);
// color // color
if (selectable_cards[i]->is_selected) if (selectable_cards[i]->is_selected)
...@@ -542,8 +540,7 @@ void ClientField::ShowChainCard() { ...@@ -542,8 +540,7 @@ void ClientField::ShowChainCard() {
mainGame->btnCardSelect[i]->setPressed(false); mainGame->btnCardSelect[i]->setPressed(false);
mainGame->btnCardSelect[i]->setVisible(true); mainGame->btnCardSelect[i]->setVisible(true);
wchar_t formatBuffer[2048]; wchar_t formatBuffer[2048];
myswprintf(formatBuffer, L"%ls[%d]", dataManager.FormatLocation(selectable_cards[i]->location, selectable_cards[i]->sequence), myswprintf(formatBuffer, L"%ls[%d]", dataManager.FormatLocation(selectable_cards[i]), selectable_cards[i]->sequence + 1);
selectable_cards[i]->sequence + 1);
mainGame->stCardPos[i]->setText(formatBuffer); mainGame->stCardPos[i]->setText(formatBuffer);
if(selectable_cards[i]->location == LOCATION_OVERLAY) { if(selectable_cards[i]->location == LOCATION_OVERLAY) {
if(selectable_cards[i]->owner != selectable_cards[i]->overlayTarget->controler) if(selectable_cards[i]->owner != selectable_cards[i]->overlayTarget->controler)
...@@ -597,13 +594,11 @@ void ClientField::ShowLocationCard() { ...@@ -597,13 +594,11 @@ void ClientField::ShowLocationCard() {
mainGame->btnCardDisplay[i]->setPressed(false); mainGame->btnCardDisplay[i]->setPressed(false);
mainGame->btnCardDisplay[i]->setVisible(true); mainGame->btnCardDisplay[i]->setVisible(true);
wchar_t formatBuffer[2048]; wchar_t formatBuffer[2048];
if(display_cards[i]->location == LOCATION_OVERLAY) if (display_cards[i]->location == LOCATION_OVERLAY)
myswprintf(formatBuffer, L"%ls[%d](%d)", myswprintf(formatBuffer, L"%ls[%d](%d)",
dataManager.FormatLocation(display_cards[i]->overlayTarget->location, display_cards[i]->overlayTarget->sequence), dataManager.FormatLocation(display_cards[i]->overlayTarget), display_cards[i]->overlayTarget->sequence + 1, display_cards[i]->sequence + 1);
display_cards[i]->overlayTarget->sequence + 1, display_cards[i]->sequence + 1);
else else
myswprintf(formatBuffer, L"%ls[%d]", dataManager.FormatLocation(display_cards[i]->location, display_cards[i]->sequence), myswprintf(formatBuffer, L"%ls[%d]", dataManager.FormatLocation(display_cards[i]), display_cards[i]->sequence + 1);
display_cards[i]->sequence + 1);
mainGame->stDisplayPos[i]->setText(formatBuffer); mainGame->stDisplayPos[i]->setText(formatBuffer);
if(display_cards[i]->location == LOCATION_OVERLAY) { if(display_cards[i]->location == LOCATION_OVERLAY) {
if(display_cards[i]->owner != display_cards[i]->overlayTarget->controler) if(display_cards[i]->owner != display_cards[i]->overlayTarget->controler)
......
#include "data_manager.h" #include "data_manager.h"
#include "game.h" #include "game.h"
#if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_ZIP_SUPPORT) #if !defined(YGOPRO_SERVER_MODE) || defined(SERVER_ZIP_SUPPORT)
#include "client_card.h"
#include "spmemvfs/spmemvfs.h" #include "spmemvfs/spmemvfs.h"
#endif #endif
...@@ -245,34 +246,26 @@ const wchar_t* DataManager::GetDesc(uint32_t strCode) const { ...@@ -245,34 +246,26 @@ const wchar_t* DataManager::GetDesc(uint32_t strCode) const {
return csit->second.desc[offset].c_str(); return csit->second.desc[offset].c_str();
return unknown_string; return unknown_string;
} }
const wchar_t* DataManager::GetSysString(int code) const { const wchar_t* DataManager::GetMapString(const wstring_map& table, uint32_t code) const {
if (code < 0 || code > MAX_STRING_ID) auto csit = table.find(code);
return unknown_string; if (csit == table.end())
auto csit = _sysStrings.find(code);
if(csit == _sysStrings.end())
return unknown_string; return unknown_string;
return csit->second.c_str(); return csit->second.c_str();
} }
const wchar_t* DataManager::GetVictoryString(int code) const { const wchar_t* DataManager::GetSysString(uint32_t code) const {
auto csit = _victoryStrings.find(code); return GetMapString(_sysStrings, code);
if(csit == _victoryStrings.end())
return unknown_string;
return csit->second.c_str();
} }
const wchar_t* DataManager::GetCounterName(int code) const { const wchar_t* DataManager::GetVictoryString(uint32_t code) const {
auto csit = _counterStrings.find(code); return GetMapString(_victoryStrings, code);
if(csit == _counterStrings.end())
return unknown_string;
return csit->second.c_str();
} }
const wchar_t* DataManager::GetSetName(int code) const { const wchar_t* DataManager::GetCounterName(uint32_t code) const {
auto csit = _setnameStrings.find(code); return GetMapString(_counterStrings, code);
if(csit == _setnameStrings.end()) }
return unknown_string; const wchar_t* DataManager::GetSetName(uint32_t code) const {
return csit->second.c_str(); return GetMapString(_setnameStrings, code);
} }
std::vector<unsigned int> DataManager::GetSetCodes(std::wstring setname) const { std::vector<uint32_t> DataManager::GetSetCodes(std::wstring setname) const {
std::vector<unsigned int> matchingCodes; std::vector<uint32_t> matchingCodes;
for(auto csit = _setnameStrings.begin(); csit != _setnameStrings.end(); ++csit) { for(auto csit = _setnameStrings.begin(); csit != _setnameStrings.end(); ++csit) {
auto xpos = csit->second.find_first_of(L'|');//setname|another setname or extra info auto xpos = csit->second.find_first_of(L'|');//setname|another setname or extra info
if(setname.size() < 2) { if(setname.size() < 2) {
...@@ -305,11 +298,10 @@ const wchar_t* DataManager::FormatLocation(int location, int sequence) const { ...@@ -305,11 +298,10 @@ const wchar_t* DataManager::FormatLocation(int location, int sequence) const {
else else
return GetSysString(1009); return GetSysString(1009);
} }
int i = 1000;
int string_id = 0; int string_id = 0;
for (unsigned filter = LOCATION_DECK; filter <= LOCATION_PZONE; filter <<= 1, ++i) { for (int i = 0; i < 10; ++i) {
if (filter == location) { if ((0x1U << i) == location) {
string_id = i; string_id = STRING_ID_LOCATION + i;
break; break;
} }
} }
...@@ -318,6 +310,11 @@ const wchar_t* DataManager::FormatLocation(int location, int sequence) const { ...@@ -318,6 +310,11 @@ const wchar_t* DataManager::FormatLocation(int location, int sequence) const {
else else
return unknown_string; return unknown_string;
} }
const wchar_t* DataManager::FormatLocation(ClientCard* card) const {
if (!card)
return unknown_string;
return FormatLocation(card->location, card->sequence);
}
std::wstring DataManager::FormatAttribute(unsigned int attribute) const { std::wstring DataManager::FormatAttribute(unsigned int attribute) const {
std::wstring buffer; std::wstring buffer;
for (int i = 0; i < ATTRIBUTES_COUNT; ++i) { for (int i = 0; i < ATTRIBUTES_COUNT; ++i) {
...@@ -328,7 +325,7 @@ std::wstring DataManager::FormatAttribute(unsigned int attribute) const { ...@@ -328,7 +325,7 @@ std::wstring DataManager::FormatAttribute(unsigned int attribute) const {
} }
} }
if (buffer.empty()) if (buffer.empty())
return std::wstring(unknown_string); buffer = unknown_string;
return buffer; return buffer;
} }
std::wstring DataManager::FormatRace(unsigned int race) const { std::wstring DataManager::FormatRace(unsigned int race) const {
...@@ -341,7 +338,7 @@ std::wstring DataManager::FormatRace(unsigned int race) const { ...@@ -341,7 +338,7 @@ std::wstring DataManager::FormatRace(unsigned int race) const {
} }
} }
if (buffer.empty()) if (buffer.empty())
return std::wstring(unknown_string); buffer = unknown_string;
return buffer; return buffer;
} }
std::wstring DataManager::FormatType(unsigned int type) const { std::wstring DataManager::FormatType(unsigned int type) const {
...@@ -354,7 +351,7 @@ std::wstring DataManager::FormatType(unsigned int type) const { ...@@ -354,7 +351,7 @@ std::wstring DataManager::FormatType(unsigned int type) const {
} }
} }
if (buffer.empty()) if (buffer.empty())
return std::wstring(unknown_string); buffer = unknown_string;
return buffer; return buffer;
} }
std::wstring DataManager::FormatSetName(const uint16_t setcode[]) const { std::wstring DataManager::FormatSetName(const uint16_t setcode[]) const {
...@@ -368,7 +365,7 @@ std::wstring DataManager::FormatSetName(const uint16_t setcode[]) const { ...@@ -368,7 +365,7 @@ std::wstring DataManager::FormatSetName(const uint16_t setcode[]) const {
buffer.append(setname); buffer.append(setname);
} }
if (buffer.empty()) if (buffer.empty())
return std::wstring(unknown_string); buffer = unknown_string;
return buffer; return buffer;
} }
std::wstring DataManager::FormatLinkMarker(unsigned int link_marker) const { std::wstring DataManager::FormatLinkMarker(unsigned int link_marker) const {
......
...@@ -57,6 +57,9 @@ struct CardString { ...@@ -57,6 +57,9 @@ struct CardString {
}; };
using code_pointer = std::unordered_map<uint32_t, CardDataC>::const_iterator; using code_pointer = std::unordered_map<uint32_t, CardDataC>::const_iterator;
using string_pointer = std::unordered_map<uint32_t, CardString>::const_iterator; using string_pointer = std::unordered_map<uint32_t, CardString>::const_iterator;
using wstring_map = std::unordered_map<uint32_t, std::wstring>;
class ClientCard;
class DataManager { class DataManager {
public: public:
...@@ -88,23 +91,24 @@ public: ...@@ -88,23 +91,24 @@ public:
const wchar_t* GetName(uint32_t code) const; const wchar_t* GetName(uint32_t code) const;
const wchar_t* GetText(uint32_t code) const; const wchar_t* GetText(uint32_t code) const;
const wchar_t* GetDesc(uint32_t strCode) const; const wchar_t* GetDesc(uint32_t strCode) const;
const wchar_t* GetSysString(int code) const; const wchar_t* GetSysString(uint32_t code) const;
const wchar_t* GetVictoryString(int code) const; const wchar_t* GetVictoryString(uint32_t code) const;
const wchar_t* GetCounterName(int code) const; const wchar_t* GetCounterName(uint32_t code) const;
const wchar_t* GetSetName(int code) const; const wchar_t* GetSetName(uint32_t code) const;
std::vector<unsigned int> GetSetCodes(std::wstring setname) const; std::vector<uint32_t> GetSetCodes(std::wstring setname) const;
std::wstring GetNumString(int num, bool bracket = false) const; std::wstring GetNumString(int num, bool bracket = false) const;
const wchar_t* FormatLocation(int location, int sequence) const; const wchar_t* FormatLocation(int location, int sequence) const;
const wchar_t* FormatLocation(ClientCard* card) const;
std::wstring FormatAttribute(unsigned int attribute) const; std::wstring FormatAttribute(unsigned int attribute) const;
std::wstring FormatRace(unsigned int race) const; std::wstring FormatRace(unsigned int race) const;
std::wstring FormatType(unsigned int type) const; std::wstring FormatType(unsigned int type) const;
std::wstring FormatSetName(const uint16_t setcode[]) const; std::wstring FormatSetName(const uint16_t setcode[]) const;
std::wstring FormatLinkMarker(unsigned int link_marker) const; std::wstring FormatLinkMarker(unsigned int link_marker) const;
std::unordered_map<unsigned int, std::wstring> _counterStrings; wstring_map _counterStrings;
std::unordered_map<unsigned int, std::wstring> _victoryStrings; wstring_map _victoryStrings;
std::unordered_map<unsigned int, std::wstring> _setnameStrings; wstring_map _setnameStrings;
std::unordered_map<unsigned int, std::wstring> _sysStrings; wstring_map _sysStrings;
#endif #endif
char errmsg[512]{}; char errmsg[512]{};
const wchar_t* unknown_string{ L"???" }; const wchar_t* unknown_string{ L"???" };
...@@ -112,9 +116,10 @@ public: ...@@ -112,9 +116,10 @@ public:
irr::io::IFileSystem* FileSystem{}; irr::io::IFileSystem* FileSystem{};
#endif #endif
static constexpr int STRING_ID_ATTRIBUTE = 1010; static constexpr uint32_t STRING_ID_LOCATION = 1000;
static constexpr int STRING_ID_RACE = 1020; static constexpr uint32_t STRING_ID_ATTRIBUTE = 1010;
static constexpr int STRING_ID_TYPE = 1050; static constexpr uint32_t STRING_ID_RACE = 1020;
static constexpr uint32_t STRING_ID_TYPE = 1050;
static constexpr int TYPES_COUNT = 27; static constexpr int TYPES_COUNT = 27;
static unsigned char scriptBuffer[0x100000]; static unsigned char scriptBuffer[0x100000];
...@@ -136,6 +141,7 @@ public: ...@@ -136,6 +141,7 @@ public:
#endif #endif
private: private:
const wchar_t* GetMapString(const wstring_map& table, uint32_t code) const;
std::unordered_map<uint32_t, CardDataC> _datas; std::unordered_map<uint32_t, CardDataC> _datas;
std::unordered_map<uint32_t, CardString> _strings; std::unordered_map<uint32_t, CardString> _strings;
std::unordered_map<uint32_t, std::vector<uint16_t>> extra_setcode; std::unordered_map<uint32_t, std::vector<uint16_t>> extra_setcode;
......
...@@ -179,10 +179,12 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -179,10 +179,12 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
std::sort(deckManager.current_deck.main.begin(), deckManager.current_deck.main.end(), DataManager::deck_sort_lv); std::sort(deckManager.current_deck.main.begin(), deckManager.current_deck.main.end(), DataManager::deck_sort_lv);
std::sort(deckManager.current_deck.extra.begin(), deckManager.current_deck.extra.end(), DataManager::deck_sort_lv); std::sort(deckManager.current_deck.extra.begin(), deckManager.current_deck.extra.end(), DataManager::deck_sort_lv);
std::sort(deckManager.current_deck.side.begin(), deckManager.current_deck.side.end(), DataManager::deck_sort_lv); std::sort(deckManager.current_deck.side.begin(), deckManager.current_deck.side.end(), DataManager::deck_sort_lv);
is_modified = true;
break; break;
} }
case BUTTON_SHUFFLE_DECK: { case BUTTON_SHUFFLE_DECK: {
std::shuffle(deckManager.current_deck.main.begin(), deckManager.current_deck.main.end(), rnd); std::shuffle(deckManager.current_deck.main.begin(), deckManager.current_deck.main.end(), rnd);
is_modified = true;
break; break;
} }
case BUTTON_SAVE_DECK: { case BUTTON_SAVE_DECK: {
...@@ -740,6 +742,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -740,6 +742,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
deckManager.current_deck.main.clear(); deckManager.current_deck.main.clear();
deckManager.current_deck.extra.clear(); deckManager.current_deck.extra.clear();
deckManager.current_deck.side.clear(); deckManager.current_deck.side.clear();
is_modified = true;
} else if(prev_operation == BUTTON_DELETE_DECK) { } else if(prev_operation == BUTTON_DELETE_DECK) {
int sel = prev_sel; int sel = prev_sel;
mainGame->cbDBDecks->setSelected(sel); mainGame->cbDBDecks->setSelected(sel);
...@@ -1083,6 +1086,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -1083,6 +1086,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
is_starting_dragging = false; is_starting_dragging = false;
irr::gui::IGUIElement* root = mainGame->env->getRootGUIElement(); irr::gui::IGUIElement* root = mainGame->env->getRootGUIElement();
if(!is_draging && !mainGame->is_siding && root->getElementFromPoint(mouse_pos) == mainGame->imgCard) { if(!is_draging && !mainGame->is_siding && root->getElementFromPoint(mouse_pos) == mainGame->imgCard) {
soundManager.PlaySoundEffect(SOUND_CARD_DROP);
ShowBigCard(mainGame->showingcode, 1); ShowBigCard(mainGame->showingcode, 1);
break; break;
} }
...@@ -1112,6 +1116,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) { ...@@ -1112,6 +1116,7 @@ bool DeckBuilder::OnEvent(const irr::SEvent& event) {
case irr::EMIE_LMOUSE_DOUBLE_CLICK: { case irr::EMIE_LMOUSE_DOUBLE_CLICK: {
irr::gui::IGUIElement* root = mainGame->env->getRootGUIElement(); irr::gui::IGUIElement* root = mainGame->env->getRootGUIElement();
if(!is_draging && !mainGame->is_siding && root->getElementFromPoint(mouse_pos) == root && hovered_code) { if(!is_draging && !mainGame->is_siding && root->getElementFromPoint(mouse_pos) == root && hovered_code) {
soundManager.PlaySoundEffect(SOUND_CARD_DROP);
ShowBigCard(hovered_code, 1); ShowBigCard(hovered_code, 1);
break; break;
} }
...@@ -1371,8 +1376,6 @@ void DeckBuilder::GetHoveredCard() { ...@@ -1371,8 +1376,6 @@ void DeckBuilder::GetHoveredCard() {
if(!is_draging && pre_code != hovered_code) { if(!is_draging && pre_code != hovered_code) {
if(hovered_code) if(hovered_code)
mainGame->ShowCardInfo(hovered_code); mainGame->ShowCardInfo(hovered_code);
if(pre_code)
imageManager.RemoveTexture(pre_code);
} }
} }
void DeckBuilder::StartFilter() { void DeckBuilder::StartFilter() {
...@@ -1393,7 +1396,7 @@ void DeckBuilder::FilterCards() { ...@@ -1393,7 +1396,7 @@ void DeckBuilder::FilterCards() {
results.clear(); results.clear();
struct element_t { struct element_t {
std::wstring keyword; std::wstring keyword;
std::vector<unsigned int> setcodes; std::vector<uint32_t> setcodes;
enum class type_t { enum class type_t {
all, all,
name, name,
......
...@@ -905,17 +905,15 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -905,17 +905,15 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
else else
myswprintf(formatBuffer, L""); myswprintf(formatBuffer, L"");
} else { } else {
if(select_continuous) if (select_continuous)
myswprintf(formatBuffer, L"%ls", dataManager.unknown_string); myswprintf(formatBuffer, L"%ls", dataManager.unknown_string);
else if(cant_check_grave && selectable_cards[i]->location == LOCATION_GRAVE) else if (cant_check_grave && selectable_cards[i]->location == LOCATION_GRAVE)
myswprintf(formatBuffer, L"%ls", dataManager.FormatLocation(selectable_cards[i]->location, 0)); myswprintf(formatBuffer, L"%ls", dataManager.FormatLocation(selectable_cards[i]->location, 0));
else if(selectable_cards[i + pos]->location == LOCATION_OVERLAY) else if (selectable_cards[i + pos]->location == LOCATION_OVERLAY)
myswprintf(formatBuffer, L"%ls[%d](%d)", myswprintf(formatBuffer, L"%ls[%d](%d)",
dataManager.FormatLocation(selectable_cards[i + pos]->overlayTarget->location, selectable_cards[i + pos]->overlayTarget->sequence), dataManager.FormatLocation(selectable_cards[i + pos]->overlayTarget), selectable_cards[i + pos]->overlayTarget->sequence + 1, selectable_cards[i + pos]->sequence + 1);
selectable_cards[i + pos]->overlayTarget->sequence + 1, selectable_cards[i + pos]->sequence + 1);
else else
myswprintf(formatBuffer, L"%ls[%d]", dataManager.FormatLocation(selectable_cards[i + pos]->location, selectable_cards[i + pos]->sequence), myswprintf(formatBuffer, L"%ls[%d]", dataManager.FormatLocation(selectable_cards[i + pos]), selectable_cards[i + pos]->sequence + 1);
selectable_cards[i + pos]->sequence + 1);
} }
mainGame->stCardPos[i]->setText(formatBuffer); mainGame->stCardPos[i]->setText(formatBuffer);
// color // color
...@@ -961,13 +959,11 @@ bool ClientField::OnEvent(const irr::SEvent& event) { ...@@ -961,13 +959,11 @@ bool ClientField::OnEvent(const irr::SEvent& event) {
mainGame->btnCardDisplay[i]->setImage(imageManager.tCover[display_cards[i + pos]->controler + 2]); mainGame->btnCardDisplay[i]->setImage(imageManager.tCover[display_cards[i + pos]->controler + 2]);
mainGame->btnCardDisplay[i]->setRelativePosition(irr::core::rect<irr::s32>(30 + i * 125, 55, 30 + 120 + i * 125, 225)); mainGame->btnCardDisplay[i]->setRelativePosition(irr::core::rect<irr::s32>(30 + i * 125, 55, 30 + 120 + i * 125, 225));
wchar_t formatBuffer[2048]; wchar_t formatBuffer[2048];
if(display_cards[i + pos]->location == LOCATION_OVERLAY) { if(display_cards[i + pos]->location == LOCATION_OVERLAY)
myswprintf(formatBuffer, L"%ls[%d](%d)", myswprintf(formatBuffer, L"%ls[%d](%d)",
dataManager.FormatLocation(display_cards[i + pos]->overlayTarget->location, display_cards[i + pos]->overlayTarget->sequence), dataManager.FormatLocation(display_cards[i + pos]->overlayTarget), display_cards[i + pos]->overlayTarget->sequence + 1, display_cards[i + pos]->sequence + 1);
display_cards[i + pos]->overlayTarget->sequence + 1, display_cards[i + pos]->sequence + 1); else
} else myswprintf(formatBuffer, L"%ls[%d]", dataManager.FormatLocation(display_cards[i + pos]), display_cards[i + pos]->sequence + 1);
myswprintf(formatBuffer, L"%ls[%d]", dataManager.FormatLocation(display_cards[i + pos]->location, display_cards[i + pos]->sequence),
display_cards[i + pos]->sequence + 1);
mainGame->stDisplayPos[i]->setText(formatBuffer); mainGame->stDisplayPos[i]->setText(formatBuffer);
if(display_cards[i + pos]->location == LOCATION_OVERLAY) { if(display_cards[i + pos]->location == LOCATION_OVERLAY) {
if(display_cards[i + pos]->owner != display_cards[i + pos]->overlayTarget->controler) if(display_cards[i + pos]->owner != display_cards[i + pos]->overlayTarget->controler)
......
...@@ -1135,16 +1135,13 @@ void Game::InitStaticText(irr::gui::IGUIStaticText* pControl, irr::u32 cWidth, i ...@@ -1135,16 +1135,13 @@ void Game::InitStaticText(irr::gui::IGUIStaticText* pControl, irr::u32 cWidth, i
scrCardText->setPos(0); scrCardText->setPos(0);
} }
std::wstring Game::SetStaticText(irr::gui::IGUIStaticText* pControl, irr::u32 cWidth, irr::gui::CGUITTFont* font, const wchar_t* text, irr::u32 pos) { std::wstring Game::SetStaticText(irr::gui::IGUIStaticText* pControl, irr::u32 cWidth, irr::gui::CGUITTFont* font, const wchar_t* text, irr::u32 pos) {
size_t pbuffer = 0;
irr::u32 _width = 0, _height = 0; irr::u32 _width = 0, _height = 0;
wchar_t prev = 0; wchar_t prev = 0;
wchar_t strBuffer[4096]{}; std::wstring result;
constexpr size_t buffer_len = sizeof strBuffer / sizeof strBuffer[0] - 1; result.reserve(4096);
const size_t text_len = std::wcslen(text); const size_t text_len = std::wcslen(text);
for(size_t i = 0; i < text_len ; ++i) { for(size_t i = 0; i < text_len ; ++i) {
if (pbuffer >= buffer_len)
break;
wchar_t c = text[i]; wchar_t c = text[i];
irr::u32 w = font->getCharDimension(c).Width + font->getKerningWidth(c, prev); irr::u32 w = font->getCharDimension(c).Width + font->getKerningWidth(c, prev);
prev = c; prev = c;
...@@ -1152,31 +1149,28 @@ std::wstring Game::SetStaticText(irr::gui::IGUIStaticText* pControl, irr::u32 cW ...@@ -1152,31 +1149,28 @@ std::wstring Game::SetStaticText(irr::gui::IGUIStaticText* pControl, irr::u32 cW
continue; continue;
} }
if (c == L'\n') { if (c == L'\n') {
strBuffer[pbuffer++] = L'\n'; result.push_back(L'\n');
_width = 0; _width = 0;
_height++; _height++;
prev = 0; prev = 0;
if (_height == pos) if (_height == pos)
pbuffer = 0; result.clear();
continue; continue;
} }
if (_width > 0 && _width + w > cWidth) { if (_width > 0 && _width + w > cWidth) {
strBuffer[pbuffer++] = L'\n'; result.push_back(L'\n');
_width = 0; _width = 0;
_height++; _height++;
prev = 0; prev = 0;
if (_height == pos) if (_height == pos)
pbuffer = 0; result.clear();
} }
if (pbuffer >= buffer_len)
break;
_width += w; _width += w;
strBuffer[pbuffer++] = c; result.push_back(c);
} }
strBuffer[pbuffer] = 0;
if (pControl) if (pControl)
pControl->setText(strBuffer); pControl->setText(result.c_str());
return std::wstring(strBuffer); return result;
} }
#endif //YGOPRO_SERVER_MODE #endif //YGOPRO_SERVER_MODE
void Game::LoadExpansions() { void Game::LoadExpansions() {
...@@ -1397,8 +1391,6 @@ void Game::LoadConfig() { ...@@ -1397,8 +1391,6 @@ void Game::LoadConfig() {
gameConf.antialias = std::strtol(valbuf, nullptr, 10); gameConf.antialias = std::strtol(valbuf, nullptr, 10);
} else if(!std::strcmp(strbuf, "use_d3d")) { } else if(!std::strcmp(strbuf, "use_d3d")) {
gameConf.use_d3d = std::strtol(valbuf, nullptr, 10) > 0; gameConf.use_d3d = std::strtol(valbuf, nullptr, 10) > 0;
} else if(!std::strcmp(strbuf, "use_image_scale")) {
gameConf.use_image_scale = std::strtol(valbuf, nullptr, 10) > 0;
} else if (!std::strcmp(strbuf, "use_image_scale_multi_thread")) { } else if (!std::strcmp(strbuf, "use_image_scale_multi_thread")) {
gameConf.use_image_scale_multi_thread = std::strtol(valbuf, nullptr, 10) > 0; gameConf.use_image_scale_multi_thread = std::strtol(valbuf, nullptr, 10) > 0;
} else if (!std::strcmp(strbuf, "use_image_load_background_thread")) { } else if (!std::strcmp(strbuf, "use_image_load_background_thread")) {
...@@ -1533,7 +1525,6 @@ void Game::SaveConfig() { ...@@ -1533,7 +1525,6 @@ void Game::SaveConfig() {
std::fprintf(fp, "#config file\n#nickname & gamename should be less than 20 characters\n"); std::fprintf(fp, "#config file\n#nickname & gamename should be less than 20 characters\n");
char linebuf[CONFIG_LINE_SIZE]; char linebuf[CONFIG_LINE_SIZE];
std::fprintf(fp, "use_d3d = %d\n", gameConf.use_d3d ? 1 : 0); std::fprintf(fp, "use_d3d = %d\n", gameConf.use_d3d ? 1 : 0);
std::fprintf(fp, "use_image_scale = %d\n", gameConf.use_image_scale ? 1 : 0);
std::fprintf(fp, "use_image_scale_multi_thread = %d\n", gameConf.use_image_scale_multi_thread ? 1 : 0); std::fprintf(fp, "use_image_scale_multi_thread = %d\n", gameConf.use_image_scale_multi_thread ? 1 : 0);
std::fprintf(fp, "use_image_load_background_thread = %d\n", gameConf.use_image_load_background_thread ? 1 : 0); std::fprintf(fp, "use_image_load_background_thread = %d\n", gameConf.use_image_load_background_thread ? 1 : 0);
std::fprintf(fp, "antialias = %d\n", gameConf.antialias); std::fprintf(fp, "antialias = %d\n", gameConf.antialias);
......
...@@ -57,7 +57,6 @@ bool IsExtension(const char* filename, const char(&extension)[N]) { ...@@ -57,7 +57,6 @@ bool IsExtension(const char* filename, const char(&extension)[N]) {
#ifndef YGOPRO_SERVER_MODE #ifndef YGOPRO_SERVER_MODE
struct Config { struct Config {
bool use_d3d{ false }; bool use_d3d{ false };
bool use_image_scale{ true };
bool use_image_scale_multi_thread{ true }; bool use_image_scale_multi_thread{ true };
#ifdef _OPENMP #ifdef _OPENMP
bool use_image_load_background_thread{ false }; bool use_image_load_background_thread{ false };
......
This diff is collapsed.
...@@ -10,13 +10,17 @@ ...@@ -10,13 +10,17 @@
namespace ygo { namespace ygo {
class ImageManager { class ImageManager {
private:
void resizeImage(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading);
irr::video::ITexture* addTexture(const char* name, irr::video::IImage* srcimg, irr::s32 width, irr::s32 height);
public: public:
bool Initial(); bool Initial();
void SetDevice(irr::IrrlichtDevice* dev); void SetDevice(irr::IrrlichtDevice* dev);
void ClearTexture(); void ClearTexture();
void RemoveTexture(int code);
void ResizeTexture(); void ResizeTexture();
irr::video::ITexture* GetTextureFromFile(const char* file, irr::s32 width, irr::s32 height); irr::video::ITexture* GetTextureFromFile(const char* file, irr::s32 width, irr::s32 height);
irr::video::IImage* GetImage(int code);
irr::video::ITexture* GetTexture(int code, irr::s32 width, irr::s32 height);
irr::video::ITexture* GetTexture(int code, bool fit = false); irr::video::ITexture* GetTexture(int code, bool fit = false);
irr::video::ITexture* GetBigPicture(int code, float zoom); irr::video::ITexture* GetBigPicture(int code, float zoom);
irr::video::ITexture* GetTextureThumb(int code); irr::video::ITexture* GetTextureThumb(int code);
......
#include "image_resizer.h"
#include <cmath>
#ifdef _OPENMP
#include <omp.h>
#endif
#define STB_IMAGE_RESIZE2_IMPLEMENTATION
#include "stb_image_resize2.h"
namespace ygo {
ImageResizer imageResizer;
struct StbSamplerCache {
STBIR_RESIZE resize{};
int in_w = 0;
int in_h = 0;
int out_w = 0;
int out_h = 0;
stbir_pixel_layout layout = STBIR_BGRA;
bool samplers_built = false;
~StbSamplerCache() {
if(samplers_built) {
stbir_free_samplers(&resize);
samplers_built = false;
}
}
void reset_if_needed(int new_in_w, int new_in_h, int new_out_w, int new_out_h, stbir_pixel_layout new_layout) {
if(new_in_w == in_w && new_in_h == in_h && new_out_w == out_w && new_out_h == out_h && new_layout == layout)
return;
if(samplers_built) {
stbir_free_samplers(&resize);
samplers_built = false;
}
in_w = new_in_w;
in_h = new_in_h;
out_w = new_out_w;
out_h = new_out_h;
layout = new_layout;
resize = STBIR_RESIZE{};
}
};
/**
* Scale image using stb_image_resize2.
* Returns true on success, false on failure or unsupported format.
*/
bool ImageResizer::imageScaleSTB(irr::video::IImage* src, irr::video::IImage* dest) {
if(!src || !dest)
return false;
const auto srcDim = src->getDimension();
const auto destDim = dest->getDimension();
if(srcDim.Width == 0 || srcDim.Height == 0 || destDim.Width == 0 || destDim.Height == 0)
return false;
if(src->getColorFormat() != dest->getColorFormat())
return false;
stbir_pixel_layout layout = STBIR_BGRA;
// Fast-paths (8-bit per channel only):
// - ECF_A8R8G8B8: Irrlicht stores as BGRA in memory on little-endian.
// - ECF_R8G8B8: common for JPEGs (3 channels).
switch(src->getColorFormat()) {
case irr::video::ECF_A8R8G8B8:
layout = STBIR_BGRA;
break;
case irr::video::ECF_R8G8B8:
layout = STBIR_RGB;
break;
default:
return false;
}
void* srcPtr = src->lock();
if(!srcPtr)
return false;
void* destPtr = dest->lock();
if(!destPtr) {
src->unlock();
return false;
}
const int srcStride = (int)src->getPitch();
const int destStride = (int)dest->getPitch();
thread_local StbSamplerCache cache;
cache.reset_if_needed((int)srcDim.Width, (int)srcDim.Height, (int)destDim.Width, (int)destDim.Height, layout);
if(!cache.samplers_built) {
stbir_resize_init(&cache.resize,
srcPtr, (int)srcDim.Width, (int)srcDim.Height, srcStride,
destPtr, (int)destDim.Width, (int)destDim.Height, destStride,
layout, STBIR_TYPE_UINT8);
stbir_set_edgemodes(&cache.resize, STBIR_EDGE_CLAMP, STBIR_EDGE_CLAMP);
// Use box filters to reduce aliasing when downscaling.
stbir_set_filters(&cache.resize, STBIR_FILTER_BOX, STBIR_FILTER_BOX);
cache.samplers_built = (stbir_build_samplers(&cache.resize) != 0);
if(!cache.samplers_built) {
dest->unlock();
src->unlock();
return false;
}
} else {
// Reuse samplers but update buffer pointers for the current images
stbir_set_buffer_ptrs(&cache.resize, srcPtr, srcStride, destPtr, destStride);
}
const int ok = stbir_resize_extended(&cache.resize);
dest->unlock();
src->unlock();
return ok != 0;
}
/**
* Scale image using nearest neighbor anti-aliasing.
* Function by Warr1024, from https://github.com/minetest/minetest/issues/2419, modified.
*/
void ImageResizer::imageScaleNNAA(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading) {
const auto& srcDim = src->getDimension();
const auto& destDim = dest->getDimension();
if (destDim.Width == 0 || destDim.Height == 0)
return;
// Cache scale ratios.
const double rx = (double)srcDim.Width / destDim.Width;
const double ry = (double)srcDim.Height / destDim.Height;
#pragma omp parallel if(use_threading)
{
// Walk each destination image pixel.
#pragma omp for schedule(dynamic)
for(irr::s32 dy = 0; dy < (irr::s32)destDim.Height; dy++) {
for(irr::s32 dx = 0; dx < (irr::s32)destDim.Width; dx++) {
// Calculate floating-point source rectangle bounds.
double minsx = dx * rx;
double maxsx = minsx + rx;
double minsy = dy * ry;
double maxsy = minsy + ry;
irr::u32 sx_begin = (irr::u32)std::floor(minsx);
irr::u32 sx_end = (irr::u32)std::ceil(maxsx);
if (sx_end > srcDim.Width)
sx_end = srcDim.Width;
irr::u32 sy_begin = (irr::u32)std::floor(minsy);
irr::u32 sy_end = (irr::u32)std::ceil(maxsy);
if (sy_end > srcDim.Height)
sy_end = srcDim.Height;
// Total area, and integral of r, g, b values over that area,
// initialized to zero, to be summed up in next loops.
double area = 0, ra = 0, ga = 0, ba = 0, aa = 0;
irr::video::SColor pxl, npxl;
// Loop over the integral pixel positions described by those bounds.
for(irr::u32 sy = sy_begin; sy < sy_end; sy++) {
for(irr::u32 sx = sx_begin; sx < sx_end; sx++) {
// Calculate width, height, then area of dest pixel
// that's covered by this source pixel.
double pw = 1;
if(minsx > sx)
pw += sx - minsx;
if(maxsx < (sx + 1))
pw += maxsx - sx - 1;
double ph = 1;
if(minsy > sy)
ph += sy - minsy;
if(maxsy < (sy + 1))
ph += maxsy - sy - 1;
double pa = pw * ph;
// Get source pixel and add it to totals, weighted
// by covered area and alpha.
pxl = src->getPixel(sx, sy);
area += pa;
ra += pa * pxl.getRed();
ga += pa * pxl.getGreen();
ba += pa * pxl.getBlue();
aa += pa * pxl.getAlpha();
}
}
// Set the destination image pixel to the average color.
if(area > 0) {
npxl.set((irr::u32)(aa / area + 0.5),
(irr::u32)(ra / area + 0.5),
(irr::u32)(ga / area + 0.5),
(irr::u32)(ba / area + 0.5));
} else {
npxl.set(0);
}
dest->setPixel(dx, dy, npxl);
}
}
} // end of parallel region
}
void ImageResizer::resize(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading) {
if(imageScaleSTB(src, dest))
return;
imageScaleNNAA(src, dest, use_threading);
}
} // namespace ygo
#ifndef IMAGE_RESIZER_H
#define IMAGE_RESIZER_H
#include <irrlicht.h>
namespace ygo {
class ImageResizer {
private:
bool imageScaleSTB(irr::video::IImage* src, irr::video::IImage* dest);
void imageScaleNNAA(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading);
public:
void resize(irr::video::IImage* src, irr::video::IImage* dest, bool use_threading);
};
extern ImageResizer imageResizer;
} // namespace ygo
#endif // IMAGE_RESIZER_H
...@@ -8,8 +8,10 @@ ...@@ -8,8 +8,10 @@
#ifndef _WIN32 #ifndef _WIN32
#include <dirent.h> #include <dirent.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <unistd.h>
#include <vector> #include <vector>
#include <algorithm> #include <algorithm>
#include <string>
#endif #endif
#ifdef _WIN32 #ifdef _WIN32
...@@ -182,7 +184,7 @@ public: ...@@ -182,7 +184,7 @@ public:
bool success = true; bool success = true;
TraversalDir(dir, [dir, &success](const char *name, bool isdir) { TraversalDir(dir, [dir, &success](const char *name, bool isdir) {
char full_path[1024]; char full_path[1024];
int len = mysnprintf(full_path, "%s/%s", dir, name); int len = std::snprintf(full_path, sizeof(full_path), "%s/%s", dir, name);
if (len < 0 || len >= (int)(sizeof full_path)) { if (len < 0 || len >= (int)(sizeof full_path)) {
success = false; success = false;
return; return;
...@@ -234,7 +236,7 @@ public: ...@@ -234,7 +236,7 @@ public:
file_unit funit; file_unit funit;
#endif #endif
char fname[1024]; char fname[1024];
int len = mysnprintf(fname, "%s/%s", path, dirp->d_name); int len = std::snprintf(fname, sizeof(fname), "%s/%s", path, dirp->d_name);
if (len < 0 || len >= (int)(sizeof fname)) if (len < 0 || len >= (int)(sizeof fname))
continue; continue;
stat(fname, &fileStat); stat(fname, &fileStat);
......
...@@ -88,143 +88,142 @@ void SoundManager::PlaySoundEffect(int sound) { ...@@ -88,143 +88,142 @@ void SoundManager::PlaySoundEffect(int sound) {
#ifdef YGOPRO_USE_AUDIO #ifdef YGOPRO_USE_AUDIO
if(!mainGame->chkEnableSound->isChecked()) if(!mainGame->chkEnableSound->isChecked())
return; return;
char soundName[32]; std::string soundName;
switch(sound) { switch(sound) {
case SOUND_SUMMON: { case SOUND_SUMMON: {
strcpy(soundName, "summon"); soundName = "summon";
break; break;
} }
case SOUND_SPECIAL_SUMMON: { case SOUND_SPECIAL_SUMMON: {
strcpy(soundName, "specialsummon"); soundName = "specialsummon";
break; break;
} }
case SOUND_ACTIVATE: { case SOUND_ACTIVATE: {
strcpy(soundName, "activate"); soundName = "activate";
break; break;
} }
case SOUND_SET: { case SOUND_SET: {
strcpy(soundName, "set"); soundName = "set";
break; break;
} }
case SOUND_FLIP: { case SOUND_FLIP: {
strcpy(soundName, "flip"); soundName = "flip";
break; break;
} }
case SOUND_REVEAL: { case SOUND_REVEAL: {
strcpy(soundName, "reveal"); soundName = "reveal";
break; break;
} }
case SOUND_EQUIP: { case SOUND_EQUIP: {
strcpy(soundName, "equip"); soundName = "equip";
break; break;
} }
case SOUND_DESTROYED: { case SOUND_DESTROYED: {
strcpy(soundName, "destroyed"); soundName = "destroyed";
break; break;
} }
case SOUND_BANISHED: { case SOUND_BANISHED: {
strcpy(soundName, "banished"); soundName = "banished";
break; break;
} }
case SOUND_TOKEN: { case SOUND_TOKEN: {
strcpy(soundName, "token"); soundName = "token";
break; break;
} }
case SOUND_NEGATE: { case SOUND_NEGATE: {
strcpy(soundName, "negate"); soundName = "negate";
break; break;
} }
case SOUND_ATTACK: { case SOUND_ATTACK: {
strcpy(soundName, "attack"); soundName = "attack";
break; break;
} }
case SOUND_DIRECT_ATTACK: { case SOUND_DIRECT_ATTACK: {
strcpy(soundName, "directattack"); soundName = "directattack";
break; break;
} }
case SOUND_DRAW: { case SOUND_DRAW: {
strcpy(soundName, "draw"); soundName = "draw";
break; break;
} }
case SOUND_SHUFFLE: { case SOUND_SHUFFLE: {
strcpy(soundName, "shuffle"); soundName = "shuffle";
break; break;
} }
case SOUND_DAMAGE: { case SOUND_DAMAGE: {
strcpy(soundName, "damage"); soundName = "damage";
break; break;
} }
case SOUND_RECOVER: { case SOUND_RECOVER: {
strcpy(soundName, "gainlp"); soundName = "gainlp";
break; break;
} }
case SOUND_COUNTER_ADD: { case SOUND_COUNTER_ADD: {
strcpy(soundName, "addcounter"); soundName = "addcounter";
break; break;
} }
case SOUND_COUNTER_REMOVE: { case SOUND_COUNTER_REMOVE: {
strcpy(soundName, "removecounter"); soundName = "removecounter";
break; break;
} }
case SOUND_COIN: { case SOUND_COIN: {
strcpy(soundName, "coinflip"); soundName = "coinflip";
break; break;
} }
case SOUND_DICE: { case SOUND_DICE: {
strcpy(soundName, "diceroll"); soundName = "diceroll";
break; break;
} }
case SOUND_NEXT_TURN: { case SOUND_NEXT_TURN: {
strcpy(soundName, "nextturn"); soundName = "nextturn";
break; break;
} }
case SOUND_PHASE: { case SOUND_PHASE: {
strcpy(soundName, "phase"); soundName = "phase";
break; break;
} }
case SOUND_MENU: { case SOUND_MENU: {
strcpy(soundName, "menu"); soundName = "menu";
break; break;
} }
case SOUND_BUTTON: { case SOUND_BUTTON: {
strcpy(soundName, "button"); soundName = "button";
break; break;
} }
case SOUND_INFO: { case SOUND_INFO: {
strcpy(soundName, "info"); soundName = "info";
break; break;
} }
case SOUND_QUESTION: { case SOUND_QUESTION: {
strcpy(soundName, "question"); soundName = "question";
break; break;
} }
case SOUND_CARD_PICK: { case SOUND_CARD_PICK: {
strcpy(soundName, "cardpick"); soundName = "cardpick";
break; break;
} }
case SOUND_CARD_DROP: { case SOUND_CARD_DROP: {
strcpy(soundName, "carddrop"); soundName = "carddrop";
break; break;
} }
case SOUND_PLAYER_ENTER: { case SOUND_PLAYER_ENTER: {
strcpy(soundName, "playerenter"); soundName = "playerenter";
break; break;
} }
case SOUND_CHAT: { case SOUND_CHAT: {
strcpy(soundName, "chatmessage"); soundName = "chatmessage";
break; break;
} }
default: default:
break; return;
} }
char soundPath[40]; std::string soundPath = "./sound/" + soundName + ".wav";
mysnprintf(soundPath, "./sound/%s.wav", soundName);
SetSoundVolume(mainGame->gameConf.sound_volume); SetSoundVolume(mainGame->gameConf.sound_volume);
#ifdef YGOPRO_USE_MINIAUDIO #ifdef YGOPRO_USE_MINIAUDIO
ma_engine_play_sound(&engineSound, soundPath, nullptr); ma_engine_play_sound(&engineSound, soundPath.c_str(), nullptr);
#endif #endif
#ifdef YGOPRO_USE_IRRKLANG #ifdef YGOPRO_USE_IRRKLANG
engineSound->play2D(soundPath); engineSound->play2D(soundPath.c_str());
#endif #endif
#endif // YGOPRO_USE_AUDIO #endif // YGOPRO_USE_AUDIO
} }
......
This diff is collapsed.
This diff is collapsed.
...@@ -671,6 +671,7 @@ ...@@ -671,6 +671,7 @@
!counter 0x70 盘子指示物 !counter 0x70 盘子指示物
!counter 0x71 纠罪指示物 !counter 0x71 纠罪指示物
!counter 0x1072 少女指示物 !counter 0x1072 少女指示物
!counter 0x73 T指示物
#setnames, using tab for comment #setnames, using tab for comment
!setname 0x1 正义盟军 AOJ !setname 0x1 正义盟军 AOJ
!setname 0x2 次世代 ジェネクス !setname 0x2 次世代 ジェネクス
...@@ -832,7 +833,7 @@ ...@@ -832,7 +833,7 @@
!setname 0x106e 魔导书 魔導書 !setname 0x106e 魔导书 魔導書
!setname 0x6f 英豪 ヒロイック !setname 0x6f 英豪 ヒロイック
!setname 0x106f 英豪挑战者 HC !setname 0x106f 英豪挑战者 HC
#setname 0x206f 英豪冠军 H-C !setname 0x206f 英豪冠军 HC
!setname 0x70 先史遗产 先史遺産 !setname 0x70 先史遗产 先史遺産
!setname 0x71 魔偶甜点 マドルチェ !setname 0x71 魔偶甜点 マドルチェ
!setname 0x72 齿轮齿轮 ギアギア !setname 0x72 齿轮齿轮 ギアギア
...@@ -1278,3 +1279,6 @@ ...@@ -1278,3 +1279,6 @@
!setname 0x1d8 耀圣 エルフェンノーツ !setname 0x1d8 耀圣 エルフェンノーツ
!setname 0x1d9 磁力 マグネット !setname 0x1d9 磁力 マグネット
!setname 0x1da 世界末日 エンド・オブ・ザ・ワールド !setname 0x1da 世界末日 エンド・オブ・ザ・ワールド
!setname 0x1db 妖精传姬 妖精伝姫
!setname 0x1dc 道化一座 道化の一座
!setname 0x1dd GMX
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment