]> git.jsancho.org Git - lugaru.git/blob - Source/Level/Dialog.cpp
64d30155bce7eb10e5f93452f6720196a86543e6
[lugaru.git] / Source / Level / 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 "Level/Dialog.hpp"
22
23 #include "Game.hpp"
24 #include "Objects/Person.hpp"
25 #include "Utils/binio.h"
26 #include "Utils/Folders.hpp"
27 #include "Utils/Input.hpp"
28
29 extern int hostile;
30
31 int Dialog::indialogue;
32 int Dialog::whichdialogue;
33 bool Dialog::directing;
34 float Dialog::dialoguetime;
35 std::vector<Dialog> Dialog::dialogs;
36
37 void Dialog::loadDialogs(FILE* tfile)
38 {
39     int numdialogues;
40     funpackf(tfile, "Bi", &numdialogues);
41     for (int k = 0; k < numdialogues; k++) {
42         dialogs.push_back(Dialog(tfile));
43     }
44 }
45
46 Dialog::Dialog(FILE* tfile) : gonethrough(0)
47 {
48     int numdialogscenes;
49     funpackf(tfile, "Bi", &numdialogscenes);
50     funpackf(tfile, "Bi", &type);
51     for (int l = 0; l < 10; l++) {
52         funpackf(tfile, "Bf Bf Bf", &participantlocation[l].x, &participantlocation[l].y, &participantlocation[l].z);
53         funpackf(tfile, "Bf", &participantyaw[l]);
54     }
55     for (int l = 0; l < numdialogscenes; l++) {
56         scenes.push_back(DialogScene(tfile));
57     }
58 }
59
60 std::string funpackf_string(FILE* tfile, int maxlength)
61 {
62     int templength;
63     funpackf(tfile, "Bi", &templength);
64     if ((templength > maxlength) || (templength <= 0)) {
65         templength = maxlength;
66     }
67     int m;
68     char* text = new char[maxlength];
69     for (m = 0; m < templength; m++) {
70         funpackf(tfile, "Bb", &text[m]);
71         if (text[m] == '\0')
72             break;
73     }
74     text[m] = 0;
75     std::string result(text);
76     delete[] text;
77     return result;
78 }
79
80 void fpackf_string(FILE* tfile, std::string text)
81 {
82     fpackf(tfile, "Bi", text.size());
83     for (unsigned i = 0; i < text.size(); i++) {
84         fpackf(tfile, "Bb", text[i]);
85         if (text[i] == '\0') {
86             break;
87         }
88     }
89 }
90
91 DialogScene::DialogScene(FILE* tfile)
92 {
93     funpackf(tfile, "Bi", &location);
94     funpackf(tfile, "Bf", &color[0]);
95     funpackf(tfile, "Bf", &color[1]);
96     funpackf(tfile, "Bf", &color[2]);
97     funpackf(tfile, "Bi", &sound);
98
99     text = funpackf_string(tfile, 128);
100     name = funpackf_string(tfile, 64);
101
102     funpackf(tfile, "Bf Bf Bf", &camera.x, &camera.y, &camera.z);
103     funpackf(tfile, "Bi", &participantfocus);
104     funpackf(tfile, "Bi", &participantaction);
105
106     for (int m = 0; m < 10; m++)
107         funpackf(tfile, "Bf Bf Bf", &participantfacing[m].x, &participantfacing[m].y, &participantfacing[m].z);
108
109     funpackf(tfile, "Bf Bf", &camerayaw, &camerapitch);
110 }
111
112 /* Load dialog from txt file, used by console */
113 Dialog::Dialog(int type, std::string filename) : type(type)
114 {
115     ifstream ipstream(Folders::getResourcePath(filename));
116     ipstream.ignore(256, ':');
117     int numscenes;
118     ipstream >> numscenes;
119     for (int i = 0; i < numscenes; i++) {
120         scenes.push_back(DialogScene(ipstream));
121         for (unsigned j = 0; j < Person::players.size(); j++) {
122             scenes.back().participantfacing[j] = Person::players[j]->facing;
123         }
124     }
125     ipstream.close();
126 }
127
128 DialogScene::DialogScene(ifstream &ipstream)
129 {
130     ipstream.ignore(256, ':');
131     ipstream.ignore(256, ':');
132     ipstream.ignore(256, ' ');
133     ipstream >> location;
134     ipstream.ignore(256, ':');
135     ipstream >> color[0];
136     ipstream >> color[1];
137     ipstream >> color[2];
138     ipstream.ignore(256, ':');
139     getline(ipstream, name);
140     ipstream.ignore(256, ':');
141     ipstream.ignore(256, ' ');
142     getline(ipstream, text);
143     for (int j = 0; j < 128; j++) {
144         if (text[j] == '\\')
145             text[j] = '\n';
146     }
147     ipstream.ignore(256, ':');
148     ipstream >> sound;
149 }
150
151 void Dialog::tick(int id)
152 {
153     unsigned playerId = type % 10;
154     bool special = (type > 9);
155
156     if ((!hostile || (type > 40) && (type < 50)) &&
157             (playerId < Person::players.size()) &&
158             (playerId > 0) &&
159             ((gonethrough == 0) || !special) &&
160             (special || Input::isKeyPressed(Game::attackkey))) {
161         if ((distsq(&Person::players[0]->coords, &Person::players[playerId]->coords) < 6) ||
162                 (Person::players[playerId]->howactive >= typedead1) ||
163                 (type > 40) && (type < 50)) {
164             whichdialogue = id;
165             play();
166             dialoguetime = 0;
167             gonethrough++;
168         }
169     }
170 }
171
172 void Dialog::play()
173 {
174     for (unsigned i = 0; i < scenes.size(); i++) {
175         int playerId = scenes[i].participantfocus;
176         Person::players.at(playerId)->coords = participantlocation[playerId];
177         Person::players[playerId]->yaw = participantyaw[playerId];
178         Person::players[playerId]->targetyaw = participantyaw[playerId];
179         Person::players[playerId]->velocity = 0;
180         Person::players[playerId]->animTarget = Person::players[playerId]->getIdle();
181         Person::players[playerId]->frameTarget = 0;
182     }
183
184     Dialog::directing = false;
185     Dialog::indialogue = 0;
186
187     if (scenes[indialogue].sound != 0) {
188         Game::playdialoguescenesound();
189     }
190 }
191
192 void Dialog::saveDialogs(FILE* tfile)
193 {
194     fpackf(tfile, "Bi", dialogs.size());
195
196     for (unsigned i = 0; i < dialogs.size(); i++) {
197         dialogs[i].save(tfile);
198     }
199 }
200
201 void Dialog::save(FILE* tfile)
202 {
203     fpackf(tfile, "Bi", scenes.size());
204     fpackf(tfile, "Bi", type);
205     for (int l = 0; l < 10; l++) {
206         fpackf(tfile, "Bf Bf Bf", participantlocation[l].x, participantlocation[l].y, participantlocation[l].z);
207         fpackf(tfile, "Bf", participantyaw[l]);
208     }
209     for (unsigned l = 0; l < scenes.size(); l++) {
210         scenes[l].save(tfile);
211     }
212 }
213
214 void DialogScene::save(FILE* tfile)
215 {
216     fpackf(tfile, "Bi", location);
217     fpackf(tfile, "Bf", color[0]);
218     fpackf(tfile, "Bf", color[1]);
219     fpackf(tfile, "Bf", color[2]);
220     fpackf(tfile, "Bi", sound);
221
222     fpackf_string(tfile, text);
223     fpackf_string(tfile, name);
224
225     fpackf(tfile, "Bf Bf Bf", camera.x, camera.y, camera.z);
226     fpackf(tfile, "Bi", participantfocus);
227     fpackf(tfile, "Bi", participantaction);
228
229     for (int m = 0; m < 10; m++)
230         fpackf(tfile, "Bf Bf Bf", participantfacing[m].x, participantfacing[m].y, participantfacing[m].z);
231
232     fpackf(tfile, "Bf Bf", camerayaw, camerapitch);
233 }