Application Release: Halo Stats Archiver: Desktop Edition

Jul 23, 2010

Tags: , , , ,

Halo Stats Archiver: Desktop Edition (HSA: DE) allows you to download and archive all of your Halo Stats, from Halo 2 to Halo: Reach (Console versions only), everything from Screenshots to who killed who and where (via game images). HSA: DE 2.0 is a complete rebuild from its predisessor, built on the power of the Adobe AIR platform it brings easyer installing, updating and a slick new design. As well as easyer install and many other mass improvements HSA is platform independent, with support for Linux, Mac, and of course Windows see Adobe.com for Adobe AIR requirements.

You can download HSA: DE from the Adobe AIR Marketplace or directly from this site. Hit the jump for abit of interesting ActionScript 3 binary flags work.

One of the features in Halo 3: ODST's firefight mode is game waves, and in order to figure out which skulls are on or off in a firefight game you have to look at the last normal wave. But the SLK property coming from the service was just a number. Thanks to runningturtle whome I contacted for more information about how the game waves works I have now. He told me that the SKL property in the game waves is in fact the skulls, in the form of a binary flag. Which means that the uint 4294956828 equates to the skulls Mythic,Tilt,Famine,Catch,ToughLuck,BlackEye,IWHBYD,GruntBirthdayParty, and Cowbell. runningturtle also gave me the break down of which skulls are which number in the binary flag. He didn't mention the skull Blind but i duduced its 2.

Cowbell 4
GruntBirthdayParty 8
IWHBYD 16
Iron 128
BlackEye 256
ToughLuck 512
Catch 1024
Fog 2048
Famine 4096
ThunderStorm 8192
Tilt 16384
Mythic 32768

Knowing this it took me several hours to actually get the formula for properly generating the list of active skulls in a game, but after a while I managed to come up with the code nessisary. It took allot of googling to try and find out how to use binary flags in ActionScript 3, I manged to find an article by Lee Brimelow a Platform Evangelist at Adobe that pointed me in the right direction after that it was pretty simple. BUT for some reason some of the SKL's would be negative, which didn't make sense, so I looked into the GW class that Flex Builder 3 generated via it's Import Web Service tool. It had a datatype of Number for SKL, which I realized was wrong after changing it to uint everything was great and it ended up working as I expected giving me all the skulls active in every game. The resulting code is bellow, note I pass in the initial skulls set at the start of the game, this is more for Campaign games as they do not have waves. But in Firefight games the skulls can all be retrieved from the SKL property in the Game Waves.

/**
 * Gets the skulls turned on over the entire game
 * @param gameData Game Data From the ODST Service
 * @param skulls Initial skulls turned on when the game started
 */
private function getGameSkulls(gameData:Game,skulls:Array):void {
    if(gameData.GameWaves.length==0) {
        //No waves so return
        return;
    }

    var skl:uint=gameData.GameWaves[gameData.GameWaves.length-1].SKL;
    //Check that the game didn't end on a bonus round
    if(skl==28) {
        skl=gameData.GameWaves[gameData.GameWaves.length-2].SKL;
    }

    //----- FIND SKULLS -----//

    //Is Mythic on?
    if(skl&32768 && skulls.indexOf('Mythic')==-1) {
        skulls.push('Mythic');
    }

    //Is Tilt on?
    if(skl&16384 && skulls.indexOf('Tilt')==-1) {
        skulls.push('Tilt');
    }

    //Is ThunderStorm on?
    if(skl&8192 && skulls.indexOf('ThunderStorm')==-1) {
        skulls.push('ThunderStorm');
    }

    //Is Famine on?
    if(skl&4096 && skulls.indexOf('Famine')==-1) {
        skulls.push('Famine');
    }

    //Is Fog on?
    if(skl&2048 && skulls.indexOf('Fog')==-1) {
        skulls.push('Fog');
    }

    //Is Catch on?
    if(skl&1024 && skulls.indexOf('Catch')==-1) {
        skulls.push('Catch');
    }

    //Is ToughLuck on?
    if(skl&512 && skulls.indexOf('ToughLuck')==-1) {
        skulls.push('ToughLuck');
    }

    //Is BlackEye on?
    if(skl&256 && skulls.indexOf('BlackEye')==-1) {
        skulls.push('BlackEye');
    }

    //Is Iron on?
    if(skl&128 && skulls.indexOf('Iron')==-1) {
        skulls.push('Iron');
    }

    //Is IWHBYD on?
    if(skl&16 && skulls.indexOf('IWHBYD')==-1) {
        skulls.push('IWHBYD');
    }

    //Is GruntBirthdayParty on?
    if(skl&8 && skulls.indexOf('GruntBirthdayParty')==-1) {
        skulls.push('GruntBirthdayParty');
    }

    //Is Cowbell on?
    if(skl&4 && skulls.indexOf('Cowbell')==-1) {
        skulls.push('Cowbell');
    }

    //Is Blind on?
    if(skl&2 && skulls.indexOf('Blind')==-1) {
        skulls.push('Blind');
    }
}

 

For more information about how HSA: DE works have a look at the article on my portfolio website.

Posted in: Articles |