/* * pawscharcreationmain.cpp - author: Andrew Craig * * Copyright (C) 2003 Atomic Blue (info@planeshift.it, http://www.atomicblue.org) * * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation (version 2 of the License) * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #include #include #include #include #include #include #include "../globals.h" #include "net/messages.h" #include "net/charmessages.h" #include "iclient/isoundmngr.h" #include "clientcachemanager.h" #include "paws/pawsmanager.h" #include "paws/pawstextbox.h" #include "paws/pawsradio.h" #include "paws/pawsokbox.h" #include "paws/pawsobjectview.h" #include "paws/pawsmainwidget.h" #include "pawscharpick.h" #include "pawscharcreatemain.h" #include "psclientchar.h" ////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////// // PAWS BUTTON IDENTIFIERS ////////////////////////////////////////////////////////////////////////////// #define BACK_BUTTON 1000 #define QUICK_BUTTON 2000 #define NEXT_BUTTON 3000 #define MALE_BUTTON 100 #define FEMALE_BUTTON 200 #define NAMEHELP_BUTTON 900 #define FEMALE_ICON "mainfemale" ////////////////////////////////////////////////////////////////////////////// // Copied from the server bool FilterName(const char* name); ////////////////////////////////////////////////////////////////////////////// pawsCreationMain::pawsCreationMain() { createManager = psengine->GetCharManager()->GetCreation(); msgHandler = psengine->GetMsgHandler(); msgHandler->Subscribe(this, MSGTYPE_CHAR_CREATE_CP); msgHandler->Subscribe(this, MSGTYPE_CHAR_CREATE_NAME); createManager->SetGender( PSCHARACTER_GENDER_MALE ); currentGender = PSCHARACTER_GENDER_MALE; lastGender = -1; femaleImage = new pawsImage( PawsManager::GetSingleton().GetObjectRegistry() ); psImageDescription* imageDesc = PawsManager::GetSingleton().GetTextureManager()->GetImageDescription( FEMALE_ICON ); if ( !imageDesc ) { Warning1( LOG_PAWS, "Could not locate the female icon image. This image is not part of the GPL."); } else femaleImage->Description( imageDesc ); currentFaceChoice = 0; activeHairStyle = 0; currentBeardStyleChoice = 0; activeHairColour = 0; currentSkinColour = 0; race = 0; nameWarning = 0; } void pawsCreationMain::Reset() { createManager->SetGender( PSCHARACTER_GENDER_MALE ); currentGender = PSCHARACTER_GENDER_MALE; currentFaceChoice = 0; activeHairStyle = 0; currentBeardStyleChoice = 0; activeHairColour = 0; currentSkinColour = 0; race = 0; view->Clear(); pawsRadioButtonGroup* raceBox = (pawsRadioButtonGroup*)FindWidget("RaceBox"); raceBox->TurnAllOff(); pawsEditTextBox* name = (pawsEditTextBox*)FindWidget("charnametext"); name->SetText(""); nameWarning = 0; ResetAllWindows(); } pawsCreationMain::~pawsCreationMain() { delete femaleImage; } bool pawsCreationMain::PostSetup() { cpPoints = (pawsTextBox*)FindWidget("cppoints"); if ( !(cpPoints) ) { return false; } view = (pawsObjectView*)FindWidget("ModelView"); faceLabel = (pawsTextBox*)FindWidget( "Face" ); hairStyleLabel = (pawsTextBox*)FindWidget( "HairStyles" ); beardStyleLabel = (pawsTextBox*)FindWidget( "BeardStyles" ); hairColourLabel = (pawsTextBox*)FindWidget( "HairColours" ); skinColourLabel = (pawsTextBox*)FindWidget( "SkinColours" ); nameTextBox = dynamic_cast (FindWidget("charnametext")); if (nameTextBox == NULL) return false; GrayRaceButtons(); GrayStyleButtons(); createManager->GetTraitData(); return true; } void pawsCreationMain::ResetAllWindows() { char * names[] = {"CharBirth", "data/gui/birth.xml", "Childhood", "data/gui/childhood.xml", "LifeEvents","data/gui/lifeevents.xml", "Parents","data/gui/parents.xml", /*"Paths","data/gui/paths.xml",*/ NULL}; pawsWidget * wnd; pawsMainWidget * mainWidget = PawsManager::GetSingleton().GetMainWidget(); int nameNum = 0; while (names[nameNum] != NULL) { wnd = PawsManager::GetSingleton().FindWidget(names[nameNum]); if (wnd != NULL) { mainWidget->DeleteChild(wnd); PawsManager::GetSingleton().LoadWidget(names[nameNum+1]); } else Error2("Failed to find window %s", names[nameNum]); nameNum += 2; } createManager->ClearChoices(); } void pawsCreationMain::HandleMessage( MsgEntry* me ) { switch ( me->GetType() ) { case MSGTYPE_CHAR_CREATE_CP: { int race = me->GetInt32(); createManager->SetCurrentCP( createManager->GetRaceCP( race ) ); UpdateCP(); return; } case MSGTYPE_CHAR_CREATE_NAME: { psNameCheckMessage msg; msg.FromServer( me ); if ( msg.accepted == false ) { PawsManager::GetSingleton().CreateWarningBox( msg.reason ); } else { if ( newWindow.Length() > 0 ) { Hide(); pawsEditTextBox* name = (pawsEditTextBox*)FindWidget("charnametext"); if ( name ) createManager->SetName( name->GetText() ); PawsManager::GetSingleton().FindWidget(newWindow)->Show(); } } } } } void pawsCreationMain::ChangeSkinColour( int currentChoice ) { if ( race->location[PSTRAIT_LOCATION_SKIN_TONE][currentGender].Length() == 0 ) return; iMeshWrapper * mesh = view->GetObject(); psengine->SetTrait(mesh,race->location[PSTRAIT_LOCATION_SKIN_TONE][currentGender][currentChoice]); skinColourLabel->SetText( race->location[PSTRAIT_LOCATION_SKIN_TONE][currentGender][currentChoice]->name ); } void pawsCreationMain::ChangeHairColour( int newHair ) { if ( newHair <(int) race->location[PSTRAIT_LOCATION_HAIR_COLOR][currentGender].Length() ) { Trait* trait = race->location[PSTRAIT_LOCATION_HAIR_COLOR][currentGender][newHair]; if ( activeHairStyle < (int)race->location[PSTRAIT_LOCATION_HAIR_STYLE][currentGender].Length() ) { Trait* styletrait = race->location[PSTRAIT_LOCATION_HAIR_STYLE][currentGender][activeHairStyle]; trait->mesh = styletrait->mesh; } else { trait->mesh = "Hair"; } csVector3 at(0,0,0); view->LockCamera(race->zoomLocations[PSTRAIT_LOCATION_FACE], at, true); iMeshWrapper * mesh = view->GetObject(); psengine->SetTrait(mesh, trait); hairColourLabel->SetText( trait->name ); activeHairColour = newHair; } } void pawsCreationMain::SetHairStyle( int newStyle ) { if ( newStyle < (int)race->location[PSTRAIT_LOCATION_HAIR_STYLE][currentGender].Length() ) { iMeshWrapper * mesh = view->GetObject(); Trait* trait = race->location[PSTRAIT_LOCATION_HAIR_STYLE][currentGender][newStyle]; psengine->SetTrait(mesh, trait); if ( activeHairColour < (int)race->location[PSTRAIT_LOCATION_HAIR_COLOR][currentGender].Length() ) { Trait* colourtrait = race->location[PSTRAIT_LOCATION_HAIR_COLOR][currentGender][activeHairColour]; colourtrait->mesh = trait->mesh; psengine->SetTrait(mesh, colourtrait); } csVector3 at(0,0,0); view->LockCamera(race->zoomLocations[PSTRAIT_LOCATION_FACE], at, true); hairStyleLabel->SetText( trait->name ); } } void pawsCreationMain::RemoveHairStyle( int oldStyle ) { if ( oldStyle < (int)race->location[PSTRAIT_LOCATION_HAIR_STYLE][currentGender].Length() ) { Trait* trait = race->location[PSTRAIT_LOCATION_HAIR_STYLE][currentGender][oldStyle]; iMeshWrapper * mesh = view->GetObject(); psengine->RemoveTrait( mesh, trait ); } } void pawsCreationMain::ChangeHairStyle( int newChoice, int oldChoice ) { RemoveHairStyle( oldChoice ); SetHairStyle( newChoice ); } void pawsCreationMain::ChangeBeardStyle( int currentChoice ) { if ( race->location[PSTRAIT_LOCATION_BEARD_STYLE][currentGender].Length() == 0 ) return; iMeshWrapper * mesh = view->GetObject(); psengine->SetTrait(mesh,race->location[PSTRAIT_LOCATION_BEARD_STYLE][currentGender][currentChoice]); beardStyleLabel->SetText( race->location[PSTRAIT_LOCATION_BEARD_STYLE][currentGender][currentChoice]->name ); /* TODO: Move this code to psengine SetTrait if ( race->beardStyles[currentGender].Length() == 0 ) return; iMeshWrapper * mesh = view->GetObject(); csRef spstate = SCF_QUERY_INTERFACE(mesh->GetMeshObject(), iSpriteCal3DState); if ( lastAddedBeardStyle != -1 ) { spstate->DetachCoreMesh( race->beardStyles[currentGender][lastAddedBeardStyle]->mesh ) ; } // If the choice is no mesh then make sure there is no new mesh added. if ( race->beardStyles[currentGender][currentChoice]->mesh.Length() == 0 ) { lastAddedBeardStyle = -1; beardStyleLabel->SetText( race->beardStyles[currentGender][currentChoice]->name ); return; } else { // Check to see if a mesh was given: bool attach = spstate->AttachCoreMesh( race->beardStyles[currentGender][currentChoice]->mesh ); if ( currentHairColour != -1 ) { // Use the 1. hair colour for the beard iMaterialWrapper* material = psengine->LoadMaterial( race->hairColours[currentGender][currentHairColour]->materials[0]->material, race->hairColours[currentGender][currentHairColour]->materials[0]->texture ); // If the material was found then all is ok if (material) { spstate->SetMaterial( race->beardStyles[currentGender][currentChoice]->mesh, material ); } else // Remove the mesh since there is no valid material for it. { Warning2( LOG_NEWCHAR, "Material Not Loaded ( No Texture: %s )", race->hairColours[currentGender][currentHairColour]->materials[0]->texture.GetData() ); spstate->DetachCoreMesh( race->beardStyles[currentGender][currentChoice]->mesh ) ; } } } lastAddedBeardStyle = currentChoice; beardStyleLabel->SetText( race->beardStyles[currentGender][currentChoice]->name ); */ } void pawsCreationMain::ChangeFace( int newFace ) { if ( newFace < (int)race->location[PSTRAIT_LOCATION_FACE][currentGender].Length() ) { Trait* trait = race->location[PSTRAIT_LOCATION_FACE][currentGender][newFace]; csVector3 at(0,0,0); view->LockCamera(race->zoomLocations[PSTRAIT_LOCATION_FACE], at); iMeshWrapper * mesh = view->GetObject(); psengine->SetTrait(mesh, trait ); faceLabel->SetText( trait->name ); } } void pawsCreationMain::GrayRaceButtons( ) { pawsRadioButtonGroup* raceBox = (pawsRadioButtonGroup*)FindWidget("RaceBox"); for (unsigned id = 0; id < 12; id++) { pawsRadioButton* button = (pawsRadioButton*)raceBox->FindWidget(id); if (button == NULL) continue; if (!createManager->IsAvailable(id,currentGender)) button->GetTextBox()->Grayed(true); else button->GetTextBox()->Grayed(false); } } void pawsCreationMain::GrayStyleButtons( ) { bool faceEnable = true; if ( race != 0 && race->location[PSTRAIT_LOCATION_FACE][currentGender].Length()) { faceEnable = false; } faceLabel->Grayed(faceEnable); bool hairStyleEnable = true; if ( race != 0 && race->location[PSTRAIT_LOCATION_HAIR_STYLE][currentGender].Length()) { hairStyleEnable = false; } hairStyleLabel->Grayed(hairStyleEnable); bool beardStyle = true; if ( race != 0 && race->location[PSTRAIT_LOCATION_BEARD_STYLE][currentGender].Length()) { beardStyle = false; } beardStyleLabel->Grayed(beardStyle); bool hairColour = true; if ( race != 0 && race->location[PSTRAIT_LOCATION_HAIR_COLOR][currentGender].Length()) { hairColour = false; } hairColourLabel->Grayed(hairColour); bool skinColour = true; if ( race != 0 && race->location[PSTRAIT_LOCATION_SKIN_TONE][currentGender].Length()) { skinColour = false; } skinColourLabel->Grayed(skinColour); } void pawsCreationMain::SelectGender(int newGender) { currentGender = newGender; GrayRaceButtons(); GrayStyleButtons(); if( createManager->GetSelectedRace() == -1) return; int race = createManager->GetSelectedRace(); while (!createManager->IsAvailable(race, currentGender)) { race++; if (race > 11) { race = 0; pawsRadioButtonGroup* raceBox = (pawsRadioButtonGroup*)FindWidget("RaceBox"); raceBox->TurnAllOff(); return; } } if (race != createManager->GetSelectedRace()) { //PawsManager::GetSingleton().CreateWarningBox( "That gender isn't implemented for that race yet, sorry." ); pawsRadioButtonGroup* raceBox = (pawsRadioButtonGroup*)FindWidget("RaceBox"); raceBox->TurnAllOff(); pawsRadioButton* button = (pawsRadioButton*)raceBox->FindWidget(race); button->SetState(true); } createManager->SetGender( currentGender ); // Trigger gender update UpdateRace(race); } bool pawsCreationMain::OnButtonPressed( int mouseButton, int keyModifier, pawsWidget* widget ) { //////////////////////////////////////////////////////////////////// // Previous face. //////////////////////////////////////////////////////////////////// if ( strcmp( widget->GetName(), "Custom Choice Set 1 <") == 0 ) { if ( race ) { if ( race->location[PSTRAIT_LOCATION_FACE][currentGender].Length() == 0 ) return true; currentFaceChoice--; if ( currentFaceChoice < 0 ) { currentFaceChoice = (int)race->location[PSTRAIT_LOCATION_FACE][currentGender].Length()-1; } ChangeFace( currentFaceChoice ); } return true; } //////////////////////////////////////////////////////////////////// // Next Set of faces. //////////////////////////////////////////////////////////////////// if ( strcmp( widget->GetName(), "Custom Choice Set 1 >") == 0 ) { if ( race ) { if ( race->location[PSTRAIT_LOCATION_FACE][currentGender].Length() == 0 ) return true; currentFaceChoice++; if ( currentFaceChoice == race->location[PSTRAIT_LOCATION_FACE][currentGender].Length() ) currentFaceChoice = 0; ChangeFace( currentFaceChoice ); } return true; } //////////////////////////////////////////////////////////////////// // Next Set of hair Styles. //////////////////////////////////////////////////////////////////// if ( strcmp( widget->GetName(), "Custom Choice Set 2 >") == 0 ) { if ( race ) { if ( race->location[PSTRAIT_LOCATION_HAIR_STYLE][currentGender].Length() == 0 ) return true; int old = activeHairStyle; activeHairStyle++; if ( activeHairStyle == (int)race->location[PSTRAIT_LOCATION_HAIR_STYLE][currentGender].Length() ) activeHairStyle = 0; ChangeHairStyle( activeHairStyle, old ); } return true; } //////////////////////////////////////////////////////////////////// // Previous Set of Hair Styles. //////////////////////////////////////////////////////////////////// if ( strcmp( widget->GetName(), "Custom Choice Set 2 <") == 0 ) { if ( race ) { if ( race->location[PSTRAIT_LOCATION_HAIR_STYLE][currentGender].Length() == 0 ) return true; int old = activeHairStyle; activeHairStyle--; if ( activeHairStyle < 0 ) activeHairStyle = (int)race->location[PSTRAIT_LOCATION_HAIR_STYLE][currentGender].Length()-1; ChangeHairStyle( activeHairStyle, old ); } return true; } //////////////////////////////////////////////////////////////////// // Next Beard Style. //////////////////////////////////////////////////////////////////// if ( strcmp( widget->GetName(), "Custom Choice Set 3 >") == 0 ) { if ( race ) { if ( race->location[PSTRAIT_LOCATION_BEARD_STYLE][currentGender].Length() == 0 ) return true; currentBeardStyleChoice++; if ( currentBeardStyleChoice == (int)race->location[PSTRAIT_LOCATION_BEARD_STYLE][currentGender].Length() ) currentBeardStyleChoice = 0; ChangeBeardStyle( currentBeardStyleChoice ); } return true; } //////////////////////////////////////////////////////////////////// // Previous Set of Beard Styles. //////////////////////////////////////////////////////////////////// if ( strcmp( widget->GetName(), "Custom Choice Set 3 <") == 0 ) { if ( race ) { if ( race->location[PSTRAIT_LOCATION_BEARD_STYLE][currentGender].Length() == 0 ) return true; currentBeardStyleChoice--; if ( currentBeardStyleChoice < 0 ) currentBeardStyleChoice = (int)race->location[PSTRAIT_LOCATION_BEARD_STYLE][currentGender].Length()-1; ChangeBeardStyle( currentBeardStyleChoice ); } return true; } //////////////////////////////////////////////////////////////////// // Next Hair Colours. //////////////////////////////////////////////////////////////////// if ( strcmp( widget->GetName(), "Custom Choice Set 4 >") == 0 ) { if ( race ) { if ( race->location[PSTRAIT_LOCATION_HAIR_COLOR][currentGender].Length() == 0 ) return true; activeHairColour++; if ( activeHairColour >= (int)race->location[PSTRAIT_LOCATION_HAIR_COLOR][currentGender].Length() ) activeHairColour = 0; ChangeHairColour( activeHairColour ); } return true; } //////////////////////////////////////////////////////////////////// // Previous Set of HairColours //////////////////////////////////////////////////////////////////// if ( strcmp( widget->GetName(), "Custom Choice Set 4 <") == 0 ) { if ( race ) { if ( race->location[PSTRAIT_LOCATION_HAIR_COLOR][currentGender].Length() == 0 ) return true; activeHairColour--; if ( activeHairColour < 0 ) activeHairColour = (int)race->location[PSTRAIT_LOCATION_HAIR_COLOR][currentGender].Length()-1; ChangeHairColour( activeHairColour ); } return true; } //////////////////////////////////////////////////////////////////// // Skin Colours. //////////////////////////////////////////////////////////////////// if ( strcmp( widget->GetName(), "Custom Choice Set 5 >") == 0 ) { if ( race ) { if ( race->location[PSTRAIT_LOCATION_SKIN_TONE][currentGender].Length() == 0 ) return true; currentSkinColour++; if ( currentSkinColour == (int)race->location[PSTRAIT_LOCATION_SKIN_TONE][currentGender].Length() ) currentSkinColour = 0; ChangeSkinColour( currentSkinColour ); } return true; } //////////////////////////////////////////////////////////////////// // Previous Set of Skin Colours //////////////////////////////////////////////////////////////////// if ( strcmp( widget->GetName(), "Custom Choice Set 5 <") == 0 ) { if ( race ) { if ( race->location[PSTRAIT_LOCATION_SKIN_TONE][currentGender].Length() == 0 ) return true; currentSkinColour--; if ( currentSkinColour < 0 ) currentSkinColour = (int)race->location[PSTRAIT_LOCATION_SKIN_TONE][currentGender].Length()-1; ChangeSkinColour( currentSkinColour ); } return true; } ///////////////////////////////////////////////////// // RACE SELECTION BUTTONS ///////////////////////////////////////////////////// if ( widget->GetID() >= 0 && widget->GetID() <= 11 ) { if ( !createManager->IsAvailable(widget->GetID(),1) && !createManager->IsAvailable(widget->GetID(),2) ) { PawsManager::GetSingleton().CreateWarningBox( "This race isn't implemented yet, sorry" ); pawsRadioButtonGroup* raceBox = (pawsRadioButtonGroup*)FindWidget("RaceBox"); if ( lastRaceID != -1 ) { csString raceActive; raceActive.Format("race%d", lastRaceID ); if ( raceBox ) raceBox->SetActive( raceActive ); } else { if ( raceBox ) raceBox->TurnAllOff(); } return true; } if ( widget->GetID() == PSCHARACTER_RACE_KRAN ) { SelectGender(PSCHARACTER_GENDER_NONE); } else if ( lastRaceID == -1 || lastRaceID == PSCHARACTER_RACE_KRAN ) { if ( lastGender == PSCHARACTER_GENDER_MALE ) { SelectGender(PSCHARACTER_GENDER_MALE); currentGender = PSCHARACTER_GENDER_MALE; } else { SelectGender(PSCHARACTER_GENDER_FEMALE); currentGender = PSCHARACTER_GENDER_FEMALE; } } // If current gender isn't available, try every possible if (!createManager->IsAvailable(widget->GetID(),currentGender)) { if (createManager->IsAvailable(widget->GetID(),PSCHARACTER_GENDER_FEMALE)) SelectGender(PSCHARACTER_GENDER_FEMALE); else if (createManager->IsAvailable(widget->GetID(),PSCHARACTER_GENDER_MALE)) SelectGender(PSCHARACTER_GENDER_MALE); lastGender = currentGender; } pawsOkBox* Ok = (pawsOkBox*)PawsManager::GetSingleton().FindWidget("OkWindow"); Ok->SetText( createManager->GetRaceDescription( widget->GetID() ) ); Ok->MoveTo( (graphics2D->GetWidth() - GetActualWidth(512) )/2, (GetActualHeight(600) - GetActualHeight(256))); Ok->Show(); PawsManager::GetSingleton().SetModalWidget(Ok); createManager->SetGender(currentGender); UpdateRace(widget->GetID()); ResetAllWindows(); return true; } if ( strcmp( widget->GetName(), "randomName" ) == 0 ) { csString randomName; csString lastName; if ( currentGender == PSCHARACTER_GENDER_FEMALE ) { createManager->GenerateName(NAMEGENERATOR_FEMALE_FIRST_NAME, randomName,5,5); } else { createManager->GenerateName(NAMEGENERATOR_MALE_FIRST_NAME, randomName,4,7); } createManager->GenerateName(NAMEGENERATOR_FAMILY_NAME, lastName,4,7); csString upper( randomName ); upper.Upcase(); randomName.SetAt(0, upper.GetAt(0) ); upper = lastName; upper.Upcase(); lastName.SetAt(0, upper.GetAt(0) ); randomName += " " + lastName; pawsEditTextBox* name = (pawsEditTextBox*)FindWidget("charnametext"); name->SetText( randomName ); name->SetCursorPosition(0); nameWarning = 1; // no need to warn them } ///////////////////////////////////////////////////// // END OF RACE BUTTONS ///////////////////////////////////////////////////// switch ( widget->GetID() ) { case MALE_BUTTON: if ( createManager->GetSelectedRace() == PSCHARACTER_RACE_KRAN ) SelectGender(PSCHARACTER_GENDER_NONE); else SelectGender(PSCHARACTER_GENDER_MALE); return true; case FEMALE_BUTTON: if ( createManager->GetSelectedRace() == PSCHARACTER_RACE_KRAN ) SelectGender(PSCHARACTER_GENDER_NONE); else SelectGender(PSCHARACTER_GENDER_FEMALE); return true; case BACK_BUTTON: { Hide(); pawsCharacterPickerWindow* charPicker = (pawsCharacterPickerWindow*)PawsManager::GetSingleton().FindWidget( "CharPickerWindow" ); // Reset the selected character charPicker->Show(); charPicker->SelectCharacter(0); return true; } case NAMEHELP_BUTTON: { csString help; help = "A last name is optional. If you want one, separate it with a space. "; help += "You can use any alphabetic (A-Z) in your name, but no numbers.\n"; help += "The name should follow the rules here:\n"; help += "http://www.planeshift.it/naming.html \n"; help += "If your name is inappropriate, a Game Master (GM) will change it."; PawsManager::GetSingleton().CreateWarningBox(help); return true; } case NEXT_BUTTON: case QUICK_BUTTON: { // Check to see if a race was selected. if ( race == 0 ) { psSystemMessage error(0,MSG_ERROR,"Please select a race"); error.FireEvent(); return true; } pawsEditTextBox* name = (pawsEditTextBox*)FindWidget("charnametext"); // Check to see a name was entered. if ( name->GetText() == 0 || strlen(name->GetText()) < 3) { psSystemMessage error(0,MSG_ERROR,"Please enter a name"); error.FireEvent(); return true; } csString selectedName(name->GetText()); if ( !CheckNameForRepeatingLetters(selectedName) ) { psSystemMessage error(0,MSG_ERROR,"No more than 2 letters in a row allowed"); error.FireEvent(); return true; } csString lastname,firstname; firstname = selectedName.Slice(0,selectedName.FindFirst(' ')); if (selectedName.FindFirst(' ') != SIZET_NOT_FOUND) lastname = selectedName.Slice(selectedName.FindFirst(' ') +1,selectedName.Length()); // Check the firstname if ( firstname.Length() != 0 && !FilterName(firstname) ) { psSystemMessage error(0,MSG_ERROR,"First name is invalid"); error.FireEvent(); return true; } // Check the lastname if ( lastname.Length() != 0 && !FilterName(lastname) ) { psSystemMessage error(0,MSG_ERROR,"Last name is invalid"); error.FireEvent(); return true; } firstname = NormalizeCharacterName(firstname); lastname = NormalizeCharacterName(lastname); if (lastname.Length()) name->SetText(firstname + " " + lastname); else name->SetText(firstname); // Check to see if they entered their own name. if (nameWarning == 0) { csString policy; policy = "Before clicking next again, please make sure that your character name "; policy += "is not offensive and would be appropriate for a medieval setting. "; policy += "It must be unique and not similar to that of any real person or thing. "; policy += "Names in violation of this policy (www.planeshift.it/naming.html) will "; policy += "be changed by authorized people in-game. "; policy += "The game forums can be found at: forums.hydlaa.com"; PawsManager::GetSingleton().CreateWarningBox(policy); nameWarning = 1; return true; } // Set our choices in the creation manager createManager->SetCustomization( race->location[PSTRAIT_LOCATION_FACE][currentGender].Length()?race->location[PSTRAIT_LOCATION_FACE][currentGender][currentFaceChoice]->uid:0, race->location[PSTRAIT_LOCATION_HAIR_STYLE][currentGender].Length()?race->location[PSTRAIT_LOCATION_HAIR_STYLE][currentGender][activeHairStyle]->uid:0, race->location[PSTRAIT_LOCATION_BEARD_STYLE][currentGender].Length()?race->location[PSTRAIT_LOCATION_BEARD_STYLE][currentGender][currentBeardStyleChoice]->uid:0, race->location[PSTRAIT_LOCATION_HAIR_COLOR][currentGender].Length()?race->location[PSTRAIT_LOCATION_HAIR_COLOR][currentGender][activeHairColour]->uid:0, race->location[PSTRAIT_LOCATION_SKIN_TONE][currentGender].Length()?race->location[PSTRAIT_LOCATION_SKIN_TONE][currentGender][currentSkinColour]->uid:0 ); if ( widget->GetID() == NEXT_BUTTON ) { createManager->GetChildhoodData(); newWindow = "CharBirth"; } else { newWindow = "Paths"; } psNameCheckMessage msg( name->GetText() ); msgHandler->SendMessage( msg.msg ); } } return false; } void pawsCreationMain::Draw() { ClipToParent(); pawsWidget::Draw(); graphics2D->SetClipRect( 0,0, graphics2D->GetWidth(), graphics2D->GetHeight()); if ( currentGender == PSCHARACTER_GENDER_FEMALE ) { femaleImage->Draw(GetActualWidth(363),GetActualHeight(74), GetActualWidth(82),GetActualHeight(34)); } } bool pawsCreationMain::OnChange(pawsWidget *widget) { // If we click on the name box (and we change it), then we might get the name policy warning again if (widget == nameTextBox) nameWarning=0; return true; } void pawsCreationMain::Show() { // Play some music if(psengine->GetSoundStatus()) { psengine->GetSoundManager()->OverrideBGSong("charcreation"); } pawsWidget::Show(); UpdateCP(); } void pawsCreationMain::UpdateRace(int id) { int raceCP = createManager->GetRaceCP( id ); lastRaceID = id; if ( raceCP != REQUESTING_CP && createManager->GetSelectedRace() != id ) { // Reset CP only when changing the race createManager->SetCurrentCP( raceCP ); UpdateCP(); } createManager->SetRace( id ); race = createManager->GetRace(id); // KRAN has no gender if ( id == PSCHARACTER_RACE_KRAN ) { lastGender = createManager->GetSelectedGender(); createManager->SetGender( PSCHARACTER_GENDER_NONE ); currentGender = PSCHARACTER_GENDER_NONE; } else { currentGender = createManager->GetSelectedGender(); if ( lastGender != -1 ) { currentGender = lastGender; } createManager->SetGender( currentGender ); lastGender = -1; } csString factName = createManager->GetModelName( id, currentGender ); // Store the factory name and file name for the mesh csString fileName; fileName.Format("/planeshift/models/%s/%s.cal3d",factName.GetData(), factName.GetData()); // Show the model for the selected race. view->Show(); view->EnableMouseControl(true); FactoryIndexEntry* entry = psengine->GetCacheManager()->GetFactoryEntry(fileName); if (!entry) { psengine->FatalError("The server sent an invaild model filename, please run the updater\n"); return; } if (entry->factname != "") view->View( entry->factname, entry->filename ); else view->View(entry->factory); iMeshWrapper * mesh = view->GetObject(); if (!mesh) { PawsManager::GetSingleton().CreateWarningBox("Couldn't find mesh! Please run the updater"); return; } csRef spstate = SCF_QUERY_INTERFACE(mesh->GetMeshObject(), iSpriteCal3DState); if (spstate) { // Setup cal3d to select random 0 velocity anims spstate->SetVelocity(0.0,&psengine->GetRandomGen()); } currentFaceChoice = 0; activeHairStyle = 0; currentBeardStyleChoice = 0; activeHairColour = 0; currentSkinColour = 0; ChangeFace(0); ChangeHairColour(0); SetHairStyle( activeHairStyle ); view->UnlockCamera(); GrayStyleButtons(); } bool FilterName(const char* name) { if (name == NULL) return false; size_t len = strlen(name); if ( (strspn(name,"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") != len) ) return false; if (((int)strspn(((const char*)name)+1, (const char*)"abcdefghijklmnopqrstuvwxyz") != len - 1)) return false; return true; } // Stolen from libsserverobjects - psCharacter csString pawsCreationMain::NormalizeCharacterName(const csString & name) { csString normName = name; normName.Downcase(); if (normName.Length() > 0) normName.SetAt(0,toupper(normName.GetAt(0))); return normName; } void pawsCreationMain::UpdateCP() { int cp = createManager->GetCurrentCP(); if (cp > 300 || cp < -300 ) // just some random values cp=0; char buff[10]; sprintf( buff, "CP: %d", cp ); cpPoints->SetText( buff ); } bool pawsCreationMain::CheckNameForRepeatingLetters(csString name) { name.Downcase(); char letter = ' '; int count = 1; for (size_t i=0; i 2) return false; // More than 2 of the same letter in a row } else { count = 1; letter = name[i]; } } // No more than 2 of one letter in a row return true; }