1 /***************************************************************************
2                 partyeditor.cpp  - The "create character" window
3                              -------------------
4     begin                : Tue Aug 12 2003
5     copyright            : (C) 2003 by Gabor Torok
6     email                : cctorok@yahoo.com
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "common/constants.h"
19 #include "partyeditor.h"
20 #include "render/renderlib.h"
21 #include "rpg/rpglib.h"
22 #include "item.h"
23 #include "creature.h"
24 #include "characterinfo.h"
25 #include "sdlhandler.h"
26 #include "sdleventhandler.h"
27 #include "sdlscreenview.h"
28 #include "scourge.h"
29 #include "userconfiguration.h"
30 #include "util.h"
31 #include "gui/window.h"
32 #include "gui/button.h"
33 #include "gui/canvas.h"
34 #include "gui/scrollinglist.h"
35 #include "gui/cardcontainer.h"
36 #include "gui/scrollinglabel.h"
37 #include "shapepalette.h"
38 #include "debug.h"
39 #include "skillsview.h"
40 #include "pceditor.h"
41 
42 // ###### MS Visual C++ specific ######
43 #if defined(_MSC_VER) && defined(_DEBUG)
44 # define new DEBUG_NEW
45 # undef THIS_FILE
46 static char THIS_FILE[] = __FILE__;
47 #endif
48 
49 using namespace std;
50 
51 /**
52   *@author Gabor Torok
53   */
54 
55 #define PORTRAIT_SIZE 150
56 #define MODEL_SIZE 210
57 #define STARTING_PARTY_SIZE 1
58 #define LEVEL STARTING_PARTY_LEVEL
59 
60 /// Unused.
61 struct Preset {
62 	char name[80];
63 	int deity;
64 	int charClass;
65 	int portrait;
66 	int model;
67 };
68 
69 Preset presets[] = {
70 	{ "Lezidor",     4, 4, 7, 0 }, // rogue
71 	{ "Kaz-Mokh",    1, 0, 8, 1 }, // fighter
72 	{ "Arcoraxe",    2, 1, 6, 15 }, // mage
73 	{ "Deiligiliam", 0, 2, 10, 7 }, // healer
74 };
75 
PartyEditor(Scourge * scourge)76 PartyEditor::PartyEditor( Scourge *scourge ) {
77 	this->scourge = scourge;
78 	pcEditor = new PcEditor( scourge );
79 	pcEditor->setCreature(); // use a temp. creature
80 }
81 
~PartyEditor()82 PartyEditor::~PartyEditor() {
83 	delete pcEditor;
84 }
85 
handleEvent(Widget * widget,SDL_Event * event)86 void PartyEditor::handleEvent( Widget *widget, SDL_Event *event ) {
87 
88 	//
89 	// cancel and done are handled in mainmenu.cpp
90 	//
91 
92 	if ( pcEditor->getWindow()->isVisible() ) pcEditor->handleEvent( widget, event );
93 }
94 
createParty(Creature ** pc,int * partySize,bool addRandomBackpack)95 void PartyEditor::createParty( Creature **pc, int *partySize, bool addRandomBackpack ) {
96 	for ( int i = 0; i < STARTING_PARTY_SIZE; i++ )
97 		pc[i] = pcEditor->createPartyMember();
98 	if ( addRandomBackpack ) addStartingBackpack( pc, STARTING_PARTY_SIZE );
99 	if ( partySize ) *partySize = STARTING_PARTY_SIZE;
100 }
101 
createWanderingHero(int level)102 RenderedCreature *PartyEditor::createWanderingHero( int level ) {
103 	int sex = Util::dice( 2 ) ? Constants::SEX_MALE : Constants::SEX_FEMALE;
104 	Creature *pc = scourge->getSession()->
105 	               newCreature( Character::getRandomCharacter( level ),
106 				                Rpg::createName().c_str(),
107 	                            sex,
108 	                            Util::dice( scourge->getShapePalette()->getCharacterModelInfoCount( sex ) ) );
109 	pc->setLevel( LEVEL );
110 	pc->setExp( 0 );
111 	pc->setHp();
112 	pc->setMp();
113 	pc->setHunger( Util::pickOne( 5, 9 ) );
114 	pc->setThirst( Util::pickOne( 5, 9 ) );
115 
116 	// deity
117 	pc->setDeityIndex( MagicSchool::getRandomSchoolIndex() );
118 
119 	// assign portraits
120 	pc->setPortraitTextureIndex( Util::dice( scourge->getShapePalette()->getPortraitCount( sex ) ) );
121 
122 	// compute starting skill levels
123 	pcEditor->rollSkillsForCreature( pc );
124 
125 	addStartingBackpack( pc );
126 
127 	pc->setMotion( Constants::MOTION_LOITER );
128 
129 	return pc;
130 }
131 
addStartingBackpack(Creature ** pc,int partySize)132 void PartyEditor::addStartingBackpack( Creature **pc, int partySize ) {
133 	for ( int i = 0; i < partySize; i++ ) {
134 		addStartingBackpack( pc[i] );
135 		if ( LEVEL > 1 && i == 0 ) {
136 			// add all special items
137 			for ( int t = 0; t < RpgItem::getSpecialCount(); t++ ) {
138 				pc[i]->addToBackpack( scourge->getSession()->newItem( RpgItem::getSpecial( t ) ), true );
139 			}
140 			// add some spell-containing items
141 			for ( int t = 0; t < 5; t++ ) {
142 				pc[i]->addToBackpack(
143 				  scourge->getSession()->newItem(
144 				    RpgItem::getItemByName( "Dwarven steel ring" ),
145 				    1,
146 				    MagicSchool::getRandomSpell( 1 ) ), true );
147 			}
148 		}
149 	}
150 }
151 
addStartingBackpack(Creature * pc)152 void PartyEditor::addStartingBackpack( Creature *pc ) {
153 	// add a weapon anyone can wield
154 	int n = Util::dice( 5 );
155 	switch ( n ) {
156 	case 0: pc->addToBackpack( scourge->getSession()->newItem( RpgItem::getItemByName( "Smallbow" ), LEVEL, NULL, true ), true ); break;
157 	case 1: pc->addToBackpack( scourge->getSession()->newItem( RpgItem::getItemByName( "Short sword" ), LEVEL, NULL, true ), true ); break;
158 	case 2: pc->addToBackpack( scourge->getSession()->newItem( RpgItem::getItemByName( "Dagger" ), LEVEL, NULL, true ), true ); break;
159 	case 3: pc->addToBackpack( scourge->getSession()->newItem( RpgItem::getItemByName( "Wooden club" ), LEVEL, NULL, true ), true ); break;
160 	case 4: pc->addToBackpack( scourge->getSession()->newItem( RpgItem::getItemByName( "Quarter Staff" ), LEVEL, NULL, true ), true ); break;
161 	}
162 	int invIndex = 0;
163 	pc->equipFromBackpack( invIndex++ );
164 
165 	// add some armor
166 	if ( 0 == Util::dice( 4 ) ) {
167 		pc->addToBackpack( scourge->getSession()->newItem( RpgItem::getItemByName( "Horned helmet" ), LEVEL, NULL, true ), true );
168 		pc->equipFromBackpack( invIndex++ );
169 	}
170 	if ( 0 == Util::dice( 3 ) ) {
171 		pc->addToBackpack( scourge->getSession()->newItem( RpgItem::getItemByName( "Buckler" ), LEVEL, NULL, true ), true );
172 		pc->equipFromBackpack( invIndex++ );
173 	}
174 
175 	// some potions
176 	if ( 0 == Util::dice( 4 ) )
177 		pc->addToBackpack( scourge->getSession()->newItem( RpgItem::getItemByName( "Health potion" ), LEVEL ), true );
178 	if ( 0 == Util::dice( 4 ) )
179 		pc->addToBackpack( scourge->getSession()->newItem( RpgItem::getItemByName( "Magic potion" ), LEVEL ), true );
180 	if ( 0 == Util::dice( 4 ) )
181 		pc->addToBackpack( scourge->getSession()->newItem( RpgItem::getItemByName( "Liquid armor" ), LEVEL ), true );
182 
183 	// some food
184 	for ( int t = 0; t < Util::dice( 6 ); t++ ) {
185 		if ( 0 == Util::dice( 4 ) )
186 			pc->addToBackpack( scourge->getSession()->newItem( RpgItem::getItemByName( "Apple" ) ), true );
187 		if ( 0 == Util::dice( 4 ) )
188 			pc->addToBackpack( scourge->getSession()->newItem( RpgItem::getItemByName( "Bread" ) ), true );
189 		if ( 0 == Util::dice( 4 ) )
190 			pc->addToBackpack( scourge->getSession()->newItem( RpgItem::getItemByName( "Mushroom" ) ), true );
191 		if ( 0 == Util::dice( 4 ) )
192 			pc->addToBackpack( scourge->getSession()->newItem( RpgItem::getItemByName( "Big egg" ) ), true );
193 		if ( 0 == Util::dice( 4 ) )
194 			pc->addToBackpack( scourge->getSession()->newItem( RpgItem::getItemByName( "Mutton meat" ) ), true );
195 	}
196 
197 	// some spells
198 	if ( pc->getMaxMp() > 0 ) {
199 		// useful spells
200 		pc->addSpell( Spell::getSpellByName( "Flame of Azun" ) );
201 		pc->addSpell( Spell::getSpellByName( "Ole Taffy's purty colors" ) );
202 		// attack spell
203 		if ( 0 == Util::dice( 2 ) )
204 			pc->addSpell( Spell::getSpellByName( "Silent knives" ) );
205 		else
206 			pc->addSpell( Spell::getSpellByName( "Stinging light" ) );
207 		// defensive spell
208 		if ( 0 == Util::dice( 2 ) )
209 			pc->addSpell( Spell::getSpellByName( "Lesser healing touch" ) );
210 		else
211 			pc->addSpell( Spell::getSpellByName( "Body of stone" ) );
212 
213 
214 		// testing
215 		if ( LEVEL > 1 ) {
216 			pc->addSpell( Spell::getSpellByName( "Ring of Harm" ) );
217 			pc->addSpell( Spell::getSpellByName( "Malice Storm" ) );
218 			pc->addSpell( Spell::getSpellByName( "Unholy Decimator" ) );
219 			pc->addSpell( Spell::getSpellByName( "Remove curse" ) );
220 			pc->addSpell( Spell::getSpellByName( "Teleportation" ) );
221 			pc->addSpell( Spell::getSpellByName( "Recall to life" ) );
222 			pc->addSpell( Spell::getSpellByName( "Blast of Fury" ) );
223 			pc->addSpell( Spell::getSpellByName( "Dori's Tumblers" ) );
224 			pc->addSpell( Spell::getSpellByName( "Gust of wind" ) );
225 			pc->setMp( 5000 );
226 			pc->setMoney( 10000 );
227 		}
228 	}
229 }
230 
isVisible()231 bool PartyEditor::isVisible() {
232 	return pcEditor->getWindow()->isVisible();
233 }
234 
setVisible(bool b)235 void PartyEditor::setVisible( bool b ) {
236 	//mainWin->setVisible( b );
237 	pcEditor->getWindow()->setVisible( b );
238 }
239 
getHighestSkillPC(int skill)240 Creature *PartyEditor::getHighestSkillPC( int skill ) {
241 	return NULL; // never filled: ( maxSkills.find( skill ) == maxSkills.end() ? NULL : maxSkills[ skill ] );
242 }
243 
getStartGameButton()244 Button *PartyEditor::getStartGameButton() {
245 	return pcEditor->getOkButton();
246 }
247 
getCancelButton()248 Button *PartyEditor::getCancelButton() {
249 	return pcEditor->getCancelButton();
250 }
251 
252