エイダをシンスにしてみた

環境構築

種族

ニック・バレンタインと同じにしました。

Nanakochan化

AnimeRace Nanakochan Synthにておいてニック・バレンタインをNanakochan化しましたが、それと同じ要領で作業しました。

Combat Style

壁役として近接攻撃をして欲しいので、シンスの近接タイプのものを割り当てました。

ニック・バレンタインのCombat Styleだと遠隔攻撃をしようとして、周囲の銃器を積極的にルートしてしまいます。

口パクがおかしいのをなおす

エイダの音声データに含まれているlipファイルがロボットに合わせた特殊なもののようです。

Lazy Voice Finderでエイダの音声データ(fuz)をすべてエクスポートします。

Yakitori Audio Converterでfuzファイルをwavとlipに展開します。

lipファイルは要らないのですべて削除します。

F4z Ro D-oh – Silent Voiceからlipファイルを取り出します。

あとはF4z Ro D-oh – Silent Voiceのlipファイルをエイダの音声データのlipファイルとしてコピーすればいいです。

スクリプト

この作業を行うPHPスクリプトです。

copy_lip.php (php)

<?php
define('BASE_DIR', getcwd());
define('LIP_FILE_BASE', BASE_DIR . DIRECTORY_SEPARATOR . 'Stock_%d.lip');
define('WORD_COUNT_FILE', 'C:\GAMES\SSEEdit 4.0.4\Edit Scripts\word_count_list.txt');

try {
    $lip_file_list = get_lip_file_list();
    $word_count_data = get_word_count_data();
    copy_lip('');
} catch (Exception $e) {
    echo $e->getMessage() . PHP_EOL;
}


function get_lip_file_list()
{
    $ary = [];

    for ($i = 0; $i < 10; $i++) {
        $ary[$i] = sprintf(LIP_FILE_BASE, $i + 1);
    }

    return $ary;
}


function get_word_count_data()
{
    $ary = [];

    $fp = fopen(WORD_COUNT_FILE, 'r');

    while ( !feof($fp) ) {
        $buf = fgets($fp);
        $buf = trim($buf);

        if ( !$buf ) {
            continue;
        }

        list($basename, $count) = explode(',', $buf);
        $basename = strtolower($basename);
        $ary[$basename] = $count;
    }

    fclose($fp);

    return $ary;
}


function copy_lip($path)
{
    global $lip_file_list, $word_count_data;

    $basedir = BASE_DIR . DIRECTORY_SEPARATOR . $path;

    $dh = opendir($basedir);

    if ( !$dh ) {
        throw new Exception('could not open dir - ' . $basedir);
    }

    while ( $file = readdir($dh) ) {
        if ( ($file == '.') || ($file == '..') ) {
            continue;
        }

        if ( !preg_match('!(.+)\.wav!', $file, $matches) ) {
            continue;
        }

        $file_base = strtolower($matches[1]);
        $lip_index = 0;

        if ( isset( $word_count_data[$file_base] ) ) {
            $lip_index = floor($word_count_data[$file_base] / 2);
            //printf("lip_index: %d" . PHP_EOL, $lip_index);
        } else {
            $key = $file_base;
            $key[0] = '0';
            $key[1] = '1';

            if ( isset( $word_count_data[$key] ) ) {
                $lip_index = floor($word_count_data[$key] / 2);
                //printf("lip_index: %d" . PHP_EOL, $lip_index);
            } else {
                printf('lip_index not found, file_base: %s' . PHP_EOL, $file_base);
            }
        }

        if ( $lip_index >= 10 ) {
            $lip_index = 9;
        }

        $lip_file = $lip_file_list[$lip_index];
        $fullpath_lip = $basedir . DIRECTORY_SEPARATOR . $file_base . '.lip';

        copy($lip_file, $fullpath_lip);
    }

    closedir($dh);
}

要約すると、以下のことをしています。

  • F4z Ro D-oh - Silent Voiceのlipファイル一覧を取得する
  • word_count_list.txt(後述)から単語数一覧を取得する
  • wavファイルを検索して最適なlipファイルを選び、wavと同じ名前のlipファイルとしてコピーする

word_count_list.txtが必要なのですが、これを生成するxEdit用スクリプトがこちらです。

FO4 - INFO - get response text word count list.pas (pascal)

{
    FO4 - INFO - get response text word count list.
}

unit UserScript;
uses mteFunctions;


var
    sl: TStringList;


function GetCharCount(const haystack: string; const findchar: string): integer;
var
    len: integer;
    i: integer;
begin
    Result := 0;
    len := Length(haystack);

    while (i < len) do begin
        if haystack[i] = findchar then
            Inc(Result);

        Inc(i);
    end;
end;


function Initialize: integer;
begin
    sl := TStringList.Create;
end;


function Process(e: IInterface): integer;
var
    res: IInterface;
    nam: string;
    s: string;
    i, c: integer;
begin
    if Signature(e) <> 'INFO' then
        Exit;

    for i := 0 to 4 do begin
        res := ElementByIP(e, 'Responses\[' + IntToStr(i) + ']');

        if not Assigned(res) then
            Break;

        nam := GetElementEditValues(res, 'NAM1');

        if not Assigned(nam) then
            Break;

        c := GetCharCount(nam, ' ');
        s := IntToHex(FormID(e), 8) + '_' + IntToStr(i + 1) + ',' + IntToStr(c);
        sl.Add(s);
    end;
end;


function Finalize: integer;
var
    fname: string;
begin
    fname := ProgramPath + 'Edit Scripts\word_count_list.txt';
    sl.SaveToFile(fname);
    sl.Free;
end;


end.

指定したセリフ(INFOレコード)のテキストデータから単語数を求め、一覧をテキストファイルに出力します。単語数はスペースの数で求めているため、英語である必要があります。

タイトルとURLをコピーしました