箱庭諸島/hakoniwa.cgi
箱庭諸島 > 箱庭諸島/hakoniwa.cgi
本文
以降の記述にはスクリプト本文があります。 →[記述をスキップ]
<nowiki> #!/usr/local/bin/perl # ↑はサーバーに合わせて変更して下さい。 # なお、perl5.002以降用です。 #---------------------------------------------------------------------- # 箱庭諸島 ver1.1 # # 字: 徳岡宏樹(tokuoka@taurus.bekkoame.ne.jp) # 絵: 小川克人 # テストプレイ他協力: 稲葉修吾、井上友博、小澤武史 # 箱庭諸島のページ: http://www.bekkoame.ne.jp/~tokuoka/hakoniwa.html #---------------------------------------------------------------------- #---------------------------------------------------------------------- # 使用条件 #---------------------------------------------------------------------- # このスクリプトについては、自己責任で使用する限り、基本的には自由に # 利用してもらってかまいません。ただし、変更を加えた場合は、変更した # ものを勝手に配るのはやめて下さい。 # # また、付属しているgifファイルは、小川克人氏が著作権をもっています。 # このゲーム用以外の用途に許可なく使用するのは禁止します。 # # バグを発見した場合は上記のページまでお知らせ下さい。 #---------------------------------------------------------------------- # 設置方法の説明 #---------------------------------------------------------------------- # # ----設置方法---- #・下のValue packageのところにある設定値を、適切な値に設定 # #・CGIが実行されるディレクトリを作り、パーミッションを777に設定します。 # #・そのディレクトリに、このファイル(hakoniwa.cgi)を置き、 # パーミッションを755に設定します。 # #・key-free というファイル名の、大きさが0のファイルを作成し、 # 同じディレクトリに起きます。パーミッションは644に設定します。 # #・サーバーにjcode.plがない場合は、同じディレクトリに置きます。 # #・CGIで実行されるわけではない、通常にアクセス出来る場所に、 # 付属するgifファイル(land*.gif、space*.gif)をすべて置きます。 # # 以上です。なお、一回目の実行において、hakoniwa.dat、hakoniwa.log # の2つのファイルが生成されます。 # # 構成 ()内の数字にパーミッションを設定 # # cgi実行可能なディレクトリ(755)/ # | # |-- hakoniwa.cgi (755) # |-- key-free (644) # |-- jcode.pl ※必要な場合のみ # |-- hankoniwa.dat (644) ※初回に生成される # |-- hakoniwa.log (644) ※初回に生成される # # 通常のウェブのディレクトリ/ # | # |-- land0.gif # |-- ... # |-- land9.gif # |-- space.gif #---------------------------------------------------------------------- # 注意 #---------------------------------------------------------------------- # key-freeファイルは、スクリプト実行中はkey-lockedという名前に # なっています。スクリプトが正常に終了しなかった場合、key-locked # になったままになってしまう事があり、その場合は何度アクセスしても # 同時アクセスエラーになってしまいます。 # # そういった場合は、key-locked を強制的に key-free にrenameして下さい。 # ftpのrenameコマンドで出来るはずです。 #---------------------------------------------------------------------- #Value package 各種設定値 #---------------------------------------------------------------------- package Value; BEGIN { #------------------------------------------------------------# # 必ず設定する部分 #------------------------------------------------------------# # jcode.plの位置 # $jcode = '/usr/libperl/jcode.pl'; # ベッコアメの場合 # $jcode = './jcode.pl'; # 同じディレクトリに置く場合 $jcode = '/usr/libperl/jcode.pl'; # このファイルを置くディレクトリ # $baseDir = 'http://サーバー/ディレクトリ'; # # 例) # http://cgi2.bekkoame.ne.jp/cgi-bin/user/u5534/hakoniwa/hakoniwa.cgi # として置く場合、 # $baseDir = 'http://cgi2.bekkoame.ne.jp/cgi-bin/user/u5534/hakoniwa'; # とする。最後にスラッシュ(/)は付けない。 $baseDir = 'http://cgi2.bekkoame.ne.jp/cgi-bin/user/u5534/hakoniwa'; # 画像ファイルを置くディレクトリ # $imageDir = 'http://サーバー/ディレクトリ'; $imageDir = 'http://www.bekkoame.ne.jp/~tokuoka/island'; # 管理者の名前 $admin = '徳岡宏樹'; # 管理者のメールアドレス $email = 'tokuoka@taurus.bekkoame.ne.jp'; # トップページ $toppage = 'http://www.bekkoame.ne.jp/~tokuoka/hakoniwa.html'; # 掲示板 $bbs = 'http://cgi2.bekkoame.ne.jp/cgi-bin/user/u5534/hakobbs/minibbs.cgi'; #------------------------------------------------------------# # 以降は好みによって変更 #------------------------------------------------------------# # BODYタグのoption $body = 'BGCOLOR="#90b090"'; # コマンド先行入力限界数 $commandMax = 40; # 「最近の出来事」保持ターン数 $logMax = 5; # 「最近の出来事」表示ターン数 $logPrint = 1; # 1ターンが何秒か $unitTime = 21600; # 6時間 # 初期資金 $startMoney = 50; # 島の最大数 $maxIsland = 150; # 期限切れ(資金繰りがこのターン数連続すると、島の放棄) $expire = 28; # お金の単位 $moneyUnit = '億円'; # 人口の単位 $popUnit = '000人'; # 災害発生率(1d1000で下の数字以下) $fire = 10; # 火災 $typhoon = 10; # 台風 $tsunami = 20; # 津波 $eruption = 10; # 噴火 $meteo = 10; # 隕石 $earthquake = 5; # 地震 $maizo = 10; # 埋蔵金 # 島の大きさ(変えない方がいいかも) $islandSize = 12; # デバッグ(1にすると、「ターンを進める」ボタンが出る) # $debug = 1; $debug = 0; # このファイル $thisFile = "$baseDir/hakoniwa.cgi"; } #---------------------------------------------------------------------- # main package メインルーチン #---------------------------------------------------------------------- package main; # jcode.plのよみこみ require "$Value::jcode"; # ロックをかける if(!&Lock::lock()) { # ロック失敗 # ヘッダ出力 &IO::out(&Temp::header($Value::body)); # ロック失敗メッセージ &IO::out(&Temp::lockFail()); # フッタ出力 &IO::out(&Temp::footer()); # 終了 exit(0); } # 乱数初期化 srand; # cookie入力 &Cookie::input(); # CGIコマンド入力 &IO::cgiInput(); # 島データ読み込み &IO::parseAll(); # ターン処理 # 何ターン過ぎているか計算 $now = time; $passTurn = int(($now - $Island::lastUpdateTime) / $Value::unitTime); # デバッグ用ターン処理 if(($Value::debug == 1) && ($Island::mainMode eq 'turn')) { $passTurn = 1; # top modeにもどす $Island::mainMode = 'top'; } # ターン処理(1ターンのみに改定) if($passTurn > 0) { # 最終更新時間を更新 $Island::lastUpdateTime += $Value::unitTime; # ログファイル名変更 my($i, $j); for($i = $Value::logMax - 2; $i >= 0; $i--) { $j = $i + 1; rename("hakoniwa.log$i", "hakoniwa.log$j"); } # ファイルバックアップ rename('hakoniwa.bak7','hakoniwa.bak8'); rename('hakoniwa.bak6','hakoniwa.bak7'); rename('hakoniwa.bak5','hakoniwa.bak6'); rename('hakoniwa.bak4','hakoniwa.bak5'); rename('hakoniwa.bak3','hakoniwa.bak4'); rename('hakoniwa.bak2','hakoniwa.bak3'); rename('hakoniwa.bak1','hakoniwa.bak2'); rename('hakoniwa.dat','hakoniwa.bak1'); # 1ターン進める &Process::turn(); # ファイルに書き出す &IO::writeIslands(); } # 人口順にソート &Util::sort(); # テンプレート初期化 &Temp::initialize(); # cookie出力 &Cookie::output(); # ヘッダ出力 &IO::out(&Temp::header($Value::body)); # モードにより分岐 if($Island::mainMode eq 'top') { # ロック解除 &Lock::unlock(); # トップページ &TopPage::main(); } elsif($Island::mainMode eq 'new') { # 島の新規作成 &NewIsland::main(); # ロック解除 &Lock::unlock(); } elsif($Island::mainMode eq 'print') { # ロック解除 &Lock::unlock(); # 島の表示 &PrintIsland::main(); } elsif($Island::mainMode eq 'owner') { # ロック解除 &Lock::unlock(); # 開発計画 &Owner::main(); } elsif($Island::mainMode eq 'command') { # 開発計画 &ComSend::main(); } else { # ロック解除 &Lock::unlock(); } # フッタ出力 &IO::out(&Temp::footer()); exit(0); #---------------------------------------------------------------------- # Land package 地形データ #---------------------------------------------------------------------- package Land; BEGIN { # 地形番号の設定 $sea = 0; # 海 $wasteland = 1; # 荒地 $plains = 2; # 平地 $town1 = 3; # 村 $town2 = 4; # 町 $town3 = 5; # 都市 $forest = 6; # 森 $farm = 7; # 農場 $factory = 8; # 工場 $base = 9; # ミサイル基地 $dbase = 10; # 防衛施設 # 地形の名前 $name[$sea] = '海'; $name[$wasteland] = '荒地'; $name[$plains] = '平地'; $name[$town1] = '村'; $name[$town2] = '町'; $name[$town3] = '都市'; $name[$forest] = '森'; $name[$farm] = '農場'; $name[$factory] = '工場'; $name[$base] = 'ミサイル基地'; $name[$dbase] = '防衛施設'; # 人口 $pop[$town1] = 1; $pop[$town2] = 3; $pop[$town3] = 5; # 職場 $work[$farm] = 10; $work[$factory] = 30; # 地形の文字(簡略モード用) $word[$sea] = '<FONT STYLE="background-color:blue">海</FONT>'; $word[$wasteland] = '<FONT STYLE="background-color:darkred">荒</FONT>'; $word[$plains] = '<FONT STYLE="background-color:greenyellow">平</FONT>'; $word[$town1] = '<FONT STYLE="background-color:yellow">村</FONT>'; $word[$town2] = '<FONT STYLE="background-color:orange">町</FONT>'; $word[$town3] = '<FONT STYLE="background-color:lightgrey">都</FONT>'; $word[$forest] = '<FONT STYLE="background-color:forestgreen">森</FONT>'; $word[$farm] = '<FONT STYLE="background-color:palegreen">農</FONT>'; $word[$factory] = '<FONT STYLE="background-color:gray">工</FONT>'; $word[$base] = '<FONT STYLE="background-color:olive">基</FONT>'; $word[$dbase] = '<FONT STYLE="background-color:crimson">防</FONT>'; } # 陸地である sub isLand($) { my($land) = @_; if(($land != $sea) && ($land != -1)) { return 1; } else { return 0; } } # 成長候補である sub growLand($) { my($land) = @_; if(($land == $plains) || ($land == $town1) || ($land == $town2)) { return 1; } else { return 0; } } # 成長要素である sub growFactor($) { my($land) = @_; if(($land == $town1) || ($land == $town2) || ($land == $town3) || ($land == $farm)) { return 1; } else { return 0; } } # 平地系である sub isPlain($) { my($land) = @_; if(($land == $plains) || ($land == $town1) || ($land == $town2) || ($land == $town3)) { return 1; } else { return 0; } } # 大きな建物 sub isBuilding($) { my($land) = @_; if(($land == $factory) || ($land == $town3)) { return 1; } else { return 0; } } # 森 sub isForest($) { my($land) = @_; if($land == $forest) { return 1; } else { return 0; } } # 津波にやられるやつ sub isTsunami($) { my($land) = @_; if(($land == $factory) || ($land == $town1) || ($land == $town2) || ($land == $town3) || ($land == $farm) || ($land == $base) || ($land == $dbase)) { return 1; } else { return 0; } } #---------------------------------------------------------------------- # Command package 計画データ #---------------------------------------------------------------------- package Command; BEGIN{ # 計画の総数 $total = 16; # 計画番号の設定 $doNothing = 0; # 資金繰り $prepare = 1; # 整地 $prepare2 = 11; # 地ならし $plant = 2; # 植林 $farm = 3; # 農地整備 $factory = 4; # 工場建設 $base = 5; # ミサイル基地建設 $dbase = 15; # 防衛施設建設 $reclaim = 6; # 埋め立て $donate = 14; # 寄付 $aid = 13; # 資金援助 $missileNM = 7; # ミサイル発射 $missilePP = 8; # PPミサイル発射 $missileST = 12; # STミサイル発射 $missileLD = 9; # 陸地破壊弾発射 $giveup = 10; # 島の放棄 # 順番 @list = ($doNothing, $prepare, $prepare2, $plant, $farm, $factory, $base, $dbase, $reclaim, $donate, $aid, $missileNM, $missilePP, $missileST, $missileLD, $giveup); # 計画の名前 $name[$doNothing] = '資金繰り'; $name[$prepare] = '整地'; $name[$prepare2] = '地ならし'; $name[$plant] = '植林'; $name[$farm] = '農地整備'; $name[$factory] = '工場建設'; $name[$base] = 'ミサイル基地建設'; $name[$dbase] = '防衛施設建設'; $name[$reclaim] = '埋め立て'; $name[$donate] = '寄付'; $name[$aid] = '資金援助'; $name[$missileNM] = 'ミサイル発射'; $name[$missilePP] = 'PPミサイル発射'; $name[$missileST] = 'STミサイル発射'; $name[$missileLD] = '陸地破壊弾発射'; $name[$giveup] = '島の放棄'; # 必要な資金 $cost[$doNothing] = 0; $cost[$prepare] = 5; $cost[$prepare2] = 100; $cost[$plant] = 5; $cost[$farm] = 10; $cost[$factory] = 100; $cost[$base] = 300; $cost[$dbase] = 1000; $cost[$reclaim] = 100; $cost[$donate] = 100; $cost[$aid] = 500; $cost[$missileNM] = 20; $cost[$missilePP] = 50; $cost[$missileST] = 50; $cost[$missileLD] = 150; $cost[$giveup] = 0; # 現在受け取ったコマンド $planNumber = 0; # 計画番号 $kind = 0; # コマンドの種類 $target = ''; # 標的 $x = 0; $y = 0; # 座標 $mode = 0; # モード(挿入、上書き、削除) } #---------------------------------------------------------------------- # Island package グローバル変数 #---------------------------------------------------------------------- package Island; BEGIN { # ターン数 $turn = 0; # 島の数 $totalNumber = 0; # 最終更新時間 $lastUpdateTime = 0; # CGI入力関係 $name = ''; $password = ''; $password2 = ''; $mainMode = ''; $message = ''; $printMode = ''; # クッキー $defaultName = ''; $defaultPassword = ''; $defaultTarget = ''; # 島配列(島型の配列) @island = (); # 島型 # 以下のメンバを持つハッシュ # name 名前 :文字列 # money 資金 :整数値 # land 地形 :整数の2次元配列 # command 計画 :計画型の配列 # (以降はlandより算出) # pop 人口 :整数 # work 職場 :整数 # arm 基地の数 :整数 # prod 生産力 :整数 # farm 農場の数 :整数 # factory 工場の数 :整数 # prepare 整地実行数 :整数 # prepare2 地ならし実行数 :整数 # launch ミサイル発射数 :整数 # dead 死滅 :0 or 1 # 計画型 # 以下のメンバを持つハッシュ # kind コマンド:整数値 # target 標的の島:文字列 # x,y 座標:整数 } #---------------------------------------------------------------------- #以降、各要求における動作 #---------------------------------------------------------------------- #---------------------------------------------------------------------- #TopPage package ゲームのトップページ #---------------------------------------------------------------------- package TopPage; sub main() { # トップページの表示 &IO::out(&Temp::topPage()); # ログの表示 &Log::printAll(); } #---------------------------------------------------------------------- # NewIsland package 島の新規作成 #---------------------------------------------------------------------- package NewIsland; sub main() { my($number, $land, @command, $i, $land); # 名前があるかチェック if($Island::name eq '') { &IO::out(&Temp::newIslandNoName()); return; } # 島名の設定 $Island::name .= '島'; # 名前の重複チェック if(&Util::nameToNumber($Island::name) != -1) { # すでに発見ずみ &IO::out(&Temp::newIslandAlready()); return; } # 名前の中に,がないかチェック if($Island::name =~ /[,\?\(\)\<\>]/) { # 使えない名前 &IO::out(&Temp::newIslandBadName()); return; } # passwordの存在判定 if($Island::password eq '') { # password無し &IO::out(&Temp::noPassword()); return; } # 確認用パスワード if($Island::password ne $Island::password2) { # password間違い &IO::out(&Temp::wrongPassword()); return; } # 新しい島の番号を決める $number = $Island::totalNumber; # 島の番号を一つ増やす $Island::totalNumber++; # 初期コマンドを生成 for($i = 0; $i < $Value::commandMax; $i++) { $command[$i] = { 'kind' => 0, 'target' => '', 'x' => 0, 'y' => 0 }; } # 島型を生成 $land = &createLand(); $Island::island[$number] = { 'name' => $Island::name, 'password' => &Util::encode($Island::password), 'money' => $Value::startMoney, 'land' => $land, 'command' => \@command, 'message' => "(未登録)" }; # 人口その他の計算 &Calc::estimate($Island::island[$number]); # データの書き出し &IO::writeIslands(); # logの書き出し &IO::outLog(&Temp::logNewIsland($Island::name)); #「発見した」メッセージ &IO::out(&Temp::newIslandSuccess($Island::island[$number])); } # 新規作成 sub createLand(){ my(@land, $i, $count); # 島の基礎を作る @land = &createLandBase(); # 平地を増殖 for($i = 0; $i < 50; $i++) { &Hex::randomVisit(\&makePlains, @land); } # 森を増殖 for($i = 0; $i < 20; $i++) { &Hex::randomVisit(\&makeForest, @land); } # 村を作る $count = 0; while($count < 2) { $count += &Hex::randomVisit(\&makeTown, @land); } # 基地を作る $count = 0; while($count < 1) { $count += &Hex::randomVisit(\&makeBase, @land); } return \@land; } #初期の陸地を決定 sub createLandBase() { my(@land, $x, $y, $sx, $sy, $ex, $ey, $v); #陸地を作る座標の範囲を設定 $sx = $Value::islandSize / 4; $sy = $Value::islandSize / 4; $ex = $Value::islandSize - $sx; $ey = $Value::islandSize - $sy; for($x = 0; $x < $Value::islandSize; $x++) { for($y = 0; $y < $Value::islandSize; $y++) { if(($x >= $sx) && ($x < $ex) && ($y >= $sy) && ($y < $ey)) { #範囲内の場合、陸地(荒地)に設定 $land[$x][$y] = $Land::wasteland; } else { #範囲外の場合、海に設定 $land[$x][$y] = $Land::sea; } } } return @land; } #平地を増やす sub makePlains($$$$@) { my($land, $x, $y, $unit, @land) = @_; #周囲すべて海なら増やさない if(&Hex::countLand(\&Land::isLand, $x, $y, @land) != 0) { return $Land::plains; } else { return $land; } } #森を増やす sub makeForest($$$$@) { my($land, $x, $y, $unit, @land) = @_; #陸地だった場合に森にする if(&Land::isLand($land)) { return $Land::forest; } else { return $land; } } #村を増やす sub makeTown($$$$@) { my($land, $x, $y, $unit, @land) = @_; #周囲すべて陸地で、まだ村でない場合に村にする if((&Hex::countLand(\&Land::isLand, $x, $y, @land) == 7) && ($land != $Land::town1)) { $$unit = 1; #村にした場合はカウント return $Land::town1; } else { return $land; } } #基地を増やす sub makeBase($$$$@) { my($land, $x, $y, $unit, @land) = @_; #周囲すべて陸地で、村でない場合に村にする if((&Hex::countLand(\&Land::isLand, $x, $y, @land) == 7) && ($land != $Land::town1)) { $$unit = 1; #基地にした場合はカウント return $Land::base; } else { return $land; } } #---------------------------------------------------------------------- # PrintIsland package 島の表示 #---------------------------------------------------------------------- package PrintIsland; sub main() { my($number); # 島番号の取得 $number = &Util::nameToNumber($Island::name); if($number == -1) { # 何かの間違い &IO::out($Temp::back); return; } # 「ようこそ」メッセージ &IO::out(&Temp::printIsland($Island::island[$number])); # 最近の出来事表示 &Log::printOther($Island::name); } #---------------------------------------------------------------------- # Owner package 開発計画編集画面 #---------------------------------------------------------------------- package Owner; sub main() { my($number, $island); # 島番号の取得 $number = &Util::nameToNumber($Island::name); if($number == -1) { # 何かの間違い &IO::out($Temp::back); return; } # 島の取得 $island = $Island::island[$number]; # password if(&Util::encode($Island::password) ne $island->{'password'}) { &IO::out(&Temp::wrongPassword()); return; } #コマンド編集画面の表示 &IO::out(&Temp::ownerMode($island)); # 最近の出来事表示 &Log::printOwner($Island::name); } #---------------------------------------------------------------------- # ComSend package 開発計画送信 #---------------------------------------------------------------------- package ComSend; sub main() { my($number, $island); # 島番号の取得 $number = &Util::nameToNumber($Island::name); if($number == -1) { # 何かの間違い &IO::out($Temp::back); return; } # 島の取得 $island = $Island::island[$number]; # password if(&Util::encode($Island::password) ne $island->{'password'}) { &IO::out(&Temp::wrongPassword()); return; } # modeで分岐 if($Command::mode eq 'delete') { &Util::slideFront($island->{'command'},$Command::planNumber); &IO::out(&Temp::comDelete()); } else { if($Command::mode eq 'insert') { &Util::slideBack($island->{'command'},$Command::planNumber); } # コマンドをさしかえ $island->{'command'}->[$Command::planNumber] = { 'kind' => $Command::kind, 'target' => $Command::target, 'x' => $Command::x, 'y' => $Command::y }; &IO::out(&Temp::comAdd()); } # データの書き出し &IO::writeIslands(); # ロック解除 &Lock::unlock(); # 開発計画画面へ &Owner::main(); } #---------------------------------------------------------------------- # Process package ターン進行処理 #---------------------------------------------------------------------- package Process; # 1ターン進める sub turn() { my($i, $r, $total, $island, @order); $total = $Island::totalNumber; # turnの数をふやす $Island::turn++; # 収入フェイズ for($i = 0; $i < $total; $i++) { $island = $Island::island[$i]; $island->{'money'} += $island->{'prod'}; } # コマンドフェイズ # コマンド処理順番を決める for($i = 0; $i < $total; $i++ ){ $order[$i] = -1; } for($i = 0; $i < $total; $i++ ){ $r = int(rand(1) * $total); if($order[$r] == -1) { $order[$r] = $i; } else { $i--; } } # orderに従ってコマンド処理 for($i = 0; $i < $total; $i++ ){ $island = $Island::island[$order[$i]]; if($island->{'dead'} != 1){ # コマンド1つ実行出来るまで回す while(&doCommand($island) == 0){} } } # 災害フェイズ for($i = 0; $i < $total; $i++ ){ $island = $Island::island[$order[$i]]; if($island->{'dead'} != 1){ $currentName = $island->{'name'}; &doDisaster($island); } } # 町の成長フェイズ for($i = 0; $i < $total; $i++ ){ $island = $Island::island[$order[$i]]; if($island->{'dead'} != 1){ $currentName = $island->{'name'}; &doGrow($island); } } # 死滅判定 for($i = 0; $i < $total; $i++ ){ $island = $Island::island[$i]; if($island->{'dead'} != 1){ # 人口計算 &Calc::estimate($island); if($island->{'pop'} == 0) { # ぜんめつ $island->{'dead'} = 1; &IO::outLog(&Temp::procDead($island->{'name'})); } } } # 遅延ログを書き出し &IO::lateLogWrite(); } # コマンド一つ実行 sub doCommand($) { my($island) = @_; my($command, $kind, $target, $x, $y, $cost, $comName, $land, $pt, $landKind, $landName, $tn); # コマンド取り出し $command = $island->{'command'}; $kind = $command->[0]->{'kind'}; $target = $command->[0]->{'target'}; $x = $command->[0]->{'x'}; $y = $command->[0]->{'y'}; # 導出値 $name = $island->{'name'}; $land = $island->{'land'}; $landKind = $land->[$x][$y]; $landName = $Land::name[$landKind]; $cost = $Command::cost[$kind]; $comName = $Command::name[$kind]; $pt = &Temp::point($x, $y); # 1つ詰めておく &Util::slideFront($command, 0); # 資金チェック if($island->{'money'} < $cost) { # 足りない場合 &IO::outLog(&Temp::procNoMoney($name, $comName)); return 0; } # コマンドで分岐 if($kind == $Command::doNothing) { # 資金繰り $island->{'money'} += 10; $island->{'absent'} += 1; if($island->{'absent'} >= $Value::expire) { # 期限切れ # 次のコマンドを放棄に $command->[0]->{'kind'} = $Command::giveup; } return 1; } else { $island->{'absent'} = 0; if(($kind == $Command::prepare) || ($kind == $Command::prepare2)){ # 整地 if($landKind == $Land::sea) { # 海だと失敗 &IO::outLog(&Temp::procNotAdeqLand($name, $pt, $comName, $landName)); return 0; } # 成功 # コマンド名を'整地'に統一 $comName = $Command::name[$Command::prepare]; $land->[$x][$y] = $Land::plains; $island->{'money'} -= $cost; &IO::outLog(&Temp::procSuccess($name, $pt, $comName)); if($kind == $Command::prepare2) { $island->{'prepare2'}++; return 0; } $island->{'prepare'}++; return 1; } elsif($kind == $Command::reclaim) { # 埋め立て if($landKind != $Land::sea) { # 海じゃないと失敗 &IO::outLog(&Temp::procNotAdeqLand($name, $pt, $comName, $landName)); return 0; } # 成功 $land->[$x][$y] = $Land::wasteland; $island->{'money'} -= $cost; &IO::outLog(&Temp::procSuccess($name, $pt, $comName)); return 1; } elsif(($kind == $Command::plant) || ($kind == $Command::farm) || ($kind == $Command::factory) || ($kind == $Command::base) || ($kind == $Command::dbase)) { # 建設系 if(!&Land::isPlain($land->[$x][$y])) { # 平地系じゃないと失敗 &IO::outLog(&Temp::procNotAdeqLand($name, $pt, $comName, $landName)); return 0; } # 成功 if($kind == $Command::farm) { # 農地 $land->[$x][$y] = $Land::farm; &IO::outLog(&Temp::procSuccess($name, $pt, $comName)); } elsif($kind == $Command::factory) { # 工場 $land->[$x][$y] = $Land::factory; &IO::outLog(&Temp::procSuccess($name, $pt, $comName)); } elsif($kind == $Command::dbase) { # 防衛施設 $land->[$x][$y] = $Land::dbase; &IO::outLog(&Temp::procSuccess($name, $pt, $comName)); } elsif($kind == $Command::plant) { # 森 $land->[$x][$y] = $Land::forest; &IO::outLog(&Temp::procPBSuccess($name)); &IO::outLogSecret($name, &Temp::procSuccess($name, $pt, $comName)); } elsif($kind == $Command::base) { # 基地 $land->[$x][$y] = $Land::base; &IO::outLog(&Temp::procPBSuccess($name)); &IO::outLogSecret($name,&Temp::procSuccess($name, $pt, $comName)); } $island->{'money'} -= $cost; return 1; } elsif($kind == $Command::giveup) { # 島の放棄 &IO::outLog(&Temp::procGiveup($name)); $island->{'dead'} = 1; return 1; } elsif(($kind == $Command::donate) || ($kind == $Command::aid)) { #資金援助、寄付 # targetを取得 $tn = &Util::nameToNumber($target); if($tn == -1) { # その島がすでに無かったら失敗 &IO::outLog(&Temp::procAid2($name, $comName, $target)); } else { $island->{'money'} -= $cost; $Island::island[$tn]->{'money'} += $cost; &IO::outLog(&Temp::procAid($name, $comName, $target)); } return 0; # どちらにしてもターンは進まない } elsif($kind == $Command::missileNM) { return &launchMissile(19, 0, $island, $comName, $target, $pt, $cost, $x, $y, $pt); } elsif($kind == $Command::missilePP) { return &launchMissile(7, 0, $island, $comName, $target, $pt, $cost, $x, $y, $pt); } elsif($kind == $Command::missileST) { return &launchMissile(19, 2, $island, $comName, $target, $pt, $cost, $x, $y, $pt); } elsif($kind == $Command::missileLD) { return &launchMissile(19, 1, $island, $comName, $target, $pt, $cost, $x, $y, $pt); } } return 0; } # ミサイル発射 sub launchMissile($$$$$$$$$$) { my($err, $power, $island, $comName, $target, $pt, $cost, $x, $y, $pt) = @_; my($name, $arm, $attack, $tn, $i, $tIsland, $tLand, $tx, $ty, $tPt, $en, $tKind, $tName, $sName, $defence); $name = $island->{'name'}; $arm = $island->{'arm'}; # 基地があるか判定 if($arm == 0) { # 無かったら失敗 &IO::outLog(&Temp::procNoBase($name, $comName)); return 0; } # targetを取得 $tn = &Util::nameToNumber($target); if($tn == -1) { # その島がすでに無かったら失敗 &IO::outLog(&Temp::procNoTarget($name, $comName, $target)); return 0; } $tIsland = $Island::island[$tn]; $tLand = $tIsland->{'land'}; # 何発撃つか計算 $attack = &Util::min($arm, int(($island->{'money'} / $cost))); $island->{'launch'} += $attack; # ステルス if($power == 2) { $sName = $name; $name = '???島'; } # 発射 for($i = 0; $i < $attack; $i++) { # 誤差値を計算 $en = int(rand(1) * $err); # 着弾地点を算出 ($tx, $ty) = &Hex::around($x, $y, $en); $tPt = &Temp::point($tx, $ty); # 領域外かどうか判定 if($tx == -1) { # 領域外 if($power == 2) { # ステルス &IO::outLogLate(&Temp::missileOutArea($name, $comName, $target, $pt)); &IO::outLogSecret($sName, &Temp::missileOutArea($sName, $comName, $target, $pt)); } else { # 通常 &IO::outLog(&Temp::missileOutArea($name, $comName, $target, $pt)); } } else { # 領域内 $tKind = $tLand->[$tx][$ty]; if($tKind == $Land::sea) { # 海ポチャの場合 if($power == 2) { # ステルス &IO::outLogLate(&Temp::missileSea($name, $comName, $target, $pt, $tPt)); &IO::outLogSecret($sName, &Temp::missileSea($sName, $comName, $target, $pt, $tPt)); } else { &IO::outLog(&Temp::missileSea($name, $comName, $target, $pt, $tPt)); } } else { # 防衛施設判定 if($tKind == $Land::dbase) { $defence = 0; } else { $defence = &Hex::judgeDBase($tx, $ty, $tLand); } if($defence != 0) { # キャッチされた場合 if($power == 2) { # ステルス &IO::outLogLate(&Temp::missileDef($name, $comName, $target, $pt, $tPt)); &IO::outLogSecret($sName, &Temp::missileDef($sName, $comName, $target, $pt, $tPt)); } else { &IO::outLog(&Temp::missileDef($name, $comName, $target, $pt, $tPt)); } } else { # 陸地に落ちた場合 $tName = $Land::name[$tKind]; if(($power == 0) || ($power == 2)){ if($power == 2) { # ステルス &IO::outLogLate(&Temp::missileNormal($name, $comName, $target, $pt, $tPt, $tName)); &IO::outLogSecret($sName, &Temp::missileNormal($sName, $comName, $target, $pt, $tPt, $tName)); } else { # 通常 &IO::outLog(&Temp::missileNormal($name, $comName, $target, $pt, $tPt, $tName)); } $tLand->[$tx][$ty] = $Land::wasteland; } elsif($power == 1) { # 陸地破壊 &IO::outLog(&Temp::missileLD($name, $comName, $target, $pt, $tPt, $tName)); $tLand->[$tx][$ty] = $Land::sea; } } } } $island->{'money'} -= $cost; } return 1; } # 町の成長判定 sub doGrow($) { my($island) = @_; my($count, $x, $y, $l, $d, $tx, $ty); $count = &Hex::visit(\&grow, @{$island->{'land'}}); # $countに増えた人口が入ってるはずだが、 # 現時点では使用していない。 } # 成長 sub grow($$$$@) { my($land, $x, $y, $unit, @land) = @_; my($count, $random); # 平地系じゃなければ何もしない if(!&Land::growLand($land)) { return $land; } # 周囲の町、畑を数える $count = &Hex::countLand(\&Land::growFactor, $x, $y, @land); # サイコロ(1-10) $random = &Util::dice(10); # 乱数に従って成長判定 if($count >= $random) { if($land == $Land::plains) { $$unit += 1; return $Land::town1; } elsif($land == $Land::town1) { $$unit += 2; return $Land::town2; } elsif($land == $Land::town2) { $$unit += 2; return $Land::town3; } } return $land; } # 災害判定 sub doDisaster($) { my($island) = @_; my($random, $price, $p, $i); # 埋蔵金 $random = &Util::dice(1000); if(($island->{'prepare'} > 0) && ($random <= $Value::maizo)) { $price = 99 + &Util::dice(401); $island->{'money'} += $price; &IO::outLog(&Temp::disMaizo($currentName, $price)); } # 火災 &Hex::visit(\&fire, @{$island->{'land'}}); # 台風 $random = &Util::dice(1000); $p = $Value::typhoon * ($island->{'factory'} + 1); if($random <= $p) { &IO::outLog(&Temp::disTyphoon1($currentName)); &Hex::visit(\&typhoon, @{$island->{'land'}}); } # 地震 $random = &Util::dice(1000); $p = $Value::earthquake * ($island->{'prepare2'} + 1); if($random <= $p) { &IO::outLog(&Temp::disEarthquake1($currentName)); &Hex::visit(\&earthquake, @{$island->{'land'}}); } # 津波 $random = &Util::dice(1000); if($random <= $Value::tsunami) { &IO::outLog(&Temp::disTsunami1($currentName)); &Hex::visit(\&tsunami, @{$island->{'land'}}); } # 火山噴火 $random = &Util::dice(1000); if($random <= $Value::eruption) { &Hex::randomVisit(\&eruption, @{$island->{'land'}}); } # 隕石 $random = &Util::dice(1000); $p = $Value::meteo * ($island->{'launch'} + 1); if($random <= $p) { do { &Hex::randomVisit(\&meteo, @{$island->{'land'}}); } while(&Util::dice(2) == 1); } } # 火災(工場、都市が荒地になる) sub fire($$$$@) { my($land, $x, $y, $unit, @land) = @_; my($count, $random, $lName); # 工場、都市じゃなければ何もしない if(!&Land::isBuilding($land)) { return $land; } # サイコロ(1-1000) $random = &Util::dice(1000); # 乱数に従って判定 if($random > $Value::fire) { return $land; } # 周囲の森の数を数える(1-7) $count = &Hex::countLand(\&Land::isForest, $x, $y, @land); if($count > 0) { # 森に隣接してれば何もしない return $land; } # 乱数に従って火災判定 $lName = $Land::name[$land]; &IO::outLog(&Temp::disFire($currentName, $lName, $x, $y)); return $Land::wasteland; # 荒地になる } # 台風(農場が荒地になる) sub typhoon($$$$@) { my($land, $x, $y, $unit, @land) = @_; my($count, $random, $lName); # 農場じゃなければ何もしない if($Land::farm != $land) { return $land; } # サイコロ(1-2) $random = &Util::dice(2); # 乱数に従って被害判定 if($random <= 1) { $lName = $Land::name[$land]; &IO::outLog(&Temp::disTyphoon2($currentName, $lName, $x, $y)); return $Land::plains; # 平地になる } return $land; } # 地震(建物が荒地になる) sub earthquake($$$$@) { my($land, $x, $y, $unit, @land) = @_; my($count, $random, $lName); # 工場、都市じゃなければ何もしない if(!&Land::isBuilding($land)) { return $land; } # サイコロ(1-3) $random = &Util::dice(3); # 乱数に従って被害判定 if($random <= 1) { $lName = $Land::name[$land]; &IO::outLog(&Temp::disEarthquake2($currentName, $lName, $x, $y)); return $Land::wasteland; # 荒地になる } return $land; } # 津波(沿岸の建造物が荒地になる) sub tsunami($$$$@) { my($land, $x, $y, $unit, @land) = @_; my($count, $random, $lName); # 津波対象地形かどうか調べる if(!&Land::isTsunami($land)) { return $land; } # 周囲の陸の数を数える(1-7) $count = &Hex::countLand(\&Land::isLand, $x, $y, @land); # 率を決定 $count = 6 - $count; # サイコロ(1-10) $random = &Util::dice(10); # 乱数に従って被害判定 if($random <= $count) { $lName = $Land::name[$land]; &IO::outLog(&Temp::disTsunami2($currentName, $lName, $x, $y)); return $Land::wasteland; # 荒地になる } return $land; } # 火山噴火(陸、海を問わず荒地になる) sub eruption($$$$@) { my($land, $x, $y, $unit, @land) = @_; my($count, $random, $l, $lName, $i, $tx, $ty); # 発生 &IO::outLog(&Temp::disEruption0($currentName, $lName, $x, $y)); for($i = 0; $i < 7; $i++) { ($tx, $ty) = &Hex::around($x, $y, $i); if($tx != -1) { $l = $land[$tx][$ty]; $lName = $Land::name[$l]; # 海かどうかでメッセージを分ける if($l == $Land::sea) { # 海の場合 &IO::outLog(&Temp::disEruption1($currentName, $lName, $tx, $ty)); } else { # 海じゃない場合 &IO::outLog(&Temp::disEruption2($currentName, $lName, $tx, $ty)); } $land[$tx][$ty] = $Land::wasteland; } } return $Land::wasteland; # 荒地へ。 } # 隕石 落ちた所が海になる sub meteo($$$$@) { my($land, $x, $y, $unit, @land) = @_; my($count, $random, $lName); # 海かどうかでメッセージを分ける $lName = $Land::name[$land]; if($land == $Land::sea) { # 海の場合 &IO::outLog(&Temp::disMeteo1($currentName, $lName, $x, $y)); } else { # 海じゃない場合 &IO::outLog(&Temp::disMeteo2($currentName, $lName, $x, $y)); } return $Land::sea; # 海になる } #---------------------------------------------------------------------- #Hex package 座標関係 #---------------------------------------------------------------------- package Hex; BEGIN { #周囲2ヘックスの座標 #周囲2ヘックスの座標 @dx = (0,1,1,1,0,-1,0,1,2,2,2,1,0,-1,-1,-2,-1,-1,0); @dy = (0,-1,0,1,1,0,-1,-2,-1,0,1,2,2,2,1,0,-1,-2,-2); } #周囲のヘックスを求める sub around() { my($sx, $sy, $number, $x, $y); ($sx, $sy, $number) = @_; $x = $sx + $dx[$number]; $y = $sy + $dy[$number]; if((($sy % 2) == 1) && (($y % 2) == 0)) { $x -= 1; } #範囲外の場合は(-1,-1)で統一 if(($x < 0) || ($x >= $Value::islandSize) || ($y < 0) || ($y >= $Value::islandSize)) { $x = -1; $y = -1; } return ($x, $y); } #ランダムにヘックスを選ぶ(一番外側以外) sub random() { my($x, $y); $x = int(rand(1) * ($Value::islandSize - 2)) + 1; $y = int(rand(1) * ($Value::islandSize - 2)) + 1; return ($x, $y); } #全部のヘックスをなめる #引数は、適用関数、地形型(整数の2次元配列) sub visit(&@) { my($visitor,@land) = @_; my($x, $y, $count, $unit); #ループ $count = 0; for($y = 0; $y < $Value::islandSize; $y++) { for($x = 0; $x < $Value::islandSize; $x++) { $unit = 0; #カウント要素用 $land[$x][$y] = &$visitor($land[$x][$y], $x, $y, \$unit, @land); $count += $unit; #カウント要素を加算 } } return $count; } #ランダムなヘックスに適用 #(一番外は除く) sub randomVisit(&@) { my($visitor,@land) = @_; my($x, $y, $count); #座標決定 ($x, $y) = random(); $count = 0; $land[$x][$y] = &$visitor($land[$x][$y], $x, $y, \$count, @land); return $count; } #周囲のヘックス(+自分のヘックス)のうち、引数の数字のやつの探す sub countLand(&$$@) { my($cond, $sx, $sy, @land) = @_; my($count, $i, $x, $y); $count = 0; for($i = 0; $i < 7; $i++) { ($x, $y) = &around($sx, $sy, $i); if($x != -1) { if(&$cond($land[$x][$y])) { $count++; } } } return $count; } # 周囲2ヘックス(自分除く)に防衛施設があるかどうか sub judgeDBase($$$) { my($sx, $sy, $land) = @_; my($i, $x, $y); for($i = 1; $i < 19; $i++) { ($x, $y) = &around($sx, $sy, $i); if($x != -1) { if($land->[$x][$y] == $Land::dbase) { return 1; } } } return 0; } #---------------------------------------------------------------------- #Calc package 人口や生産力等の計算 #---------------------------------------------------------------------- package Calc; sub estimate($) { my($island) = @_; my($x, $y); # 初期化 $island->{'pop'} = 0; $island->{'farm'} = 0; $island->{'factory'} = 0; $island->{'work'} = 0; $island->{'arm'} = 0; # ループ for($y = 0; $y < $Value::islandSize; $y++) { for($x = 0; $x < $Value::islandSize; $x++) { $l = $island->{'land'}->[$x][$y]; if($l == $Land::town1) { # 村 $island->{'pop'} ++; } elsif($l == $Land::town2) { # 町 $island->{'pop'} += 3; } elsif($l == $Land::town3) { # 都市 $island->{'pop'} += 5; } elsif($l == $Land::farm) { # 農場 $island->{'farm'} ++; $island->{'work'} +=10; } elsif($l == $Land::factory) { # 工場 $island->{'factory'} ++; $island->{'work'} +=30; } elsif($l == $Land::base) { # 基地 $island->{'arm'} ++; } } } #生産力 $island->{'prod'} = &Util::min($island->{'pop'}, $island->{'work'}); } #---------------------------------------------------------------------- # IO package 入出力 #---------------------------------------------------------------------- package IO; # cgiデータの読み込み sub cgiInput() { my($line); # 入力を受け取って日本語変換 $line = <>; $line =~ tr/+/ /; $line =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg; $line = &jcode::euc($line); $line =~ s/[\x00-\x1f\,]//g; # 対象の島の名前 if($line =~ /CommandButton=(.*)へ送信/) { # コマンド送信ボタンの場合 $Island::name = $1; $Island::defaultName = $1; } elsif($line =~ /ISLANDNAME=([^\&]*)\&/){ # その他の場合 $Island::name = $1; $Island::defaultName = $1; } else { $Island::name = $line; } # パスワード if($line =~ /PASSWORD=([^\&]*)\&/) { $Island::password = $1; $Island::defaultPassword = $1; } if($line =~ /PASSWORD2=([^\&]*)\&/) { $Island::password2 = $1; } # メッセージ if($line =~ /MESSAGE=([^\&]*)\&/) { $Island::message = $1; } # 簡略表示モード if($line =~ /SIMPLEMODE=simple\&/) { $Island::printMode = 'simple'; } else { $Island::printMode = ''; } # main modeの取得 if($line =~ /TurnButton/) { if($Value::debug == 1) { $Island::mainMode = 'turn'; } } elsif($line =~ /OwnerButton/) { $Island::mainMode = 'owner'; } elsif($line =~ /SightButton/) { $Island::mainMode = 'print'; } elsif($line =~ /NewIslandButton/) { $Island::mainMode = 'new'; } elsif($line =~ /CommandButton/) { $Island::mainMode = 'command'; # コマンドモードの場合、コマンドの取得 $line =~ /NUMBER=([^\&]*)\&/; $Command::planNumber = $1; $line =~ /COMMAND=([^\&]*)\&/; $Command::kind = $1; $line =~ /TARGETNAME=([^\&]*)\&/; $Command::target = $1; $Island::defaultTarget = $1; $line =~ /POINTX=([^\&]*)\&/; $Command::x = $1; $line =~ /POINTY=([^\&]*)\&/; $Command::y = $1; $line =~ /COMMANDKIND=([^\&]*)\&/; $Command::mode = $1; } else { $Island::mainMode = 'top'; } } # 島データの読み込み sub parseAll() { # ファイルを開く if(open(IN, "hakoniwa.dat") == 0) { close(IN); my($now); # データファイルが無かった場合、作る open(OUT, ">hakoniwa.dat"); print OUT "1\n"; #ターン数 $now = time; $now = $now - ($now % ($Value::unitTime)); print OUT "$now\n"; # 開始時間 print OUT "0\n"; # 島の数 close(OUT); chmod(0666, 'hakoniwa.dat'); return &parseAll(); } # 現在のターン数を読み込む chomp($Island::turn = <IN>); chomp($Island::lastUpdateTime = <IN>); chomp($Island::totalNumber = <IN>); my($i); for($i = 0; $i < $Island::totalNumber; $i++) { # 各島を読み込む $Island::island[$i] = &parseIsland(); #人口その他の計算 &Calc::estimate($Island::island[$i]); } close(IN); } # 島一つをよみこみ sub parseIsland() { my($name, $password, $money, $y, $x, $i, $line, @land, @command); chomp($name = <IN>); # 名前 chomp($absent = <IN>); # 連続資金繰り chomp($message = <IN>); # メッセージ chomp($password = <IN>); # password chomp($money = <IN>); # 金 # 土地 for($y = 0; $y < $Value::islandSize; $y++) { $line = <IN>; for($x = 0; $x < $Value::islandSize; $x++) { $line =~ s/.//; if($& eq 'a') { $land[$x][$y] = 10; } else { $land[$x][$y] = $&; } } } #コマンド for($i = 0; $i < $Value::commandMax; $i++) { $line = <IN>; $line =~ /^(.*),(.*),(.*),(.*)$/; $command[$i] = { 'kind' => $1, 'target' => $2, 'x' => $3, 'y' => $4 }; } #島型にして返す return { 'name' => $name, 'password' => $password, 'money' => $money, 'land' => \@land, 'command' => \@command, 'message' => $message, 'absent' => $absent }; } # 島データの書き出し sub writeIslands() { my($total, $i); # 生きてる島を数える $total = 0; for($i = 0; $i < $Island::totalNumber; $i++) { if($Island::island[$i]->{'dead'} != 1) { $total++; } } # ファイル開く if(open(OUT, '>hakoniwa.dat') == 0) { print "HOGE STOP"; exit(1); } # ターン数、最終更新、島の数 print OUT "$Island::turn\n"; print OUT "$Island::lastUpdateTime\n"; print OUT "$total\n"; # 各島を書き出す for($i = 0; $i < $Island::totalNumber; $i++) { if($Island::island[$i]->{'dead'} != 1) { &writeIsland($Island::island[$i]); } } # ファイル閉じる close(OUT); } # 島一つの書き出し sub writeIsland($) { my($island) = @_; my($land, $command, $x, $y, $i); #名前、message、password、資金 print OUT "$island->{'name'}\n"; print OUT "$island->{'absent'}\n"; if($island->{'name'} eq $Island::defaultName) { if($Island::message ne "") { print OUT "${Island::message}\n"; } else { print OUT "$island->{'message'}\n"; } } else { print OUT "$island->{'message'}\n"; } print OUT "$island->{'password'}\n"; print OUT "$island->{'money'}\n"; # 要素取り出し $land = $island->{'land'}; $command = $island->{'command'}; # 陸地の書き出し for($y = 0; $y < $Value::islandSize; $y++) { for($x = 0; $x < $Value::islandSize; $x++) { printf OUT "%x",$land->[$x][$y]; } print OUT "\n"; } # 計画の書き出し for($i = 0; $i < $Value::commandMax; $i++) { print OUT "$command->[$i]->{'kind'},"; print OUT "$command->[$i]->{'target'},"; print OUT "$command->[$i]->{'x'},"; print OUT "$command->[$i]->{'y'}\n"; } } # 標準出力への出力 sub out($) { my($str) = @_; print STDOUT &jcode::sjis($str); } # logfile 1行追記 sub outLog($) { my($str) = @_; my($turn); open(OUT, '>>hakoniwa.log0'); $turn = &Temp::logTurn(); print OUT "$turn$str\n"; close(OUT); } # logfile 遅延追記 sub outLogLate($) { my($str) = @_; my($turn); $turn = &Temp::logTurn(); push(@lateLog, "$turn$str\n"); } sub lateLogWrite() { open(OUT, '>>hakoniwa.log0'); print OUT @lateLog; close(OUT); @lateLog = (); } # logfile 1行追記 sub outLogSecret($$) { my($name, $str) = @_; my($turn); open(OUT, '>>hakoniwa.log0'); $turn = &Temp::logTurn(); print OUT "secretinfo$name${turn}<B>(機密)</B>$str\n"; close(OUT); } #---------------------------------------------------------------------- #Lock package 同時アクセス対策 #---------------------------------------------------------------------- package Lock; sub lock() { my($t); # ロックを試す if(unlink('./key-free')) { # 成功 # ロック時間書き出し open(OUT, '>key-locked'); print OUT time; close(OUT); return 1; } else { # ロック時間チェック if(!open(IN, 'key-locked')) { return 0; } $t = <IN>; close(IN); if(($t != 0) && (($t + 120) < time)) { # 120秒以上経過してたら、強制的にロックを外す unlock(); } return 0; } } sub unlock() { # ロックを外す my($i); $i = rename('./key-locked', './key-free'); } #---------------------------------------------------------------------- #Util package 各種便利ツール #---------------------------------------------------------------------- package Util; #島の名前から番号を取得するやつ sub nameToNumber { my($i, $name); $name = $_[0]; for($i = 0; $i < $Island::totalNumber; $i++){ if($Island::island[$i]->{'name'} eq $name) { return $i; } } return -1; } #pass wordをエンコードするやつ sub encode($) { return crypt($_[0], 'hakoniwa'); # (cryptの使い方の自信無し) } #小さい方を返すやつ sub min($$) { my($x, $y) = @_; if($x > $y) { return $y; } else { return $x } } # コマンドを後ろにずらすやつ sub slideBack($$) { my($command,$number,$i) = @_; my($i); for($i = $Value::commandMax - 1; $i > $number; $i--) { $command->[$i] = $command->[$i - 1]; } } # コマンドを前につめるやつ sub slideFront($$) { my($command,$number) = @_; my($i); for($i = $number; $i < ($Value::commandMax - 1); $i++) { $command->[$i] = $command->[$i + 1]; } $command->[$Value::commandMax - 1] = { 'kind' => 0, 'target' => '', 'x' => 0, 'y' => 0 }; } # 1d10 sub dice($) { return int(rand(1) * $_[0]) + 1; } # 人口順にソート sub sort() { my($flag, $size, $i, $tmp); # ばぶるそおと $flag = 1; $size = $Island::totalNumber; while($flag == 1) { $flag = 0; for($i = 0; $i < ($size - 1); $i++) { if($Island::island[$i]->{'pop'} < $Island::island[$i + 1]->{'pop'}) { $flag = 1; # 島の入れ換え $tmp = $Island::island[$i]; $Island::island[$i] = $Island::island[$i + 1]; $Island::island[$i + 1] = $tmp; } } } } #---------------------------------------------------------------------- #Cookie package cookie入出力 #---------------------------------------------------------------------- package Cookie; #cookie入力 sub input() { my($cookie); $cookie = &jcode::euc($ENV{'HTTP_COOKIE'}); if($cookie =~ /${Value::baseDir}OWNISLANDNAME=\(([^\)]*)\)/) { $Island::defaultName = $1; } if($cookie =~ /${Value::baseDir}OWNISLANDPASSWORD=\(([^\)]*)\)/) { $Island::defaultPassword = $1; } if($cookie =~ /${Value::baseDir}TARGETISLANDNAME=\(([^\)]*)\)/) { $Island::defaultTarget = $1; } } #cookie出力 sub output() { my($cookie, $info); # 消える期限の設定 my($sec, $min, $hour, $date, $mon, $year, $day, $yday, $dummy) = gmtime(time + 30 * 86400); # 現在 + 30日 # 2ケタ化 if ($year < 10) { $year = "0$year"; } if ($date < 10) { $date = "0$date"; } if ($hour < 10) { $hour = "0$hour"; } if ($min < 10) { $min = "0$min"; } if ($sec < 10) { $sec = "0$sec"; } # 曜日を文字に $day = ("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")[$day]; # 月を文字に $mon = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec")[$mon]; # パスと期限のセット $info = "; expires=$day, $date\-$mon\-$year $hour:$min:$sec GMT\n"; # $info = "path=$Value::baseDir/\n"; $cookie = ''; if(($Island::name) && ($Island::mainMode eq 'owner')){ # if($Island::name) { $cookie .= "Set-Cookie: ${Value::baseDir}OWNISLANDNAME=($Island::name) $info"; } if($Island::password) { $cookie .= "Set-Cookie: ${Value::baseDir}OWNISLANDPASSWORD=($Island::password) $info"; } if($Command::target) { $cookie .= "Set-Cookie: ${Value::baseDir}TARGETISLANDNAME=($Command::target) $info"; } &IO::out($cookie); } #---------------------------------------------------------------------- #Log package Log表示関係 #---------------------------------------------------------------------- package Log; sub printAll() { my($i); for($i = 0; $i < $Value::logPrint; $i++) { &print('', 0, "hakoniwa.log$i"); } } sub printOther($) { my($i); for($i = 0; $i < $Value::logMax; $i++) { &print($_[0], 0, "hakoniwa.log$i"); } } sub printOwner($) { my($i); for($i = 0; $i < $Value::logMax; $i++) { &print($_[0], 1, "hakoniwa.log$i"); } } sub print($$$) { my($name, $secret, $fileName) = @_; my($count, @line, $i, $line, $turn); $turn = &Temp::logTurn(); # ログファイルを読み込む open(IN, $fileName); $count = 0; while(<IN>) { $line[$count] = $_; $count++; } close(IN); # 表示 for($i = $count - 1; $i >= 0; $i--) { $line = $line[$i]; if($line =~ /^secretinfo/) { # 機密情報チェック if(($secret == 1) && ($line =~ s/^secretinfo$name//)) { &IO::out($line . '<BR>'); } } else { if(($name eq '') || ($line =~ /$name/)) { &IO::out($line . '<BR>'); } } } } #---------------------------------------------------------------------- #Temp package 出力Template #---------------------------------------------------------------------- package Temp; BEGIN { my($i, $j, $c, $selected); # タイトル $tt_ = '<FONT COLOR="#4040a0"><B>'; $_tt = '</B></FONT>'; # 大きい文字 $big_ = '<FONT SIZE=6><B>'; $_big = '</B></FONT>'; # ちょっと大きい文字 $mid_ = '<FONT SIZE=4><B>'; $_mid = '</B></FONT>'; # 強調文字、表項目 $ind_ = '<FONT COLOR="#800000"><B>'; $_ind = '</B></FONT>'; # 位置、島の名前 $pt_ = '<FONT COLOR="#a06040"><B>'; $_pt = '</B></FONT>'; # 島の名前、薄め $pt2_ = '<FONT COLOR="#808080"><B>'; $_pt2 = '</B></FONT>'; # コマンド $com_ = '<FONT COLOR="#202060"><B>'; $_com = '</B></FONT>'; # 災害 $red_ = '<FONT COLOR="#e00000"><B>'; $_red = '</B></FONT>'; # 島のSELECTの中身 $islandList = ''; $targetList = ''; # 「戻る」リンク $back = "<A HREF=\"$Value::thisFile\">${big_}戻る${_big}</A>"; # 計画番号用のリストボックス $numberList = ''; for($i = 0; $i < $Value::commandMax; $i++) { $j = $i + 1; $numberList .= "<OPTION VALUE=$i>$j\n"; } # 座標用のリストボックス $pointList = ''; for($i = 0; $i < $Value::islandSize; $i++) { $pointList .= "<OPTION VALUE=$i>$i\n"; } # 計画用のリストボックス $commandList = ''; for($i = 0; $i < $Command::total; $i++) { $c = $Command::list[$i]; if($c == $Command::prepare) { $selected = 'SELECTED'; # 整地をデフォルトに } else { $selected = ''; } $commandList .= "<OPTION VALUE=$c $selected>$Command::name[$c]($Command::cost[$c]$Value::moneyUnit)"; } } # 島データのプルダウンメニュー用 sub getIslandList($) { my($select) = @_; my($list, $name); #島リストのメニュー $list = ''; for($i = 0; $i < $Island::totalNumber; $i++) { $name = $Island::island[$i]->{'name'}; if($name eq $select) { $s = 'SELECTED'; } else { $s = ''; } $list .= "<OPTION VALUE=\"$name\" $s>$name\n"; } return $list; } #プルダウンメニューの内容等を更新する #(島データが更新された後に呼ばれる) sub initialize() { my($i, $j, $s, $name, $pop, $money, $farm, $factory, $message, $absent, $pm); # 簡略表示チェックボックス if($Island::printMode eq 'simple') { $pm = 'CHECKED'; } else { $pm = ''; } $simpleBox = "<INPUT TYPE=checkbox NAME=SIMPLEMODE VALUE=\"simple\" $pm>簡略表示\n"; # 島リストのメニュー $islandList = &getIslandList($Island::defaultName); $targetList = &getIslandList($Island::defaultTarget); # ランキングの中身 $islandRanking = ''; for($i = 0; $i < $Island::totalNumber; $i++) { $j = $i + 1; $name = $Island::island[$i]->{'name'}; $pop = $Island::island[$i]->{'pop'}; $money = $Island::island[$i]->{'money'}; $farm = $Island::island[$i]->{'farm'}; $factory = $Island::island[$i]->{'factory'}; $message = $Island::island[$i]->{'message'}; $message = &escape($message); $absent = $Island::island[$i]->{'absent'}; if($absent > 0) { $name = "<TD><NOBR>${pt2_}$name${_pt2}</NOBR></TD>"; } else { $name = "<TD><NOBR>${pt_}$name${_pt}</NOBR></TD>"; } $islandRanking .= <<END; <TR> <TD align=center><NOBR>${mid_}$j${_mid}</NOBR></TD> $name <TD><NOBR>$pop$Value::popUnit</NOBR></TD> <TD><NOBR>$money$Value::moneyUnit</NOBR></TD> <TD align=center><NOBR>$factory</NOBR></TD> <TD align=center><NOBR>$farm</NOBR></TD> <TD><NOBR>$message</NOBR></TD> </TR> END } } # HTMLの文字をエスケープ sub escape($) { my($s) = @_; $s =~ s/&/&/g; $s =~ s/</</g; $s =~ s/>/>/g; $s =~ s/\"/"/g; #" return $s; } # HTMLのアタマ sub header($) { my($body) = @_; return <<END; Content-type: text/html <HTML> <HEAD> <TITLE> 箱庭諸島 </TITLE> </STYLE> </HEAD> <BODY $body> END } # HTMLのケツ sub footer() { return <<END; <HR> <P align=center> 管理者:$Value::admin(<A HREF="mailto:$Value::email">$Value::email</A>)<BR> 掲示板(<A HREF="$Value::bbs">$Value::bbs</A>)<BR> トップページ(<A HREF="$Value::toppage">$Value::toppage</A>)<BR> 箱庭諸島のページ(<A HREF="http://www.bekkoame.ne.jp/~tokuoka/hakoniwa.html">http://www.bekkoame.ne.jp/~tokuoka/hakoniwa.html</A>)<BR> </P> </BODY> </HTML> END } #トップページ sub topPage() { my($debugStr, $newStr); $debugStr = ''; if($Value::debug == 1) { $debugStr = <<END; <FORM action="$Value::thisFile" method=POST> <INPUT TYPE=submit VALUE="ターンを進める" NAME=TurnButton> </FORM> END } if($Island::totalNumber >= $Value::maxIsland) { $newStr = <<END; <H1>${tt_}新しい島を探す${_tt}</H1> 島の数が最大数です・・・現在登録できません。 END } else { $newStr = <<END; <H1>${tt_}新しい島を探す${_tt}</H1> <FORM action="$Value::thisFile" method=POST> どんな名前をつける予定?<BR> <INPUT TYPE=text NAME=ISLANDNAME SIZE=32 MAXLENGTH=32>島<BR> パスワードは?<BR> <INPUT TYPE=password NAME=PASSWORD SIZE=32 MAXLENGTH=32><BR> 念のためパスワードをもう一回<BR> <INPUT TYPE=password NAME=PASSWORD2><BR> <INPUT TYPE=submit VALUE="探しに行く" NAME=NewIslandButton> </FORM> END } return <<END; $debugStr <H1>${tt_}自分の島へ${_tt}</H1> <FORM action="$Value::thisFile" method=POST> あなたの島の名前は?<BR> <SELECT NAME=ISLANDNAME> $islandList </SELECT><BR> パスワードをどうぞ!!<BR> <INPUT TYPE=password NAME=PASSWORD VALUE="$Island::defaultPassword"><BR> $simpleBox<BR> <INPUT TYPE=submit VALUE="開発しに行く" NAME=OwnerButton><BR> </FORM> <HR> <H1>${tt_}その他の島へ${_tt}</H1> <FORM action="$Value::thisFile" method=POST> どの島を見に行く?<BR> <SELECT NAME=ISLANDNAME> $islandList </SELECT> <BR> $simpleBox<BR> <INPUT TYPE=submit VALUE="観光しに行く" NAME=SightButton> </FORM> <HR> $newStr <HR> <H1>${tt_}諸島の状況${_tt}</H1> <TABLE BORDER> <TR><TD COLSPAN=7> ${big_}ターン${Island::turn}:${_big} </TD></TR> <TR> <TH><NOBR>${ind_}順位${_ind}</NOBR></TH> <TH><NOBR>${ind_}島${_ind}</NOBR></TH> <TH><NOBR>${ind_}人口${_ind}</NOBR></TH> <TH><NOBR>${ind_}資金${_ind}</NOBR></TH> <TH><NOBR>${ind_}工場${_ind}</NOBR></TH> <TH><NOBR>${ind_}農場${_ind}</NOBR></TH> <TH><NOBR>${ind_}コメント${_ind}</NOBR></TH> $islandRanking </TR> </TABLE> <HR> <H1>${tt_}最近の出来事${_tt}</H1> END } # 島の表示 sub islandMap($$) { my($mode, $island) = @_; my($str, $x, $y, $kind, $caption, $land, $sm, $tmp); $land = $island->{'land'}; if($Island::printMode eq 'simple') { $sm = 1; } else { $sm = 0; } # 本体 $str = ''; $str .= <<END; <CENTER> <TABLE BORDER> <TR> <TH>${ind_}人口${_ind}</TH> <TD>$island->{'pop'}$Value::popUnit</TD> <TH>${ind_}資金${_ind}</B></TH> <TD>$island->{'money'}$Value::moneyUnit</TD> </TR> <TR> <TH>${ind_}工場${_ind}</TH> <TD align=center>$island->{'factory'}</TD> <TH>${ind_}農場${_ind}</B></TH> <TD align=center>$island->{'farm'}</TD> </TR> </TABLE> <TABLE BORDER WIDTH=0 HEIGHT=0 CELLSPACING=0 CELLPADDING=0> <TR><TD> END if($sm == 0) { $str .= "<IMG SRC=\"$Value::imageDir/xbar.gif\" width=400 height=16><BR>"; } else { $str .= "<PRE><FONT SIZE=5> 0 1 2 3 4 5 6 7 8 9 0 1\n"; } for($y = 0; $y < $Value::islandSize; $y++) { if($sm == 1) { if($y < 10) { $str .= "$y"; } else { $tmp = $y - 10; $str .= "$tmp"; } } if(($y % 2) == 0) { if($sm == 0) { $str .= "<IMG SRC=\"$Value::imageDir/space${y}.gif\" width=16 height=32>"; } else { $str .= " "; } } for($x = 0; $x < $Value::islandSize; $x++) { $kind = $land->[$x][$y]; if(($kind == $Land::base) && ($mode == 0)) { $kind = $Land::forest; } $caption= "($x, $y)$Land::name[$kind]"; if($sm == 0) { $str .= "<IMG SRC=\"$Value::imageDir/land$kind.gif\" ALT=\"$caption\" width=32 height=32>"; } else { $str .= $Land::word[$kind]; } } if(($y % 2) == 1) { if($sm == 0) { $str .= "<IMG SRC=\"$Value::imageDir/space${y}.gif\" width=16 height=32>"; } else { $str .= " "; } } if($sm == 0) { $str .= "<BR>"; } else { $str .= "\n"; } } if($sm == 1) { $str .= "</FONT>";
} $str .= "</TD></TR></TABLE></CENTER>";
return $str;
}
- 新規で名前が無い場合
sub newIslandNoName() { return <<END; ${big_}島につける名前が必要です。${_big}$back END }
- 新規で名前がすでに使用されている場合
sub newIslandAlready() { return <<END; ${big_}その島ならすでに発見されています。${_big}$back END }
- 新規で名前が反則な場合
sub newIslandBadName() { return <<END; ${big_}',?()<>'とか入った変な文字入った名前はやめましょうよ~。${_big}$back END }
- 新規で島が作成された場合
sub newIslandSuccess($) {
my($island) = @_; $map = &Temp::islandMap(1,$island);
return <<END;
${big_}島を発見しました!!${_big}
${big_}${pt_}「$island->{'name'}」${_pt}${_big}
${big_}と名付けます。${_big}
$map
$back
END }
- 島の表示モード
sub printIsland($) {
my($island) = @_; $map = &Temp::islandMap(0,$island);
return <<END;
${big_}${pt_}$island->{'name'}${_pt}へようこそ!!${_big}
$back
$map
$back
${big_}${pt_}$island->{'name'}${_pt}の近況${_big}
END
}
- コマンド変数モード
sub ownerMode($) {
my($island) = @_; my($map, $command1, $command2, $command3, $command4); $map = &islandMap(1,$island); $command1 = &islandCommand($island->{'command'}, 0,
int($Value::commandMax / 5 * 2));
$command2 = &islandCommand($island->{'command'},
int($Value::commandMax / 5 * 2), int($Value::commandMax / 5 * 3));
$command3 = &islandCommand($island->{'command'},
int($Value::commandMax / 5 * 3), int($Value::commandMax / 5 * 4));
$command4 = &islandCommand($island->{'command'},
int($Value::commandMax / 5 * 4), $Value::commandMax); return <<END;
${big_}${pt_}$island->{'name'}${_pt}開発計画${_big}
$back
<FORM action="$Value::thisFile" method=POST>
計画番号 | 開発計画 | ターゲット | 座標 |
---|---|---|---|
<SELECT NAME=NUMBER> $numberList </SELECT> |
<SELECT NAME=COMMAND> $commandList </SELECT> |
<SELECT NAME=TARGETNAME> $targetList </SELECT> |
( <SELECT NAME=POINTX> $pointList </SELECT> , <SELECT NAME=POINTY> $pointList </SELECT> ) |
<INPUT TYPE=radio NAME=COMMANDKIND VALUE=insert CHECKED>挿入
<INPUT TYPE=radio NAME=COMMANDKIND VALUE=write>上書き
<INPUT TYPE=radio NAME=COMMANDKIND VALUE=delete>削除
$simpleBox |
|||
コメント<INPUT TYPE=text NAME=MESSAGE SIZE=80 MAXLENGTH=80> |
|||
パスワード
<INPUT TYPE=password NAME=PASSWORD VALUE="$Island::defaultPassword"> |
<INPUT TYPE=submit VALUE="$island->{'name'}へ送信" NAME=CommandButton> |
</FORM>
|
$map |
|
|
|
|
$back
${big_}${pt_}$island->{'name'}${_pt}の近況${_big}
END
}
sub islandCommand($$$) {
my($command, $start, $end) = @_; my($i, $j, $kind, $target, $x, $y, $str, $pt); $str = ; for($i = $start; $i < $end; $i++) {
$j = $i + 1; $str .= "<TR><TD>$ind_$j$_ind</TD><TD>";
# 各値の取り出し $kind = $command->[$i]->{'kind'}; $target = $command->[$i]->{'target'}; $x = $command->[$i]->{'x'}; $y = $command->[$i]->{'y'};
# 基本部品 $pt = &point($x, $y); # 座標 $tg = &targetName($target); # 発射目標
# 分岐 if(($kind == $Command::doNothing) ||($kind == $Command::giveup)) { # 資金繰り、島の放棄 $str .= "${com_}$Command::name[$kind]${_com}"; } elsif(($kind == $Command::prepare) ||($kind == $Command::prepare2) ||($kind == $Command::plant) ||($kind == $Command::farm) ||($kind == $Command::factory) ||($kind == $Command::base) ||($kind == $Command::dbase) ||($kind == $Command::reclaim)) { $str .= "$ptで${com_}$Command::name[$kind]${_com}"; } elsif(($kind == $Command::missileNM) ||($kind == $Command::missilePP) ||($kind == $Command::missileST) ||($kind == $Command::missileLD)) { $str .= "$tgの$ptへ${com_}$Command::name[$kind]${_com}"; } elsif(($kind == $Command::donate) || ($kind == $Command::aid)) { $str .= "$tgへ${com_}$Command::name[$kind]${_com}"; }
$str .= "</TD></TR>";
} return $str;
}
- 座標
sub point($$) {
my($x, $y) = @_; return "$pt_($x,$y)$_pt";
}
- 座標
sub targetName($) {
return "$pt_$_[0]$_pt";
}
- password無し
sub noPassword() { return <<END; ${big_}パスワードがありません。${_big}$back END }
- password間違い
sub wrongPassword() { return <<END; ${big_}パスワードが違います。${_big}$back END }
- lock失敗
sub lockFail() { return <<END; ${big_}同時アクセスエラーです。${_big}$back END }
- ターン
sub logTurn() {
return "${ind_}ターン${Island::turn}:${_ind}";
}
- 島発見の log記述
sub logNewIsland($) {
return "新しく${pt_}$_[0]${_pt}が発見されました。";
}
- コマンド削除
sub comDelete() {
return "${big_}コマンドを削除しました${_big}";
}
- コマンド登録
sub comAdd() {
return "${big_}コマンドを登録しました${_big}";
}
- 資金不足
sub procNoMoney($$) {
my($name, $com) = @_; return "${pt_}$name${_pt}で予定されていた${com_}$com${_com}は、資金不足のため実行できませんでした。";
}
- 整地等の失敗
sub procNotAdeqLand($$$$) {
my($name, $pt, $com, $land) = @_; return "${pt_}$name${_pt}で予定されていた${com_}$com${_com}は、予定地の${pt_}$pt${_pt}地点が${big_}$land${_big}であったため実施できませんでした。";
}
- 整地等の成功
sub procSuccess($$$) {
my($name, $pt, $com) = @_; return "${pt_}$name$pt${_pt}で${com_}$com${_com}が行われました。";
}
- 森か基地の建設
sub procPBSuccess($) {
my($name) = @_; return "こころなしか、${pt_}$name${_pt}の${big_}森${_big}が増えたようです。";
}
- 島の放棄
sub procGiveup($) {
my($name) = @_; return "${pt_}$name${_pt}は放棄され、${big_}無人島${_big}になりました。";
}
- 資金援助
sub procAid($$$) {
my($name, $com, $target) = @_; return "${pt_}$name${_pt}が${pt_}$target${_pt}へ${com_}$com${_com}を行いました。";
}
sub procAid2($$$) {
my($name, $com, $target) = @_; return "${pt_}$name${_pt}で予定されていた${com_}$com${_com}は、${pt_}$target${_pt}がすでに${big_}無人島${_big}になっているため手遅れでした。";
}
- 基地が無くてミサイルが打てない
sub procNoBase($$) {
my($name, $com) = @_; return "${pt_}$name${_pt}で予定されていた${com_}$com${_com}は、ミサイル基地を保有していないため実施できませんでした。";
}
- 目標が無くてミサイルが打てない
sub procNoTarget($$$) {
my($name, $com, $target) = @_; return "${pt_}$name${_pt}で予定されていた${com_}$com${_com}は、目標の${pt_}$target${_pt}がすでに放棄されているため、中止されました。";
}
- 画面外に落ちる
sub missileOutArea($$$$) {
my($name, $com, $target, $pt) = @_; return "${pt_}$name${_pt}が${pt_}$target${_pt}の${pt_}$pt${_pt}地点に向けて${com_}$com${_com}を行いましたが、領域外の海に落ちた模様です。";
}
- 海ポチャ
sub missileSea($$$$$) {
my($name, $com, $target, $pt, $tPt) = @_; return "${pt_}$name${_pt}が${pt_}$target${_pt}の${pt_}$pt${_pt}地点に向けて${com_}$com${_com}を行いましたが、${pt_}$tPt${_pt}の海に落ちた模様です。";
}
- 防衛施設でキャッチ
sub missileDef($$$$$) {
my($name, $com, $target, $pt, $tPt) = @_; return "${pt_}$name${_pt}が${pt_}$target${_pt}の${pt_}$pt${_pt}地点に向けて${com_}$com${_com}を行いましたが、${pt_}$tPt${_pt}地点上空で力場に捕らえられ、${big_}空中爆破${_big}しました。";
}
- 通常弾
sub missileNormal($$$$$$) {
my($name, $com, $target, $pt, $tPt, $tName) = @_; return "${pt_}$name${_pt}が${pt_}$target${_pt}の${pt_}$pt${_pt}地点に向けて${com_}$com${_com}を行い、${pt_}$tPt${_pt}の${big_}$tName${_big}に着弾。一帯が荒地と化しました。";
}
- 陸地破壊
sub missileLD($$$$$$) {
my($name, $com, $target, $pt, $tPt, $tName) = @_; return "${pt_}$name${_pt}が${pt_}$target${_pt}の${pt_}$pt${_pt}地点に向けて${com_}$com${_com}を行い、${pt_}$tPt${_pt}の${big_}$tName${_big}に着弾。一帯が水没しました。";
}
- 死滅
sub procDead($) {
my($name) = @_; return "${pt_}$name${_pt}から人がいなくなり、${big_}無人島${_big}になりました。";
}
- 火災発生
sub disFire($$$$) {
my($name, $lName, $x, $y) = @_; return "${pt_}$name($x,$y)${_pt}地点の${big_}$lName${_big}で${red_}火災発生${_red}、${lName}は壊滅しました。";
}
- 台風発生
sub disTyphoon1($) {
my($name) = @_; return "${pt_}$name${_pt}を${red_}台風${_red}が襲いました。";
}
- 台風被害
sub disTyphoon2($$$$) {
my($name, $lName, $x, $y) = @_; return "${pt_}$name($x,$y)${_pt}地点の${big_}$lName${_big}は${red_}台風${_red}によりドームごと飛ばされました。";
}
- 地震発生
sub disEarthquake1($) {
my($name) = @_; return "${pt_}$name${_pt}で大規模な${red_}地震${_red}が発生しました。";
}
- 地震被害
sub disEarthquake2($$$$) {
my($name, $lName, $x, $y) = @_; return "${pt_}$name($x,$y)${_pt}地点の${big_}$lName${_big}は${red_}地震${_red}により壊滅しました。";
}
- 津波発生
sub disTsunami1($) {
my($name) = @_; return "${pt_}$name${_pt}付近で巨大な${red_}津波${_red}が発生しました。";
}
- 津波被害
sub disTsunami2($$$$) {
my($name, $lName, $x, $y) = @_; return "${pt_}$name($x,$y)${_pt}地点の${big_}$lName${_big}は${red_}津波${_red}により壊滅しました。";
}
- 火山噴火発生
sub disEruption0($$$$) {
my($name, $lName, $x, $y) = @_; return "${pt_}$name($x,$y)${_pt}地点の${big_}$lName${_big}で突然${red_}火山が噴火${_red}!!";
}
- 噴火の影響、海
sub disEruption1($$$$) {
my($name, $lName, $x, $y) = @_; return "${pt_}$name($x,$y)${_pt}地点の${big_}$lName${_big}に陸地ができました。";
}
- 噴火の影響、陸
sub disEruption2($$$$) {
my($name, $lName, $x, $y) = @_; return "${pt_}$name($x,$y)${_pt}地点の${big_}$lName${_big}だった所は、${red_}噴火${_red}により荒地になりました。";
}
- 海に隕石落下
sub disMeteo1($$$$) {
my($name, $lName, $x, $y) = @_; return "${pt_}$name($x,$y)${_pt}地点に${red_}隕石${_red}が落ちましたが、${big_}$lName${_big}であったため無事でした。";
}
- 陸に隕石落下
sub disMeteo2($$$$) {
my($name, $lName, $x, $y) = @_; return "${pt_}$name($x,$y)${_pt}地点の${big_}$lName${_big}に${red_}隕石${_red}が落ち、一帯の陸地が水没しました。";
}
- 埋蔵金
sub disMaizo($$) {
my($name, $price) = @_; return "${pt_}$name${_pt}で行われた整地中に、${big_}$price$Value::moneyUnit${_big}もの埋蔵金が発見されました。";
}
</nowiki>
</pre>
以上でスクリプト本文の記述は終わりです。
解説
箱庭諸島ver1のスクリプト
[1]より