Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - JWP

Pages: 1 2 3 4 [5] 6 7 8
101
FF8 Tools / Re: [FF8] Enemy editor - IFRIT (0.11)
« on: 2016-06-29 22:11:51 »
Ifrit numbers are decimal, the list I linked uses hexadecimal.
So:
38 -> 0x26 -> Blind
39 -> 0x27 -> Confuse
46 -> 0x2E -> Berserk
36 -> 0x24 -> Slow
41 -> 0x29 -> Silence

102
FF8 Tools / Re: [FF8] Enemy editor - IFRIT (0.11)
« on: 2016-06-29 21:34:39 »
I think you're misunderstanding slightly, the drop-down with Magic, Custom and Item in it has an affect on which list the ability number refers to.
Custom attacks 2 and 66 are a physical attack and sticky icky, the rest of the abilities are just standard magic.
So there are several lists that can be confusing.
There's a magic ID list (see here), which governs what attack animation to use, this is used indirectly by all the other lists - you don't use these directly in Ifrit.
There's an enemy attack list (see here), which is all the moves that are marked as "custom" in Ifrit.
There's an item list and a magic list (see here), which are for items and magic respectively.

103
wherecard and setcard are the operations you'll probably need, see the director0 script in eapod1 in Deling for examples. You might be able to edit init.out to change the initial owner too (or this might also be in field scripts, I'm not sure).
There's also a bunch of scripts when the card queen makes new cards, see queen_dol talk script in dopub_2 or the scripts in bcsta_1 for an example.

104
Scripting and Reverse Engineering / Re: FF8 ID item's list
« on: 2016-06-28 21:45:12 »
The items in order of ID are (just ignore the descriptions):
not sure if there's a cleaner list somewhere with the IDs

Potion
<$>= HP by 200
Potion+
<$>= HP by 400
Hi-Potion
<$>= HP by 1000
Hi-Potion+
<$>= HP by 2000
X-Potion
Fully <$>= HP
Mega-Potion
<$>= HP by 1000 to all members
Phoenix Down
Removes KO <$>*
Mega Phoenix
Removes KO <$>* from all members
Elixir
Fully restores abnormal status and HP
Megalixir
Fully restores abnormal status and HP to all
Antidote
Cures Poison
Soft
Cures Petrify
Eye Drops
Cures Darkness
Echo Screen
Cures Silence
Holy Water
Cures Zombie, Curse
Remedy
Cures abnormal <$>*
Remedy+
Cures abnormal <$>* and <$>[jap"] effects
Hero-trial
Makes character invincible sometimes
Hero
Makes character invincible
Holy War-trial
Makes all party members invincible sometimes
Holy War
Makes all party members invincible
Shell Stone
Same effect as Shell
Protect Stone
Same effect as Protect
Aura Stone
Same effect as Aura
Death Stone
Same effect as Death
Holy Stone
Same effect as Holy
Flare Stone
Same effect as Flare
Meteor Stone
Same effect as Meteor
Ultima Stone
Same effect as Ultima
Gysahl Greens
Chocobo related...?
Phoenix Pinion
When used in battle...
Friendship
When used in battle...
Tent
Fully restores abnormal status and HP to all
Pet House
<$>= HP to all GF
Cottage
Same effect as Tent plus restores all GF
G-Potion
<$>= 200 HP to GF
G-Hi-Potion
<$>= 1000 HP to GF
G-Mega-Potion
<$>= 1000 HP to all GF
G-Returner
Revives GF from KO
Rename Card
Changes GF`s name
Amnesia Greens
Makes GF forget an <$>[jap "]
HP-J Scroll
GF <$>& HP-J <$>[jap "]
Str-J Scroll
GF <$>&Str-J <$>[jap "]
Vit-J Scroll
GF <$>& Vit-J <$>[jap "]
Mag-J Scroll
GF <$>& Mag-J <$>[jap "]
Spr-J Scroll
GF <$>&Spr-J <$>[jap "]
Spd-J Scroll
GF <$>&Spd-J <$>[jap "]
Luck-J Scroll
GF <$>& Luck-J <$>[jap "]
Aegis Amulet
GF <$>& Eva-J <$>[jap "]
Elem Atk
GF <$>& Elem-Atk-J <$>[jap "]
Elem Guard
GF <$>& Elem-Defx4 <$>[jap "]
Status Atk
GF <$>&ST-Atk-J <$>[jap "]
Status Guard
GF <$>&ST-Defx4 <$>[jap "]
Rosetta Stone
GF <$>& <$>[jap "]x4 <$>[jap "]
Magic Scroll
GF <$>& <$>[jap"] <$>[jap "]
GF Scroll
GF <$>& GF <$>[jap "]
Draw Scroll
GF <$>& Draw <$>[jap "]
Item Scroll
GF <$>& Item <$>[jap "]
Gambler Spirit
GF <$>& Card <$>[jap "]
Healing Ring
GF <$>& Recover <$>[jap "]
Phoenix Spirit
GF <$>& Revive <$>[jap "]
Med Kit
GF <$>& Treatment <$>[jap "]
Bomb Spirit
GF <$>& Kamikaze <$>[jap "]
Hungry Cookpot
GF <$>& Devour <$>[jap "]
Mog`s Amulet
GF <$>& MiniMog <$>[jap "]
Steel Pipe
GF <$>&SumMag+10% <$>[jap "]
Star Fragment
GF <$>&SumMag+20% <$>[jap "]
Energy Crystal
GF <$>&SumMag+30% <$>[jap "]
Samantha Soul
GF <$>&SumMag+40% <$>[jap "]
Healing Mail
GF <$>& GFHP+10% <$>[jap "]
Silver Mail
GF <$>& GFHP+20% <$>[jap "]
Gold Armor
GF <$>& GFHP+30% <$>[jap "]
Diamond Armor
GF <$>& GFHP+40% <$>[jap "]
Regen Ring
GF <$>& HP+20% <$>[jap "]
Giant`s Ring
GF <$>& HP+40% <$>[jap "]
Gaea`s Ring
GF <$>& HP+80% <$>[jap "]
Strength Love
GF <$>&Str+20% <$>[jap "]
Power Wrist
GF <$>&Str+40% <$>[jap "]
Hyper Wrist
GF <$>&Str+60% <$>[jap "]
Turtle Shell
GF <$>& Vit+20% <$>[jap "]
Orihalcon
GF <$>& Vit+40% <$>[jap "]
Adamantine
GF <$>& Vit+60% <$>[jap "]
Rune Armlet
GF <$>&Spr+20% <$>[jap "]
Force Armlet
GF <$>&Spr+40% <$>[jap "]
Magic Armlet
GF <$>&Spr+60% <$>[jap "]
Circlet
GF <$>& Mag+20% <$>[jap "]
Hypno Crown
GF <$>& Mag+40% <$>[jap "]
Royal Crown
GF <$>& Mag+60% <$>[jap "]
Jet Engine
GF <$>&Spd+20% <$>[jap "]
Rocket Engine
GF <$>&Spd+40% <$>[jap "]
Moon Curtain
GF <$>& Auto-Shell <$>[jap "]
Steel Curtain
GF <$>& Auto-Protect <$>[jap "]
Glow Curtain
GF <$>& Auto-Reflect <$>[jap "]
Accelerator
GF <$>& Auto-Haste <$>[jap "]
Monk`s Code
GF <$>& Counter <$>[jap "]
Knight`s Code
GF <$>& Cover <$>[jap "]
Doc`s Code
GF <$>& Med Data <$>[jap "]
Hundred Needles
GF <$>& Return Damage <$>[jap "]
Three Stars
GF <$>& Expendx3-1 <$>[jap "]
Ribbon
GF <$>& Ribbon <$>[jap "]
Normal Ammo
Normal Ammo
Shotgun Ammo
Ammo that attacks all opponents
Dark Ammo
Ammo with <$>* changing effect
Fire Ammo
Ammo with Fire element
Demolition Ammo
Ammo 3 times more powerful than Normal Ammo
Fast Ammo
Ammo for rapid fire
AP Ammo
Armor-piercing ammo
Pulse Ammo
Ammo that contains powerful energy
M-Stone Piece
Stone with a little <$>[jap"] power
Magic Stone
Stone with <$>[jap"] power
Wizard Stone
Stone with strong <$>[jap"] power
Ochu Tentacle
Strong, flexible tentacle
Healing Water
Water with life force
Cockatrice Pinion
Feather with petrifying power
Zombie Powder
Powder with Zombie effect
Lightweight
Shoes to make you light on your feet
Sharp Spike
Long, sharp claw
Screw
Use to remodel weapons
Saw Blade
Serrated blade
Mesmerize Blade
Long, sharp blade
Vampire Fang
Fang that makes Vampire attack
Fury Fragment
Stone that contains morale
Betrayal Sword
Sword that betrays allies
Sleep Powder
Induces sleep
Life Ring
Ring with life force
Dragon Fang
Dragon`s fang with recovery force
Spider Web
Quistis can learn Blue Magic, Ultra Waves
Coral Fragment
Quistis can learn Blue Magic, Electrocute
Curse Spike
Quistis can learn Blue Magic, LV?Death
Black Hole
Quistis can learn Blue Magic, Degenerator
Water Crystal
Quistis can learn Blue Magic, Aqua Breath
Missile
Quistis can learn Blue Magic, Micro Missiles
Mystery Fluid
Quistis can learn Blue Magic, Acid
Running Fire
Quistis can learn Blue Magic, Gatling Gun
Inferno Fang
Quistis can learn Blue Magic, Fire Breath
Malboro Tentacle
Quistis can learn Blue Magic, Bad Breath
Whisper
Quistis can learn Blue Magic, White Wind
Laser Cannon
Quistis can learn Blue Magic, Homing Laser
Barrier
Quistis can learn Blue Magic, Mighty Guard
Power Generator
Quistis can learn Blue Magic, Ray-Bomb
Dark Matter
Quistis can learn Blue Magic,Shockwave Pulsar
Bomb Fragment
Stone with Fire element
Red Fang
Dragon`s fang with Fire element
Arctic Wind
Contains Ice element wind
North Wind
Contains strong Ice element wind
Dynamo Stone
Stone with Thunder element
Shear Feather
Bird`s feather that flies on wind
Venom Fang
Poisonous monster fang
Steel Orb
Steel orb with gravitational power
Moon Stone
Holy moon stone with monsters living inside
Dino Bone
Large dinosaur bone
Windmill
Windmill containing wind energy
Dragon Skin
Durable dragon skin
Fish Fin
Fish`s fin
Dragon Fin
Very hard dragon`s scale
Silence Powder
Powder containingSilence
Poison Powder
Powder containing Poison
Dead Spirit
Contains Death
Chef`s Knife
Tonberry`s knife
Cactus Thorn
Cactuar`s thorn
Shaman Stone
Stone with mystical power
Fuel
Fuel for a rental car
Girl Next Door
Naughty <$>,
Sorceress` Letter
Edea`s introduction letter
Chocobo`s Tag
Changes Chocobo`s name
Pet Nametag
Changes pet`s name
Solomon Ring
Mysterious old ring
Magical Lamp
You shouldSave your game before using it!
HP Up
<$>[' in midd HP
Str Up
<$>[' in middStrength
Vit Up
<$>[' in midd Vitality
Mag Up
<$>[' in midd <$>[jap"]
Spr Up
<$>[' in middSpirit
Spd Up
<$>[' in middSpeed
Luck Up
<$>[' in midd Luck
LuvLuv G
<$>[' in midd compatibility with all GF
Weapons Mon 1st
Weapons research <$>,
Weapons Mon Mar
Weapons research <$>,
Weapons Mon Apr
Weapons research <$>,
Weapons Mon May
Weapons research <$>,
Weapons Mon Jun
Weapons research <$>,
Weapons Mon Jul
Weapons research <$>,
Weapons Mon Aug
Weapons research <$>,
Combat King 001
<$>, for fighters
Combat King 002
<$>, for fighters
Combat King 003
<$>, for fighters
Combat King 004
<$>, for fighters
Combat King 005
<$>, for fighters
Pet Pals Vol.1
<$>, for dog lovers
Pet Pals Vol.2
<$>, for dog lovers
Pet Pals Vol.3
<$>, for dog lovers
Pet Pals Vol.4
<$>, for dog lovers
Pet Pals Vol.5
<$>, for dog lovers
Pet Pals Vol.6
<$>, for dog lovers
Occult Fan I
World`s Mysteries <$>, Scoop Issue
Occult Fan II
World`s Mysteries <$>,  Photo Issue
Occult Fan III
World`s Mysteries <$>,  <$>[jap"] Issue
Occult Fan IV
World`s Mysteries <$>,  Report Issue

105
Scripting and Reverse Engineering / Re: FF8 ID item's list
« on: 2016-06-28 21:20:55 »
There's a list in this post

106
FF8 Tools / Re: [FF8] Enemy editor - IFRIT (0.11)
« on: 2016-06-25 18:13:29 »
It is possible to do if you check each character individually - although I haven't implemented this test yet.
There might be another way since there are other options to that specific test that I haven't worked out what they do.

107
I think due to the attack type for Squall's weapon being different from other weapons (10 instead of 1, I think), the damage formula for that attack type might ignore hit (I can't actually check right now). Changing the attack type to the same as the other weapons might fix that.
I think the gunblade trigger only determines if it crits or not.

108
FF8 Tools / Re: [FF8] Enemy editor - IFRIT (0.11)
« on: 2016-06-25 16:24:54 »
Ah yes, I see what you mean now.
I could look at adding this sort of option in the future :).

109
FF8 Tools / Re: [FF8] Enemy editor - IFRIT (0.11)
« on: 2016-06-25 03:22:51 »
If you're trying to target non-berserk enemies, it should be more like:
Code: [Select]
if (rand() % 3 == 0) {
    return
}
if (self.status == CONFUSION) {
    target(207)
    domoveid(0)
    return
}
if (enemy.status != BERSERK) {
    targetadv(0, 200, 3, 5)
    domoveid(1)
    return
}
target(201)
domoveid(0)

but I'm not sure if that still crashes the game or not, I'll need to do a bit more digging into the code but I'm running an event this weekend, so it probably won't be until Monday evening.

110
FF8 Tools / Re: [FF8] Enemy editor - IFRIT (0.11)
« on: 2016-06-22 21:40:32 »
What happens when you use the standard version of Ifrit?
Bear in mind it stores some stuff in the registry (HKEY_CURRENT_USER\SOFTWARE\Ifrit) that's used in both versions and I've only tested the new version with folder opening.

I'm going to guess that error is a null reference exception of some sort due to it not being able to open the requested file.
Have you moved the file you last had open in Ifrit - or was the last file you had open one the 3 files that the new version doesn't deal with well?

111
FF8 Tools / Re: [FF8] Enemy editor - IFRIT (0.11)
« on: 2016-06-21 23:40:09 »
Very early beta can be found here.
A list of functions can be found here.
In theory the AI editing stuff should mostly work now aside from 3 files that can't be opened (Dummy, Tri-point and one of the Ultimecia ones) and Unknown tests (in if statements) can't currently be compiled but unknown functions as part of statements can. If all the words are highlighted, it should compile.
Editing text section currently does nothing and only displays "." instead of characters.
I have no idea if it works in-game or actually patches the offsets correctly, I've not had a chance to thoroughly test it yet.

EDIT: here is a list of constants, the text value can be used in tests but only the numeric converted to decimal can be used in functions at the moment:
characters:
            SQUALL = 0x00,
            ZELL = 0x01,
            IRVINE = 0x02,
            QUISTIS = 0x03,
            RINOA = 0x04,
            SELPHIE = 0x05,
            SEIFER = 0x06,
            EDEA = 0x07,
            SELF = 0xC8,
            RANDOM_ENEMY = 0xC9,
            LAST_ATTACKER = 0xCB,
            ALL_ENEMIES = 0xCC,
            ALL_ALLIES = 0xCD,
            RANDOM_ALLY = 0xCF
statuses:
            DEAD = 0x00,
            POISON = 0x01,
            PETRIFY = 0x02,
            BLIND = 0x03,
            SILENCE = 0x04,
            BERSERK = 0x05,
            ZOMBIE = 0x06,
            SLEEP = 0x10,
            HASTE = 0x11,
            SLOW = 0x12,
            STOP = 0x13,
            REGEN = 0x14,
            PROTECT = 0x15,
            SHELL = 0x16,
            REFLECT = 0x17,
            AURA = 0x18,
            CURSE = 0x19,
            DOOM = 0x1A,
            INVINCIBLE = 0x1B,
            PETRIFYING = 0x1C,
            FLOAT = 0x1D,
            CONFUSION = 0x1E,
            DRAIN = 0x1F,
            EJECT = 0x20,
            DOUBLE = 0x21,
            TRIPLE = 0x22,
            DEFEND = 0x23,
            CHARGED = 0x26,
            BACK_ATTACKED = 0x27,
            VIT0 = 0x28,
            ANGEL_WING = 0x29,
            HASMAGIC = 0x2E,
            SUMMONING = 0x2F

List of tests:
battle
enemy.alive
enemy.status
self.varXX - XX = DC-E3
battle.varXX - XX = 60-67
save.varXX - XX = 50-57
rand() % X
self.status
self.hp
character.alive
monster(X).hp
difficulty
timer
gfstolen

I'm pretty sure that 0x0A followed by 0x00 is last attack type but I haven't coded it yet (0x0A tests 6 different bytes, I think 0x01 is character ID of last attacker and 0x02 is turn count)

random_npc's information on the AI stuff might also be useful, see here and here

EDIT2: updated link with a version that fixes file shrinking issues

112
FF8 Tools / Re: [FF8] Enemy editor - IFRIT (0.11)
« on: 2016-06-21 01:26:43 »
I'll see what I can do about releasing a beta later today.

113
Gameplay / Re: FF VIII: How to modify damage formulas?
« on: 2016-06-20 00:03:31 »
Surely the damage boost wouldn't apply for one of the monsters in the Granaldo boss battle in that case?
Since you'd have IDs up to 6 with 4 monsters and the less than check would fail for the monster with ID 6.

114
FF8 Tools / Re: [FF8] Enemy editor - IFRIT (0.11)
« on: 2016-06-19 01:40:10 »
Ah ok :).
I wasn't going to commit it for a while anyway, I've still got a lot of kinks to iron out, I was just trying to figure out what I was going to do with it in the end :).

115
FF8 Tools / Re: [FF8] Enemy editor - IFRIT (0.11)
« on: 2016-06-19 00:58:25 »
Ok, I'll spend a bit of time tidying the code up and adding more error checking and then I'll commit it :).
One question, would I need to be added to a list in order to be able to commit to the repo?
Also would you want to me add it as a branch instead of commiting master? - mainly since it requires .NET 4.5 instead of .NET 2.0 the current version requires

116
FF8 Tools / Re: [FF8] Enemy editor - IFRIT (0.11)
« on: 2016-06-18 19:40:05 »
I've been working on an AI editor recently and it can currently decompile bytecode into a C-like syntax and compile back into AI byte code.
I've been using Ifrit to develop it because it was a convenient way to access the dat files without much effort.
I was wondering if you wanted to include it in an Ifrit release, if not I'll probably pull the AI editing stuff out and make a standalone tool.

The major changes aside from the AI stuff is that Ifrit now targets .NET Framework 4.5 and would require the ANTLR and ScintillaNET runtime files.

117
Changing the rand syntax is a 2 second job, boolean expressions I'd definitely leave until a later release.
I did realize that I could make it a lot easier by encoding metadata using useless/illegal opcodes though since the game pretty much ignores them.

118
Heh, alex asked me the same question a week or so ago. I tried to find out and I could see the mwepon.bin file being loaded into memory but for some reason I couldn't get a memory breakpoint on the price byte to trigger which makes it pretty hard to track down.
I kinda wish I wasn't using the Steam version in cases like these >_>.

119
Yes, all of the probabilities can be changed, they are currently in the form of something like:
Code: [Select]
...
if (rand() % 3 == 0) {
...

which means random number modulo 3 - this gives a random number between 0 and 2
and the test is == 0, which has a 1/3 chance of being triggered.

You can change both the numbers and the test: e.g.

Code: [Select]
...
if (rand() % 4 < 3) {
...

gives a 3/4 chance of the code being executed.
You could then combine it with other tests to make it more likely in certain circumstances.

Thinking about it, I could change the syntax to something like [0..2] to make it easier to understand.

you can test to see if you have a status too, so you can easily stop enemies from casting the same spell over and over.

I might put in boolean expressions at some point, the main problem being that decompiling boolean or statements back from the byte code seems like it'd be a pain.

120
I've been toying around with the AI code some more and I've added a working compiler for my pseudocode :D.
I can now make bytecode but I still haven't injected it into the dat files yet as I'd need to patch some offsets in.
In addition to this I've added if/else parsing to turn code like this:

Code: [Select]
self.varDC = 0
self.varDD = 0
self.varDE = 0
if (character.alive == 3) {
    movesay(1)
    if (character.alive == 0) {
        movesay(6)
    }
    else {
        if (character.alive == 1) {
            movesay(8)
        }
        else {
            if (character.alive == 5) {
                movesay(9)
            }
            else {
                if (character.alive == 2) {
                    movesay(10)
                }
                else {
                    if (character.alive == 4) {
                        movesay(11)
                    }
                }
            }
        }
    }
}
else {
    if (character.alive == 1) {
        movesay(2)
        if (character.alive == 0) {
            movesay(6)
        }
        else {
            if (character.alive == 3) {
                movesay(7)
            }
            else {
                if (character.alive == 5) {
                    movesay(9)
                }
                else {
                    if (character.alive == 2) {
                        movesay(10)
                    }
                    else {
                        if (character.alive == 4) {
                            movesay(11)
                        }
                    }
                }
            }
        }
    }
    else {
        if (character.alive == 5) {
            movesay(3)
            if (character.alive == 0) {
                movesay(6)
            }
            else {
                if (character.alive == 3) {
                    movesay(7)
                }
                else {
                    if (character.alive == 1) {
                        movesay(8)
                    }
                    else {
                        if (character.alive == 2) {
                            movesay(10)
                        }
                        else {
                            if (character.alive == 4) {
                                movesay(11)
                            }
                        }
                    }
                }
            }
        }
        else {
            if (character.alive == 2) {
                movesay(4)
                if (character.alive == 0) {
                    movesay(6)
                }
                else {
                    if (character.alive == 3) {
                        movesay(7)
                    }
                    else {
                        if (character.alive == 1) {
                            movesay(8)
                        }
                        else {
                            if (character.alive == 5) {
                                movesay(9)
                            }
                            else {
                                if (character.alive == 4) {
                                    movesay(11)
                                }
                            }
                        }
                    }
                }
            }
            else {
                if (character.alive == 0) {
                    movesay(0)
                    if (character.alive == 3) {
                        movesay(7)
                    }
                    else {
                        if (character.alive == 1) {
                            movesay(8)
                        }
                        else {
                            if (character.alive == 5) {
                                movesay(9)
                            }
                            else {
                                if (character.alive == 2) {
                                    movesay(10)
                                }
                                else {
                                    if (character.alive == 4) {
                                        movesay(11)
                                    }
                                }
                            }
                        }
                    }
                }
                else {
                    movesay(5)
                    if (character.alive == 0) {
                        movesay(6)
                    }
                    else {
                        if (character.alive == 3) {
                            movesay(7)
                        }
                        else {
                            if (character.alive == 1) {
                                movesay(8)
                            }
                            else {
                                if (character.alive == 5) {
                                    movesay(9)
                                }
                                else {
                                    if (character.alive == 2) {
                                        movesay(10)
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
movesay(12)
movesay(13)
unknown1C(4)

into this:
Code: [Select]
self.varDC = 0
self.varDD = 0
self.varDE = 0
if (character.alive == 3) {
    movesay(1)
    if (character.alive == 0) {
        movesay(6)
    }
    else if (character.alive == 1) {
        movesay(8)
    }
    else if (character.alive == 5) {
        movesay(9)
    }
    else if (character.alive == 2) {
        movesay(10)
    }
    else if (character.alive == 4) {
        movesay(11)
    }
}
else if (character.alive == 1) {
    movesay(2)
    if (character.alive == 0) {
        movesay(6)
    }
    else if (character.alive == 3) {
        movesay(7)
    }
    else if (character.alive == 5) {
        movesay(9)
    }
    else if (character.alive == 2) {
        movesay(10)
    }
    else if (character.alive == 4) {
        movesay(11)
    }
}
else if (character.alive == 5) {
    movesay(3)
    if (character.alive == 0) {
        movesay(6)
    }
    else if (character.alive == 3) {
        movesay(7)
    }
    else if (character.alive == 1) {
        movesay(8)
    }
    else if (character.alive == 2) {
        movesay(10)
    }
    else if (character.alive == 4) {
        movesay(11)
    }
}
else if (character.alive == 2) {
    movesay(4)
    if (character.alive == 0) {
        movesay(6)
    }
    else if (character.alive == 3) {
        movesay(7)
    }
    else if (character.alive == 1) {
        movesay(8)
    }
    else if (character.alive == 5) {
        movesay(9)
    }
    else if (character.alive == 4) {
        movesay(11)
    }
}
else if (character.alive == 0) {
    movesay(0)
    if (character.alive == 3) {
        movesay(7)
    }
    else if (character.alive == 1) {
        movesay(8)
    }
    else if (character.alive == 5) {
        movesay(9)
    }
    else if (character.alive == 2) {
        movesay(10)
    }
    else if (character.alive == 4) {
        movesay(11)
    }
}
else {
    movesay(5)
    if (character.alive == 0) {
        movesay(6)
    }
    else if (character.alive == 3) {
        movesay(7)
    }
    else if (character.alive == 1) {
        movesay(8)
    }
    else if (character.alive == 5) {
        movesay(9)
    }
    else if (character.alive == 2) {
        movesay(10)
    }
}
movesay(12)
movesay(13)
unknown1C(4)

In addition to this, the editor now has better highlighting and line numbering due to the use of ScintillaNET.

I'm not really sure what to do with the tool though since it's tied into Ifrit at the moment.
I guess there's a few things I could do:
a) pull out the code and put it in a standalone application
b) speak to the person who wrote Ifrit and try to get it put into the main release
c) fork Ifrit (although I don't really want to do this one)

What do you guys think?

121
Most of the stuff relating to stores is in the menu.fi archive, while it's possible to edit this we only currently have plans for a kernel.bin editor.

122
Sure :)

Sorc1 init:
Code: [Select]
if (var60 != 0){
    var60 += 1
    if (var62 == 0){
        var62 = 1
    }
    else {
        var62 = 2
    }
    target(200)
    domove(1)
    if (var60 == 2){
        self.varDC = 2
    }
    if (var60 == 3){
        self.varDC = 3
    }
    if (var60 == 4){
        self.varDC = 4
    }
    if (var60 == 5){
        self.varDC = 5
    }
    if (var60 == 6){
        self.varDC = 6
    }
    if (var61 == 3){
        var61 = 0
        self.varDD = 3
    }
    else {
        var61 = 0
        self.varDD = 6
    }
}
else {
    var60 += 1
    var62 = 1
    var63 = 0
    self.varDC = 1
    self.varDD = 3
    target(200)
    domove(0)
}

Sorc1 turn:
Code: [Select]
if (var60 >= 10){
}
else {
    if (rand() % 2 == 0){
        if (var62 == 1){
            if (self.varDD == 3){
                if (var60 >= 6){
                    var61 = 4
                    unknown33()
                    launch(1)
                    return
                }
                else {
                    var61 = 6
                    unknown33()
                    launch(3)
                    return
                }
            }
            else {
                if (self.varDD == 6){
                    if (var60 >= 6){
                        var61 = 5
                        unknown33()
                        launch(2)
                        return
                    }
                    else {
                        var61 = 3
                        unknown33()
                        launch(0)
                        return
                    }
                }
            }
        }
    }
}
if (rand() % 3 == 0){
    return
}
if (rand() % 3 == 0){
    target(201)
    domove(3)
    return
}
if (self.varDC == 1){
    if (unknown(0x14) == 23){
        if (enemy.status == 23){
            targetadv(0, 201, 0, 23)
            domove(2)
            return
        }
        else {
            target(202)
            domove(5)
            return
        }
    }
    else {
        targetadv(0, 200, 3, 23)
        domove(2)
        return
    }
}
if (self.varDC == 2){
    if (enemies.alive == 1){
        if (unknown(0x14) == 23){
            target(201)
            domove(3)
            return
        }
    }
    else {
        target(201)
        domove(4)
        return
    }
}
if (self.varDC == 3){
    if (enemies.alive == 1){
        if (unknown(0x14) == 23){
            target(201)
            domove(3)
            return
        }
    }
    else {
        target(201)
        domove(8)
        return
    }
}
if (self.varDC == 4){
    if (unknown(0x14) == 23){
        if (enemy.status == 23){
            targetadv(0, 201, 0, 23)
            domove(9)
            return
        }
        else {
            target(202)
            domove(5)
            return
        }
    }
    else {
        target(201)
        domove(9)
        return
    }
}
if (self.varDC == 5){
    if (enemy.status == 4){
        targetadv(0, 201, 0, 4)
        domove(11)
        return
    }
    else {
        if (unknown(0x14) == 23){
            if (enemies.alive == 1){
                target(201)
                domove(3)
                return
            }
            else {
                target(201)
                domove(7)
                return
            }
        }
        else {
            target(201)
            domove(10)
            return
        }
    }
}
if (self.varDC == 6){
    if (unknown(0x14) == 23){
        if (enemies.alive == 1){
            target(201)
            domove(3)
            return
        }
        else {
            target(201)
            domove(7)
            return
        }
    }
    else {
        target(201)
        domove(15)
        return
    }
}

Sorc1 death:
Code: [Select]
if (var63 >= 9){
    die()
    unknown33()
    launch(4)
}
else {
    if (var62 == 1){
        var62 = 0
        var63 += 1
        die()
        if (self.varDD == 3){
            if (var60 >= 6){
                var61 = 4
                unknown33()
                launch(1)
            }
            else {
                var61 = 6
                unknown33()
                launch(3)
            }
        }
        else {
            if (self.varDD == 6){
                if (var60 >= 6){
                    var61 = 5
                    unknown33()
                    launch(2)
                }
                else {
                    var61 = 3
                    unknown33()
                    launch(0)
                }
            }
        }
    }
    else {
        var62 = 1
        var63 += 1
        die()
    }
}

-----------------------------------------------------------------------------------

Sorc2 init:
Code: [Select]
var60 += 1
if (var62 == 0){
    var62 = 1
}
else {
    var62 = 2
}
target(200)
domove(1)
if (var60 == 7){
    self.varDC = 7
}
if (var60 == 8){
    self.varDC = 8
}
if (var60 == 9){
    self.varDC = 9
}
if (var60 == 10){
    self.varDC = 10
}
if (var61 == 4){
    var61 = 0
    self.varDD = 4
}
else {
    var61 = 0
    self.varDD = 5
}

Sorc2 turn:
Code: [Select]
if (var60 >= 10){
}
else {
    if (rand() % 2 == 0){
        if (var62 == 1){
            if (self.varDD == 4){
                var61 = 5
                unknown33()
                launch(2)
                return
            }
            else {
                if (self.varDD == 5){
                    var61 = 4
                    unknown33()
                    launch(1)
                    return
                }
            }
        }
    }
}
if (rand() % 3 == 0){
    return
}
if (enemies.alive == 1){
    if (rand() % 3 == 0){
        target(201)
        choose(4, 3, 15)
        return
    }
    else {
        return
    }
}
if (rand() % 3 == 0){
    target(201)
    domove(4)
    return
}
if (self.varDC == 7){
    if (self.status != 23){
        if (self.status != 33){
            if (rand() % 2 == 0){
                target(200)
                domove(11)
                return
            }
        }
    }
    if (self.status == 33){
        target(201)
        domove(3)
        if (enemies.alive != 0){
            target(201)
            domove(3)
        }
    }
    else {
        target(201)
        domove(3)
    }
    return
}
if (self.varDC == 8){
    if (rand() % 2 == 0){
        target(204)
        domove(13)
        return
    }
    else {
        target(201)
        domove(12)
        return
    }
}
if (self.varDC == 9){
    target(208)
    domove(8)
    return
}
if (self.varDC == 10){
    if (self.status != 23){
        if (self.status != 33){
            if (rand() % 2 == 0){
                target(200)
                domove(11)
                return
            }
        }
    }
    if (self.status == 33){
        target(201)
        domove(7)
        if (enemies.alive != 0){
            target(201)
            domove(7)
        }
    }
    else {
        target(201)
        domove(7)
    }
    return
}

Sorc2 death:
Code: [Select]
if (var63 >= 9){
    die()
    unknown33()
    launch(4)
}
else {
    if (var62 == 1){
        var62 = 0
        var63 += 1
        die()
        if (self.varDD == 4){
            var61 = 5
            unknown33()
            launch(2)
            return
        }
        else {
            if (self.varDD == 5){
                var61 = 4
                unknown33()
                launch(1)
                return
            }
        }
    }
    else {
        var62 = 1
        var63 += 1
        die()
    }
}

-----------------------------------------------------------------------------------

Sorc3 init:
Code: [Select]
self.varDC = 0
self.varDD = 0
target(200)
domove(1)
target(200)
domove(3)

Sorc3 turn:
Code: [Select]
if (self.varDC != 0){
    return
}
self.varDD += 1
if (self.varDD == 3){
    unknown18(0)
    self.varDE = 1
    target(200)
    domove(4)
}
else {
    if (self.varDD == 4){
        unknown18(1)
    }
    else {
        if (self.varDD == 5){
            unknown18(2)
            self.varDE = 1
            target(200)
            domove(5)
        }
        else {
            if (self.varDD == 6){
                unknown18(3)
            }
            else {
                if (self.varDD == 7){
                    unknown18(4)
                    self.varDE = 1
                    target(200)
                    domove(6)
                }
                else {
                    if (self.varDD >= 8){
                        self.varDD = 0
                        target(204)
                        domove(2)
                        self.varDE = 1
                        target(200)
                        domove(3)
                    }
                }
            }
        }
    }
}

Sorc 3 counter:
Code: [Select]
if (self.varDE == 1){
    self.varDE = 0
}
else {
    if (self.varDD <= 2){
        target(203)
        domove(0)
    }
}

Sorc3 death:
Code: [Select]
if (self.varDC == 0){
    self.varDC = 1
    target(200)
    domove(7)
    remove(200)
}

Sorc3 unknown:
Code: [Select]
if (self.varDC == 0){
    if (self.status == 0){
        unknown09(3)
    }
}

I make no claims as to the accuracy of the above code :P - I know some of the if statements aren't very clear on their meaning and I haven't bothered fixing it yet.

123
I've been working quite a lot on Doomtrain but I also decided to take another look at the battle AI and coded a quick extension to Ifrit to help me view the AI data.

Here's a list of opcodes - the names are just ones that I'm using for the pseudo-code:
Code: [Select]
0x01 - say(arg1)
0x02 - if
0x03 - setmagic(arg1) - sets a magic spell to use - not used but this can be used with 0x06 to cast the magic
0x04 - target(arg1)
0x05 - unknown05(arg1) - Used by Elvoret
0x06 - domove() - not used in the game
0x07 - setenemyattack(arg1) - similar to 0x03 but uses 0x08 as the type flag
0x08 - die() - used a lot in death code to actually kill the entity (e.g. creeps, NORG Pod, Biggs, Wedge) - monsters that use this cannot be killed normally
0x09 - unknown09(arg1) - I think this sets a flag byte to the byte specified - used by Seifer, Raijin, Edea, Left/Right Orb, Fake President, Adel
0x0B - choose(arg1, arg2, arg3) - pick randomly between 3 moves
0x0C - domoveid(arg1) - does the specified move from the move list
0x0D - unused and appears to do nothing
0x0E - set self variable (vars are DC - E3)
0x0F - set global battle variable (vars are 60 - 67)
0x11 - set save variable (vars are 50-57 - these are stored in the save game file - tonberry count etc.)
0x12 - add to self variable
0x13 - add to battle variable
0x15 - add to save variable
0x16 - fillhp()
0x17 - cannotescape(arg1)
0x18 - unknown18(arg1) - appears to be another text print function - used by Tiamat, Wedge
0x19 - all this does is skip a byte, it's used in the init code for Biggs and Wedge but does nothing useful
0x1A - movesay(arg1)
0x1B - unknown1B(arg1, arg2) - used by Biggs
0x1C - unknown1C(arg1) - used by Fake President, BGH251F2, Mobile Type 8, Slapper, Biggs
0x1D - remove(arg1)
0x1E - magicid(arg1) - play specified magic id - used by Biggs, Wedge, Elvoret, G-soldier (for BGH251F2 battle)
0x1F - launch(arg1)
0x20 - similar to 0x1C but unused
0x22 - unknown and unused
0x23 - jump X bytes
0x24 - fillatb()
0x25 - scanadd(arg1)
0x26 - targetadv(arg1, arg2, arg3, arg4)
0x27 - autostatus(arg1, arg2)
0x28 - changestat(arg1, arg2)
0x29 - stealmagic() - steal random magic
0x2A - castmagic() - cast stolen magic
0x2B - targetposition(arg1)
0x2C - uknown2C() - kills the entity and does something? - used by Seifer, Elvoret?
0x2D - changeresistance(arg1, arg2)
0x2E - killmagic() - blow away random magic
0x2F - targetable() - not used
0x30 - untargetable() - makes current entity untargetable
0x31 - givegf(arg1)
0x32 - unknown32() - used by Sphinxaur, Griever, Trauma
0x33 - unknown33() - used by Sphinxara, Edea, Trauma, "Sorceress", Ultimecia
0x34 - unknown34(arg1) - used by Trauma
0x35 - unknown35(arg1) - used by Griever, Trauma
0x36 - gilgamesh() - disables Odin and enabled Gilgamesh
0x37 - givecard(arg1)
0x38 - giveitem(arg1)
0x39 - gameover()
0x3A - targetableid(arg1) - makes entity in slot X targetable
0x3B - unknown3B(arg1, arg2) - used by Ultimecia when spawning helixes and final form
0x3C - addhp(arg1)
0x3D - proofofomega()
note: opcodes 0x0A, 0x10, 0x14 and 0x21 don't exist.
Quite a few of the unknown codes might be related to spawning enemies, changing music or changing scene.

I might go into detail about some of the opcodes at another point.

124
Gameplay / Re: FF VIII: How to modify damage formulas?
« on: 2016-06-12 11:42:38 »
That is correct but I'm still not sure where it ends. You could just change it to something like 100 and it'd probably work.
Replacing the division (the "sar esi, 1" line) with NOPs would also work.

125
Gameplay / Re: FF VIII: How to modify damage formulas?
« on: 2016-06-12 11:25:04 »
The reason that happens is because he's changing the test on the battle id.
For player characters this is 0-2 and for monsters this is 3+. The way he's changed the test means that anything with an ID of 4+ still gets the damage divided - so any monster other than the first.
I would change 0x491CC7 to an unconditional jump (JMP).
This would be changing 0x491CC7 (or 0x91CC7 in the exe):

Code: [Select]
From: 7C
To:   EB

Pages: 1 2 3 4 [5] 6 7 8