Skip to content

Commit

Permalink
Fixed issue where localized strings would not be copied during copy c…
Browse files Browse the repository at this point in the history
…onstructor

Fixed in-game sex change by updating CurrentTemplate field
  • Loading branch information
dairymoose committed Sep 1, 2014
1 parent 47e7458 commit e7a591e
Show file tree
Hide file tree
Showing 7 changed files with 146 additions and 44 deletions.
72 changes: 45 additions & 27 deletions AppearanceEditorFrame.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -191,11 +191,11 @@ void AppearanceEditorFrame::updateAllFields() {
changeFieldValue("underwearLabel", underwearIdx, underwears);

updateToCurrentPortrait();
updateToCurrentSkinColor();
updateToCurrentHairColor();
updateToCurrentHair();
updateToCurrentHead();
updateToCurrentUnderwear();

updatePortraitData();
}

void AppearanceEditorFrame::generateFields() {
Expand Down Expand Up @@ -674,8 +674,8 @@ void AppearanceEditorFrame::initIndexesToCustomData() {
LsbObject *randomObject = playerCustomDataObject->lookupByUniquePath("Random");
if (randomObject != 0) {
unsigned long random = *((unsigned long*)randomObject->getData());
hairIdx = (random & 0xF0) >> 4;
underwearIdx = (random & 0xF00) >> 8;
hairIdx = (random & 0xF00) >> 4;
underwearIdx = (random & 0xF0) >> 8;
headIdx = (random & 0x0F);
}
LsbObject *hairColorObject = playerCustomDataObject->lookupByUniquePath("HairColor");
Expand Down Expand Up @@ -841,7 +841,7 @@ void AppearanceEditorFrame::setup() {
generateFields();
initIndexesToCustomData();
updateAllFields();
loadEquipmentData();
//loadEquipmentData();
}

AppearanceEditorFrame::~AppearanceEditorFrame()
Expand Down Expand Up @@ -906,6 +906,22 @@ void AppearanceEditorFrame::updatePortraitImage() {
// }
}

void AppearanceEditorFrame::updatePortraitData() {
LsbObject *iconObject = playerCustomDataObject->lookupByUniquePath("Icon");
if (iconObject != 0) {
iconObject->setData(portrait.c_str(), portrait.length() + 1);
}
updatePortraitImage();
}

void AppearanceEditorFrame::updateColorData(const char *colorPath, VertexRGB *colorInfo) {
LsbObject *colorObject = playerCustomDataObject->lookupByUniquePath(colorPath);
if (colorObject != 0) {
unsigned long color = (colorInfo->a << 24) | (colorInfo->r << 16) | (colorInfo->g << 8) | (colorInfo->b);
colorObject->setData((char *)&color, sizeof(color));
}
}

void AppearanceEditorFrame::updateObjectValue(const char *labelName, int& idx, std::vector<fieldValue_t> &vec) {
std::string label;
fieldValue_t &newFieldValue = vec[idx];
Expand All @@ -914,11 +930,7 @@ void AppearanceEditorFrame::updateObjectValue(const char *labelName, int& idx, s
label = "portraitLabel";
if (labelName == label) {
portrait = newValue;
LsbObject *iconObject = playerCustomDataObject->lookupByUniquePath("Icon");
if (iconObject != 0) {
iconObject->setData(portrait.c_str(), portrait.length() + 1);
}
updatePortraitImage();
updatePortraitData();
return;
}
label = "aiPersonalityLabel";
Expand All @@ -939,11 +951,7 @@ void AppearanceEditorFrame::updateObjectValue(const char *labelName, int& idx, s
}
label = "skinColorLabel";
if (labelName == label) {
LsbObject *skinColorObject = playerCustomDataObject->lookupByUniquePath("SkinColor");
if (skinColorObject != 0) {
unsigned long color = (skinColor->a << 24) | (skinColor->r << 16) | (skinColor->g << 8) | (skinColor->b);
skinColorObject->setData((char *)&color, sizeof(color));
}
updateColorData("SkinColor", skinColor);
return;
}
label = "headLabel";
Expand All @@ -961,26 +969,22 @@ void AppearanceEditorFrame::updateObjectValue(const char *labelName, int& idx, s
LsbObject *randomObject = playerCustomDataObject->lookupByUniquePath("Random");
if (randomObject != 0) {
unsigned long random = *((unsigned long*)randomObject->getData());
random = (random & 0xFFFFFF0F) | hairIdx;
random = (random & 0xFFFFF0FF) | (hairIdx << 8);
randomObject->setData((char *)&random, sizeof(random));
}
return;
}
label = "hairColorLabel";
if (labelName == label) {
LsbObject *hairColorObject = playerCustomDataObject->lookupByUniquePath("HairColor");
if (hairColorObject != 0) {
unsigned long color = (hairColor->a << 24) | (hairColor->r << 16) | (hairColor->g << 8) | (hairColor->b);
hairColorObject->setData((char *)&color, sizeof(color));
}
updateColorData("HairColor", hairColor);
return;
}
label = "underwearLabel";
if (labelName == label) {
LsbObject *randomObject = playerCustomDataObject->lookupByUniquePath("Random");
if (randomObject != 0) {
unsigned long random = *((unsigned long*)randomObject->getData());
random = (random & 0xFFFFF0FF) | underwearIdx;
random = (random & 0xFFFFFF0F) | (underwearIdx << 4);
randomObject->setData((char *)&random, sizeof(random));
}
return;
Expand Down Expand Up @@ -1058,12 +1062,14 @@ void AppearanceEditorFrame::on_skinColorPrev_clicked()
{
changeFieldValue("skinColorLabel", skinColorIdx, skinColors, -1);
updateToCurrentSkinColor();
updateColorData("SkinColor", skinColor);
}

void AppearanceEditorFrame::on_skinColorNext_clicked()
{
changeFieldValue("skinColorLabel", skinColorIdx, skinColors, 1);
updateToCurrentSkinColor();
updateColorData("SkinColor", skinColor);
}

void AppearanceEditorFrame::on_headPrev_clicked()
Expand Down Expand Up @@ -1255,12 +1261,14 @@ void AppearanceEditorFrame::on_hairColorPrev_clicked()
{
changeFieldValue("hairColorLabel", hairColorIdx, hairColors, -1);
updateToCurrentHairColor();
updateColorData("HairColor", hairColor);
}

void AppearanceEditorFrame::on_hairColorNext_clicked()
{
changeFieldValue("hairColorLabel", hairColorIdx, hairColors, 1);
updateToCurrentHairColor();
updateColorData("HairColor", hairColor);
}

void AppearanceEditorFrame::on_underwearPrev_clicked()
Expand Down Expand Up @@ -1291,7 +1299,7 @@ void AppearanceEditorFrame::on_skinColorPicker_clicked()
skinColor->g = selected.green();
skinColor->b = selected.blue();
skinColor->a = selected.alpha();
updateObjectValue("skinColorLabel", skinColorIdx, skinColors);
updateColorData("SkinColor", skinColor);
}
}

Expand All @@ -1306,7 +1314,7 @@ void AppearanceEditorFrame::on_hairColorPicker_clicked()
hairColor->g = selected.green();
hairColor->b = selected.blue();
hairColor->a = selected.alpha();
updateObjectValue("hairColorLabel", hairColorIdx, hairColors);
updateColorData("HairColor", hairColor);
}
}
GamePakData *AppearanceEditorFrame::getGamePakData() const
Expand All @@ -1319,6 +1327,11 @@ void AppearanceEditorFrame::setGamePakData(GamePakData *value)
gamePakData = value;
}

void AppearanceEditorFrame::registerAppearanceChangeCallback(AppearanceChangeCallback *appearanceChangeCallback)
{
this->appearanceChangeCallback = appearanceChangeCallback;
}

EquipmentHandler *AppearanceEditorFrame::getEquipHandler() const
{
return equipHandler;
Expand All @@ -1344,9 +1357,6 @@ void AppearanceEditorFrame::on_armorToggleButton_clicked()
success = success && glContext->removeGrannyScene(eid.scene);
}
}
if (!success || sceneCount == glContext->getSceneCount()) {
MessageBoxA(0, "Toggle failure", 0, 0);
}
}

void AppearanceEditorFrame::on_femaleButton_clicked()
Expand All @@ -1372,3 +1382,11 @@ void AppearanceEditorFrame::on_portraitNext_clicked()
changeFieldValue("portraitLabel", portraitIdx, portraits, 1);
updatePortraitImage();
}

void AppearanceEditorFrame::on_applyButton_clicked()
{
if (appearanceChangeCallback != 0) {
appearanceChangeCallback->onAppearanceChange(this->oldPlayerCustomDataObject, this->playerCustomDataObject);
}
this->close();
}
11 changes: 11 additions & 0 deletions AppearanceEditorFrame.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,11 @@ typedef struct {
MeshAttachmentPoint *attachmentPoint;
} equippedItemData_t;

class AppearanceChangeCallback {
public:
virtual void onAppearanceChange(LsbObject *oldPlayerCustomDataObject, LsbObject *newPlayerCustomDataObject) = 0;
};

class AppearanceEditorFrame : public QFrame
{
Q_OBJECT
Expand All @@ -54,6 +59,7 @@ class AppearanceEditorFrame : public QFrame

GamePakData *getGamePakData() const;
void setGamePakData(GamePakData *value);
void registerAppearanceChangeCallback(AppearanceChangeCallback *appearanceChangeCallback);

private slots:
void on_aiPersonalityNext_clicked();
Expand Down Expand Up @@ -100,6 +106,8 @@ private slots:

void on_portraitNext_clicked();

void on_applyButton_clicked();

private:
std::vector<fieldValue_t> portraits;
std::vector<fieldValue_t> aiPersonalities;
Expand Down Expand Up @@ -136,6 +144,7 @@ private slots:
GameCharacter *character;
LsbObject *oldPlayerCustomDataObject = 0;
LsbObject *playerCustomDataObject = 0;
AppearanceChangeCallback *appearanceChangeCallback = 0;

std::string portrait;
VertexRGB *skinColor = 0;
Expand All @@ -161,13 +170,15 @@ private slots:
std::string getTextureFromTextureTemplate(LsbObject *resourceBankObject, std::string &textureTemplate);
bool getTextureMaps(LsbObject *resourceBankObject, LsbObject *materialsResourceBankObject, std::string &visualTemplate, std::string &diffuseMap, std::string &normalMap, std::string &maskMap);
void updateToCurrentModel(ZGrannyScene *&current, std::vector<fieldValue_t> &models, std::vector<fieldValue_t> &textures, int index, VertexRGB *foreColor, VertexRGB *backColor);
void updatePortraitData();
void updateToCurrentPortrait();
void updatePortraitImage();
void updateToCurrentHead();
void updateToCurrentHair();
void updateToCurrentUnderwear();
void updateToCurrentSkinColor();
void updateToCurrentHairColor();
void updateColorData(const char *colorPath, VertexRGB *colorInfo);
ZGrannyScene *createModelForItem(GameItem *item, std::vector<GLuint > &textures);
void setup();
void generateFields();
Expand Down
12 changes: 12 additions & 0 deletions GameCharacter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,18 @@ unsigned long GameCharacter::getCreatorId() {
return 0;
}

LsbObject *GameCharacter::getPlayerCustomDataObject() {
LsbObject *characterObject = this->getObject();
if (characterObject != 0) {
LsbObject *playerDataObject = characterObject->lookupByUniquePath("PlayerData");
if (playerDataObject != 0) {
LsbObject *playerCustomDataObject = playerDataObject->lookupByUniquePath("PlayerCustomData");
return playerCustomDataObject;
}
}
return 0;
}

void GameCharacter::ensureInventoryCapacity(LsbObject *viewMapValueObject, unsigned long viewSlot) {
std::vector<LsbObject *> itemsObjects = LsbObject::lookupAllEntitiesWithName(viewMapValueObject, "Items");
long additionalSlotsRequired = (viewSlot + 1) - itemsObjects.size();
Expand Down
1 change: 1 addition & 0 deletions GameCharacter.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ class GameCharacter
LsbObject *getInventoryObject();
unsigned long getInventoryId();
unsigned long getCreatorId();
LsbObject *getPlayerCustomDataObject();
bool addItemToInventoryObject(LsbObject *itemCreatorObject, unsigned long viewSlot, unsigned long extraInventoryTab, unsigned long extraViewSlot, bool equippedItem);
};

Expand Down
2 changes: 2 additions & 0 deletions LsbObject.h
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,8 @@ class LsbObject {
this->bIsDirectory = other.bIsDirectory;
this->parent = other.parent;
this->tagList = other.tagList;
this->localized1 = other.localized1;
this->localized2 = other.localized2;
}

static TAG_LSB *getTagByName(const char *name, std::vector<TAG_LSB *> *tagList)
Expand Down
86 changes: 70 additions & 16 deletions charactertab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -293,6 +293,7 @@ void characterTab::setCharacter(GameCharacter *character) {
}

appearanceEditorFrame = new AppearanceEditorFrame(gameDataPath, character);
appearanceEditorFrame->registerAppearanceChangeCallback(this);
}

characterTab::~characterTab()
Expand Down Expand Up @@ -343,30 +344,83 @@ void characterTab::setGamePakData(GamePakData *value)
appearanceEditorFrame->setGamePakData(gamePakData);
}

void characterTab::updateToCurrentPortrait() {
QLabel *portraitLabel = this->findChild<QLabel *>("portraitLabel");
LsbObject *characterObject = character->getObject();
if (characterObject != 0) {
LsbObject *playerDataObject = characterObject->lookupByUniquePath("PlayerData");
void characterTab::onAppearanceChange(LsbObject *oldPlayerCustomDataObject, LsbObject *newPlayerCustomDataObject) {
if (oldPlayerCustomDataObject == 0 || newPlayerCustomDataObject == 0) {
return;
}
LsbObject *copyOldPlayerCustomDataObject = new LsbObject(*oldPlayerCustomDataObject);
LsbObject *copyPlayerCustomDataObject = new LsbObject(*newPlayerCustomDataObject);
bool success = false;
LsbObject *playerCustomDataObject = character->getPlayerCustomDataObject();
if (playerCustomDataObject != 0) {
LsbObject *playerDataObject = playerCustomDataObject->getParent();
if (playerDataObject != 0) {
LsbObject *playerCustomDataObject = playerDataObject->lookupByUniquePath("PlayerCustomData");
if (playerCustomDataObject != 0) {
LsbObject *iconObject = playerCustomDataObject->lookupByUniquePath("Icon");
if (iconObject != 0) {
std::string icon = iconObject->getData();
if (gamePakData != 0) {
QImage image;
bool success = gamePakData->getPortraitAtlas().getNamedTexture(icon.c_str(), &image);
if (success) {
if (portraitLabel != 0) {
portraitLabel->setPixmap(QPixmap::fromImage(image));
if (playerDataObject->replaceChild(playerCustomDataObject, copyPlayerCustomDataObject)) {
success = true;
LsbObject *oldIsMaleObject = copyOldPlayerCustomDataObject->lookupByUniquePath("IsMale");
LsbObject *newIsMaleObject = copyPlayerCustomDataObject->lookupByUniquePath("IsMale");
if (oldIsMaleObject != 0 && newIsMaleObject != 0) {
bool oldIsMale = *((bool *)oldIsMaleObject->getData());
bool newIsMale = *((bool *)newIsMaleObject->getData());
if (oldIsMale != newIsMale) {
LsbObject *characterObject = character->getObject();
LsbObject *currentTemplateObject = characterObject->lookupByUniquePath("CurrentTemplate");
if (currentTemplateObject != 0) {
std::string currentTemplate = currentTemplateObject->getData();
if (currentTemplate == ROOT_TEMPLATE_FEMALE || currentTemplate == ROOT_TEMPLATE_MALE) {
if (newIsMale == true) {
currentTemplate = ROOT_TEMPLATE_MALE;
} else {
currentTemplate = ROOT_TEMPLATE_FEMALE;
}
currentTemplateObject->setData(currentTemplate.c_str(), currentTemplate.length() + 1);
}
}
}
}
}
}
}
updateToCurrentPortrait();
if (!success) {
MessageBoxA(0, "Failed to change appearance", 0, 0);
}
delete copyOldPlayerCustomDataObject;
}

void characterTab::updateToCurrentPortrait() {
QLabel *portraitLabel = this->findChild<QLabel *>("portraitLabel");
LsbObject *playerCustomDataObject = character->getPlayerCustomDataObject();
if (playerCustomDataObject != 0) {
LsbObject *iconObject = playerCustomDataObject->lookupByUniquePath("Icon");
if (iconObject != 0) {
std::string icon = iconObject->getData();
if (gamePakData != 0) {

LsbObject *characterObject = character->getObject();
if (characterObject != 0) {
LsbObject *originalTemplateIdObject = characterObject->lookupByUniquePath("OriginalTemplate");
std::string origTemplateId = "";
if (originalTemplateIdObject != 0) {
origTemplateId = originalTemplateIdObject->getData();
}
if (origTemplateId == "5c5447e5-c1cf-4677-b84b-006d9be3f075") {
icon = "Portrait_CP_Madora";
} else if (origTemplateId == "80240f83-778e-4753-850b-48b05729589c") {
icon = "Portrait_CP_Jahan";
}
}

QImage image;
bool success = gamePakData->getPortraitAtlas().getNamedTexture(icon.c_str(), &image);
if (success) {
if (portraitLabel != 0) {
portraitLabel->setPixmap(QPixmap::fromImage(image));
}
}
}
}
}
}

EquipmentHandler *characterTab::getEquipmentHandler() const
Expand Down
Loading

0 comments on commit e7a591e

Please sign in to comment.