GothicKit / ZenKit

A re-implementation of file formats used by the early 2000's ZenGin
http://zk.gothickit.dev/
MIT License
47 stars 10 forks source link

`npc_type` mismatch between G1 and G2 #67

Closed thokkat closed 1 year ago

thokkat commented 1 year ago

npc_type enum has the Gothic 2 types. Gothic 1 uses a different mapping taken from script file AI_Constants.d:

const int NPCTYPE_AMBIENT       = 0;    //Amient-Nscs In Den Lagern
const int NPCTYPE_MAIN          = 1;
const int NPCTYPE_GUARD         = 2;
const int NPCTYPE_FRIEND        = 3;
const int NPCTYPE_MINE_AMBIENT      = 4;
const int NPCTYPE_MINE_GUARD        = 5;
const int NPCTYPE_OW_AMBIENT        = 6;
const int NPCTYPE_OW_GUARD      = 7;
const int NPCTYPE_ROGUE         = 8;    //Npcs im Banditenlager

This causes some conflicts like non attacking orcs in OpenGothic because currently G1's NPCTYPE_GUARD is mapped to friend_.

lmichaelis commented 1 year ago

Thanks for reporting :) Looks like the proper solution would be to grab the correct value from within the script but in phoenix I'll see what I can do. I have the following solution in mind:


template <game_version ver>
class npc_type;

template <>
class npc_type<game_version::gothic_1> {
    static constexpr uint8_t ambient = 0U;
    static constexpr uint8_t main = 1U;
    static constexpr uint8_t guard = 2U;
    static constexpr uint8_t friend_ = 3U;
    static constexpr uint8_t mine_ambient = 4U;
    static constexpr uint8_t mine_guard = 5U;
    static constexpr uint8_t ow_ambient = 6U;
    static constexpr uint8_t ow_guard = 7U;
    static constexpr uint8_t rogue = 8U;
}

template <>
class npc_type<game_version::gothic_2> {
    static constexpr uint8_t ambient = 0U;
    static constexpr uint8_t main = 1U;
    static constexpr uint8_t friend_ = 2U;
    static constexpr uint8_t oc_ambient = 3U;
    static constexpr uint8_t oc_main = 4U;
    static constexpr uint8_t bl_ambient = 5U;
    static constexpr uint8_t tal_ambient = 6U;
    static constexpr uint8_t bl_main = 7U;
}

What do you think?

thokkat commented 1 year ago

Looks like the proper solution would be to grab the correct value from within the script but in phoenix I'll see what I can do.

Actually I only saw the enum located in phoenix and just assumed it's a phoenix issue. Let's hear what @Try is thinking.

Try commented 1 year ago

Global constants, like (NPCTYPE_AMBIENT) in game scripts are generally assumed to be non-configurable constants in OpenGothic and original game likely works same way.

class npc_type What do you think?

Then declaration of c_npc::type will become tricky. Maybe it's better to introduce extra values to existing enum?


enum class npc_type : std::uint32_t {
    ambient = 0U,
    main = 1U,
    g2_friend = 2U,
    g1_guard  = 2U,
    ...
    };
``
lmichaelis commented 1 year ago

Hey @thokkat, sorry for the long delay. I've pushed a fix now. Can you confirm that it works as required?

thokkat commented 1 year ago

Works.

Is it possible to keep main and ambient without prefix? In OpenGothic there's variable definition

  const bool isMainNpc = (npcType==phoenix::npc_type::g2_main ||
                         (g2 && (npcType==phoenix::npc_type::g2_oc_main || npcType==phoenix::npc_type::g2_bl_main)));

and it looks a bit cumbersome that all used types have a g2 prefix but g2_main is not checked for game version.