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