2023-08-01 19:50:29 +02:00

333 lines
9.3 KiB
C++

/*
Copyright (C) 2003, 2010 - Wolfire Games
Copyright (C) 2010-2017 - 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 "Level/Dialog.hpp"
#include "Game.hpp"
#include "Objects/Person.hpp"
#include "Utils/Folders.hpp"
#include "Utils/Input.hpp"
#include "Utils/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));
}
}
void Dialog::loadDialogs(Json::Value values)
{
for (unsigned i = 0; i < values.size(); i++) {
dialogs.push_back(Dialog(values[i]));
}
}
Dialog::Dialog(Json::Value data)
: gonethrough(0)
{
type = data["type"].asInt();
for (int l = 0; l < 10; l++) {
participantlocation[l] = data["participant"][l]["pos"];
participantyaw[l] = data["participant"][l]["yaw"].asFloat();
}
for (unsigned l = 0; l < data["scenes"].size(); l++) {
scenes.push_back(DialogScene(data["scenes"][l]));
}
}
Dialog::Dialog(FILE* tfile)
: gonethrough(0)
{
int numdialogscenes;
funpackf(tfile, "Bi", &numdialogscenes);
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 < numdialogscenes; l++) {
scenes.push_back(DialogScene(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 (unsigned i = 0; i < text.size(); i++) {
fpackf(tfile, "Bb", text[i]);
if (text[i] == '\0') {
break;
}
}
}
DialogScene::DialogScene(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);
}
DialogScene::DialogScene(Json::Value data)
{
location = data["location"].asInt();
color[0] = data["color"][0].asFloat();
color[1] = data["color"][1].asFloat();
color[2] = data["color"][2].asFloat();
sound = data["sound"].asInt();
text = data["text"].asString();
name = data["name"].asString();
camera = data["camera"]["pos"];
camerayaw = data["camera"]["yaw"].asFloat();
camerapitch = data["camera"]["pitch"].asFloat();
participantfocus = data["participantfocus"].asInt();
participantaction = data["participantaction"].asInt();
for (int m = 0; m < 10; m++) {
participantfacing[m] = data["participantfacing"][m];
}
}
/* Load dialog from txt file, used by console */
Dialog::Dialog(int type, std::string filename)
: type(type)
{
ifstream ipstream(Folders::getResourcePath(filename));
ipstream.ignore(256, ':');
int numscenes;
ipstream >> numscenes;
for (int i = 0; i < numscenes; i++) {
scenes.push_back(DialogScene(ipstream));
for (unsigned j = 0; j < Person::players.size(); j++) {
scenes.back().participantfacing[j] = Person::players[j]->facing;
}
}
ipstream.close();
}
DialogScene::DialogScene(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 (unsigned i = 0; i < scenes.size(); i++) {
int playerId = scenes[i].participantfocus;
Person::players.at(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 (scenes[indialogue].sound != 0) {
Game::playdialoguescenesound();
}
}
void Dialog::saveDialogs(FILE* tfile)
{
fpackf(tfile, "Bi", dialogs.size());
for (unsigned i = 0; i < dialogs.size(); i++) {
dialogs[i].save(tfile);
}
}
Json::Value Dialog::saveDialogs()
{
Json::Value dialogsarray;
for (unsigned i = 0; i < dialogs.size(); i++) {
dialogsarray[i] = dialogs[i].save();
}
return dialogsarray;
}
void Dialog::save(FILE* tfile)
{
fpackf(tfile, "Bi", scenes.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 (unsigned l = 0; l < scenes.size(); l++) {
scenes[l].save(tfile);
}
}
Json::Value Dialog::save()
{
Json::Value dialog;
dialog["type"] = type;
for (int l = 0; l < 10; l++) {
dialog["participant"][l]["pos"] = participantlocation[l];
dialog["participant"][l]["yaw"] = participantyaw[l];
}
for (unsigned l = 0; l < scenes.size(); l++) {
dialog["scenes"][l] = scenes[l];
}
return dialog;
}
void DialogScene::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);
}
Json::Value DialogScene::save()
{
Json::Value dialogscene;
dialogscene["location"] = location;
dialogscene["color"][0] = color[0];
dialogscene["color"][1] = color[1];
dialogscene["color"][2] = color[2];
dialogscene["sound"] = sound;
dialogscene["text"] = text;
dialogscene["name"] = name;
dialogscene["camera"]["pos"] = camera;
dialogscene["camera"]["yaw"] = camerayaw;
dialogscene["camera"]["pitch"] = camerapitch;
dialogscene["participantfocus"] = participantfocus;
dialogscene["participantaction"] = participantaction;
for (int m = 0; m < 10; m++) {
dialogscene["participantfacing"][m] = participantfacing[m];
}
return dialogscene;
}