+/*
+Copyright (C) 2003, 2010 - Wolfire Games
+Copyright (C) 2010-2016 - Lugaru contributors (see AUTHORS file)
+
+This file is part of Lugaru.
+
+Lugaru 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; either version 2 of the License, or
+(at your option) any later version.
+
+Lugaru 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 Lugaru. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "Dialog.h"
+#include "Person.h"
+#include "Input.h"
+#include "Game.h"
+#include "binio.h"
+
+extern int hostile;
+
+int Dialog::indialogue;
+int Dialog::whichdialogue;
+bool Dialog::directing;
+float Dialog::dialoguetime;
+std::vector<Dialog> Dialog::dialogs;
+
+void Dialog::loadDialogs(FILE* tfile)
+{
+ int numdialogues;
+ funpackf(tfile, "Bi", &numdialogues);
+ for (int k = 0; k < numdialogues; k++) {
+ dialogs.push_back(Dialog(tfile));
+ }
+}
+
+Dialog::Dialog(FILE* tfile) : gonethrough(0)
+{
+ int numdialogboxes;
+ funpackf(tfile, "Bi", &numdialogboxes);
+ funpackf(tfile, "Bi", &type);
+ for (int l = 0; l < 10; l++) {
+ funpackf(tfile, "Bf Bf Bf", &participantlocation[l].x, &participantlocation[l].y, &participantlocation[l].z);
+ funpackf(tfile, "Bf", &participantyaw[l]);
+ }
+ for (int l = 0; l < numdialogboxes; l++) {
+ boxes.push_back(DialogBox(tfile));
+ }
+}
+
+std::string funpackf_string(FILE* tfile, int maxlength)
+{
+ int templength;
+ funpackf(tfile, "Bi", &templength);
+ if ((templength > maxlength) || (templength <= 0)) {
+ templength = maxlength;
+ }
+ int m;
+ char* text = new char[maxlength];
+ for (m = 0; m < templength; m++) {
+ funpackf(tfile, "Bb", &text[m]);
+ if (text[m] == '\0')
+ break;
+ }
+ text[m] = 0;
+ std::string result(text);
+ delete[] text;
+ return result;
+}
+
+void fpackf_string(FILE* tfile, std::string text)
+{
+ fpackf(tfile, "Bi", text.size());
+ for (int m = 0; m < text.size(); m++) {
+ fpackf(tfile, "Bb", text[m]);
+ if (text[m] == '\0')
+ break;
+ }
+}
+
+DialogBox::DialogBox(FILE* tfile)
+{
+ funpackf(tfile, "Bi", &location);
+ funpackf(tfile, "Bf", &color[0]);
+ funpackf(tfile, "Bf", &color[1]);
+ funpackf(tfile, "Bf", &color[2]);
+ funpackf(tfile, "Bi", &sound);
+
+ text = funpackf_string(tfile, 128);
+ name = funpackf_string(tfile, 64);
+
+ funpackf(tfile, "Bf Bf Bf", &camera.x, &camera.y, &camera.z);
+ funpackf(tfile, "Bi", &participantfocus);
+ funpackf(tfile, "Bi", &participantaction);
+
+ for (int m = 0; m < 10; m++)
+ funpackf(tfile, "Bf Bf Bf", &participantfacing[m].x, &participantfacing[m].y, &participantfacing[m].z);
+
+ funpackf(tfile, "Bf Bf", &camerayaw, &camerapitch);
+}
+
+/* Load dialog from txt file, used by console */
+Dialog::Dialog(int type, std::string filename) : type(type)
+{
+ ifstream ipstream(ConvertFileName(filename.c_str()));
+ ipstream.ignore(256, ':');
+ int numboxes;
+ ipstream >> numboxes;
+ for (int i = 0; i < numboxes; i++) {
+ boxes.push_back(DialogBox(ipstream));
+ for (unsigned j = 0; j < Person::players.size(); j++) {
+ boxes.back().participantfacing[j] = Person::players[j]->facing;
+ }
+ }
+ ipstream.close();
+}
+
+DialogBox::DialogBox(ifstream &ipstream)
+{
+ ipstream.ignore(256, ':');
+ ipstream.ignore(256, ':');
+ ipstream.ignore(256, ' ');
+ ipstream >> location;
+ ipstream.ignore(256, ':');
+ ipstream >> color[0];
+ ipstream >> color[1];
+ ipstream >> color[2];
+ ipstream.ignore(256, ':');
+ getline(ipstream, name);
+ ipstream.ignore(256, ':');
+ ipstream.ignore(256, ' ');
+ getline(ipstream, text);
+ for (int j = 0; j < 128; j++) {
+ if (text[j] == '\\')
+ text[j] = '\n';
+ }
+ ipstream.ignore(256, ':');
+ ipstream >> sound;
+}
+
+void Dialog::tick(int id)
+{
+ unsigned playerId = type % 10;
+ bool special = (type > 9);
+
+ if ((!hostile || (type > 40) && (type < 50)) &&
+ (playerId < Person::players.size()) &&
+ (playerId > 0) &&
+ ((gonethrough == 0) || !special) &&
+ (special || Input::isKeyPressed(Game::attackkey))) {
+ if ((distsq(&Person::players[0]->coords, &Person::players[playerId]->coords) < 6) ||
+ (Person::players[playerId]->howactive >= typedead1) ||
+ (type > 40) && (type < 50)) {
+ whichdialogue = id;
+ play();
+ dialoguetime = 0;
+ gonethrough++;
+ }
+ }
+}
+
+void Dialog::play()
+{
+ for (int i = 0; i < boxes.size(); i++) {
+ int playerId = boxes[i].participantfocus;
+ Person::players[playerId]->coords = participantlocation[playerId];
+ Person::players[playerId]->yaw = participantyaw[playerId];
+ Person::players[playerId]->targetyaw = participantyaw[playerId];
+ Person::players[playerId]->velocity = 0;
+ Person::players[playerId]->animTarget = Person::players[playerId]->getIdle();
+ Person::players[playerId]->frameTarget = 0;
+ }
+
+ Dialog::directing = false;
+ Dialog::indialogue = 0;
+
+ if (boxes[indialogue].sound != 0) {
+ Game::playdialogueboxsound();
+ }
+}
+
+void Dialog::saveDialogs(FILE* tfile)
+{
+ fpackf(tfile, "Bi", dialogs.size());
+
+ for (int k = 0; k < dialogs.size(); k++) {
+ dialogs[k].save(tfile);
+ }
+}
+
+void Dialog::save(FILE* tfile)
+{
+ fpackf(tfile, "Bi", boxes.size());
+ fpackf(tfile, "Bi", type);
+ for (int l = 0; l < 10; l++) {
+ fpackf(tfile, "Bf Bf Bf", participantlocation[l].x, participantlocation[l].y, participantlocation[l].z);
+ fpackf(tfile, "Bf", participantyaw[l]);
+ }
+ for (int l = 0; l < boxes.size(); l++) {
+ boxes[l].save(tfile);
+ }
+}
+
+void DialogBox::save(FILE* tfile)
+{
+ fpackf(tfile, "Bi", location);
+ fpackf(tfile, "Bf", color[0]);
+ fpackf(tfile, "Bf", color[1]);
+ fpackf(tfile, "Bf", color[2]);
+ fpackf(tfile, "Bi", sound);
+
+ fpackf_string(tfile, text);
+ fpackf_string(tfile, name);
+
+ fpackf(tfile, "Bf Bf Bf", camera.x, camera.y, camera.z);
+ fpackf(tfile, "Bi", participantfocus);
+ fpackf(tfile, "Bi", participantaction);
+
+ for (int m = 0; m < 10; m++)
+ fpackf(tfile, "Bf Bf Bf", participantfacing[m].x, participantfacing[m].y, participantfacing[m].z);
+
+ fpackf(tfile, "Bf Bf", camerayaw, camerapitch);
+}