2011/02/07(月)チーター

久しぶりに UO の話。

SA が導入されて1年くらいになるのかな。錬成で装備品の敷居が低くなり、色々と動き始めるのかと思いきやほぼ何もせずに過ごしてる。
匠のチキンという便利な有料アイテムも出て、生産で作れるレベルの最高の品も簡単に作れるようになったんだけど、色々と計算するのが面倒で、作ろう作ろうとは思いつつもなかなか腰が重い。
一番資材をつぎ込んだのは堀師用の装備かもしれない。ニッチな構成のキャラクター向けの装備は出まわってない(ゴミとして捨てられるから)ので、これを思い通りに作れるというのは素晴らしい。
2アカの堀師も育てて装備を整えたりした。

んで、せっかくだから他のシャードでも掘ろう、と思い立ってキャラクターを作ってみたりしてた。
いろんな要因があってそうそううまくは行ってないけど。


ネガティブポイント:
  • シャードによっては、フルスペルブックが目玉が飛び出るほど高い
  • 掘ろうにも、人口の少ないシャードでは火ゴキを手に入れるのが大変
    • 22:00 頃にヘイブンやブリテンに行っても誰もいない
      • 街に人がいないだけじゃなく、ベインが街を陥落させるくらいシャード自体に人がいない
    • 自分でテイマーを育てるのは錬成スキルを上げる以上に大変
    • 取引サイトを見ると、火ゴキは数十万gp とかで取引されてて無理
  • 錬成スキルを上げるには、一朝一夕では資材が揃わない
    • 中級程度のモンスターを短時間で大量に狩れるWWA戦士が欲しい
      • 1体1 で強くても意味が無いので、簡単に育てられるメイジではダメ
    • プロスペクターツールを使ってダルカッパーを大量に掘れれば戦士がいなくてもなんとかなるけど、資材を使うスキルを上げるには鉄を掘りたかったり、プロスペクターツールを手に入れる為の鉄ももったいなかったり
      • スキルだけ上げても中々無理。装備も整えないと戦えない
ポジティブポイント:
  • 秘薬低減装備は、錬成に50を振った初期キャラで作れる
    • 人がいて商売が回ってるシャードだったら買えばいい
    • 旧ヘイブンのゾンビからたまに出るマジックアイテムを拾って魔法の残骸をゲット
    • 戦士のスキルが 60くらいになる頃には琥珀を買うだけの資金は貯まってる
    • 錬成する装備は街の革屋で買う
  • マゲ上げ用の魔道ワンドが売ってなくても、これも初期キャラでトレハンできる
わかったこと:
  • 生産キャラを育てるなら、細工スキルを最初から 50 近くまで付けておく事が重要
  • 今は、初期キャラの持ち物はブレス属性じゃないらしい
  • 丈夫なツルハシやシャベルは、生産品よりもチャージあたりの資材コストが高い
    • トラメルで掘ると足が出る

んで、マゲ上げめんどいなぁ、と思って書いた。
http://www.autohotkey.com/ に食わせるスクリプト。
実際に使ったことはないので不具合があるかもしれない。
;;; Magery スキル値に応じて、実行するマクロを切り替える
;;; 要 UOA
;;;
;;; F1 に 2nd の魔法、F2 に 3rd の魔法...
;;; という具合に UO のマクロを設定しておいて使う
;;; UO を多重起動してるとうまくいかない事があると思う

AppName = UOmage
Gui, Add, Text, w256 vTarget ,Target:
Gui, Add, Text, w256 vUOA, UOA
Gui, Add, Text, w256 vSkill, Skill
Gui, Add, Button, vButtonStart, Start
Gui, Show, AutoSize, %AppName%

;;; ループが走ってるかどうかのフラグ
isRun := False

;;; UOA の hwnd 取得
WinGet, uoa, ID, ,UOAssist
WinGetTitle, title, ahk_id %uoa%
GuiControl, ,UOA, UOA: %title%

;;; UO の hwnd 取得
;;; なんでか、UOA から UO の hwnd が取れない
SendMessage, 1237, , , ,ahk_id %uoa%
Target := ErrorLevel
if (%ErrorLevel% == 0) {
   ;;; UOA から取れないので自分で探す
   WinGet, Target, ID, Ultima Online
}
if (0)
{
    ;;; 多重起動してる時で、UOA から UO の hwnd が取れない時用
    ;;; スクリプトを起動してから、最初にクリックしたウィンドウにメッセージを飛ばす
    ;;; 寝マクロしたい UO のウィンドウをクリックすればいい。
    ;;; うまく行けば、ツールの画面に UO のウィンドウタイトルが表示されるので確認できる。
    KeyWait, Lbutton, D
    MouseGetPos, x, y, Target, ctrl, 1
}
WinGetTitle, title, ahk_id %Target%
GuiControl, ,Target, Target: %title%
return

ButtonStart:
if (isRun == False) {
    GuiControl, ,ButtonStart, Stop
    SetTimer, TimerRepeat, 6500
    isRun := True
} else if (isRun == True) {
    GuiControl, ,ButtonStart, Start    
    SetTimer, TimerRepeat, Off
    isRun := False
}
return

TimerRepeat:
;;; Magery の ID は 25。スキル値取得用の WM_COMMAND は 0x400 + 200 = 1227。
SendMessage, 1227, 25, 0, ,ahk_id  %uoa%
level := ErrorLevel
GuiControl, , Skill, Skill: %level%
IfLess, level, 250
{
    ControlSend, , {F1}, ahk_id %Target%, , ,
}
else IfLess, level, 400
{
    ControlSend, , {F2}, ahk_id %Target%, , ,
}
else IfLess, level, 550
{
    ControlSend, , {F3}, ahk_id %Target%, , ,
}
else IfLess, level, 700
{
    ControlSend, , {F4}, ahk_id %Target%, , ,
}
else IfLess, level, 850
{
    ControlSend, , {F5}, ahk_id %Target%, , ,
}
else IfLess ,level, 950
{
    ControlSend, , {F6}, ahk_id %Target%, , ,
}
else
{
    ControlSend, , {F7}, ahk_id %Target%, , ,    
}
return

GuiClose:
ExitApp
スクリプトだから楽かな、と思ったけど、さすがに Perl 程変数の自動キャストとかが上手くないので、これなら静的型付き言語で書かせてくれって感じ。自分で Win32API を叩いたほうが、そういう Try & Error しないといけない部分が無い分楽だったかも。
仕様を確認するのに、DllCall() を呼んだ時はホントにそう思った。
でも、SendMessage() で lparam を組み立ててやる手間を ControlSend() を使うことで省けるので、自動キャストのクセをつかむ手間とどっこいどっこいかなって感じ。

非アクティブウィンドウにメッセージを飛ばすときには、モディフィアキーを使わないほうがいいらしい。GetKeyState() を呼ばないとわからないキーは kbd_event() で生成しないといけなくて、kbd_event() を呼んじゃうと目的のウィンドウだけに収まらずシステム全体に影響が出ちゃう。そうすると、他所で操作してる時に突然 Ctrl が押された状態になって驚いたり、逆に Ctrl がリリースされてキーバインドのつもりが普通の入力になって驚いたりする。