[FE8] [C] Three Houses style pick-skills in PrepScreen

  • Prep-Pick-Skill-Screen:
    0
  • Add & remove skill:
    6
  • Replace skill if skill-list is already filled:
    5
  • Fail to add or remove ROM skill:
    4

Soure code at here.

Reference:


This reconstructs a set of c-SkillSystem (W.I.P.) based on FE-CHAX and Skill-Lite (thanks to @StanH ). It is welcome for you to fork or port it for your own skillsystem construction.


1

Update 2022.04.22
re-designed on UI so that

  1. Extend the maximum length of each line of skill desc text to avoid text overflow issues.
  2. Reduced the maximum number of icons in the interface to avoid icon overflow (the number of icons displayed at the same time should be less than 0x20)
45 Likes

updated to fix some bugs, also introduced parallel-worker to fasten the system.

3 Likes

Is this dependent on C-SkillSystem? Would this work with the SkillSystem Fe8u github?

1 Like

In fact, it is not that PrepSkillScreen is only suitable for cSkillSystem, but because the original SkillSystem is not capable of free equipment on skills, so I have to remade a new C-based skill-system in turn.

Free equipment on skills calls for a large Free-RAM-Spaces for each units to store skills list, where as far as I know the current asm-based SkillSystem doesn’t seem to fulfill this requirement.

To be honest, I agree more with thoughts on construction of SkillsLite by StanH,which is constructed based on decomp project and enjoys code quality and system stability. Ideas on build cSkillSystem is also based on that, where we move unit support list to BWL table and then occupy unit->supports[] table as units’ RAM skills list, you may take my reworked SkillTester for more details. This needs a thoroughly rework on SkillTester. However, considering that the SkillTester in current ASM based SkillSystem_FE8 has been extremely complex, I have no confidence whether anyone can make a rework on it. But once the vanilla SkillTester is able to give units a larger RAM Skills list, then I think there should not be too difficult to transplant such work on SkillSystem_FE8, since Proc:PrepSkillScreen is just designed as a child of “AtMenu”(if you have finish reading StanH’s DOC on PrepScreen, you will know its meaning). Maybe you just need to adjust on file PrepSkill-ListMisc.c.

Actually the entire PrepScreen proc was redone, including the At-Menu and Map view process. You can check here, it may help you to understand how it works on PrepScreen.

2 Likes

Yeah, I’d need to save a list of learned skills in ram of course. Thanks!

I may eventually write my own skill calc loop, because I don’t really like how convoluted the skill sys one is.

Summary

I would like to calc all the skills a unit has (including from items/equipment etc.) and save that in a buffer. Then, when calculating what battle effects should take place, I can use the index of each skill to get the effect. Eg. Effect of skill id 8 is +20 avoid. This way I don’t need to check if a unit has each of the 255 skills one by one.

3 Likes

Using SkillsGetter over a lot of SkillTester calls during common hook locations is something I’ve been meaning to bring up actually. I think it’s a good idea.

My recommondation is introducing two Temp-list for judgement, one for attacker, one for denfender. Like this:

enum{
	SKILL_FAST_LIST_LENGTH = 0x20,
};

struct SkillFastList{
	u8 unit_id;
	u8 len;
	u8 skills[SKILL_FAST_LIST_LENGTH];
}


extern struct SkillFastList *aFreeRAMSpace0, *aFreeRAMSpace1;




void MakeSkillFastList(struct Unit* unit, struct SkillFastList* list){
	
	extern int (*SkillTesterOld)(struct Unit* unit, const u8 skill_id);
	
	list->unit_id = unit->index;
	list->len = 0;
	
	for( int i = 1; i < 0xFF; i++)
	{
		if( 1 == (*SkillTesterOld)(unit, i) )
			list->skills[list->len++] = i;
		
		if( !(list->len < SKILL_FAST_LIST_LENGTH) )
			break;
	}
}


struct SkillFastList* GetSkillFastList(struct Unit* unit){
	
	struct SkillFastList* list; 
	
	if( &gBattleActor.unit == unit )
		list = aFreeRAMSpace0;
	else
		list = aFreeRAMSpace1;
	
	if( list->unit_id != unit->index )
		MakeSkillFastList(unit, list);
	
	return list;
	
}

Then make a new SkillTester based on these two Fast-List:

int JudgeSkillNew(struct Unit* unit, const u8 skill_id){
	
	struct SkillFastList* list;
	
	if( 0 == skill_id )
		return 1;
	
	if ( 0xFF == skill_id )
		return 0;
	
	
	list = GetSkillFastList(unit);
	
	for( int i = 0; i < list->len; i++ )
		if( skill_id == list->skills[i] )
			return 1;
	
	return 0;
}

and then define this new judgement routine as SkillTester in EA:

ALIGN 4
SkillTester:
	POIN JudgeSkillNew

aFreeRAMSpace0: WORD 0x2026E20
aFreeRAMSpace1: WORD 0x2026E50

I think the biggest advantage of doing this is that you no longer need to think about how to optimize the algorithm of SkillTesterOld itself. After all, you only need to build a list for the character once, and then all skills can be quickly judged.

1 Like

1

Update 2022.04.22
re-designed on UI so that:

  1. Extend the maximum length of each line of skill desc text to avoid text overflow issues.
  2. Reduced the maximum number of icons in the interface to avoid icon overflow (the number of icons displayed at the same time should be less than 0x20)
4 Likes