種族
ニック・バレンタインと同じにしました。
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レコード)のテキストデータから単語数を求め、一覧をテキストファイルに出力します。単語数はスペースの数で求めているため、英語である必要があります。