Объявления

Друзья, если не получается зарегистрироваться, напишите на почту vdv_forever@bk.ru.
Я оторву свою задницу от всех дел и обязательно Вас активирую! :smile10:
Добро пожаловать на геройский форум! :smile25:

T-800 mod для Free Heroes II

Не запускается игра? Проблемы со звуком? Где, в конце концов, взять игру, скачать патчи, приложения и карты? Как установить все это? Все проблемы обсуждаем в этом разделе
offlineАватара пользователя
t800  
Ветеран
Ветеран
 
Сообщения: 982
Зарегистрирован: 22 июл 2015, 11:36
Пол: Не указан
Награды: 4
Наградной знак (1) Деревянный Щит (1) Золотой Меч (1) Серебряные Сапоги (1)
Поблагодарили: 191 раз.

Re: Кампания во Free Heroes II

Сообщение t800 » 17 сен 2015, 02:16

DeathLust писал(а):

Изучаем, как в C++ делается чтение из файла, пишем функцию, которая читает и возвращает содержимое нужной строчки, присваиваем результат строковой переменной file, PROFIT.


Я нашел команды чтобы игра брала имя карты из файлика.


Код: Выделить всё
int Game::NeхtСampain(void)
{
    std::ifstream scenarioListFile;
    std::string scenarioFilePath;

    scenarioListFile.open("files/campain/t800.txt");
    std::getline(scenarioListFile, scenarioFilePath);
    scenarioListFile.close();

    if(scenarioFilePath.empty() || !Game::Load(scenarioFilePath)) return MAINMENU;
    return STARTGAME;
}


Но она сейчас берет тольк первую карту из файла. А мне нужно чтобы игра смотрела какую карту уже закончила. Проверяла по списку и брала из файлика следующую карту. И чтобы при разных камапаниях читала из разных файлов. У меня их сейчас три. И может будет больше. Может еще 4 добавлю из Цены Верности.
Вернуться к началу

offlineАватара пользователя
DeathLust  
Подмастерье
Подмастерье
 
Сообщения: 140
Зарегистрирован: 29 ноя 2012, 15:19
Пол: Не указан
Поблагодарили: 62 раз.

Re: Кампания во Free Heroes II

Сообщение DeathLust » 17 сен 2015, 10:44

t800 писал(а):

DeathLust писал(а):

Изучаем, как в C++ делается чтение из файла, пишем функцию, которая читает и возвращает содержимое нужной строчки, присваиваем результат строковой переменной file, PROFIT.

Но она сейчас берет тольк первую карту из файла. А мне нужно чтобы игра смотрела какую карту уже закончила. Проверяла по списку и брала из файлика следующую карту. И чтобы при разных камапаниях читала из разных файлов. У меня их сейчас три. И может будет больше. Может еще 4 добавлю из Цены Верности.

Естественно, что первую, т.к. читает с начала файла только одну строку, которая по странному стечению обстоятельств оказывается первой строкой :smile6: Соответственно, нужно читать файл до нужной строки. А вот каким образом определить номер следующей строки-названия файла кампании - может оказаться не самой тривиальной задачей, ведь во время игры не факт, что где-то в файле сохранения хранится название файла карты, из которой этот сейв был сгенерирован.
Как минимум, придётся изучить циклы for или даже while.
Вернуться к началу

offlineАватара пользователя
t800  
Ветеран
Ветеран
 
Сообщения: 982
Зарегистрирован: 22 июл 2015, 11:36
Пол: Не указан
Награды: 4
Наградной знак (1) Деревянный Щит (1) Золотой Меч (1) Серебряные Сапоги (1)
Поблагодарили: 191 раз.

Re: Кампания во Free Heroes II

Сообщение t800 » 17 сен 2015, 14:24

DeathLust писал(а):

t800 писал(а):

DeathLust писал(а):

Изучаем, как в C++ делается чтение из файла, пишем функцию, которая читает и возвращает содержимое нужной строчки, присваиваем результат строковой переменной file, PROFIT.

Но она сейчас берет тольк первую карту из файла. А мне нужно чтобы игра смотрела какую карту уже закончила. Проверяла по списку и брала из файлика следующую карту. И чтобы при разных камапаниях читала из разных файлов. У меня их сейчас три. И может будет больше. Может еще 4 добавлю из Цены Верности.

Естественно, что первую, т.к. читает с начала файла только одну строку, которая по странному стечению обстоятельств оказывается первой строкой :smile6: Соответственно, нужно читать файл до нужной строки. А вот каким образом определить номер следующей строки-названия файла кампании - может оказаться не самой тривиальной задачей, ведь во время игры не факт, что где-то в файле сохранения хранится название файла карты, из которой этот сейв был сгенерирован.
Как минимум, придётся изучить циклы for или даже while.


Я посмотрел в hexeditor там в начале сейва такие строчки

Изображение
Вернуться к началу

offlineАватара пользователя
DeathLust  
Подмастерье
Подмастерье
 
Сообщения: 140
Зарегистрирован: 29 ноя 2012, 15:19
Пол: Не указан
Поблагодарили: 62 раз.

Re: Кампания во Free Heroes II

Сообщение DeathLust » 18 сен 2015, 10:19

Значит, что-то сохраняет. Но отличается расширение файла. Значит, нужно будет видоизменить строчку CAMPExx.MP2 -> CAMPExx.CAM. E говорит нам, что нужно искать строчку в файле "злых" кампаний evil1.txt. Читаем из файла построчно, проверяем на соответствие текущей строки искомой (как раз пригодится цикл while). Когда нашли, что искали, то нужно будет прочитать ещё 1-2 следующие строки (т.к. иногда встречается ветвление сюжетного хода), в которых и будет название файла сценария кампании, который следует загрузить.
Осталась, правда, проблема, как инициализировать переходящие бонусы, типа, убегающих гномов.
Вернуться к началу

offlineАватара пользователя
t800  
Ветеран
Ветеран
 
Сообщения: 982
Зарегистрирован: 22 июл 2015, 11:36
Пол: Не указан
Награды: 4
Наградной знак (1) Деревянный Щит (1) Золотой Меч (1) Серебряные Сапоги (1)
Поблагодарили: 191 раз.

Re: Кампания во Free Heroes II

Сообщение t800 » 18 сен 2015, 17:52

DeathLust писал(а):

Значит, что-то сохраняет. Но отличается расширение файла. Значит, нужно будет видоизменить строчку CAMPExx.MP2 -> CAMPExx.CAM. E говорит нам, что нужно искать строчку в файле "злых" кампаний evil1.txt. Читаем из файла построчно, проверяем на соответствие текущей строки искомой (как раз пригодится цикл while). Когда нашли, что искали, то нужно будет прочитать ещё 1-2 следующие строки (т.к. иногда встречается ветвление сюжетного хода), в которых и будет название файла сценария кампании, который следует загрузить.
Осталась, правда, проблема, как инициализировать переходящие бонусы, типа, убегающих гномов.


Кажется получилось! Но пришлось переименовать сейвы кампаний обратно в как назывались их карты.
И записать в файлах .txt названия файлов карт (сейвов переименованных в карты) потому что при сейвах
игра помнит имена исходных карт а не сейвов.

Код: Выделить всё
int Game::NextCampain(void)
{
        std::string file;
   Settings & conf = Settings::Get();
   std::string savname = conf.MapsFile();
   std::string path = Settings::GetCampainDir();
        std::cout << path << " Путь\n";
   std::cout << savname << " Имя карты\n";
    std::string listname = StringLower(conf.MapsFile().substr(0,4)) + ".txt";
    std::cout << listname << " Имя списка\n";
    listname = System::ConcatePath(path,listname);
    std::cout << listname << " Имя списка с путем\n";
 
    std::ifstream scenarioListFile;
    std::string scenarioFileName;
 
    scenarioListFile.open(listname.c_str());
    while(getline(scenarioListFile, scenarioFileName))
   {
    if(savname == scenarioFileName)
      {
      getline(scenarioListFile, scenarioFileName);
      break;
      }
   }
   
   file = System::ConcatePath(path,scenarioFileName);
   std::cout << file << " Имя файла чтобы загружать\n";
   
if(file.empty() || !Game::Load(file)) return MAINMENU;
return STARTGAME;
}



[youtube]http://youtu.be/T3kscXZOlow[/youtube]
Вернуться к началу

offlineАватара пользователя
t800  
Ветеран
Ветеран
 
Сообщения: 982
Зарегистрирован: 22 июл 2015, 11:36
Пол: Не указан
Награды: 4
Наградной знак (1) Деревянный Щит (1) Золотой Меч (1) Серебряные Сапоги (1)
Поблагодарили: 191 раз.

Re: Кампания во Free Heroes II

Сообщение t800 » 19 сен 2015, 05:04

А как надо считать рейтинги для кампаний? Просто складывать обычный рейтинг для каждого из сценарие? Или как?
Вернуться к началу

offlineАватара пользователя
VDV_forever  
имя: Дмитрий
Администратор
 
Сообщения: 3859
Зарегистрирован: 22 мар 2009, 12:36
Пол: Мужчина
Поблагодарили: 982 раз.

Re: Кампания во Free Heroes II

Сообщение VDV_forever » 19 сен 2015, 05:08

t800 писал(а):

А как надо считать рейтинги для кампаний? Просто складывать обычный рейтинг для каждого из сценарие? Или как?

Читаем справочник. :smile2: Тут
http://www.handbookhmm.ru- Познай все тонкости игры!
Вернуться к началу

offlineАватара пользователя
t800  
Ветеран
Ветеран
 
Сообщения: 982
Зарегистрирован: 22 июл 2015, 11:36
Пол: Не указан
Награды: 4
Наградной знак (1) Деревянный Щит (1) Золотой Меч (1) Серебряные Сапоги (1)
Поблагодарили: 191 раз.

Re: Кампания во Free Heroes II

Сообщение t800 » 19 сен 2015, 13:58

VDV_forever писал(а):

t800 писал(а):

А как надо считать рейтинги для кампаний? Просто складывать обычный рейтинг для каждого из сценарие? Или как?

Читаем справочник. :smile2: Тут


С справочнике про одну карту. А для кампании как надо cчитать? Если у первой игры рейтинг получился 100 , у второй игры 200 а у третей 300. Какой будет общий рейтиг для кампании? 100 + 200 + 300 = 600 или какой то другой ?
Вернуться к началу

offlineАватара пользователя
t800  
Ветеран
Ветеран
 
Сообщения: 982
Зарегистрирован: 22 июл 2015, 11:36
Пол: Не указан
Награды: 4
Наградной знак (1) Деревянный Щит (1) Золотой Меч (1) Серебряные Сапоги (1)
Поблагодарили: 191 раз.

Re: Кампания во Free Heroes II

Сообщение t800 » 21 сен 2015, 05:48

Стал делать рейтинги для кампаний! Для этого сперва открыл файлик highscores_game.cpp

Код: Выделить всё
#include <algorithm>
#include <sstream>
#include <vector>
#include <string>
#include <cstring>
#include <ctime>

#include "system.h"
#include "gamedefs.h"
#include "text.h"
#include "agg.h"
#include "cursor.h"
#include "button.h"
#include "dialog.h"
#include "settings.h"
#include "world.h"
#include "zzlib.h"
#include "game.h"
#include "game_over.h"

#define HGS_ID    0xF1F3
#define HGS_MAX    10

struct hgs_t
{
    hgs_t() : days(0), rating(0) {};

    bool operator== (const hgs_t &) const;

    std::string    player;
    std::string    land;
    u32        localtime;
    u32        days;
    u32        rating;
};

StreamBase & operator<< (StreamBase & msg, const hgs_t & hgs)
{
    return msg << hgs.player << hgs.land << hgs.localtime << hgs.days << hgs.rating;
}

StreamBase & operator>> (StreamBase & msg, hgs_t & hgs)
{
    return msg >> hgs.player >> hgs.land >> hgs.localtime >> hgs.days >> hgs.rating;
}

bool hgs_t::operator== (const hgs_t & h) const
{
    return player == h.player && land == h.land && days == h.days;
}

bool RatingSort(const hgs_t & h1, const hgs_t & h2)
{
    return h1.rating > h2.rating;
}

class HGSData
{
public:
    HGSData() {}

    bool Load(const std::string &);
    bool Save(const std::string &);
    void ScoreRegistry(const std::string &, const std::string &, u32, u32);
    void RedrawList(s32, s32);
private:
    std::vector<hgs_t> list;
};

bool HGSData::Load(const std::string & fn)
{
    ZStreamFile hdata;
    if(! hdata.read(fn)) return false;

    hdata.setbigendian(true);
    u16 hgs_id = 0;

    hdata >> hgs_id;

#ifdef FORMAT_VERSION_3225
    // old stream ver. skip 4 byte
    if(hgs_id != HGS_ID)
    hdata >> hgs_id >> hgs_id;
#endif

    if(hgs_id == HGS_ID)
    {
    hdata >> list;
    return ! hdata.fail();
    }

    return false;
}

bool HGSData::Save(const std::string & fn)
{
    ZStreamFile hdata;
    hdata.setbigendian(true);
    hdata << static_cast<u16>(HGS_ID) << list;
    if(hdata.fail() || ! hdata.write(fn)) return false;

    return true;
}

void HGSData::ScoreRegistry(const std::string & p, const std::string & m, u32 r, u32 s)
{
    hgs_t h;

    h.player = p;
    h.land = m;
    h.localtime = std::time(NULL);
    h.days = r;
    h.rating = s;

    if(list.end() == std::find(list.begin(), list.end(), h))
    {
    list.push_back(h);
    std::sort(list.begin(), list.end(), RatingSort);
    if(list.size() > HGS_MAX) list.resize(HGS_MAX);
    }
}

void HGSData::RedrawList(s32 ox, s32 oy)
{
    const Settings & conf = Settings::Get();

    // image background
    const Sprite &back = AGG::GetICN(ICN::HSBKG, 0);
    back.Blit(ox, oy);

    const Sprite &head = AGG::GetICN(ICN::HISCORE, 6);
    if(conf.QVGA())
    head.Blit(ox + 25, oy + 15);
    else
    head.Blit(ox + 50, oy + 31);

    std::sort(list.begin(), list.end(), RatingSort);

    std::vector<hgs_t>::const_iterator it1 = list.begin();
    std::vector<hgs_t>::const_iterator it2 = list.end();

    Text text;
    text.Set(conf.QVGA() ? Font::SMALL : Font::BIG);

    for(; it1 != it2 && (it1 - list.begin() < HGS_MAX); ++it1)
    {
    const hgs_t & hgs = *it1;

    text.Set(hgs.player);
    text.Blit(ox + (conf.QVGA() ? 45 : 88), oy + (conf.QVGA() ? 33 : 70));

    text.Set(hgs.land);
    text.Blit(ox + (conf.QVGA() ? 170 : 260), oy + (conf.QVGA() ? 33 : 70));

    text.Set(GetString(hgs.days));
    text.Blit(ox + (conf.QVGA() ? 250 : 420), oy + (conf.QVGA() ? 33 : 70));

    text.Set(GetString(hgs.rating));
    text.Blit(ox + (conf.QVGA() ? 270 : 480), oy + (conf.QVGA() ? 33 : 70));

    oy += conf.QVGA() ? 20 : 40;
    }
}

int Game::HighScores(bool fill)
{
    Cursor & cursor = Cursor::Get();
    Display & display = Display::Get();
    const Settings & conf = Settings::Get();

    cursor.Hide();
    if(fill) display.Fill(ColorBlack);

#ifdef WITH_DEBUG
    if(IS_DEVEL() && world.CountDay())
    {
    std::string msg = std::string("Devepoper mode, not save! \n \n Your result: ") + GetString(GetGameOverScores());
    Dialog::Message("High Scores", msg, Font::BIG, Dialog::OK);
    return MAINMENU;
    }
#endif

    HGSData hgs;

    std::ostringstream stream;
    stream << System::ConcatePath(conf.GetSaveDir(), "fheroes2.hgs");

    cursor.SetThemes(cursor.POINTER);
    Mixer::Pause();
    AGG::PlayMusic(MUS::MAINMENU);
    hgs.Load(stream.str().c_str());

    const Sprite &back = AGG::GetICN(ICN::HSBKG, 0);

    cursor.Hide();
    const Point top((display.w() - back.w()) / 2, (display.h() - back.h()) / 2);

    hgs.RedrawList(top.x, top.y);

    LocalEvent & le = LocalEvent::Get();

    Button buttonCampain(top.x + (conf.QVGA() ? 0 : 9), top.y + (conf.QVGA() ? 100 : 315), ICN::HISCORE, 0, 1);
    Button buttonExit(top.x + back.w() - (conf.QVGA() ? 27 : 36), top.y + (conf.QVGA() ? 100 : 315), ICN::HISCORE, 4, 5);

    buttonCampain.Draw();
    buttonExit.Draw();

    cursor.Show();
    display.Flip();

    const u32 rating = GetGameOverScores();
    const u32 days = world.CountDay();
    GameOver::Result & gameResult = GameOver::Result::Get();

    if(rating && (gameResult.GetResult() & GameOver::WINS))
    {
    std::string player(_("Unknown Hero"));
    Dialog::InputString(_("Your Name"), player);
    cursor.Hide();
    if(player.empty()) player = _("Unknown Hero");
    hgs.ScoreRegistry(player, Settings::Get().CurrentFileInfo().name, days, rating);
    hgs.Save(stream.str().c_str());
    hgs.RedrawList(top.x, top.y);
    buttonCampain.Draw();
    buttonExit.Draw();
    cursor.Show();
    display.Flip();
    gameResult.Reset();
    }

    // highscores loop    {
    // key code info
        if(Settings::Get().Debug() == 0x12 && le.KeyPress())
            Dialog::Message("Key Press:", GetString(le.KeyValue()), Font::SMALL, Dialog::OK);
    le.MousePressLeft(buttonCampain) ? buttonCampain.PressDraw() : buttonCampain.ReleaseDraw();
    le.MousePressLeft(buttonExit) ? buttonExit.PressDraw() : buttonExit.ReleaseDraw();

    if(le.MouseClickLeft(buttonExit) || HotKeyCloseWindow) return MAINMENU;
    }

    return QUITGAME;
}


Потом я скопировал весь код команд начиная с

Код: Выделить всё
#define HGS_ID    0xF1F3
#define HGS_MAX    10


И до самого конца и вставил тут же в файл highscores_game.cpp только ниже. Потом в том что вставил везде переименовал все HGS в HGSС , а все hgs в hgsc и RatingSort в RatingSortСampain, а fheroes2.hgs в fheroes2.hgsс

Потом в в файлике gameover.cpp вместо

Код: Выделить всё
res = Game::NEXTCAMPAIN;



Написал

Код: Выделить всё
res = Game::HIGHSCORESCAMPAIN;


Собрал игру запустил. Выиграл одну карту из тестовой кампании и сразу попал в Рейтинг для кампании!

[youtube]http://youtu.be/_aXgYHsDFI0[/youtube]
Последний раз редактировалось t800 21 сен 2015, 06:39, всего редактировалось 3 раз(а).
Вернуться к началу

offlineАватара пользователя
t800  
Ветеран
Ветеран
 
Сообщения: 982
Зарегистрирован: 22 июл 2015, 11:36
Пол: Не указан
Награды: 4
Наградной знак (1) Деревянный Щит (1) Золотой Меч (1) Серебряные Сапоги (1)
Поблагодарили: 191 раз.

Re: Кампания во Free Heroes II

Сообщение t800 » 21 сен 2015, 06:20

Сейчас в highscores_game.cpp в


Код: Выделить всё
int Game::HighScoresCampain(bool fill)
{
   Cursor & cursor = Cursor::Get();
   Display & display = Display::Get();
   const Settings & conf = Settings::Get();

   cursor.Hide();
   if(fill) display.Fill(ColorBlack);

#ifdef WITH_DEBUG
   if(IS_DEVEL() && world.CountDay())
   {
   std::string msg = std::string("Devepoper mode, not save! \n \n Your result: ") + GetString(GetGameOverScores());
   Dialog::Message("High Scores", msg, Font::BIG, Dialog::OK);
   return MAINMENU;
   }
#endif

   HGSCData hgsc;

   std::ostringstream stream;
   stream << System::ConcatePath(conf.GetSaveDir(), "fheroes2.hgsc");

   cursor.SetThemes(cursor.POINTER);
   Mixer::Pause();
   AGG::PlayMusic(MUS::MAINMENU);
   hgsc.Load(stream.str().c_str());

   const Sprite &back = AGG::GetICN(ICN::HSBKG, 0);

   cursor.Hide();
   const Point top((display.w() - back.w()) / 2, (display.h() - back.h()) / 2);

   hgsc.RedrawList(top.x, top.y);

   LocalEvent & le = LocalEvent::Get();

   Button buttonStandart(top.x + (conf.QVGA() ? 0 : 9), top.y + (conf.QVGA() ? 100 : 315), ICN::HISCORE, 2, 3);
   Button buttonExit(top.x + back.w() - (conf.QVGA() ? 27 : 36), top.y + (conf.QVGA() ? 100 : 315), ICN::HISCORE, 4, 5);

   buttonStandart.Draw();
   buttonExit.Draw();

   cursor.Show();
   display.Flip();

   const u32 rating = GetGameOverScores();
   const u32 days = world.CountDay();
   GameOver::Result & gameResult = GameOver::Result::Get();

   if(rating && (gameResult.GetResult() & GameOver::WINS))
   {
   std::string player(_("Unknown Hero"));
   Dialog::InputString(_("Your Name"), player);
   cursor.Hide();
   if(player.empty()) player = _("Unknown Hero");
   hgsc.ScoreRegistryC(player, Settings::Get().CurrentFileInfo().name, days, rating);
   hgsc.Save(stream.str().c_str());
   hgsc.RedrawList(top.x, top.y);
   buttonStandart.Draw();
   buttonExit.Draw();
   cursor.Show();
   display.Flip();
   gameResult.Reset();
   }

   // highscores loop
   while(le.HandleEvents())
   {
   // key code info
      if(Settings::Get().Debug() == 0x12 && le.KeyPress())
         Dialog::Message("Key Press:", GetString(le.KeyValue()), Font::SMALL, Dialog::OK);
   le.MousePressLeft(buttonStandart) ? buttonStandart.PressDraw() : buttonStandart.ReleaseDraw();
   le.MousePressLeft(buttonExit) ? buttonExit.PressDraw() : buttonExit.ReleaseDraw();

   if(le.MouseClickLeft(buttonStandart) || HotKeyCloseWindow) return HIGHSCORES;
   if(le.MouseClickLeft(buttonExit) || HotKeyCloseWindow) return MAINMENU;
   }

   return QUITGAME;
}


Поменял везде где было написано buttonCampain на buttonStandart и теперь у меня рейтинги переключаются!!! :smile21: :smile21: :smile21:

[youtube]http://youtu.be/vvDD_B9CU6w[/youtube]
Вернуться к началу

Пред.След.

Вернуться в Техническая часть

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 7

cron