Monday, April 6, 2009

RPG VX Script Fixes

The Ruby script in RPG Maker VX has at least 2 bugs I'm aware of... Just documenting them here so I don't forget.
The first one, concerning the multiply-equal operator, I found myself. This one is so dumb and wrong that it makes me wonder what else is wrong in the script.
The second, concering a screwed-up case-statement, was found at this link (rpgvx faq) http://www.rpgrevolution.com/forums/index.php?s=98899f4cf56b32cd8003f3ec4ea52835&showtopic=14610&pid=291208&st=0&#entry291208.

Also, further googling turned up this link... which is a full replacement script and how to make the changes permanent.
http://www.rpgmakervx.com/variables-fix


#1. Multiplication doesn't work with Variables...

Orig code line 840-841 of "Game_Interpreter".
when 3 # Mul
$game_variables[i] = value

Fixed code:
when 3 # Mul
$game_variables[i] *= value

#2. Variable operation on an actor not working?...

Orig lines 748-752 of game_interpreter:
when 3 # Item
value = $game_party.item_number($data_items[@params[4]])
actor = $game_actors[@parameters[1]]
actor = $game_actors[@params[4]]
if actor != nil

Fixed code:
when 3 # Item
value = $game_party.item_number($data_items[@params[4]])
when 4 # Actor
actor = $game_actors[@params[4]]
if actor != nil

Tuesday, December 2, 2008

WPF Binding to ObservableCollection and a Converter



So, I had nearly the exact same problem described here:
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/944c8058-8b9a-4833-b0fc-32c47d0900d5/

In a nutshell, when you bind an observable collection to a textbox using a converter (for example, to combine all the elements into a comma-separated string), and you add/remove items from the observable collection, the text box's text doesen't change (the converter doesn't fire).

Why? Well, the reference to the observable collection didn't actually change, so the binding doesn't get re-evaluated (even though the number of members do change).

Very frustrating... So, because I'm doing dyanamically loaded xaml from a database table (via System.Windows.Markup.XamlReader.Load), I need a very generic way to handle this...

So, my solution is to iterate over all the controls on the page (using
System.Windows.LogicalTreeHelper.GetChildren) and invoke the UpdateTarget method on the dependency property's BindingExpression (where appropriate, of course).


So, going into this snippet of code:




source: is the control that hosts the observable collection that had an item added/removed.


_allControls: a List<> of all FrameworkElements on page (found via recurisve function calling
System.Windows.LogicalTreeHelper.GetChildren(dependencyobj)).




--- snip---

foreach (var c in _allControls)
{

System.Windows.LocalValueEnumerator lve;

lve = c.GetLocalValueEnumerator();
while (lve.MoveNext())
{
System.Windows.LocalValueEntry e = lve.Current;
if(System.Windows.Data.BindingOperations.IsDataBound(c, e.Property))
{
System.Windows.Data.BindingExpression be;
be = (System.Windows.Data.BindingExpression)e.Value;

if(be.DataItem == source)
{
be.UpdateTarget();
}
}
}
}


So, does anyone have a better solution than this?

Sunday, February 24, 2008

vbscript to extract data from xdata DDS file (so you don't have to buy M$ Access)

paste the following script into a VBS file (example, x.vbs) and run it with CSCRIPT.EXE from a command prompt (1st argument is the path to the exported XDATA dds file)

Example:

cscript.exe x.vbs "c:\programdata\delorme docs\datasets\47129-m.dds" >poi.csv


Note: change q to chr(34) (eg, q=chr(34)) if you want each elemement surrounded by a quote, and change qcq to whatever delemiter you want (eg, qcq = q & "," & q for comma separated)



Dim cn, rs, sout, q, qcq, xdata
q = ""
qcq = vbtab
xdata = WScript.Arguments.Item(0)

Set cn = CreateObject("ADODB.Connection")
cn.CursorLocation = 3

cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & xdata & ";Jet OLEDB:Database Password=SELECT USER;"

Set rs = CreateObject("ADODB.Recordset")

rs.Open "select q.id, q.listing, q.address, q.city, q.state, q.zip, q.phone, q.yellow_page_heading, p.geolat / -8388608.07678 as lat, p.geolon / 8388607.9284564 as lon from (select a.* from xusertable a inner join ( select min(id) as i, ucase(phone) as ph, address, zip from xusertable where score >= 97 group by ucase(phone), address, zip ) b on a.id = b.i ) q inner join point p on q.id = p.pointid", cn, 3, 4

If Not (rs.EOF And rs.BOF) Then
Do Until rs.EOF

sout = q & rs.fields("id").value & qcq & rs.fields("listing").value & qcq & rs.fields("address").value & qcq & rs.fields("city").value & qcq & rs.fields("State").value & qcq & rs.fields("zip").value & qcq & rs.fields("phone").value & qcq & rs.fields("yellow_page_heading").value & qcq & rs.fields("lat").value & qcq & rs.fields("lon").value & q

wscript.echo sout
rs.MoveNext
Loop
End If
rs.Close
cn.Close

Set rs = Nothing
Set cn = Nothing

Tuesday, February 19, 2008

Geocoding for free (nearly)

So, what is "geocoding"? Apparently, it's translating addresses into longitude/latitude.

I got a Magellan GPS for christmas and was disappointed by the crappy POIs included. I then got a TomTom and was even more disappointed than I was about the Magellan.
The Magellan is like a fairly average human (average, dependable, gets along fairly well), while the TomTom is like RainMan (brilliant, buys underwear at KMart, but not very useful)...

So, I started researching.... How do I get useful POIs into these crappy GPS devices? Geeze. What I really want is the "yellow pages" on the GPS... So, when I want to look up a phone number, I'd open my GPS, search, call, and *THEN* the GPS would give me directions to address. Way cool, right?

So, here's my $60 solution (nearly free, right??)...

Hear me out on this... it's a bit convoluted but it works...

1. grab a copy of Street Atlas 2008 PLUS (the one with the phone book included)...

2. Export a bunch of "locations" (via the phone search) as XDATA. The serach is limited to 1,000 so, you'll have to do a "batch at a time"... eg, do one zip code, then another zip code, etc... This is the "geocoding" part. Exproting as XDATA is the where the magic happens.

3. The XDATA created by Street Atlas is actually an MDB (access) database (it names it as filename.DDS or something). The password is "SELECT USER". Under vista, the location is "C:\ProgramData\DeLorme Docs\Datasets"... Open this file with Access.

4. Use access to create an a set of Excel/CSV ready rows... Yummy!!!
Use a query like:
SELECT XUserTable.Listing, XUserTable.Address, XUserTable.City, XUserTable.State, XUserTable.Yellow_Page_Heading, geolat / -8388608.07678 as lat, geolon / 8388607.9284564 as lon FROM XUserTable INNER JOIN Point ON XUserTable.ID = Point.PointID;

Note: the "Score" column in the XUserTable indicates the accuracy of the "geocoding" algorithm (0-100). The higher the score, the better the lon/lat results. I'd suggest squelching anything below 97.


If all this sounds exciting but you don't have M$ Access... well, you can extract the data to CSV using just VB script (which you have if you run Vista/XP/2000). If someone is interested, I can post a .VBS example.

And there you go...