Skip to content

Commit

Permalink
Merge pull request #1 from Silver-Ore-Team/wip
Browse files Browse the repository at this point in the history
Working Multilogue system
  • Loading branch information
muczc1wek authored Sep 16, 2024
2 parents 013519d + e1457d9 commit 0157284
Show file tree
Hide file tree
Showing 9 changed files with 416 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# zMultilogue
Multi-NPC dialogue system for Gothic,
based on the solution form [AFSP Trialogue package](https://github.com/Bad-Scientists/AF-Script-Packet/blob/main/Standalone-Packages/G12-Trialogue/trialogue.d).
38 changes: 38 additions & 0 deletions _externals/zMultilogue.d
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/// Invites Npc to the Multilogue
///
/// @param slf Npc to invite
func void zMul_Invite(var C_NPC slf) {};

/// Starts the Multilogue
func void zMul_Start() {};

/// Changes talking NPC
///
/// @param slf Next talking NPC
func void zMul_Next(var C_NPC slf) {};

/// Finishes the Multilogue
func void zMul_Finish() {};

/// Makes invited NPC's wait for `slf` and each other
///
/// @param slf NPC to wait for
func void zMul_Wait(var C_NPC slf) {};


/*
* To Include:
*/
func void ZS_MULTILOGUE() {
};

func int ZS_MULTILOGUE_Loop() {
if (InfoManager_hasFinished()) {
return LOOP_END;
} else {
return LOOP_CONTINUE;
};
};

func void ZS_MULTILOGUE_End() {
};
43 changes: 43 additions & 0 deletions src/Gothic/Externals.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
namespace GOTHIC_NAMESPACE {

int zMul_Invite() {
zCParser* par = zCParser::GetParser();
oCNpc* npc = reinterpret_cast<oCNpc*>(par->GetInstance());
zMultilogue.AddNpc(npc);
return 0;
};

int zMul_Start() {
zMultilogue.Start();
return 0;
};

int zMul_Finish() {
zMultilogue.Finish();
return 0;
};

int zMul_Next() {
zCParser* par = zCParser::GetParser();
oCNpc* npc = reinterpret_cast<oCNpc*>(par->GetInstance());
zMultilogue.MakeSelf(npc);
return 0;
};

int zMul_Wait() {
zCParser* par = zCParser::GetParser();
oCNpc* npc = reinterpret_cast<oCNpc*>(par->GetInstance());
zMultilogue.Wait(npc);
return 0;
};


void DefineExternals()
{
parser->DefineExternal("ZMul_Invite", zMul_Invite, zPAR_TYPE_VOID, zPAR_TYPE_INSTANCE, zPAR_TYPE_VOID);
parser->DefineExternal("ZMul_Start", zMul_Start, zPAR_TYPE_VOID, zPAR_TYPE_VOID);
parser->DefineExternal("ZMul_Finish", zMul_Finish, zPAR_TYPE_VOID, zPAR_TYPE_VOID);
parser->DefineExternal("ZMul_Next", zMul_Next, zPAR_TYPE_VOID, zPAR_TYPE_INSTANCE, zPAR_TYPE_VOID);
parser->DefineExternal("ZMul_Wait", zMul_Wait, zPAR_TYPE_VOID, zPAR_TYPE_INSTANCE, zPAR_TYPE_VOID);
}
}
47 changes: 47 additions & 0 deletions src/Gothic/Hooks.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
namespace GOTHIC_NAMESPACE {
// G1: 0x006495B0 private: void __thiscall oCGame::DefineExternals_Ulfi(class zCParser *)
// G1A: 0x006715F0 private: void __thiscall oCGame::DefineExternals_Ulfi(class zCParser *)
// G2: 0x00677A00 private: void __thiscall oCGame::DefineExternals_Ulfi(class zCParser *)
// G2A: 0x006D4780 private: void __thiscall oCGame::DefineExternals_Ulfi(class zCParser *)
void* oCGame_DefineExternals_Ulfi = reinterpret_cast<void*>(zSwitch(0x006495B0, 0x006715F0, 0x00677A00, 0x006D4780));
void __fastcall DefineExternals_Ulfi_PartialHook(Union::Registers& reg)
{
DefineExternals();
}
auto Partial_DefineExternals_Ulfi = Union::CreatePartialHook(oCGame_DefineExternals_Ulfi, &DefineExternals_Ulfi_PartialHook);


// G2A: 0x00758130 public: int __thiscall oCNpc::ActivateDialogCam(float)
// auto Ivk_oCNpc_ActivateDialogCam = Union::CreateHook(reinterpret_cast<void*>(0x00758130), &oCNpc::ActivateDialogCam_Hook);
// int oCNpc::ActivateDialogCam_Hook(float p1)
// {
// if (zMultilogue) {
// if (zMultilogue->IsRunning()) {
// oCNpc* target = zMultilogue->GetCameraAdapter()->GetTarget();
// if (target) {
// this->talkOther = target;
// }
// }
// }
// return (this->*Ivk_oCNpc_ActivateDialogCam)(p1);
// }

auto Ivk_oCNpc_EV_Exchange = Union::CreateHook(reinterpret_cast<void*>(0x00753E30), &oCNpc::EV_Exchange_Hook);
int oCNpc::EV_Exchange_Hook( oCMsgManipulate* csg ) {
zSTRING slot = csg->slot;
if(slot) {
if (slot.Upper() == "EV_FINISH") {
zMultilogue.EV_Finish();
return TRUE;
}
if (slot.Upper() == "EV_NEXT") {
zMultilogue.EV_Next(csg->flag);
return TRUE;
}

}
return (this->*Ivk_oCNpc_EV_Exchange)(csg);
}


}
16 changes: 16 additions & 0 deletions src/Gothic/zMul_Camera.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@

namespace GOTHIC_NAMESPACE {
class zCMultilogueCameraAdapter
{
private:
oCNpc* m_Target = nullptr;
public:
void SetTarget(oCNpc* npc);
oCNpc* GetTarget() const { return m_Target; }
};

inline void zCMultilogueCameraAdapter::SetTarget(oCNpc* npc)
{
m_Target = npc;
}
}
57 changes: 57 additions & 0 deletions src/Gothic/zMul_Helper.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
namespace GOTHIC_NAMESPACE
{
oCNpc* GetSelfInstance()
{
static NH::Logger* log = NH::CreateLogger("GetSelfInstance");
zCPar_Symbol* sym = parser->GetSymbol("SELF");
if (sym) {
oCNpc* self = dynamic_cast<oCNpc*>((zCVob*)sym->GetInstanceAdr());
if (self) {
return self;
}
log->Error("Failed to cast SELF to oCNpc.");
return nullptr;
}
log->Error("Symbol SELF not found.");
return nullptr;
}

bool Npc_IsInActiveVoblist(oCNpc* npc) {
if (npc) {
for (int i = 0; i < ogame->GetWorld()->activeVobList.numInArray; i++) {
if (npc == dynamic_cast<oCNpc*>(ogame->GetWorld()->activeVobList[i])) {
return true;
}
}
return false;
}
return false;
}

void AI_WaitTillEnd(oCNpc* self, oCNpc* other)
{
if (self && other) {
oCMsgConversation* msg = zNEW(oCMsgConversation)(oCMsgConversation::EV_WAITTILLEND,other);
int nr = other -> GetEM()->GetNumMessages();
zCEventMessage* watch = nullptr;
for (int i = nr - 1; i >= 0; i--) {
watch = other->GetEM()->GetEventMessage(i);
if (!watch->IsOverlay()) {
msg->watchMsg = watch;
break;
}
}
self->GetEM()->OnMessage(msg, self);
}
}


void Npc_FakeTalkState(oCNpc* npc) {
if (npc) {
npc->state.curState.valid = 1;
npc->state.curState.index = parser->GetIndex("ZS_TALK");
npc->state.curState.name = parser->GetSymbol("ZS_TALK")->name;
}
}

};
Loading

0 comments on commit 0157284

Please sign in to comment.