ドキュメント無し版α!

経過報告 - 永字八法の続き。
ドキュメントが整備されていないけれども、できた。

導入

  • nscr.exeをluaの使えるバージョンに。最新版にするのがベスト。
  • nslua.dllをnscr.exeに同梱。
  • 下記の内容をsystem.luaにコピペして保存。nscr.exeに同梱。
  • 下記の内容をgame_list.txtにコピペして保存。nscr.exeに同梱。

以上。
サンプルの00.txtもつける。

注意書き

以下の命令について、自動的にファイルの場所を探す機能を加えた。

  • bg
  • ld
  • lsp
  • lsph
  • bgm
  • bgmonce
  • loopbgm(ただし、この命令は潜在的ogg関係のバグを持っている)
  • dwave
  • dwaveload
  • dwaveloop

あー、print文の後のdll指定とかにもいるなあ。次のバージョンでつけますよ、と。

2009-08-141追記

bg命令の使い方の一つ、bg white や bg black は対応していません。
これを使う場合は、_bg white と言う風にbgの前にアンダーバーをつけてください。
これはLuaの仕様に関係する制限ですので、今後解決される見通しは立っていません。

system.lua

-- む式 ver.lua おくだけ 2009-05-29
NSExec("nsa")

function error_end(message)
	NSOkBox(message, "む式。")
	NSSystemCall("end")
end

-- nsaも探すよ!
function fileexist_in_nsa(file)
	local temp = NSGetIntValue(0)
	NSExec('_fileexist %0,"'..file..'"')
	local res = NSGetIntValue(0)
	NSSetIntValue(0, temp)
	return res
end

-- nsaは探さないよ!
function fileexist_not_nsa(file)
	local fh = io.open(file)
	if io.type(fh) == nil then
		return 0
	else
		fh:close()
		return 1
	end
end

-- addnsadir を上書き
local add_nsa_dir = ""
NSExec("luasub addnsadir")
function NSCOM_addnsadir()
	addnsadir(NSPopStr())
end
function addnsadir(dir)
	if add_nsa_dir ~= dir then
		NSExec('_addnsadir "'..dir..'"')
		add_nsa_dir = dir
		return true
	end
	return false
end

-- インストールされているゲームの情報を取得
local install_game = {} -- ゲームの情報を格納するテーブル
local keyword2install_game = {} -- ゲームのエイリアスの定義テーブル
local base_dir = 0 -- インストールされている中で一番最後のゲーム番号=デフォルト
do
	local reg1 = ""
	local reg2 = ""
	for line in io.lines("game_list.txt") do -- game_list.txtの中に書いてある。
		local temp1 = {}
		for word in string.gmatch(line, "([^%,]+)%,") do -- 一行をばらす
			table.insert(temp1, word)
		end
		local temp2 = {}
		temp2.title = table.remove(temp1, 1) -- ゲームのタイトルを登録
		reg1 = table.remove(temp1, 1) -- reg1
		reg2 = table.remove(temp1, 1) -- reg2
		NSExec('_getreg $0,"'..reg1..'","'..reg2..'"') -- レジストリを探る
		temp2.dir = NSGetStrValue(0) -- レジストリを登録
		if temp2.dir ~= "" then
			if string.char(temp2.dir:byte(temp2.dir:len())) ~= '\\' then
				temp2.dir = temp2.dir .. '\\' -- 末尾に\がなければ\をつける。
			end
			if fileexist_not_nsa(temp2.dir.."arc.nsa") == 0 then
				temp2.dir = "" -- 存在しないならないことにする。
			end
		end
		table.insert(install_game, temp2)
		temp2.num = # install_game
		for i = 1, # temp1 do
			local temp3 = table.remove(temp1)
			keyword2install_game[temp3] = temp2.num
			keyword2install_game['<'..temp3..'>'] = temp2.num
		end
		if temp2.dir ~= "" then base_dir = temp2.num end
	end
end

-- fileexist
local fileexist_list = {} -- ファイルの有無のキャッシュ
NSExec("luasub fileexist_lua")
function NSCOM_fileexist_lua()
	local res = NSPopIntRef()
	NSPopComma()
	local file = NSPopStr()
	NSPopComma()
	local mode = NSPopInt()
	if mode == 0 then mode = nil end
	if mode == 1 then mode = true end
	NSSetIntValue(res, fileexist(file, mode))
end
function fileexist(file, mode, ...) -- ファイルの有無をディレクトリを切り替えながら調べる。なければnil、あれば、ディレクトリの番号を返す。
	fileexist_list[file] = fileexist_list[file] or {} -- 初期化
	local dir_code = ... -- 初期検索ディレクトリを決定
	dir_code = dir_code or base_dir
	return fileexist_recursion(file, mode, dir_code) -- 実行
end
-- fileexist の本体
function fileexist_recursion(file, mode, dir_code)
	if dir_code == 0 then return nil end -- 再帰終了
	if install_game[dir_code].dir == "" then -- そのディレクトリ番号がなければ。
		return fileexist_recursion(file, mode, dir_code - 1) -- 再帰
	end
	if fileexist_list[file][dir_code] == nil then -- キャッシュがなければ
		if mode == nil then
			if chnsa(dir_code) then
				fileexist_list[file][dir_code] = fileexist_in_nsa(file)
			else
				fileexist_list[file][dir_code] = 0
			end
		else
			fileexist_list[file][dir_code] = fileexist_not_nsa(install_game[dir_code].dir..file)
		end
	end
	if fileexist_list[file][dir_code] == 1 then return dir_code end
	return fileexist_recursion(file, mode, dir_code - 1) -- 再帰
end

-- chnsaを作成
NSExec("luasub chnsa")
function NSCOM_chnsa()
	local id = NSPopID()
	local new_dir = keyword2install_game[id:lower()]
	if type(new_dir) == "number" then
		base_dir = new_dir
		chnsa(base_dir)
	else
		error_end(id.."は有効なIDではありません。")
	end
end
NSExec("luasub music_set")
NSCOM_music_set = NSCOM_chnsa
function chnsa(code)
	if install_game[code].dir == "" then return false end
	addnsadir(install_game[code].dir)
	return true
end

-- recommend を作成
NSExec("luasub recommend")
function NSCOM_recommend()
	local id = NSPopID()
	local new_dir = keyword2install_game[id:lower()]
	if type(new_dir) == "number" then
		if install_game[new_dir].dir == "" then
			error_end(install_game[new_dir].title.."はインストールされていません。")
		end
	else
		error_end(id.."は有効なIDではありません。")
	end
end

-- ファイルを判別し、必要ならchnsaする。もしなければそこで止まる。
NSExec("luasub file_identify")
function NSCOM_file_identify()
	local res = NSPopStrRef()
	NSPopComma()
	NSSetStrValue(res, file_identify(NSPopStr(), true))
end
function file_identify(fulltag, mode)
	local tag = ""
	local file = ""
	tag, file = head_cutter(fulltag, ";") -- タグとファイル部分に分ける。
	local time_param = ""
	local head = string.char(file:byte(1)) -- 最初の一文字を取得。
	if head == "#" then -- 文字列スプライトの場合
		return fulltag
	elseif head == ">" then -- 塗りつぶし長方形の場合
		return fulltag
	elseif head == "(" then -- oggのアレの場合
		time_param, file = head_cutter(file, ")")
	end
	local dir = ""
	dir, file = head_cutter(file, ">") -- 独自仕様
	local dir_code = base_dir
	if dir ~= "" then dir_code = keyword2install_game[dir:lower()] end
	if dir_code == nil then error_end(dir.."は無効なIDです。") end
	if mode then
		if fileexist_not_nsa(file) == 1 then return time_param..file end
	end
	dir_code = fileexist(file, mode, dir_code)
	if dir_code == nil then error_end(file.."は存在しません。") end
	if mode == nil then
		chnsa(dir_code)
		return tag..file
	else
		return time_param..install_game[dir_code].dir..file
	end
end

-- ある文字列の先頭にある形式のものがあれば、それを分離して返す。
function head_cutter(str, rep)
	local flag = false
	local head = ""
	local body = ""
	local letter = ""
	for i = 1, str:len() do
		letter = string.char(str:byte(i))
		if flag == false then
			head = head .. letter
		else
			body = body .. letter
		end
		if letter == rep then flag = true end
	end
	if body == "" then head, body = body, head end
	return head, body
end

-- ld を上書き
NSExec("luasub ld")
function NSCOM_ld()
	local id = NSPopID()
	NSPopComma()
	local str = file_identify(NSPopStr())
	NSPopComma()
	NSExec('_ld '..id..',"'..str..'",'..NSPopInt())
	chnsa(base_dir)
end
-- bg を上書き
NSExec("luasub bg")
function NSCOM_bg()
	local str = file_identify(NSPopStr())
	NSPopComma()
	NSExec('_bg "'..str..'",'..NSPopInt())
	chnsa(base_dir)
end
-- lsp, lsph を上書き
NSExec("luasub lsp")
NSExec("luasub lsph")
function NSCOM_lsp()
	lsp(true)
end
function NSCOM_lsph()
	lsp(false)
end
function lsp(visible)
	local sp = NSPopInt()
	NSPopComma()
	local str = file_identify(NSPopStr())
	NSPopComma()
	local x = NSPopInt()
	NSPopComma()
	local y = NSPopInt()
	local alpha = 255
	if NSCheckComma() then
		NSPopComma()
		alpha = NSPopInt()
	end
	NSSpLoad(sp, str)
	NSSpMove(sp, x, y, alpha)
	NSSpVisible(sp, visible)
end
-- 既存命令の上書き
NSExec("luasub bgm")
function NSCOM_bgm()
	NSExec('_bgm "'..file_identify(NSPopStr(), true)..'"')
end
NSExec("luasub bgmonce")
function NSCOM_bgmonce()
	NSExec('_bgmonce "'..file_identify(NSPopStr(), true)..'"')
end
NSExec("luasub loopbgm")
function NSCOM_loopbgm()
	local file1 = NSPopStr()
	NSPopComma()
	local file2 = NSPopStr()
	NSExec('_loopbgm "'..file_identify(NSPopStr(), true)..'","'..file_identify(NSPopStr(), true)..'"')
end
NSExec("luasub dwave")
function NSCOM_dwave()
	local ch = NSPopInt()
	NSPopComma()
	NSExec('_dwave '..ch..',"'..file_identify(NSPopStr(), true)..'"')
end
NSExec("luasub dwaveload")
function NSCOM_dwaveload()
	local ch = NSPopInt()
	NSPopComma()
	NSExec('_dwaveload '..ch..',"'..file_identify(NSPopStr(), true)..'"')
end
NSExec("luasub dwaveloop")
function NSCOM_dwaveloop()
	local ch = NSPopInt()
	NSPopComma()
	NSExec('_dwaveloop '..ch..',"'..file_identify(NSPopStr(), true)..'"')
end

game_list.txt

歌月十夜,Software\TYPE-MOON\歌月十夜,directory,sm,singingmoon,
ひぐらしのなく頃に 鬼隠し編,Software\07th_Expansion\higurasi,gamedir,h1,higurasi1,
ひぐらしのなく頃に 綿流し編,Software\07th_Expansion\higurasi2,gamedir,h2,higurasi2,
ひぐらしのなく頃に 祟殺し編,Software\07th_Expansion\higurasi3,gamedir,h3,higurasi3,
ひぐらしのなく頃に 暇潰し編,Software\07th_Expansion\higurasi4,gamedir,h4,higurasi4,
ひぐらしのなく頃に解 目明し編,Software\07th_Expansion\higurasi5,gamedir,h5,higurasi5,
ひぐらしのなく頃に解 罪滅し編,Software\07th_Expansion\higurasi6,gamedir,h6,higurasi6,
ひぐらしのなく頃に解 皆殺し編,Software\07th_Expansion\higurasi7,gamedir,h7,higurasi7,
ひぐらしのなく頃に解 祭囃し編,Software\07th_Expansion\higurasi8,gamedir,h8,higurasi8,
ひぐらしのなく頃に礼,Software\07th_Expansion\higurasi9,gamedir,h9,higurasi9,
うみねこのなく頃に Legend of the golden witch,Software\07th_Expansion\Umineko1,gamedir,u1,umineko1,
うみねこのなく頃に Turn of the golden witch,Software\07th_Expansion\Umineko2,gamedir,u2,umineko2,
うみねこのなく頃に Banquet of the golden witch,Software\07th_Expansion\Umineko3,gamedir,u3,umineko3,
うみねこのなく頃に Alliance of the golden witch,Software\07th_Expansion\Umineko4,gamedir,u4,umineko4,
うみねこのなく頃に5,Software\07th_Expansion\Umineko5,gamedir,u5,umineko5,
うみねこのなく頃に6,Software\07th_Expansion\Umineko6,gamedir,u6,umineko6,
うみねこのなく頃に7,Software\07th_Expansion\Umineko7,gamedir,u7,umineko7,
うみねこのなく頃に8,Software\07th_Expansion\Umineko8,gamedir,u8,umineko8,

00.txt

*define
killmenu 7
killmenu 4
killmenu 2
game
*start
caption "月下の魔女たち"
bgm "WAV\LP\depressive paranoia(心象音楽系).mp3"
bg "image\bg\ima_18.jpg",0
ld r,":a;image\tachi\ren_t06.jpg",0
ld c,":a;bmp\tati\rika\nekomimi\ri_waraia1.bmp",0
ld l,":a;bmp\TATI\ber\1\ber_akuwaraia1.bmp",0
print 1
click
end

第8話「誕生!あしゅら男爵!」

第7話「伝説!バードス島の機械獣!」を見た。 - 永字八法の続き。
screenshot
ただ単に「作った時に細工しておきました」と言うネタにかなりひっぱったなあ(笑)
で、結局、あしゅら男爵を作った時に、過去何があったかを聞き出せたんだろうか。この様子なら無理っぽいな。
さて、今夜はガミアQ3が見れるかねえ。

む式ライブラリ ver.lua おくだけ(仮公開)

ドキュメント無し版α! - 永字八法の続き。
ドキュメントを添付したバージョンを作成しました。下記URLからダウンロードできます。
http://www.eiji8pou.pics/download/mushiki.zip
詳しくは添付のマニュアルを見てください。

マニュアルの内容

む式ライブラリ ver.lua おくだけについて(2009-05-30版)

どういうものか

07th-Expansionの同人ゲーム、「うみねこのなく頃に」「ひぐらしのなく頃に」(そしておまけとして)TYPE-MOONの同人ゲーム「歌月十夜」の素材を利用したオリスク(二次創作)のお手伝いをするものです。

入っているもの
  • む式マニュアル.txt(このファイル)
  • nscr.exeの最新版
  • luasub.dll
  • system.lua
  • mushiki(フォルダ)
    • game_list.txt
    • okudake.lua
    • select_dir.exe
    • plug-ins(フォルダ)
      • dnako.dll
      • nakofile.dll
使い方1(初めての人向き)

ダウンロードしてできたフォルダに、00.txtを普通に書いてください。
画像や音楽ファイルは、オリジナルと同様の指定をしてください。ライブラリがそれを読み取って、自動的にハードディスクの中からファイルを見つけ出して読み込めるようにします。

例)
たとえば、あなたが以下のような命令を00.txtに書いたとします。

	ld l,":a;bmp\TATI\ber\1\ber_akuwaraia1.bmp",0

そうすると、ライブラリが「bmp\TATI\ber\1\ber_akuwaraia1.bmp」を、ハードディスクの中から順番に探していきます。
探す順番は、「うみねこ」の最新版から1→「ひぐらし礼」→「ひぐらし解」の8から5→「ひぐらし」の4から1→「歌月十夜」です。
もし、見つかればそれを読み込みます。

(わかる人向け:具体的な順番は、game_list.txtに記述しています。この中身を変更すれば、順番や探す場所を変更できます。他のNScripter製ゲームも追加できます)

画像関係は、arc.nsaの中を探すようにします。
音楽関係は、arc.nsaの中を探しません。(07th-Expansionは、音楽ファイルを剥きだしにしていますし、全角ファイル名も使っていますので)

なお、このライブラリの影響を受けるのは、以下の命令です。
画像関係:bg, ld, lsp, lsph, lsp2add, lsph2add, lsp2sub, lsph2sub
音楽関係:bgm, bgmonce, loopbgm, dwave, dwaveload, dwaveloop
※print文への対応はしていません。

使い方(以前から使っていた人)

chnsa、music_setは必須ではなくなりました。
ライブラリの基本的な動作が「新しい物から順番に探していく」に変更されたので、決め打ちする必要がなくなったからです。
chnsaは残っていますが、その機能は「探し始める最初を設定する」に変更されました。
たとえば、「chnsa umineko2」とすると、「うみねこ3」以上が入っていてもそこは最初から探さなくなります。
古いオリスクをいじる場合は、基本的にchnsaを書き換えるのではなく、削除だけで対応できるでしょう。
music_setはchnsaのエイリアス(=別名)になりました。

追加された命令

recommend命令

	recommend umineko4

このように指定します。
こうすると、その実行環境に「うみねこ4」が入っているかどうかを調べます。
入っていれば何も起こりません。
入っていなければ、「うみねこ4」のarc.nsaがどこにあるかを別窓を開いて聞いてきます。
ここでarc.nsaを指定すると、以後は、そのディレクトリを「うみねこ4」と認識して動作します。
ここでも指定をしなければ、落ちるようになっています。

正規インストールをしていないユーザーへの対応策としてお使いください。

ちょっと高度な使い方

たとえば、「ひぐらしのなく頃に」には、「title\logo.bmp」と言うファイルがどのバージョンにも入っていますが、その実体は、無印と解と礼で違います。
ですので、「基本的には最新のバージョンの画像を使えばいいんだけれども、ある画像だけは特定のバージョンのを使いたい」と思われるかも知れません。
その場合、このように記述すれば対応します。

	lsp 0,":a;<h4>title\logo.bmp",0,0

画像タグの後、ファイル名の先頭に、<と>で囲まれた特殊タグを記述してください。
上記の場合、暇潰し編のロゴが使われます。(暇潰しがなければ祟殺し、綿流し、鬼隠しとさかのぼっていきます)
(そんな人はまずいないと思いますが)鷹野さんを昔のバージョンで使いたいと言う場合は、頑張って全部のファイル名の先頭に特殊タグを追加していってください。ガーターベルトが嫌いな男子なんていません!

なお、この特殊タグは音楽ファイルにも適応できます。今と昔で音が違うってありましたっけ? そうでなければ意味はないですが。

キーワードのリスト

chnsa(とmusic_set)、特殊タグで使われる文字列は、以下のものが登録されています。

singingmoon sm
higurasi1 h1
(中略)
higurasi9 h9
umineko1 u1
(中略)
umineko8 u8

game_list.txtに記述されています。

未解決の問題

まだ、「孫の手セット」との連携の完全な検証は終わっていません。

著作権関係

NScripterhttp://www.nscripter.com/
luahttp://www.lua.org/
・なでしこ(http://nadesi.com/
07th Expansionhttp://07th-expansion.net/
・むいむい。(http://www.eiji8pou.pics/

御意見御要望エラー等があれば、下記へ。
http://d.hatena.ne.jp/eiji8pou/20090530/1243677714

感想

太ったなあ……。

こういうの開発中

「む式おくだけ」に組み込む形で今こういうのを作っている。ツールキット以来だなあ。

00.txt

*define
killmenu 7
killmenu 4
killmenu 2
game
*start
ld c,":a;@戦人・叫2・指",1 ; ←ここがポイント
click
end

実行結果

「復唱してみろよぉおおおっ!」

仕様

「>」で始まる長方形の仕様に感銘を受けたので。
通常のファイル指定をするところに、「@」で始まる日本語文字列を使うと、それを解釈してキャラクターの画像に変換する。
※mタグには流石に対応していない。
キーワードは「・」で区切る。全角文字。日本語打ちながら半角文字を入れるのは面倒だろうから。

キャラクター名として解釈する文字列。

アスモ/エヴァ/ガァプ/さく/サタン/シェ00/シェ41/シェ45/ベアト/ベルゼ/ベルフェ/ベルン/マモン/ラムダ/ルシフ/レヴィ/ロノウェ/ワルギ/縁寿/嘉音/夏妃/霞/雅行/絵羽/偽嘉音/郷田/金蔵/熊沢/源次/鯖吉/山羊/紗音/朱志香/秀吉/小此木/譲治/真里亞/川畑/戦人/蔵臼/大槻/天草/南條/霧江/留弗夫/楼座
エヴァは脳内絵羽。セーラー服がデフォルトの衣装で、魔女のキーワード追加で魔女化する。

表情名として解釈する文字列

あちゃ/おや/お任/デフォ/とほほ/ニヤ/ヒス/ふむ/愛想笑/悪笑/我慢/悔/泣/泣笑/叫/驚/言訳/困/焦/照/笑/真面目/恥/怒/頭痛/得意/悩/半/疲/微笑/不機嫌/不敵/不満/呆/睨
(実際には、この後に全角数字をつける)

衣装名として解釈する文字列

魔女(エヴァ&真里亞)/制服(ベアト&縁寿)/私服(譲治&紗音&嘉音)
人間として現われたベアトリーチェは……まあ、制服と解釈していいんではないかと思うのです。女学生ベアト。

その他オプションとして解釈する文字列

暗(真里亞のみ)/汗(ガァプのみ)/指(戦人のみ)/銃(大人たち)/狙(大人たち)/刃(嘉音&偽嘉音&山羊)/曇(譲治のみ)
銃と狙の違いは、銃は持っているだけで狙は構えている。ちなみに留弗夫や秀吉は狙がなく、霧江は銃がない。こわい。
曇は譲治の眼鏡。当然か。

@戦人・デフォ1
@楼座・困1・狙

現状

EP4のキャラクターはできたと思う。
後は背景画像と音楽と……データ作るのだるいな。誰か……すでに作ってたっけ?

名前と外見の不一致

今日は結局、寝たり起きたりピザ食ったりコーラ飲んだりアニメみたりして過ごした訳ですが、海外のチャーリーズエンジェルのパロエロフラを見つけたのが印象に残っております。
キャラクターはブロンド、ブルネット、東洋系の三人。東洋系の名前は○○コでモロに日本人名なんだけど、ダダみたいにつりあがった目と刺さりそうな頬骨を持っていて力のない笑いしか出てこなかった。
こんなところでも、か……。

名前と外見の不一致

今日は結局、寝たり起きたりピザ食ったりコーラ飲んだりアニメみたりして過ごした訳ですが、海外のチャーリーズエンジェルのパロエロフラを見つけたのが印象に残っております。
キャラクターはブロンド、ブルネット、東洋系の三人。東洋系の名前は○○コでモロに日本人名なんだけど、ダダみたいにつりあがった目と刺さりそうな頬骨を持っていて力のない笑いしか出てこなかった。
こんなところでも、か……。

こういうの開発中

「む式おくだけ」に組み込む形で今こういうのを作っている。ツールキット以来だなあ。

00.txt

*define
killmenu 7
killmenu 4
killmenu 2
game
*start
ld c,":a;@戦人・叫2・指",1 ; ←ここがポイント
click
end

実行結果

「復唱してみろよぉおおおっ!」

仕様

「>」で始まる長方形の仕様に感銘を受けたので。
通常のファイル指定をするところに、「@」で始まる日本語文字列を使うと、それを解釈してキャラクターの画像に変換する。
※mタグには流石に対応していない。
キーワードは「・」で区切る。全角文字。日本語打ちながら半角文字を入れるのは面倒だろうから。

キャラクター名として解釈する文字列。

アスモ/エヴァ/ガァプ/さく/サタン/シェ00/シェ41/シェ45/ベアト/ベルゼ/ベルフェ/ベルン/マモン/ラムダ/ルシフ/レヴィ/ロノウェ/ワルギ/縁寿/嘉音/夏妃/霞/雅行/絵羽/偽嘉音/郷田/金蔵/熊沢/源次/鯖吉/山羊/紗音/朱志香/秀吉/小此木/譲治/真里亞/川畑/戦人/蔵臼/大槻/天草/南條/霧江/留弗夫/楼座
エヴァは脳内絵羽。セーラー服がデフォルトの衣装で、魔女のキーワード追加で魔女化する。

表情名として解釈する文字列

あちゃ/おや/お任/デフォ/とほほ/ニヤ/ヒス/ふむ/愛想笑/悪笑/我慢/悔/泣/泣笑/叫/驚/言訳/困/焦/照/笑/真面目/恥/怒/頭痛/得意/悩/半/疲/微笑/不機嫌/不敵/不満/呆/睨
(実際には、この後に全角数字をつける)

衣装名として解釈する文字列

魔女(エヴァ&真里亞)/制服(ベアト&縁寿)/私服(譲治&紗音&嘉音)
人間として現われたベアトリーチェは……まあ、制服と解釈していいんではないかと思うのです。女学生ベアト。

その他オプションとして解釈する文字列

暗(真里亞のみ)/汗(ガァプのみ)/指(戦人のみ)/銃(大人たち)/狙(大人たち)/刃(嘉音&偽嘉音&山羊)/曇(譲治のみ)
銃と狙の違いは、銃は持っているだけで狙は構えている。ちなみに留弗夫や秀吉は狙がなく、霧江は銃がない。こわい。
曇は譲治の眼鏡。当然か。

@戦人・デフォ1
@楼座・困1・狙

現状

EP4のキャラクターはできたと思う。
後は背景画像と音楽と……データ作るのだるいな。誰か……すでに作ってたっけ?

む式ライブラリ ver.lua おくだけ(仮公開)

ドキュメント無し版α! - 永字八法の続き。
ドキュメントを添付したバージョンを作成しました。下記URLからダウンロードできます。
http://www.eiji8pou.pics/download/mushiki.zip
詳しくは添付のマニュアルを見てください。

マニュアルの内容

む式ライブラリ ver.lua おくだけについて(2009-05-30版)

どういうものか

07th-Expansionの同人ゲーム、「うみねこのなく頃に」「ひぐらしのなく頃に」(そしておまけとして)TYPE-MOONの同人ゲーム「歌月十夜」の素材を利用したオリスク(二次創作)のお手伝いをするものです。

入っているもの
  • む式マニュアル.txt(このファイル)
  • nscr.exeの最新版
  • luasub.dll
  • system.lua
  • mushiki(フォルダ)
    • game_list.txt
    • okudake.lua
    • select_dir.exe
    • plug-ins(フォルダ)
      • dnako.dll
      • nakofile.dll
使い方1(初めての人向き)

ダウンロードしてできたフォルダに、00.txtを普通に書いてください。
画像や音楽ファイルは、オリジナルと同様の指定をしてください。ライブラリがそれを読み取って、自動的にハードディスクの中からファイルを見つけ出して読み込めるようにします。

例)
たとえば、あなたが以下のような命令を00.txtに書いたとします。

	ld l,":a;bmp\TATI\ber\1\ber_akuwaraia1.bmp",0

そうすると、ライブラリが「bmp\TATI\ber\1\ber_akuwaraia1.bmp」を、ハードディスクの中から順番に探していきます。
探す順番は、「うみねこ」の最新版から1→「ひぐらし礼」→「ひぐらし解」の8から5→「ひぐらし」の4から1→「歌月十夜」です。
もし、見つかればそれを読み込みます。

(わかる人向け:具体的な順番は、game_list.txtに記述しています。この中身を変更すれば、順番や探す場所を変更できます。他のNScripter製ゲームも追加できます)

画像関係は、arc.nsaの中を探すようにします。
音楽関係は、arc.nsaの中を探しません。(07th-Expansionは、音楽ファイルを剥きだしにしていますし、全角ファイル名も使っていますので)

なお、このライブラリの影響を受けるのは、以下の命令です。
画像関係:bg, ld, lsp, lsph, lsp2add, lsph2add, lsp2sub, lsph2sub
音楽関係:bgm, bgmonce, loopbgm, dwave, dwaveload, dwaveloop
※print文への対応はしていません。

使い方(以前から使っていた人)

chnsa、music_setは必須ではなくなりました。
ライブラリの基本的な動作が「新しい物から順番に探していく」に変更されたので、決め打ちする必要がなくなったからです。
chnsaは残っていますが、その機能は「探し始める最初を設定する」に変更されました。
たとえば、「chnsa umineko2」とすると、「うみねこ3」以上が入っていてもそこは最初から探さなくなります。
古いオリスクをいじる場合は、基本的にchnsaを書き換えるのではなく、削除だけで対応できるでしょう。
music_setはchnsaのエイリアス(=別名)になりました。

追加された命令

recommend命令

	recommend umineko4

このように指定します。
こうすると、その実行環境に「うみねこ4」が入っているかどうかを調べます。
入っていれば何も起こりません。
入っていなければ、「うみねこ4」のarc.nsaがどこにあるかを別窓を開いて聞いてきます。
ここでarc.nsaを指定すると、以後は、そのディレクトリを「うみねこ4」と認識して動作します。
ここでも指定をしなければ、落ちるようになっています。

正規インストールをしていないユーザーへの対応策としてお使いください。

ちょっと高度な使い方

たとえば、「ひぐらしのなく頃に」には、「title\logo.bmp」と言うファイルがどのバージョンにも入っていますが、その実体は、無印と解と礼で違います。
ですので、「基本的には最新のバージョンの画像を使えばいいんだけれども、ある画像だけは特定のバージョンのを使いたい」と思われるかも知れません。
その場合、このように記述すれば対応します。

	lsp 0,":a;<h4>title\logo.bmp",0,0

画像タグの後、ファイル名の先頭に、<と>で囲まれた特殊タグを記述してください。
上記の場合、暇潰し編のロゴが使われます。(暇潰しがなければ祟殺し、綿流し、鬼隠しとさかのぼっていきます)
(そんな人はまずいないと思いますが)鷹野さんを昔のバージョンで使いたいと言う場合は、頑張って全部のファイル名の先頭に特殊タグを追加していってください。ガーターベルトが嫌いな男子なんていません!

なお、この特殊タグは音楽ファイルにも適応できます。今と昔で音が違うってありましたっけ? そうでなければ意味はないですが。

キーワードのリスト

chnsa(とmusic_set)、特殊タグで使われる文字列は、以下のものが登録されています。

singingmoon sm
higurasi1 h1
(中略)
higurasi9 h9
umineko1 u1
(中略)
umineko8 u8

game_list.txtに記述されています。

未解決の問題

まだ、「孫の手セット」との連携の完全な検証は終わっていません。

著作権関係

NScripterhttp://www.nscripter.com/
luahttp://www.lua.org/
・なでしこ(http://nadesi.com/
07th Expansionhttp://07th-expansion.net/
・むいむい。(http://www.eiji8pou.pics/

御意見御要望エラー等があれば、下記へ。
http://d.hatena.ne.jp/eiji8pou/20090530/1243677714

感想

太ったなあ……。

第8話「誕生!あしゅら男爵!」

第7話「伝説!バードス島の機械獣!」を見た。 - 永字八法の続き。
screenshot
ただ単に「作った時に細工しておきました」と言うネタにかなりひっぱったなあ(笑)
で、結局、あしゅら男爵を作った時に、過去何があったかを聞き出せたんだろうか。この様子なら無理っぽいな。
さて、今夜はガミアQ3が見れるかねえ。

ドキュメント無し版α!

経過報告 - 永字八法の続き。
ドキュメントが整備されていないけれども、できた。

導入

  • nscr.exeをluaの使えるバージョンに。最新版にするのがベスト。
  • nslua.dllをnscr.exeに同梱。
  • 下記の内容をsystem.luaにコピペして保存。nscr.exeに同梱。
  • 下記の内容をgame_list.txtにコピペして保存。nscr.exeに同梱。

以上。
サンプルの00.txtもつける。

注意書き

以下の命令について、自動的にファイルの場所を探す機能を加えた。

  • bg
  • ld
  • lsp
  • lsph
  • bgm
  • bgmonce
  • loopbgm(ただし、この命令は潜在的ogg関係のバグを持っている)
  • dwave
  • dwaveload
  • dwaveloop

あー、print文の後のdll指定とかにもいるなあ。次のバージョンでつけますよ、と。

2009-08-141追記

bg命令の使い方の一つ、bg white や bg black は対応していません。
これを使う場合は、_bg white と言う風にbgの前にアンダーバーをつけてください。
これはLuaの仕様に関係する制限ですので、今後解決される見通しは立っていません。

system.lua

-- む式 ver.lua おくだけ 2009-05-29
NSExec("nsa")

function error_end(message)
	NSOkBox(message, "む式。")
	NSSystemCall("end")
end

-- nsaも探すよ!
function fileexist_in_nsa(file)
	local temp = NSGetIntValue(0)
	NSExec('_fileexist %0,"'..file..'"')
	local res = NSGetIntValue(0)
	NSSetIntValue(0, temp)
	return res
end

-- nsaは探さないよ!
function fileexist_not_nsa(file)
	local fh = io.open(file)
	if io.type(fh) == nil then
		return 0
	else
		fh:close()
		return 1
	end
end

-- addnsadir を上書き
local add_nsa_dir = ""
NSExec("luasub addnsadir")
function NSCOM_addnsadir()
	addnsadir(NSPopStr())
end
function addnsadir(dir)
	if add_nsa_dir ~= dir then
		NSExec('_addnsadir "'..dir..'"')
		add_nsa_dir = dir
		return true
	end
	return false
end

-- インストールされているゲームの情報を取得
local install_game = {} -- ゲームの情報を格納するテーブル
local keyword2install_game = {} -- ゲームのエイリアスの定義テーブル
local base_dir = 0 -- インストールされている中で一番最後のゲーム番号=デフォルト
do
	local reg1 = ""
	local reg2 = ""
	for line in io.lines("game_list.txt") do -- game_list.txtの中に書いてある。
		local temp1 = {}
		for word in string.gmatch(line, "([^%,]+)%,") do -- 一行をばらす
			table.insert(temp1, word)
		end
		local temp2 = {}
		temp2.title = table.remove(temp1, 1) -- ゲームのタイトルを登録
		reg1 = table.remove(temp1, 1) -- reg1
		reg2 = table.remove(temp1, 1) -- reg2
		NSExec('_getreg $0,"'..reg1..'","'..reg2..'"') -- レジストリを探る
		temp2.dir = NSGetStrValue(0) -- レジストリを登録
		if temp2.dir ~= "" then
			if string.char(temp2.dir:byte(temp2.dir:len())) ~= '\\' then
				temp2.dir = temp2.dir .. '\\' -- 末尾に\がなければ\をつける。
			end
			if fileexist_not_nsa(temp2.dir.."arc.nsa") == 0 then
				temp2.dir = "" -- 存在しないならないことにする。
			end
		end
		table.insert(install_game, temp2)
		temp2.num = # install_game
		for i = 1, # temp1 do
			local temp3 = table.remove(temp1)
			keyword2install_game[temp3] = temp2.num
			keyword2install_game['<'..temp3..'>'] = temp2.num
		end
		if temp2.dir ~= "" then base_dir = temp2.num end
	end
end

-- fileexist
local fileexist_list = {} -- ファイルの有無のキャッシュ
NSExec("luasub fileexist_lua")
function NSCOM_fileexist_lua()
	local res = NSPopIntRef()
	NSPopComma()
	local file = NSPopStr()
	NSPopComma()
	local mode = NSPopInt()
	if mode == 0 then mode = nil end
	if mode == 1 then mode = true end
	NSSetIntValue(res, fileexist(file, mode))
end
function fileexist(file, mode, ...) -- ファイルの有無をディレクトリを切り替えながら調べる。なければnil、あれば、ディレクトリの番号を返す。
	fileexist_list[file] = fileexist_list[file] or {} -- 初期化
	local dir_code = ... -- 初期検索ディレクトリを決定
	dir_code = dir_code or base_dir
	return fileexist_recursion(file, mode, dir_code) -- 実行
end
-- fileexist の本体
function fileexist_recursion(file, mode, dir_code)
	if dir_code == 0 then return nil end -- 再帰終了
	if install_game[dir_code].dir == "" then -- そのディレクトリ番号がなければ。
		return fileexist_recursion(file, mode, dir_code - 1) -- 再帰
	end
	if fileexist_list[file][dir_code] == nil then -- キャッシュがなければ
		if mode == nil then
			if chnsa(dir_code) then
				fileexist_list[file][dir_code] = fileexist_in_nsa(file)
			else
				fileexist_list[file][dir_code] = 0
			end
		else
			fileexist_list[file][dir_code] = fileexist_not_nsa(install_game[dir_code].dir..file)
		end
	end
	if fileexist_list[file][dir_code] == 1 then return dir_code end
	return fileexist_recursion(file, mode, dir_code - 1) -- 再帰
end

-- chnsaを作成
NSExec("luasub chnsa")
function NSCOM_chnsa()
	local id = NSPopID()
	local new_dir = keyword2install_game[id:lower()]
	if type(new_dir) == "number" then
		base_dir = new_dir
		chnsa(base_dir)
	else
		error_end(id.."は有効なIDではありません。")
	end
end
NSExec("luasub music_set")
NSCOM_music_set = NSCOM_chnsa
function chnsa(code)
	if install_game[code].dir == "" then return false end
	addnsadir(install_game[code].dir)
	return true
end

-- recommend を作成
NSExec("luasub recommend")
function NSCOM_recommend()
	local id = NSPopID()
	local new_dir = keyword2install_game[id:lower()]
	if type(new_dir) == "number" then
		if install_game[new_dir].dir == "" then
			error_end(install_game[new_dir].title.."はインストールされていません。")
		end
	else
		error_end(id.."は有効なIDではありません。")
	end
end

-- ファイルを判別し、必要ならchnsaする。もしなければそこで止まる。
NSExec("luasub file_identify")
function NSCOM_file_identify()
	local res = NSPopStrRef()
	NSPopComma()
	NSSetStrValue(res, file_identify(NSPopStr(), true))
end
function file_identify(fulltag, mode)
	local tag = ""
	local file = ""
	tag, file = head_cutter(fulltag, ";") -- タグとファイル部分に分ける。
	local time_param = ""
	local head = string.char(file:byte(1)) -- 最初の一文字を取得。
	if head == "#" then -- 文字列スプライトの場合
		return fulltag
	elseif head == ">" then -- 塗りつぶし長方形の場合
		return fulltag
	elseif head == "(" then -- oggのアレの場合
		time_param, file = head_cutter(file, ")")
	end
	local dir = ""
	dir, file = head_cutter(file, ">") -- 独自仕様
	local dir_code = base_dir
	if dir ~= "" then dir_code = keyword2install_game[dir:lower()] end
	if dir_code == nil then error_end(dir.."は無効なIDです。") end
	if mode then
		if fileexist_not_nsa(file) == 1 then return time_param..file end
	end
	dir_code = fileexist(file, mode, dir_code)
	if dir_code == nil then error_end(file.."は存在しません。") end
	if mode == nil then
		chnsa(dir_code)
		return tag..file
	else
		return time_param..install_game[dir_code].dir..file
	end
end

-- ある文字列の先頭にある形式のものがあれば、それを分離して返す。
function head_cutter(str, rep)
	local flag = false
	local head = ""
	local body = ""
	local letter = ""
	for i = 1, str:len() do
		letter = string.char(str:byte(i))
		if flag == false then
			head = head .. letter
		else
			body = body .. letter
		end
		if letter == rep then flag = true end
	end
	if body == "" then head, body = body, head end
	return head, body
end

-- ld を上書き
NSExec("luasub ld")
function NSCOM_ld()
	local id = NSPopID()
	NSPopComma()
	local str = file_identify(NSPopStr())
	NSPopComma()
	NSExec('_ld '..id..',"'..str..'",'..NSPopInt())
	chnsa(base_dir)
end
-- bg を上書き
NSExec("luasub bg")
function NSCOM_bg()
	local str = file_identify(NSPopStr())
	NSPopComma()
	NSExec('_bg "'..str..'",'..NSPopInt())
	chnsa(base_dir)
end
-- lsp, lsph を上書き
NSExec("luasub lsp")
NSExec("luasub lsph")
function NSCOM_lsp()
	lsp(true)
end
function NSCOM_lsph()
	lsp(false)
end
function lsp(visible)
	local sp = NSPopInt()
	NSPopComma()
	local str = file_identify(NSPopStr())
	NSPopComma()
	local x = NSPopInt()
	NSPopComma()
	local y = NSPopInt()
	local alpha = 255
	if NSCheckComma() then
		NSPopComma()
		alpha = NSPopInt()
	end
	NSSpLoad(sp, str)
	NSSpMove(sp, x, y, alpha)
	NSSpVisible(sp, visible)
end
-- 既存命令の上書き
NSExec("luasub bgm")
function NSCOM_bgm()
	NSExec('_bgm "'..file_identify(NSPopStr(), true)..'"')
end
NSExec("luasub bgmonce")
function NSCOM_bgmonce()
	NSExec('_bgmonce "'..file_identify(NSPopStr(), true)..'"')
end
NSExec("luasub loopbgm")
function NSCOM_loopbgm()
	local file1 = NSPopStr()
	NSPopComma()
	local file2 = NSPopStr()
	NSExec('_loopbgm "'..file_identify(NSPopStr(), true)..'","'..file_identify(NSPopStr(), true)..'"')
end
NSExec("luasub dwave")
function NSCOM_dwave()
	local ch = NSPopInt()
	NSPopComma()
	NSExec('_dwave '..ch..',"'..file_identify(NSPopStr(), true)..'"')
end
NSExec("luasub dwaveload")
function NSCOM_dwaveload()
	local ch = NSPopInt()
	NSPopComma()
	NSExec('_dwaveload '..ch..',"'..file_identify(NSPopStr(), true)..'"')
end
NSExec("luasub dwaveloop")
function NSCOM_dwaveloop()
	local ch = NSPopInt()
	NSPopComma()
	NSExec('_dwaveloop '..ch..',"'..file_identify(NSPopStr(), true)..'"')
end

game_list.txt

歌月十夜,Software\TYPE-MOON\歌月十夜,directory,sm,singingmoon,
ひぐらしのなく頃に 鬼隠し編,Software\07th_Expansion\higurasi,gamedir,h1,higurasi1,
ひぐらしのなく頃に 綿流し編,Software\07th_Expansion\higurasi2,gamedir,h2,higurasi2,
ひぐらしのなく頃に 祟殺し編,Software\07th_Expansion\higurasi3,gamedir,h3,higurasi3,
ひぐらしのなく頃に 暇潰し編,Software\07th_Expansion\higurasi4,gamedir,h4,higurasi4,
ひぐらしのなく頃に解 目明し編,Software\07th_Expansion\higurasi5,gamedir,h5,higurasi5,
ひぐらしのなく頃に解 罪滅し編,Software\07th_Expansion\higurasi6,gamedir,h6,higurasi6,
ひぐらしのなく頃に解 皆殺し編,Software\07th_Expansion\higurasi7,gamedir,h7,higurasi7,
ひぐらしのなく頃に解 祭囃し編,Software\07th_Expansion\higurasi8,gamedir,h8,higurasi8,
ひぐらしのなく頃に礼,Software\07th_Expansion\higurasi9,gamedir,h9,higurasi9,
うみねこのなく頃に Legend of the golden witch,Software\07th_Expansion\Umineko1,gamedir,u1,umineko1,
うみねこのなく頃に Turn of the golden witch,Software\07th_Expansion\Umineko2,gamedir,u2,umineko2,
うみねこのなく頃に Banquet of the golden witch,Software\07th_Expansion\Umineko3,gamedir,u3,umineko3,
うみねこのなく頃に Alliance of the golden witch,Software\07th_Expansion\Umineko4,gamedir,u4,umineko4,
うみねこのなく頃に5,Software\07th_Expansion\Umineko5,gamedir,u5,umineko5,
うみねこのなく頃に6,Software\07th_Expansion\Umineko6,gamedir,u6,umineko6,
うみねこのなく頃に7,Software\07th_Expansion\Umineko7,gamedir,u7,umineko7,
うみねこのなく頃に8,Software\07th_Expansion\Umineko8,gamedir,u8,umineko8,

00.txt

*define
killmenu 7
killmenu 4
killmenu 2
game
*start
caption "月下の魔女たち"
bgm "WAV\LP\depressive paranoia(心象音楽系).mp3"
bg "image\bg\ima_18.jpg",0
ld r,":a;image\tachi\ren_t06.jpg",0
ld c,":a;bmp\tati\rika\nekomimi\ri_waraia1.bmp",0
ld l,":a;bmp\TATI\ber\1\ber_akuwaraia1.bmp",0
print 1
click
end

名前と外見の不一致

今日は結局、寝たり起きたりピザ食ったりコーラ飲んだりアニメみたりして過ごした訳ですが、海外のチャーリーズエンジェルのパロエロフラを見つけたのが印象に残っております。
キャラクターはブロンド、ブルネット、東洋系の三人。東洋系の名前は○○コでモロに日本人名なんだけど、ダダみたいにつりあがった目と刺さりそうな頬骨を持っていて力のない笑いしか出てこなかった。
こんなところでも、か……。

こういうの開発中

「む式おくだけ」に組み込む形で今こういうのを作っている。ツールキット以来だなあ。

00.txt

*define
killmenu 7
killmenu 4
killmenu 2
game
*start
ld c,":a;@戦人・叫2・指",1 ; ←ここがポイント
click
end

実行結果

「復唱してみろよぉおおおっ!」

仕様

「>」で始まる長方形の仕様に感銘を受けたので。
通常のファイル指定をするところに、「@」で始まる日本語文字列を使うと、それを解釈してキャラクターの画像に変換する。
※mタグには流石に対応していない。
キーワードは「・」で区切る。全角文字。日本語打ちながら半角文字を入れるのは面倒だろうから。

キャラクター名として解釈する文字列。

アスモ/エヴァ/ガァプ/さく/サタン/シェ00/シェ41/シェ45/ベアト/ベルゼ/ベルフェ/ベルン/マモン/ラムダ/ルシフ/レヴィ/ロノウェ/ワルギ/縁寿/嘉音/夏妃/霞/雅行/絵羽/偽嘉音/郷田/金蔵/熊沢/源次/鯖吉/山羊/紗音/朱志香/秀吉/小此木/譲治/真里亞/川畑/戦人/蔵臼/大槻/天草/南條/霧江/留弗夫/楼座
エヴァは脳内絵羽。セーラー服がデフォルトの衣装で、魔女のキーワード追加で魔女化する。

表情名として解釈する文字列

あちゃ/おや/お任/デフォ/とほほ/ニヤ/ヒス/ふむ/愛想笑/悪笑/我慢/悔/泣/泣笑/叫/驚/言訳/困/焦/照/笑/真面目/恥/怒/頭痛/得意/悩/半/疲/微笑/不機嫌/不敵/不満/呆/睨
(実際には、この後に全角数字をつける)

衣装名として解釈する文字列

魔女(エヴァ&真里亞)/制服(ベアト&縁寿)/私服(譲治&紗音&嘉音)
人間として現われたベアトリーチェは……まあ、制服と解釈していいんではないかと思うのです。女学生ベアト。

その他オプションとして解釈する文字列

暗(真里亞のみ)/汗(ガァプのみ)/指(戦人のみ)/銃(大人たち)/狙(大人たち)/刃(嘉音&偽嘉音&山羊)/曇(譲治のみ)
銃と狙の違いは、銃は持っているだけで狙は構えている。ちなみに留弗夫や秀吉は狙がなく、霧江は銃がない。こわい。
曇は譲治の眼鏡。当然か。

@戦人・デフォ1
@楼座・困1・狙

現状

EP4のキャラクターはできたと思う。
後は背景画像と音楽と……データ作るのだるいな。誰か……すでに作ってたっけ?

む式ライブラリ ver.lua おくだけ(仮公開)

ドキュメント無し版α! - 永字八法の続き。
ドキュメントを添付したバージョンを作成しました。下記URLからダウンロードできます。
http://www.eiji8pou.net/download/mushiki.zip
詳しくは添付のマニュアルを見てください。

マニュアルの内容

む式ライブラリ ver.lua おくだけについて(2009-05-30版)

どういうものか

07th-Expansionの同人ゲーム、「うみねこのなく頃に」「ひぐらしのなく頃に」(そしておまけとして)TYPE-MOONの同人ゲーム「歌月十夜」の素材を利用したオリスク(二次創作)のお手伝いをするものです。

入っているもの
  • む式マニュアル.txt(このファイル)
  • nscr.exeの最新版
  • luasub.dll
  • system.lua
  • mushiki(フォルダ)
    • game_list.txt
    • okudake.lua
    • select_dir.exe
    • plug-ins(フォルダ)
      • dnako.dll
      • nakofile.dll
使い方1(初めての人向き)

ダウンロードしてできたフォルダに、00.txtを普通に書いてください。
画像や音楽ファイルは、オリジナルと同様の指定をしてください。ライブラリがそれを読み取って、自動的にハードディスクの中からファイルを見つけ出して読み込めるようにします。

例)
たとえば、あなたが以下のような命令を00.txtに書いたとします。

	ld l,":a;bmp\TATI\ber\1\ber_akuwaraia1.bmp",0

そうすると、ライブラリが「bmp\TATI\ber\1\ber_akuwaraia1.bmp」を、ハードディスクの中から順番に探していきます。
探す順番は、「うみねこ」の最新版から1→「ひぐらし礼」→「ひぐらし解」の8から5→「ひぐらし」の4から1→「歌月十夜」です。
もし、見つかればそれを読み込みます。

(わかる人向け:具体的な順番は、game_list.txtに記述しています。この中身を変更すれば、順番や探す場所を変更できます。他のNScripter製ゲームも追加できます)

画像関係は、arc.nsaの中を探すようにします。
音楽関係は、arc.nsaの中を探しません。(07th-Expansionは、音楽ファイルを剥きだしにしていますし、全角ファイル名も使っていますので)

なお、このライブラリの影響を受けるのは、以下の命令です。
画像関係:bg, ld, lsp, lsph, lsp2add, lsph2add, lsp2sub, lsph2sub
音楽関係:bgm, bgmonce, loopbgm, dwave, dwaveload, dwaveloop
※print文への対応はしていません。

使い方(以前から使っていた人)

chnsa、music_setは必須ではなくなりました。
ライブラリの基本的な動作が「新しい物から順番に探していく」に変更されたので、決め打ちする必要がなくなったからです。
chnsaは残っていますが、その機能は「探し始める最初を設定する」に変更されました。
たとえば、「chnsa umineko2」とすると、「うみねこ3」以上が入っていてもそこは最初から探さなくなります。
古いオリスクをいじる場合は、基本的にchnsaを書き換えるのではなく、削除だけで対応できるでしょう。
music_setはchnsaのエイリアス(=別名)になりました。

追加された命令

recommend命令

	recommend umineko4

このように指定します。
こうすると、その実行環境に「うみねこ4」が入っているかどうかを調べます。
入っていれば何も起こりません。
入っていなければ、「うみねこ4」のarc.nsaがどこにあるかを別窓を開いて聞いてきます。
ここでarc.nsaを指定すると、以後は、そのディレクトリを「うみねこ4」と認識して動作します。
ここでも指定をしなければ、落ちるようになっています。

正規インストールをしていないユーザーへの対応策としてお使いください。

ちょっと高度な使い方

たとえば、「ひぐらしのなく頃に」には、「title\logo.bmp」と言うファイルがどのバージョンにも入っていますが、その実体は、無印と解と礼で違います。
ですので、「基本的には最新のバージョンの画像を使えばいいんだけれども、ある画像だけは特定のバージョンのを使いたい」と思われるかも知れません。
その場合、このように記述すれば対応します。

	lsp 0,":a;<h4>title\logo.bmp",0,0

画像タグの後、ファイル名の先頭に、<と>で囲まれた特殊タグを記述してください。
上記の場合、暇潰し編のロゴが使われます。(暇潰しがなければ祟殺し、綿流し、鬼隠しとさかのぼっていきます)
(そんな人はまずいないと思いますが)鷹野さんを昔のバージョンで使いたいと言う場合は、頑張って全部のファイル名の先頭に特殊タグを追加していってください。ガーターベルトが嫌いな男子なんていません!

なお、この特殊タグは音楽ファイルにも適応できます。今と昔で音が違うってありましたっけ? そうでなければ意味はないですが。

キーワードのリスト

chnsa(とmusic_set)、特殊タグで使われる文字列は、以下のものが登録されています。

singingmoon sm
higurasi1 h1
(中略)
higurasi9 h9
umineko1 u1
(中略)
umineko8 u8

game_list.txtに記述されています。

未解決の問題

まだ、「孫の手セット」との連携の完全な検証は終わっていません。

著作権関係

NScripterhttp://www.nscripter.com/
luahttp://www.lua.org/
・なでしこ(http://nadesi.com/
07th Expansionhttp://07th-expansion.net/
・むいむい。(http://www.eiji8pou.net/

御意見御要望エラー等があれば、下記へ。
http://d.hatena.ne.jp/eiji8pou/20090530/1243677714

感想

太ったなあ……。

第8話「誕生!あしゅら男爵!」

第7話「伝説!バードス島の機械獣!」を見た。 - 永字八法の続き。
screenshot
ただ単に「作った時に細工しておきました」と言うネタにかなりひっぱったなあ(笑)
で、結局、あしゅら男爵を作った時に、過去何があったかを聞き出せたんだろうか。この様子なら無理っぽいな。
さて、今夜はガミアQ3が見れるかねえ。

ドキュメント無し版α!

経過報告 - 永字八法の続き。
ドキュメントが整備されていないけれども、できた。

導入

  • nscr.exeをluaの使えるバージョンに。最新版にするのがベスト。
  • nslua.dllをnscr.exeに同梱。
  • 下記の内容をsystem.luaにコピペして保存。nscr.exeに同梱。
  • 下記の内容をgame_list.txtにコピペして保存。nscr.exeに同梱。

以上。
サンプルの00.txtもつける。

注意書き

以下の命令について、自動的にファイルの場所を探す機能を加えた。

  • bg
  • ld
  • lsp
  • lsph
  • bgm
  • bgmonce
  • loopbgm(ただし、この命令は潜在的ogg関係のバグを持っている)
  • dwave
  • dwaveload
  • dwaveloop

あー、print文の後のdll指定とかにもいるなあ。次のバージョンでつけますよ、と。

2009-08-141追記

bg命令の使い方の一つ、bg white や bg black は対応していません。
これを使う場合は、_bg white と言う風にbgの前にアンダーバーをつけてください。
これはLuaの仕様に関係する制限ですので、今後解決される見通しは立っていません。

system.lua

-- む式 ver.lua おくだけ 2009-05-29
NSExec("nsa")

function error_end(message)
	NSOkBox(message, "む式。")
	NSSystemCall("end")
end

-- nsaも探すよ!
function fileexist_in_nsa(file)
	local temp = NSGetIntValue(0)
	NSExec('_fileexist %0,"'..file..'"')
	local res = NSGetIntValue(0)
	NSSetIntValue(0, temp)
	return res
end

-- nsaは探さないよ!
function fileexist_not_nsa(file)
	local fh = io.open(file)
	if io.type(fh) == nil then
		return 0
	else
		fh:close()
		return 1
	end
end

-- addnsadir を上書き
local add_nsa_dir = ""
NSExec("luasub addnsadir")
function NSCOM_addnsadir()
	addnsadir(NSPopStr())
end
function addnsadir(dir)
	if add_nsa_dir ~= dir then
		NSExec('_addnsadir "'..dir..'"')
		add_nsa_dir = dir
		return true
	end
	return false
end

-- インストールされているゲームの情報を取得
local install_game = {} -- ゲームの情報を格納するテーブル
local keyword2install_game = {} -- ゲームのエイリアスの定義テーブル
local base_dir = 0 -- インストールされている中で一番最後のゲーム番号=デフォルト
do
	local reg1 = ""
	local reg2 = ""
	for line in io.lines("game_list.txt") do -- game_list.txtの中に書いてある。
		local temp1 = {}
		for word in string.gmatch(line, "([^%,]+)%,") do -- 一行をばらす
			table.insert(temp1, word)
		end
		local temp2 = {}
		temp2.title = table.remove(temp1, 1) -- ゲームのタイトルを登録
		reg1 = table.remove(temp1, 1) -- reg1
		reg2 = table.remove(temp1, 1) -- reg2
		NSExec('_getreg $0,"'..reg1..'","'..reg2..'"') -- レジストリを探る
		temp2.dir = NSGetStrValue(0) -- レジストリを登録
		if temp2.dir ~= "" then
			if string.char(temp2.dir:byte(temp2.dir:len())) ~= '\\' then
				temp2.dir = temp2.dir .. '\\' -- 末尾に\がなければ\をつける。
			end
			if fileexist_not_nsa(temp2.dir.."arc.nsa") == 0 then
				temp2.dir = "" -- 存在しないならないことにする。
			end
		end
		table.insert(install_game, temp2)
		temp2.num = # install_game
		for i = 1, # temp1 do
			local temp3 = table.remove(temp1)
			keyword2install_game[temp3] = temp2.num
			keyword2install_game['<'..temp3..'>'] = temp2.num
		end
		if temp2.dir ~= "" then base_dir = temp2.num end
	end
end

-- fileexist
local fileexist_list = {} -- ファイルの有無のキャッシュ
NSExec("luasub fileexist_lua")
function NSCOM_fileexist_lua()
	local res = NSPopIntRef()
	NSPopComma()
	local file = NSPopStr()
	NSPopComma()
	local mode = NSPopInt()
	if mode == 0 then mode = nil end
	if mode == 1 then mode = true end
	NSSetIntValue(res, fileexist(file, mode))
end
function fileexist(file, mode, ...) -- ファイルの有無をディレクトリを切り替えながら調べる。なければnil、あれば、ディレクトリの番号を返す。
	fileexist_list[file] = fileexist_list[file] or {} -- 初期化
	local dir_code = ... -- 初期検索ディレクトリを決定
	dir_code = dir_code or base_dir
	return fileexist_recursion(file, mode, dir_code) -- 実行
end
-- fileexist の本体
function fileexist_recursion(file, mode, dir_code)
	if dir_code == 0 then return nil end -- 再帰終了
	if install_game[dir_code].dir == "" then -- そのディレクトリ番号がなければ。
		return fileexist_recursion(file, mode, dir_code - 1) -- 再帰
	end
	if fileexist_list[file][dir_code] == nil then -- キャッシュがなければ
		if mode == nil then
			if chnsa(dir_code) then
				fileexist_list[file][dir_code] = fileexist_in_nsa(file)
			else
				fileexist_list[file][dir_code] = 0
			end
		else
			fileexist_list[file][dir_code] = fileexist_not_nsa(install_game[dir_code].dir..file)
		end
	end
	if fileexist_list[file][dir_code] == 1 then return dir_code end
	return fileexist_recursion(file, mode, dir_code - 1) -- 再帰
end

-- chnsaを作成
NSExec("luasub chnsa")
function NSCOM_chnsa()
	local id = NSPopID()
	local new_dir = keyword2install_game[id:lower()]
	if type(new_dir) == "number" then
		base_dir = new_dir
		chnsa(base_dir)
	else
		error_end(id.."は有効なIDではありません。")
	end
end
NSExec("luasub music_set")
NSCOM_music_set = NSCOM_chnsa
function chnsa(code)
	if install_game[code].dir == "" then return false end
	addnsadir(install_game[code].dir)
	return true
end

-- recommend を作成
NSExec("luasub recommend")
function NSCOM_recommend()
	local id = NSPopID()
	local new_dir = keyword2install_game[id:lower()]
	if type(new_dir) == "number" then
		if install_game[new_dir].dir == "" then
			error_end(install_game[new_dir].title.."はインストールされていません。")
		end
	else
		error_end(id.."は有効なIDではありません。")
	end
end

-- ファイルを判別し、必要ならchnsaする。もしなければそこで止まる。
NSExec("luasub file_identify")
function NSCOM_file_identify()
	local res = NSPopStrRef()
	NSPopComma()
	NSSetStrValue(res, file_identify(NSPopStr(), true))
end
function file_identify(fulltag, mode)
	local tag = ""
	local file = ""
	tag, file = head_cutter(fulltag, ";") -- タグとファイル部分に分ける。
	local time_param = ""
	local head = string.char(file:byte(1)) -- 最初の一文字を取得。
	if head == "#" then -- 文字列スプライトの場合
		return fulltag
	elseif head == ">" then -- 塗りつぶし長方形の場合
		return fulltag
	elseif head == "(" then -- oggのアレの場合
		time_param, file = head_cutter(file, ")")
	end
	local dir = ""
	dir, file = head_cutter(file, ">") -- 独自仕様
	local dir_code = base_dir
	if dir ~= "" then dir_code = keyword2install_game[dir:lower()] end
	if dir_code == nil then error_end(dir.."は無効なIDです。") end
	if mode then
		if fileexist_not_nsa(file) == 1 then return time_param..file end
	end
	dir_code = fileexist(file, mode, dir_code)
	if dir_code == nil then error_end(file.."は存在しません。") end
	if mode == nil then
		chnsa(dir_code)
		return tag..file
	else
		return time_param..install_game[dir_code].dir..file
	end
end

-- ある文字列の先頭にある形式のものがあれば、それを分離して返す。
function head_cutter(str, rep)
	local flag = false
	local head = ""
	local body = ""
	local letter = ""
	for i = 1, str:len() do
		letter = string.char(str:byte(i))
		if flag == false then
			head = head .. letter
		else
			body = body .. letter
		end
		if letter == rep then flag = true end
	end
	if body == "" then head, body = body, head end
	return head, body
end

-- ld を上書き
NSExec("luasub ld")
function NSCOM_ld()
	local id = NSPopID()
	NSPopComma()
	local str = file_identify(NSPopStr())
	NSPopComma()
	NSExec('_ld '..id..',"'..str..'",'..NSPopInt())
	chnsa(base_dir)
end
-- bg を上書き
NSExec("luasub bg")
function NSCOM_bg()
	local str = file_identify(NSPopStr())
	NSPopComma()
	NSExec('_bg "'..str..'",'..NSPopInt())
	chnsa(base_dir)
end
-- lsp, lsph を上書き
NSExec("luasub lsp")
NSExec("luasub lsph")
function NSCOM_lsp()
	lsp(true)
end
function NSCOM_lsph()
	lsp(false)
end
function lsp(visible)
	local sp = NSPopInt()
	NSPopComma()
	local str = file_identify(NSPopStr())
	NSPopComma()
	local x = NSPopInt()
	NSPopComma()
	local y = NSPopInt()
	local alpha = 255
	if NSCheckComma() then
		NSPopComma()
		alpha = NSPopInt()
	end
	NSSpLoad(sp, str)
	NSSpMove(sp, x, y, alpha)
	NSSpVisible(sp, visible)
end
-- 既存命令の上書き
NSExec("luasub bgm")
function NSCOM_bgm()
	NSExec('_bgm "'..file_identify(NSPopStr(), true)..'"')
end
NSExec("luasub bgmonce")
function NSCOM_bgmonce()
	NSExec('_bgmonce "'..file_identify(NSPopStr(), true)..'"')
end
NSExec("luasub loopbgm")
function NSCOM_loopbgm()
	local file1 = NSPopStr()
	NSPopComma()
	local file2 = NSPopStr()
	NSExec('_loopbgm "'..file_identify(NSPopStr(), true)..'","'..file_identify(NSPopStr(), true)..'"')
end
NSExec("luasub dwave")
function NSCOM_dwave()
	local ch = NSPopInt()
	NSPopComma()
	NSExec('_dwave '..ch..',"'..file_identify(NSPopStr(), true)..'"')
end
NSExec("luasub dwaveload")
function NSCOM_dwaveload()
	local ch = NSPopInt()
	NSPopComma()
	NSExec('_dwaveload '..ch..',"'..file_identify(NSPopStr(), true)..'"')
end
NSExec("luasub dwaveloop")
function NSCOM_dwaveloop()
	local ch = NSPopInt()
	NSPopComma()
	NSExec('_dwaveloop '..ch..',"'..file_identify(NSPopStr(), true)..'"')
end

game_list.txt

歌月十夜,Software\TYPE-MOON\歌月十夜,directory,sm,singingmoon,
ひぐらしのなく頃に 鬼隠し編,Software\07th_Expansion\higurasi,gamedir,h1,higurasi1,
ひぐらしのなく頃に 綿流し編,Software\07th_Expansion\higurasi2,gamedir,h2,higurasi2,
ひぐらしのなく頃に 祟殺し編,Software\07th_Expansion\higurasi3,gamedir,h3,higurasi3,
ひぐらしのなく頃に 暇潰し編,Software\07th_Expansion\higurasi4,gamedir,h4,higurasi4,
ひぐらしのなく頃に解 目明し編,Software\07th_Expansion\higurasi5,gamedir,h5,higurasi5,
ひぐらしのなく頃に解 罪滅し編,Software\07th_Expansion\higurasi6,gamedir,h6,higurasi6,
ひぐらしのなく頃に解 皆殺し編,Software\07th_Expansion\higurasi7,gamedir,h7,higurasi7,
ひぐらしのなく頃に解 祭囃し編,Software\07th_Expansion\higurasi8,gamedir,h8,higurasi8,
ひぐらしのなく頃に礼,Software\07th_Expansion\higurasi9,gamedir,h9,higurasi9,
うみねこのなく頃に Legend of the golden witch,Software\07th_Expansion\Umineko1,gamedir,u1,umineko1,
うみねこのなく頃に Turn of the golden witch,Software\07th_Expansion\Umineko2,gamedir,u2,umineko2,
うみねこのなく頃に Banquet of the golden witch,Software\07th_Expansion\Umineko3,gamedir,u3,umineko3,
うみねこのなく頃に Alliance of the golden witch,Software\07th_Expansion\Umineko4,gamedir,u4,umineko4,
うみねこのなく頃に5,Software\07th_Expansion\Umineko5,gamedir,u5,umineko5,
うみねこのなく頃に6,Software\07th_Expansion\Umineko6,gamedir,u6,umineko6,
うみねこのなく頃に7,Software\07th_Expansion\Umineko7,gamedir,u7,umineko7,
うみねこのなく頃に8,Software\07th_Expansion\Umineko8,gamedir,u8,umineko8,

00.txt

*define
killmenu 7
killmenu 4
killmenu 2
game
*start
caption "月下の魔女たち"
bgm "WAV\LP\depressive paranoia(心象音楽系).mp3"
bg "image\bg\ima_18.jpg",0
ld r,":a;image\tachi\ren_t06.jpg",0
ld c,":a;bmp\tati\rika\nekomimi\ri_waraia1.bmp",0
ld l,":a;bmp\TATI\ber\1\ber_akuwaraia1.bmp",0
print 1
click
end