]> git.jsancho.org Git - lugaru.git/blob - Source/Dialog.cpp
Cleaned up dialog handling using a Dialog class
[lugaru.git] / Source / Dialog.cpp
1 /*
2 Copyright (C) 2003, 2010 - Wolfire Games
3 Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
4
5 This file is part of Lugaru.
6
7 Lugaru is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 Lugaru is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with Lugaru.  If not, see <http://www.gnu.org/licenses/>.
19 */
20
21 #include "Dialog.h"
22 #include "Person.h"
23 #include "Input.h"
24 #include "Game.h"
25 #include "binio.h"
26
27 extern int hostile;
28
29 int Dialog::indialogue;
30 int Dialog::whichdialogue;
31 bool Dialog::directing;
32 float Dialog::dialoguetime;
33 std::vector<Dialog> Dialog::dialogs;
34
35 void Dialog::loadDialogs(FILE* tfile)
36 {
37     int numdialogues;
38     funpackf(tfile, "Bi", &numdialogues);
39     for (int k = 0; k < numdialogues; k++) {
40         dialogs.push_back(Dialog(tfile));
41     }
42 }
43
44 Dialog::Dialog(FILE* tfile) : gonethrough(0)
45 {
46     int numdialogboxes;
47     funpackf(tfile, "Bi", &numdialogboxes);
48     funpackf(tfile, "Bi", &type);
49     for (int l = 0; l < 10; l++) {
50         funpackf(tfile, "Bf Bf Bf", &participantlocation[l].x, &participantlocation[l].y, &participantlocation[l].z);
51         funpackf(tfile, "Bf", &participantyaw[l]);
52     }
53     for (int l = 0; l < numdialogboxes; l++) {
54         boxes.push_back(DialogBox(tfile));
55     }
56 }
57
58 std::string funpackf_string(FILE* tfile, int maxlength)
59 {
60     int templength;
61     funpackf(tfile, "Bi", &templength);
62     if ((templength > maxlength) || (templength <= 0)) {
63         templength = maxlength;
64     }
65     int m;
66     char* text = new char[maxlength];
67     for (m = 0; m < templength; m++) {
68         funpackf(tfile, "Bb", &text[m]);
69         if (text[m] == '\0')
70             break;
71     }
72     text[m] = 0;
73     std::string result(text);
74     delete[] text;
75     return result;
76 }
77
78 void fpackf_string(FILE* tfile, std::string text)
79 {
80     fpackf(tfile, "Bi", text.size());
81     for (int m = 0; m < text.size(); m++) {
82         fpackf(tfile, "Bb", text[m]);
83         if (text[m] == '\0')
84             break;
85     }
86 }
87
88 DialogBox::DialogBox(FILE* tfile)
89 {
90     funpackf(tfile, "Bi", &location);
91     funpackf(tfile, "Bf", &color[0]);
92     funpackf(tfile, "Bf", &color[1]);
93     funpackf(tfile, "Bf", &color[2]);
94     funpackf(tfile, "Bi", &sound);
95
96     text = funpackf_string(tfile, 128);
97     name = funpackf_string(tfile, 64);
98
99     funpackf(tfile, "Bf Bf Bf", &camera.x, &camera.y, &camera.z);
100     funpackf(tfile, "Bi", &participantfocus);
101     funpackf(tfile, "Bi", &participantaction);
102
103     for (int m = 0; m < 10; m++)
104         funpackf(tfile, "Bf Bf Bf", &participantfacing[m].x, &participantfacing[m].y, &participantfacing[m].z);
105
106     funpackf(tfile, "Bf Bf", &camerayaw, &camerapitch);
107 }
108
109 /* Load dialog from txt file, used by console */
110 Dialog::Dialog(int type, std::string filename) : type(type)
111 {
112     ifstream ipstream(ConvertFileName(filename.c_str()));
113     ipstream.ignore(256, ':');
114     int numboxes;
115     ipstream >> numboxes;
116     for (int i = 0; i < numboxes; i++) {
117         boxes.push_back(DialogBox(ipstream));
118         for (unsigned j = 0; j < Person::players.size(); j++) {
119             boxes.back().participantfacing[j] = Person::players[j]->facing;
120         }
121     }
122     ipstream.close();
123 }
124
125 DialogBox::DialogBox(ifstream &ipstream)
126 {
127     ipstream.ignore(256, ':');
128     ipstream.ignore(256, ':');
129     ipstream.ignore(256, ' ');
130     ipstream >> location;
131     ipstream.ignore(256, ':');
132     ipstream >> color[0];
133     ipstream >> color[1];
134     ipstream >> color[2];
135     ipstream.ignore(256, ':');
136     getline(ipstream, name);
137     ipstream.ignore(256, ':');
138     ipstream.ignore(256, ' ');
139     getline(ipstream, text);
140     for (int j = 0; j < 128; j++) {
141         if (text[j] == '\\')
142             text[j] = '\n';
143     }
144     ipstream.ignore(256, ':');
145     ipstream >> sound;
146 }
147
148 void Dialog::tick(int id)
149 {
150     unsigned playerId = type % 10;
151     bool special = (type > 9);
152
153     if ((!hostile || (type > 40) && (type < 50)) &&
154             (playerId < Person::players.size()) &&
155             (playerId > 0) &&
156             ((gonethrough == 0) || !special) &&
157             (special || Input::isKeyPressed(Game::attackkey))) {
158         if ((distsq(&Person::players[0]->coords, &Person::players[playerId]->coords) < 6) ||
159                 (Person::players[playerId]->howactive >= typedead1) ||
160                 (type > 40) && (type < 50)) {
161             whichdialogue = id;
162             play();
163             dialoguetime = 0;
164             gonethrough++;
165         }
166     }
167 }
168
169 void Dialog::play()
170 {
171     for (int i = 0; i < boxes.size(); i++) {
172         int playerId = boxes[i].participantfocus;
173         Person::players[playerId]->coords = participantlocation[playerId];
174         Person::players[playerId]->yaw = participantyaw[playerId];
175         Person::players[playerId]->targetyaw = participantyaw[playerId];
176         Person::players[playerId]->velocity = 0;
177         Person::players[playerId]->animTarget = Person::players[playerId]->getIdle();
178         Person::players[playerId]->frameTarget = 0;
179     }
180
181     Dialog::directing = false;
182     Dialog::indialogue = 0;
183
184     if (boxes[indialogue].sound != 0) {
185         Game::playdialogueboxsound();
186     }
187 }
188
189 void Dialog::saveDialogs(FILE* tfile)
190 {
191     fpackf(tfile, "Bi", dialogs.size());
192
193     for (int k = 0; k < dialogs.size(); k++) {
194         dialogs[k].save(tfile);
195     }
196 }
197
198 void Dialog::save(FILE* tfile)
199 {
200     fpackf(tfile, "Bi", boxes.size());
201     fpackf(tfile, "Bi", type);
202     for (int l = 0; l < 10; l++) {
203         fpackf(tfile, "Bf Bf Bf", participantlocation[l].x, participantlocation[l].y, participantlocation[l].z);
204         fpackf(tfile, "Bf", participantyaw[l]);
205     }
206     for (int l = 0; l < boxes.size(); l++) {
207         boxes[l].save(tfile);
208     }
209 }
210
211 void DialogBox::save(FILE* tfile)
212 {
213     fpackf(tfile, "Bi", location);
214     fpackf(tfile, "Bf", color[0]);
215     fpackf(tfile, "Bf", color[1]);
216     fpackf(tfile, "Bf", color[2]);
217     fpackf(tfile, "Bi", sound);
218
219     fpackf_string(tfile, text);
220     fpackf_string(tfile, name);
221
222     fpackf(tfile, "Bf Bf Bf", camera.x, camera.y, camera.z);
223     fpackf(tfile, "Bi", participantfocus);
224     fpackf(tfile, "Bi", participantaction);
225
226     for (int m = 0; m < 10; m++)
227         fpackf(tfile, "Bf Bf Bf", participantfacing[m].x, participantfacing[m].y, participantfacing[m].z);
228
229     fpackf(tfile, "Bf Bf", camerayaw, camerapitch);
230 }