* SpecialCaseDeathPenalty restored to the engine ScenarioRole (SCNROLE.h/ .cpp) -- the 4.10-only role field the 2007 WinTesla source dropped (record slot [1] after KillBonus, fail-hard read; role+0x20; the DefaultRendererRate pattern). Its consumer decoded from the @004c05c4 export gap (@004c07cd, missing from the #52 reconstruction): every death with advancedDamageOn hands the ENGINE base ScoreMessageHandler (@0042da20 == PLAYER.cpp:138, a DIRECT call bypassing the BT type Verifies) a type-1 award of -penalty. Wired verbatim. Shipped content authors the key nowhere -> cost 0 in the field. NUANCE [T4]: the 1995 engine adds at Player+0x1c8, which no BT scoreboard reads (+0x278) -- the pod's cost may never have displayed; our single-cell port shows it. * The eject console notice: FUN_004c198c IS the ConsolePlayerMechDeathWithoutHonorMessage ctor (T0 BTCNSL.CPP survives and is compiled) -- "death without honor" is the punch-out record. BTPlayerEjectBookkeeping now sends it to the console host through the same ConsoleClientID path as the VTVDamaged notify, then latches suppressConsole: the eject notice REPLACES the death notify. Verified two-node: "notice -> console host 1" fires on the ejecting node; the relay-side delivery of client-5 traffic is a pre-existing question shared with the never-observed VTVDamaged sibling (operator-console workstream). * Eject alarm-10 audio: resolved NEGATIVE -- the five Eject*.wav ship in AUDIO/ but BTL4.RES references them nowhere (orphaned like the SQUAT clips); wiring them would be a stand-in. Operator-optional deviation. * RIO 0x38 panic control: deferred with the plumbing documented (the glass Flight-Controls window already renders the 0x38 bank; consumer = read buttonGroup[ButtonPanic] alongside the binding-engine edge) -- pod-hardware-only, untestable on this bench. Two-node verify (fresh-exe rerun after a stale-exe trap): REFUSED healthy, PUNCH-OUT after generator kill, death + wreck swap + smoke + un-wreck warp all replicated on the observer, respawned mech refuses again, console notice fired. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
129 lines
2.7 KiB
C++
129 lines
2.7 KiB
C++
#pragma once
|
|
|
|
#include "node.h"
|
|
#include "cstr.h"
|
|
#include "resource.h"
|
|
#include "scalar.h"
|
|
|
|
class NotationFile;
|
|
|
|
struct ScenarioRole__ModelResource
|
|
{
|
|
// BT 4.10 carries specialCaseDeathPenalty as record slot [1], right after
|
|
// killBonus (role reader @00429bec dest offsets; the 2007 WinTesla source
|
|
// dropped the BT-only field -- restored 2026-08-02, the DefaultRendererRate
|
|
// pattern). Consumed by the BT death handler tail (@004c07cd): every death
|
|
// with advancedDamageOn costs -specialCaseDeathPenalty score.
|
|
Scalar killBonus, specialCaseDeathPenalty, damageReceivedModifier, damageInflictedModifier, damageBias, friendlyFirePenalty;
|
|
int returnFromDeath;
|
|
};
|
|
|
|
class ScenarioRole : public Node
|
|
{
|
|
public:
|
|
Scalar CalcDamageReceivedScore(const Scalar &damage_received);
|
|
|
|
protected:
|
|
Scalar damageInflictedModifier, damageReceivedModifier, friendlyFirePenalty, damageBias, killBonus;
|
|
Scalar specialCaseDeathPenalty; // BT 4.10 role+0x20 (restored 2026-08-02)
|
|
CString roleName;
|
|
|
|
int returnFromDeath;
|
|
|
|
public:
|
|
const int GetReturnFromDeath()
|
|
{
|
|
Check(this);
|
|
return returnFromDeath;
|
|
}
|
|
|
|
Scalar GetDamageInflictedModifier() const
|
|
{
|
|
Check(this);
|
|
return damageInflictedModifier;
|
|
}
|
|
|
|
Scalar GetDamageReceivedModifier() const
|
|
{
|
|
Check(this);
|
|
return damageReceivedModifier;
|
|
}
|
|
|
|
Scalar GetFriendlyFirePenalty() const
|
|
{
|
|
Check(this);
|
|
return friendlyFirePenalty;
|
|
}
|
|
|
|
Scalar GetDamageBias() const
|
|
{
|
|
Check(this);
|
|
return damageBias;
|
|
}
|
|
|
|
Scalar GetKillBonus() const
|
|
{
|
|
Check(this);
|
|
return killBonus;
|
|
}
|
|
|
|
Scalar GetSpecialCaseDeathPenalty() const // BT 4.10 role+0x20
|
|
{
|
|
Check(this);
|
|
return specialCaseDeathPenalty;
|
|
}
|
|
|
|
CString GetRoleName() const
|
|
{
|
|
Check(this);
|
|
return roleName;
|
|
}
|
|
|
|
void SetDamageInflictedModifier(const Scalar &value)
|
|
{
|
|
Check(this);
|
|
damageInflictedModifier = value;
|
|
}
|
|
|
|
void SetDamageReceivedModifier(const Scalar value)
|
|
{
|
|
Check(this);
|
|
damageReceivedModifier = value;
|
|
}
|
|
|
|
void SetFriendlyFirePenalty(const Scalar &value)
|
|
{
|
|
Check(this);
|
|
friendlyFirePenalty = value;
|
|
}
|
|
|
|
void SetDamageBias(const Scalar &value)
|
|
{
|
|
Check(this);
|
|
damageBias = value;
|
|
}
|
|
|
|
void SetKillBonus(const Scalar &value)
|
|
{
|
|
Check(this);
|
|
killBonus = value;
|
|
}
|
|
|
|
void SetReturnFromDeath(const int &value)
|
|
{
|
|
Check(this);
|
|
returnFromDeath = value;
|
|
}
|
|
|
|
public:
|
|
typedef ScenarioRole__ModelResource ModelResource;
|
|
|
|
ScenarioRole(const CString &role_name, const CString &model_file);
|
|
|
|
ScenarioRole(const CString &role_name);
|
|
|
|
~ScenarioRole();
|
|
|
|
static ResourceDescription::ResourceID CreateModelResource(ResourceFile *resource_file, const char* model_name, NotationFile * model_file, const ResourceDirectories *directories, ModelResource *model = NULL);
|
|
};
|