ethanmoffat / EndlessClient

An open source client for Endless Online written in C#
MIT License
34 stars 16 forks source link

Make Character/NPC rendering authentic #216

Closed ethanmoffat closed 10 months ago

ethanmoffat commented 2 years ago

Right now, various methods/"enhancements" are used to make character equipment and NPC rendering work "well enough". Instead, EndlessClient should start by emulating the vanilla client's default hard-coded behavior, but allow for overrides via metadata.

Examples of this include:

Instead of trying to improve on this behavior by default, EndlessClient should properly emulate the behavior from the vanilla client which is usually hard-coded based on gfx or npc ID, and load additional metadata for overriding this behavior from the EGF files.

The idea is to add an RCDATA entry with a well-known name (e.g. METADATA) with the contents set to a well-defined JSON format, and load that alongside the EGF files. This would be completely ignored by the vanilla client, but a custom client could make enhancements based on what is specified in this metadata file much more easily than the currently required hex editing process.

Something like the following could be added to INativeGraphicsManager:

MetadataFromResource<TMetadata>(GFXTypes file, int graphic);

Where TMetaData is the model type of the JSON object (this is easily mapped using Newtonsoft).

Using a generic metadata model type would allow different types based on the file being loaded, which would be convenient for properties that don't make sense between different gfx files.

Improvements to PELoaderLib also required since loading RCData is currently not supported.

ethanmoffat commented 1 year ago

Default NPC rendering offsets here: https://docs.google.com/spreadsheets/d/1GMo3c2xcPW5Uv3pOsaIS2EwtVA_N0Qfwo9TCTDibUoI/edit#gid=0

ethanmoffat commented 1 year ago

Effect metadata available here: https://docs.google.com/spreadsheets/d/1DQgN4r2cH6HA2ydn4M6CpUJlClWXXBemosYP57k_o5I/edit#gid=0

ethanmoffat commented 10 months ago

Shield metadata is a hard-coded branch:

shield_gfxid = player->shield_sprite;
if ( shield_gfxid == 10
  || shield_gfxid == 11
  || shield_gfxid == 14
  || shield_gfxid == 15
  || shield_gfxid == 16
  || shield_gfxid == 18
  || shield_gfxid == 19 )
{
  is_back_slot_item = 1;
}
ethanmoffat commented 10 months ago

Hat metadata is a couple hard-coded branches:

if ( player->hat_sprite >= 7 && player->hat_sprite <= 15 )
  is_under_hair_hat = 1;
if ( player->hat_sprite == 32 || player->hat_sprite == 33 || player->hat_sprite == 48 || player->hat_sprite == 50 )
  is_under_hair_hat = 1;
if ( player->hat_sprite >= 16 && player->hat_sprite <= 21 )
  is_bald_hat = 1;
hat_gfxid = player->hat_sprite;
if ( hat_gfxid == 25
  || hat_gfxid == 26
  || hat_gfxid == 28
  || hat_gfxid == 30
  || hat_gfxid == 31
  || hat_gfxid == 34
  || hat_gfxid == 35
  || hat_gfxid == 36
  || hat_gfxid == 37
  || hat_gfxid == 38
  || hat_gfxid == 40
  || hat_gfxid == 41
  || hat_gfxid == 44
  || hat_gfxid == 46
  || hat_gfxid == 47 )
{
  is_bald_hat = 1;
}

Source for this and last comment: https://gist.github.com/tehsausage/2d9e56cb34519ceac54f385bd5f15558