Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions Assets/Gothic-Core/Scripts/Models/Config/DeveloperConfig.cs
Original file line number Diff line number Diff line change
Expand Up @@ -177,6 +177,10 @@ public class DebugChannelTypesCollection : CollectionWrapper<DeveloperConfigEnum

[Tooltip("Enable player→NPC melee combat (hit detection, damage, hurt/death animations). WIP - debug damage values only.")]
public bool EnableCombatSystem;

[ConditionalField(fieldToCheck: nameof(EnableCombatSystem), compareValues: true)]
[Tooltip("Call B_DeathXP on kill to grant XP. WIP - XP values may be incorrect.")]
public bool EnableDeathXP;

[ConditionalField(fieldToCheck: nameof(EnableNpcs), compareValues: true)]
public bool EnableNpcMeshCulling = true;
Expand Down Expand Up @@ -291,5 +295,6 @@ public class DebugChannelTypesCollection : CollectionWrapper<DeveloperConfigEnum
public bool EnableDecalVisuals;
public bool EnableParticleEffects;


}
}
34 changes: 34 additions & 0 deletions Assets/Gothic-Core/Scripts/Services/Npc/FightService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ public class FightService
[Inject] private PhysicsService _physicsService;
[Inject] private NpcHelperService _npcHelperService;
[Inject] private readonly ConfigService _configService;
[Inject] private readonly Gothic.Core.Services.GameStateService _gameStateService;
[Inject] private readonly NpcService _npcService;

public void Init()
{
Expand All @@ -39,6 +41,8 @@ private void OnHit(NpcContainer attacker, NpcContainer target, Vector3 __)
Logger.Log($"[FightService.OnHit] {target.Instance.GetName(NpcNameSlot.Slot0)} is DEAD", LogCat.Npc);
target.Props.BodyState = VmGothicEnums.BodyState.BsDead;
OnDyingChangeAnimation(target);
if (_configService.Dev.EnableDeathXP)
OnNpcDied(target, attacker);
}
else
{
Expand Down Expand Up @@ -96,6 +100,36 @@ private bool OnHitUpdateHealth(NpcContainer attacker, NpcContainer target)
return hitPoints <= 0;
}

private void OnNpcDied(NpcContainer dead, NpcContainer killer)
{
var vm = _gameStateService.GothicVm;
var aivPlundered = vm.GetSymbolByName("AIV_PLUNDERED")?.GetInt(0) ?? 8;
dead.Instance.SetAiVar(aivPlundered, 0);

var oldSelf = vm.GlobalSelf;
var oldOther = vm.GlobalOther;
vm.GlobalSelf = dead.Instance;
vm.GlobalOther = killer.Instance;

if (_configService.Dev.EnableDeathXP && killer.PrefabProps.IsHero())
{
var bDeathXp = vm.GetSymbolByName("B_DeathXP");
if (bDeathXp != null)
{
vm.Call(bDeathXp.Index);
_npcService.SyncHeroInstanceToVob();
Logger.Log($"[FightService.OnNpcDied] B_DeathXP: {dead.Instance.GetName(NpcNameSlot.Slot0)} killed by hero", LogCat.Npc);
}
}

var bGiveDeathInv = vm.GetSymbolByName("B_GiveDeathInv");
if (bGiveDeathInv != null)
vm.Call(bGiveDeathInv.Index);

vm.GlobalSelf = oldSelf;
vm.GlobalOther = oldOther;
}

/// <summary>
/// C_ITEM.damageType is a DAM_* bitmask whose bit positions match the PROT_* indices.
/// Weapons carry one damage type; the first set bit wins.
Expand Down
9 changes: 9 additions & 0 deletions Assets/Gothic-Core/Scripts/Services/Npc/NpcService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,15 @@ public void ExtNpcChangeAttribute(NpcInstance npc, int attributeId, int value)
vob.Attributes[attributeId] = value;
}

public void SyncHeroInstanceToVob()
{
var hero = GetHeroContainer();
hero.Vob.Level = hero.Instance.Level;
hero.Vob.Xp = hero.Instance.Exp;
hero.Vob.XpNextLevel = hero.Instance.ExpNext;
hero.Vob.Lp = hero.Instance.Lp;
}

public NpcContainer GetHeroContainer()
{
return ((NpcInstance)_gameStateService.GothicVm.GlobalHero).GetUserData();
Expand Down