Implement CWarWasp

This commit is contained in:
Jack Andersen 2019-01-15 18:22:44 -10:00
parent f9b0614327
commit 851e113dc0
27 changed files with 1473 additions and 146 deletions

View File

@ -12,25 +12,6 @@
<option name="SPACE_AFTER_REFERENCE_IN_DECLARATION" value="true" />
</Objective-C>
<Objective-C-extensions>
<file>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Import" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Macro" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Typedef" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Enum" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Constant" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Global" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Struct" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="FunctionPredecl" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Function" />
</file>
<class>
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Property" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="Synthesize" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InitMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="StaticMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="InstanceMethod" />
<option name="com.jetbrains.cidr.lang.util.OCDeclarationKind" value="DeallocMethod" />
</class>
<extensions>
<pair source="cpp" header="hpp" fileNamingConvention="NONE" />
<pair source="c" header="h" fileNamingConvention="NONE" />

View File

@ -105,6 +105,16 @@ void PATH::sendToBlender(hecl::blender::Connection& conn, std::string_view entry
#endif
}
#if 0
for (const Node& n : nodes) {
zeus::simd_floats f(n.position.simd);
zeus::simd_floats no(n.position.simd + n.normal.simd);
os.format("v = bm.verts.new((%f,%f,%f))\n"
"v2 = bm.verts.new((%f,%f,%f))\n"
"bm.edges.new((v, v2))\n", f[0], f[1], f[2], no[0], no[1], no[2]);
}
#endif
os << "bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.001)\n"
"path_mesh = bpy.data.meshes.new('PATH')\n"
"bm.to_mesh(path_mesh)\n"

View File

@ -9,26 +9,26 @@ struct Eyeball : IScriptObject {
AT_DECL_DNA_YAML
AT_DECL_DNAV
String<-1> name;
Value<atUint32> unknown1;
Value<atUint32> flavor;
Value<atVec3f> location;
Value<atVec3f> orientation;
Value<atVec3f> scale;
PatternedInfo patternedInfo;
ActorParameters actorParameters;
Value<float> unknown2;
Value<float> unknown3;
Value<float> attackDelay;
Value<float> attackStartTime;
UniqueID32 wpsc;
DamageInfo damageInfo;
UniqueID32 particle1;
UniqueID32 particle2;
UniqueID32 texture1;
UniqueID32 texture2;
Value<atUint32> unknown4;
Value<atUint32> unknown5; // always ff
Value<atUint32> unknown6; // always ff
Value<atUint32> unknown7; // always ff
Value<atUint32> unknown8;
Value<bool> unknown9;
UniqueID32 beamContactFxId;
UniqueID32 beamPulseFxId;
UniqueID32 beamTextureId;
UniqueID32 beamGlowTextureId;
Value<atUint32> anim0;
Value<atUint32> anim1; // always ff
Value<atUint32> anim2; // always ff
Value<atUint32> anim3; // always ff
Value<atUint32> beamSfx;
Value<bool> attackDisabled;
void addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const {
actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters);
@ -39,20 +39,20 @@ struct Eyeball : IScriptObject {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc);
ent->name = name + "_wpsc";
}
if (particle1) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle1);
if (beamContactFxId) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamContactFxId);
ent->name = name + "_part1";
}
if (particle2) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle2);
if (beamPulseFxId) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamPulseFxId);
ent->name = name + "_part2";
}
if (texture1) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture1);
if (beamTextureId) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamTextureId);
ent->name = name + "_tex1";
}
if (texture2) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(texture2);
if (beamGlowTextureId) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(beamGlowTextureId);
ent->name = name + "_tex2";
}
patternedInfo.nameIDs(pakRouter, name + "_patterned");
@ -61,10 +61,10 @@ struct Eyeball : IScriptObject {
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut, std::vector<hecl::ProjectPath>& lazyOut) const {
g_curSpec->flattenDependencies(wpsc, pathsOut);
g_curSpec->flattenDependencies(particle1, pathsOut);
g_curSpec->flattenDependencies(particle2, pathsOut);
g_curSpec->flattenDependencies(texture1, pathsOut);
g_curSpec->flattenDependencies(texture2, pathsOut);
g_curSpec->flattenDependencies(beamContactFxId, pathsOut);
g_curSpec->flattenDependencies(beamPulseFxId, pathsOut);
g_curSpec->flattenDependencies(beamTextureId, pathsOut);
g_curSpec->flattenDependencies(beamGlowTextureId, pathsOut);
patternedInfo.depIDs(pathsOut);
actorParameters.depIDs(pathsOut, lazyOut);
}

View File

@ -11,7 +11,7 @@ struct ScriptBeam : IScriptObject {
String<-1> name;
Value<atVec3f> location;
Value<atVec3f> orientation;
Value<bool> unknown1;
Value<bool> active;
UniqueID32 wpsc;
BeamInfo beamInfo;
DamageInfo damageInfo;

View File

@ -9,30 +9,30 @@ struct Warwasp : IScriptObject {
AT_DECL_DNA_YAML
AT_DECL_DNAV
String<-1> name;
Value<atUint32> unknown1;
Value<atUint32> flavor;
Value<atVec3f> location;
Value<atVec3f> orientation;
Value<atVec3f> scale;
PatternedInfo patternedInfo;
ActorParameters actorParameters;
Value<bool> unknown2;
Value<atUint8> colliderType;
DamageInfo damageInfo1;
UniqueID32 wpsc1;
DamageInfo damageInfo2;
UniqueID32 particle;
Value<atUint32> unknown3;
UniqueID32 projectileWeapon;
DamageInfo projectileDamage;
UniqueID32 projectileVisorParticle;
Value<atUint32> projectileVisorSfx;
void addCMDLRigPairs(PAKRouter<PAKBridge>& pakRouter, CharacterAssociations<UniqueID32>& charAssoc) const {
actorParameters.addCMDLRigPairs(pakRouter, charAssoc, patternedInfo.animationParameters);
}
void nameIDs(PAKRouter<PAKBridge>& pakRouter) const {
if (wpsc1) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(wpsc1);
if (projectileWeapon) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(projectileWeapon);
ent->name = name + "_wpsc";
}
if (particle) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(particle);
if (projectileVisorParticle) {
PAK::Entry* ent = (PAK::Entry*)pakRouter.lookupEntry(projectileVisorParticle);
ent->name = name + "_part";
}
patternedInfo.nameIDs(pakRouter, name + "_patterned");
@ -40,8 +40,8 @@ struct Warwasp : IScriptObject {
}
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut, std::vector<hecl::ProjectPath>& lazyOut) const {
g_curSpec->flattenDependencies(wpsc1, pathsOut);
g_curSpec->flattenDependencies(particle, pathsOut);
g_curSpec->flattenDependencies(projectileWeapon, pathsOut);
g_curSpec->flattenDependencies(projectileVisorParticle, pathsOut);
patternedInfo.depIDs(pathsOut);
actorParameters.depIDs(pathsOut, lazyOut);
}

View File

@ -176,6 +176,7 @@ SAdvancementResults CAnimTreeTimeScale::VAdvanceView(const CCharAnimTime& dt) {
SAdvancementResults res2;
if (newDt.GreaterThanZero())
res2 = x14_child->VAdvanceView(newDt);
x20_curAccelTime = x28_targetAccelTime;
res2.x0_remTime = res2.x0_remTime + (newTime - x28_targetAccelTime);
return res2;
}

View File

@ -331,7 +331,7 @@ void CGroundMovement::MoveGroundCollider_New(CStateManager& mgr, CPhysicsActor&
player.x9c5_28_slidingOnWall = false;
bool applyJump = player.x258_movementState == CPlayer::EPlayerMovementState::ApplyJump;
bool dampUnderwater = false;
if (player.x9c4_31_dampUnderwaterMotion)
if (player.x9c4_31_inWaterMovement)
if (!mgr.GetPlayerState()->HasPowerUp(CPlayerState::EItemType::GravitySuit))
dampUnderwater = true;

View File

@ -78,7 +78,7 @@ enum class EStepDirection { Invalid = -1, Forward = 0, Backward = 1, Left = 2, R
enum class EStepType { Normal = 0, Dodge = 1, BreakDodge = 2, RollDodge = 3 };
enum class ESeverity { Invalid = -1, Zero = 0, One = 1, Two = 2 };
enum class ESeverity { Invalid = -1, Zero = 0, One = 1, Two = 2, Eight = 8 };
enum class EGetupType { Invalid = -1, Zero = 0 };

View File

@ -9,29 +9,30 @@
#include "TCastTo.hpp"
namespace urde::MP1 {
CEyeball::CEyeball(TUniqueId uid, std::string_view name, CPatterned::EFlavorType flavor, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, float f1, float f2,
CAssetId aId1, const CDamageInfo& dInfo, CAssetId aId2, CAssetId aId3, CAssetId aId4, CAssetId aId5,
u32 w1, u32 w2, u32 w3, u32 w4, u32 w5, bool b1, const CActorParameters& actParms)
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, float attackDelay,
float attackStartTime, CAssetId wpscId, const CDamageInfo& dInfo, CAssetId beamContactFxId,
CAssetId beamPulseFxId, CAssetId beamTextureId, CAssetId beamGlowTextureId, u32 anim0, u32 anim1,
u32 anim2, u32 anim3, u32 beamSfx, bool attackDisabled, const CActorParameters& actParms)
: CPatterned(ECharacter::EyeBall, uid, name, flavor, info, xf, std::move(mData), pInfo, EMovementType::Flyer,
EColliderType::Zero, EBodyType::Restricted, actParms, EKnockBackVariant::Medium)
, x568_attackDelay(f1)
, x56c_maxAttackDelay(f2)
, x568_attackDelay(attackDelay)
, x56c_attackStartTime(attackStartTime)
, x570_boneTracking(*GetModelData()->GetAnimationData(), "Eye"sv, zeus::degToRad(45.f), zeus::degToRad(180.f), true)
, x5b4_projectileInfo(aId1, dInfo)
, x5dc_(aId2)
, x5e0_(aId3)
, x5e4_(aId4)
, x5e8_(aId5)
, x604_beamSfxId(CSfxManager::TranslateSFXID(w5))
, x5b4_projectileInfo(wpscId, dInfo)
, x5dc_beamContactFxId(beamContactFxId)
, x5e0_beamPulseFxId(beamPulseFxId)
, x5e4_beamTextureId(beamTextureId)
, x5e8_beamGlowTextureId(beamGlowTextureId)
, x604_beamSfxId(CSfxManager::TranslateSFXID(beamSfx))
, x60c_24_canAttack(false)
, x60c_25_playerInRange(false)
, x60c_26_alert(false)
, x60c_27_attackDisabled(b1)
, x60c_27_attackDisabled(attackDisabled)
, x60c_28_firingBeam(false) {
x5f4_animIdxs[0] = w1;
x5f4_animIdxs[1] = w2;
x5f4_animIdxs[2] = w3;
x5f4_animIdxs[3] = w4;
x5f4_animIdxs[0] = anim0;
x5f4_animIdxs[1] = anim1;
x5f4_animIdxs[2] = anim2;
x5f4_animIdxs[3] = anim3;
x460_knockBackController.SetAutoResetImpulse(false);
}
@ -119,8 +120,9 @@ void CEyeball::CreateBeam(CStateManager& mgr) {
if (x5ec_projectileId != kInvalidUniqueId)
return;
CBeamInfo beamInfo(3, x5dc_, x5e0_, x5e4_, x5e8_, 50, .5f, 1.f, 2.f, 20.f, 1.f, 1.f, 2.f,
zeus::CColor(1.f, 1.f, 1.f, 0.f), zeus::CColor(0.f, 1.f, 0.5f, 0.f), 150.f);
CBeamInfo beamInfo(3, x5dc_beamContactFxId, x5e0_beamPulseFxId, x5e4_beamTextureId, x5e8_beamGlowTextureId,
50, 0.05f, 1.f, 2.f, 20.f, 1.f, 1.f, 2.f, zeus::CColor(1.f, 1.f, 1.f, 0.f),
zeus::CColor(0.f, 1.f, 0.5f, 0.f), 150.f);
x5ec_projectileId = mgr.AllocateUniqueId();
mgr.AddObject(new CPlasmaProjectile(x5b4_projectileInfo.Token(), "EyeBall_Beam"sv, EWeaponType::AI, beamInfo,
zeus::CTransform::Identity(), EMaterialTypes::Immovable,
@ -161,7 +163,7 @@ void CEyeball::Active(CStateManager& mgr, EStateMsg msg, float) {
x450_bodyController->SetLocomotionType(pas::ELocomotionType::Combat);
x60c_24_canAttack = false;
} else if (msg == EStateMsg::Update) {
if (x330_stateMachineState.GetDelay() > x56c_maxAttackDelay)
if (x330_stateMachineState.GetTime() > x56c_attackStartTime)
x60c_24_canAttack = true;
UpdateAnimation();

View File

@ -8,14 +8,14 @@ namespace urde::MP1 {
class CEyeball : public CPatterned {
static constexpr std::string_view skEyeLocator = "Laser_LCTR"sv;
float x568_attackDelay;
float x56c_maxAttackDelay;
float x56c_attackStartTime;
CBoneTracking x570_boneTracking;
zeus::CVector3f x5a8_targetPosition;
CProjectileInfo x5b4_projectileInfo;
CAssetId x5dc_;
CAssetId x5e0_;
CAssetId x5e4_;
CAssetId x5e8_;
CAssetId x5dc_beamContactFxId;
CAssetId x5e0_beamPulseFxId;
CAssetId x5e4_beamTextureId;
CAssetId x5e8_beamGlowTextureId;
TUniqueId x5ec_projectileId = kInvalidUniqueId;
u32 x5f0_currentAnim = 0;
s32 x5f4_animIdxs[4];
@ -36,9 +36,11 @@ class CEyeball : public CPatterned {
public:
DEFINE_PATTERNED(EyeBall)
CEyeball(TUniqueId, std::string_view, EFlavorType, const CEntityInfo&, const zeus::CTransform&, CModelData&&,
const CPatternedInfo&, float, float, CAssetId, const CDamageInfo&, CAssetId, CAssetId, CAssetId, CAssetId,
u32, u32, u32, u32, u32, bool, const CActorParameters&);
CEyeball(TUniqueId uid, std::string_view name, CPatterned::EFlavorType flavor, const CEntityInfo& info,
const zeus::CTransform& xf, CModelData&& mData, const CPatternedInfo& pInfo, float attackDelay,
float attackStartTime, CAssetId wpscId, const CDamageInfo& dInfo, CAssetId beamContactFxId,
CAssetId beamPulseFxId, CAssetId beamTextureId, CAssetId beamGlowTextureId, u32 anim0, u32 anim1,
u32 anim2, u32 anim3, u32 beamSfx, bool attackDisabled, const CActorParameters& actParms);
void Accept(IVisitor& visitor);
void PreRender(CStateManager&, const zeus::CFrustum&);

File diff suppressed because it is too large Load Diff

View File

@ -1,19 +1,122 @@
#pragma once
#include "World/CPatterned.hpp"
#include "World/CPathFindSearch.hpp"
#include "Weapon/CProjectileInfo.hpp"
#include "Collision/CCollidableSphere.hpp"
namespace urde {
class CDamageInfo;
namespace MP1 {
class CWarWasp : public CPatterned {
s32 x568_stateProg = -1;
CCollidableSphere x570_cSphere;
CPathFindSearch x590_pfSearch;
TUniqueId x674_aiMgr = kInvalidUniqueId;
zeus::CVector3f x678_targetPos;
CDamageInfo x684_;
zeus::CQuaternion x6a0_initialRot;
zeus::CVector3f x6b0_circleBurstPos;
zeus::CVector3f x6bc_circleBurstDir;
zeus::CVector3f x6c8_circleBurstRight;
CProjectileInfo x6d4_projectileInfo;
float x6fc_initialSpeed = x3b4_speed;
float x700_attackRemTime = 0.f;
pas::EStepDirection x704_dodgeDir = pas::EStepDirection::Invalid;
s32 x708_circleAttackTeam = -1;
s32 x70c_initialCircleAttackTeam = -1;
s32 x710_initialCircleAttackTeamUnit = -1;
float x714_circleTelegraphSeekHeight = 0.f;
float x718_circleBurstOffTotemAngle = zeus::degToRad(90.f);
TLockedToken<CGenDescription> x71c_projectileVisorParticle; // Used to be optional
u16 x72c_projectileVisorSfx;
union {
struct {
bool x72e_24_jumpBackRepeat : 1;
bool x72e_25_canApplyDamage : 1;
bool x72e_26_initiallyInactive : 1;
bool x72e_27_teamMatesMelee : 1;
bool x72e_28_inProjectileAttack : 1;
bool x72e_29_pathObstructed : 1;
bool x72e_30_isRetreating : 1;
bool x72e_31_heardNoise : 1;
};
u32 _dummy = 0;
};
void SwarmAdd(CStateManager& mgr);
void SwarmRemove(CStateManager& mgr);
void ApplyDamage(CStateManager& mgr);
void SetUpCircleBurstWaypoint(CStateManager& mgr);
zeus::CVector3f GetProjectileAimPos(CStateManager& mgr, float zBias);
zeus::CVector3f GetCloseInPos(const CStateManager& mgr, const zeus::CVector3f& aimPos) const;
float GetCloseInZBasis(const CStateManager& mgr) const;
void SetUpPathFindBehavior(CStateManager& mgr);
s32 GetAttackTeamSize(CStateManager& mgr, s32 team);
float CalcTimeToNextAttack(CStateManager& mgr);
float CalcOffTotemAngle(CStateManager& mgr);
void JoinCircleAttackTeam(s32 unit, CStateManager& mgr);
void SetUpCircleTelegraphTeam(CStateManager& mgr);
TUniqueId GetAttackTeamLeader(CStateManager& mgr, s32 team);
void TryCircleTeamMerge(CStateManager& mgr);
float GetTeamZStratum(s32 team);
float CalcSeekMagnitude(CStateManager& mgr);
void UpdateTelegraphMoveSpeed(CStateManager& mgr);
bool CheckCircleAttackSpread(CStateManager& mgr, s32 team);
void ApplyNormalSteering(CStateManager& mgr);
void ApplySeparationBehavior(CStateManager& mgr, float sep);
bool PathToHiveIsClear(CStateManager& mgr);
bool SteerToDeactivatePos(CStateManager& mgr, EStateMsg msg, float dt);
zeus::CVector3f CalcShuffleDest(CStateManager& mgr);
public:
DEFINE_PATTERNED(WarWasp)
CWarWasp(TUniqueId uid, std::string_view name, const CEntityInfo& info, const zeus::CTransform& xf,
CModelData&& mData, const CPatternedInfo& pInfo, CPatterned::EFlavorType flavor, CPatterned::EColliderType,
const CDamageInfo& dInfo1, const CActorParameters&, CAssetId weapon, const CDamageInfo& dInfo2,
CAssetId particle, u32 w3);
const CDamageInfo& dInfo1, const CActorParameters&, CAssetId projectileWeapon,
const CDamageInfo& projectileDamage, CAssetId projectileVisorParticle, u32 projecileVisorSfx);
void Accept(IVisitor& visitor);
void Think(float dt, CStateManager& mgr);
void AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId sender, CStateManager& mgr);
std::experimental::optional<zeus::CAABox> GetTouchBounds() const;
void DoUserAnimEvent(CStateManager& mgr, const CInt32POINode& node, EUserEventType type, float dt);
const CCollisionPrimitive* GetCollisionPrimitive() const;
void Death(CStateManager& mgr, const zeus::CVector3f& direction, EScriptObjectState state);
bool IsListening() const;
bool Listen(const zeus::CVector3f&, EListenNoiseType);
zeus::CVector3f GetOrigin(const CStateManager& mgr, const CTeamAiRole& role,
const zeus::CVector3f& aimPos) const;
void UpdateTouchBounds();
bool IsRetreating() const { return x72e_30_isRetreating; }
void Patrol(CStateManager&, EStateMsg, float);
void PathFind(CStateManager& mgr, EStateMsg msg, float dt);
void TargetPatrol(CStateManager&, EStateMsg, float);
void Generate(CStateManager&, EStateMsg, float);
void Deactivate(CStateManager&, EStateMsg, float);
void Attack(CStateManager&, EStateMsg, float);
void JumpBack(CStateManager&, EStateMsg, float);
void Shuffle(CStateManager&, EStateMsg, float);
void ProjectileAttack(CStateManager&, EStateMsg, float);
void TelegraphAttack(CStateManager&, EStateMsg, float);
void Dodge(CStateManager&, EStateMsg, float);
void Retreat(CStateManager&, EStateMsg, float);
void SpecialAttack(CStateManager&, EStateMsg, float);
bool InAttackPosition(CStateManager&, float);
bool Leash(CStateManager&, float);
bool PathShagged(CStateManager&, float);
bool AnimOver(CStateManager&, float);
bool ShouldAttack(CStateManager&, float);
bool InPosition(CStateManager&, float);
bool ShouldTurn(CStateManager&, float);
bool HearShot(CStateManager&, float);
bool ShouldFire(CStateManager&, float);
bool ShouldDodge(CStateManager&, float);
bool ShouldSpecialAttack(CStateManager&, float);
CPathFindSearch* GetSearchPath();
CProjectileInfo* GetProjectileInfo();
};
} // namespace MP1
} // namespace urde

View File

@ -27,6 +27,7 @@ CENTITY_TYPES = (
('CInterpolationCamera', 'Camera/CInterpolationCamera.hpp'),
Namespace('MP1'),
('CMetroidPrimeRelay', 'MP1/World/CMetroidPrimeRelay.hpp', 'MP1'),
('CWarWasp', 'MP1/World/CWarWasp.hpp', 'MP1'),
EndNamespace(),
('CPathCamera', 'Camera/CPathCamera.hpp'),
('CAi', 'World/CAi.hpp'),

View File

@ -51,8 +51,9 @@ public:
, x40_outerColor(zeus::CColor::ReadRGBABig(in)) {}
CBeamInfo(s32 beamAttributes, CAssetId contactFxId, CAssetId pulseFxId, CAssetId textureId, CAssetId glowTextureId,
s32 length, float radius, float f2, float f3, float f4, float f5, float contactFxScale, float pulseFxScale,
const zeus::CColor& innerColor, const zeus::CColor& outerColor, float travelSpeed)
s32 length, float radius, float expansionSpeed, float lifeTime, float pulseSpeed, float shutdownTime,
float contactFxScale, float pulseFxScale, const zeus::CColor& innerColor, const zeus::CColor& outerColor,
float travelSpeed)
: x4_beamAttributes(beamAttributes)
, x8_contactFxId(contactFxId)
, xc_pulseFxId(pulseFxId)
@ -60,10 +61,10 @@ public:
, x14_glowTextureId(glowTextureId)
, x18_length(length)
, x1c_radius(radius)
, x20_expansionSpeed(f2)
, x24_lifeTime(f3)
, x28_pulseSpeed(f4)
, x2c_shutdownTime(f5)
, x20_expansionSpeed(expansionSpeed)
, x24_lifeTime(lifeTime)
, x28_pulseSpeed(pulseSpeed)
, x2c_shutdownTime(shutdownTime)
, x30_contactFxScale(contactFxScale)
, x34_pulseFxScale(pulseFxScale)
, x38_travelSpeed(travelSpeed)

View File

@ -22,6 +22,6 @@ public:
const CPlayer& player, bool gravity, float dt);
CDamageInfo GetDamage() const { return xc_damageInfo; }
const TToken<CWeaponDescription>& Token() { return x0_weaponDescription; }
TToken<CWeaponDescription>& Token() { return x0_weaponDescription; }
};
} // namespace urde

View File

@ -54,11 +54,11 @@ bool CPFRegion::IsPointInside(const zeus::CVector3f& point) const {
if ((point - node.GetPos()).dot(node.GetNormal()) < 0.f)
break;
}
zeus::CVector3f nodeToPoint = point - x4_startNode->GetPos();
if (i == x0_numNodes && nodeToPoint.dot(x18_normal) >= 0.f)
if ((nodeToPoint - x14_height * zeus::CVector3f::skUp).dot(x18_normal) <= 0.f)
return true;
if (i != x0_numNodes)
return false;
zeus::CVector3f nodeToPoint = point - x4_startNode->GetPos();
return nodeToPoint.dot(x18_normal) >= 0.f &&
(nodeToPoint - x14_height * zeus::CVector3f::skUp).dot(x18_normal) <= 0.f;
}
float CPFRegion::PointHeight(const zeus::CVector3f& point) const {
@ -212,16 +212,14 @@ zeus::CVector3f CPFRegion::FitThroughLink3d(const zeus::CVector3f& p1, const CPF
float f24 = (node.GetPos() - p2).dot(node.GetNormal());
float f23 = f25 + f24;
#if 0
if (chRadius < 0.5f * link.Get2dWidth())
{
if (chRadius < 0.5f * link.Get2dWidth()) {
zeus::CVector2f delta2d(nodeDelta.x, nodeDelta.y);
delta2d *= link.GetOO2dWidth();
zeus::CVector3f nodeToP1 = p1 - node.GetPos();
float f29 = delta2d.dot(zeus::CVector2f(nodeToP1.y, nodeToP1.y));
zeus::CVector3f nodeToP2 = p2 - node.GetPos();
float f1b = delta2d.dot(zeus::CVector2f(nodeToP2.y, nodeToP2.y));
if (f23 > FLT_EPSILON)
{
if (f23 > FLT_EPSILON) {
zeus::clamp(chRadius, 1.f / f23 * f24 * f29 + f25 * f1b, link.Get2dWidth() - chRadius) *
link.GetOO2dWidth();
}
@ -233,7 +231,7 @@ zeus::CVector3f CPFRegion::FitThroughLink3d(const zeus::CVector3f& p1, const CPF
float minZ = chHalfHeight + midPoint.z();
z = 0.5f * (p1.z() + p2.z());
if (f23 > FLT_EPSILON)
z = 1.f / f23 * (f24 * p1.z() + f25 * p2.z());
z = (f24 * p1.z() + f25 * p2.z()) / f23;
z = zeus::clamp(minZ, z, regionHeight + midPoint.z() - chHalfHeight);
} else {
z = (p1.z() + p2.z()) * 0.5f;

View File

@ -306,7 +306,7 @@ bool CPathFindSearch::Search(rstl::reserved_vector<CPFRegion*, 4>& regs1, const
/* Next G */
float g = (linkReg->GetCentroid() - reg->GetCentroid()).magnitude() + reg->Data()->GetG();
if ((!x0_area->ClosedSet().Test(linkReg->GetIndex()) && !x0_area->OpenList().Test(linkReg)) ||
linkReg->Data()->GetG() <= g) {
linkReg->Data()->GetG() > g) {
if (x0_area->OpenList().Test(linkReg)) {
/* In rare cases, revisiting a region will yield a lower G (actual cost) */
x0_area->OpenList().Pop(linkReg);

View File

@ -43,7 +43,7 @@ public:
u32 GetCurrentWaypoint() const { return xc8_curWaypoint; }
void SetCurrentWaypoint(u32 wp) { xc8_curWaypoint = wp; }
const rstl::reserved_vector<zeus::CVector3f, 16>& GetWaypoints() const { return x4_waypoints; }
bool IsOver() const { return GetCurrentWaypoint() >= x4_waypoints.size(); }
bool IsOver() const { return GetCurrentWaypoint() >= x4_waypoints.size() - 1; }
bool IsShagged() const { return GetResult() != EResult::Success; }
bool SegmentOver(const zeus::CVector3f& p1) const;
void GetSplinePoint(zeus::CVector3f& pOut, const zeus::CVector3f& p1) const;

View File

@ -44,9 +44,9 @@ class CPatternedInfo {
float x108_;
u32 x10c_pathfindingIndex;
zeus::CVector3f x110_particle1Scale;
CAssetId x11c_particle1;
CAssetId x120_electric;
zeus::CVector3f x124_particle2Scale;
CAssetId x130_particle2;
@ -66,5 +66,6 @@ public:
CAnimationParameters& GetAnimationParameters() { return xec_animParams; }
const CAnimationParameters& GetAnimationParameters() const { return xec_animParams; }
u32 GetPathfindingIndex() const { return x10c_pathfindingIndex; }
bool GetActive() const { return xf8_active; }
};
} // namespace urde

View File

@ -50,8 +50,6 @@ float CPhysicsActor::GetWeight() const { return 24.525002f * xe8_mass; }
void CPhysicsActor::SetPrimitiveOffset(const zeus::CVector2f& offset) { x1e8_primitiveOffset = offset; }
zeus::CVector3f CPhysicsActor::GetPrimitiveOffset() const { return x1e8_primitiveOffset; }
void CPhysicsActor::MoveCollisionPrimitive(const zeus::CVector3f& offset) { x1e8_primitiveOffset = offset; }
void CPhysicsActor::SetBoundingBox(const zeus::CAABox& box) {

View File

@ -124,7 +124,7 @@ public:
float GetMass() const { return xe8_mass; }
void SetPrimitiveOffset(const zeus::CVector2f& offset);
zeus::CVector3f GetPrimitiveOffset() const;
const zeus::CVector3f& GetPrimitiveOffset() const { return x1e8_primitiveOffset; }
void MoveCollisionPrimitive(const zeus::CVector3f& offset);
void SetBoundingBox(const zeus::CAABox& box);
zeus::CAABox GetMotionVolume(float dt) const;
@ -145,6 +145,8 @@ public:
const zeus::CAxisAngle& GetAngularVelocityWR() const { return x144_angularVelocity; }
void SetAngularVelocityWR(const zeus::CAxisAngle& angVel);
const zeus::CVector3f& GetForceOR() const { return x15c_force; }
const zeus::CVector3f& GetImpulseOR() const { return x168_impulse; }
const zeus::CVector3f& GetMoveImpulseOR() const { return x18c_moveImpulse; }
void SetVelocityWR(const zeus::CVector3f& vel);
void SetVelocityOR(const zeus::CVector3f& vel);
void SetMomentumWR(const zeus::CVector3f& m) { x150_momentum = m; }

View File

@ -2235,7 +2235,7 @@ void CPlayer::Think(float dt, CStateManager& mgr) {
x2b0_outOfWaterTicks += 1;
x9c5_24_ = x9c4_24_visorChangeRequested;
x9c4_31_dampUnderwaterMotion = x9c5_25_splashUpdated;
x9c4_31_inWaterMovement = x9c5_25_splashUpdated;
x9c5_25_splashUpdated = false;
UpdateBombJumpStuff();
@ -5242,7 +5242,7 @@ const CScriptWater* CPlayer::GetVisorRunoffEffect(const CStateManager& mgr) cons
void CPlayer::SetMorphBallState(EPlayerMorphBallState state, CStateManager& mgr) {
if (x2f8_morphBallState == EPlayerMorphBallState::Morphed && state != EPlayerMorphBallState::Morphed)
x9c5_26_ = x9c4_31_dampUnderwaterMotion;
x9c5_26_ = x9c4_31_inWaterMovement;
x2f8_morphBallState = state;
xf9_standardCollider = state == EPlayerMorphBallState::Morphed;

View File

@ -288,7 +288,7 @@ private:
bool x9c4_28_canLeaveMorphBall : 1;
bool x9c4_29_spiderBallControlXY : 1;
bool x9c4_30_controlDirOverride : 1;
bool x9c4_31_dampUnderwaterMotion : 1;
bool x9c4_31_inWaterMovement : 1;
bool x9c5_24_ : 1;
bool x9c5_25_splashUpdated : 1;
bool x9c5_26_ : 1;
@ -314,7 +314,7 @@ private:
float x9c8_eyeZBias = 0.f;
float x9cc_stepCameraZBias = 0.f;
u32 x9d0_bombJumpCount = 0;
u32 x9d4_bombJumpCheckDelayFrames = 0;
s32 x9d4_bombJumpCheckDelayFrames = 0;
zeus::CVector3f x9d8_controlDirOverrideDir = zeus::CVector3f::skForward;
rstl::reserved_vector<TUniqueId, 5> x9e4_orbitDisableList;
@ -614,5 +614,6 @@ public:
void Set_X590(bool b) { x590_ = b; }
const zeus::CVector3f& GetOrbitPoint() const { return x314_orbitPoint; }
float GetAverageSpeed() const;
bool IsInWaterMovement() const { return x9c4_31_inWaterMovement; }
};
} // namespace urde

View File

@ -48,7 +48,7 @@ void CScriptCounter::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId objId,
if (GetActive() && x38_current < x3c_max) {
++x38_current;
if (x38_current >= x3c_max) {
SendScriptMsgs(EScriptObjectState::Zero, stateMgr, EScriptObjectMessage::None);
SendScriptMsgs(EScriptObjectState::MaxReached, stateMgr, EScriptObjectMessage::None);
if (x40_autoReset)
x38_current = x34_initial;
}

View File

@ -100,6 +100,13 @@ public:
bool AddProjectileAttacker(TUniqueId aiId);
void RemoveProjectileAttacker(TUniqueId aiId);
bool HasMeleeAttackers() const { return !x68_meleeAttackers.empty(); }
bool HasProjectileAttackers() const { return !x78_projectileAttackers.empty(); }
s32 GetNumRoles() const { return x58_roles.size(); }
const std::vector<CTeamAiRole>& GetRoles() const { return x58_roles; }
s32 GetMaxMeleeAttackerCount() const { return x34_data.x10_maxMeleeAttackerCount; }
s32 GetMaxProjectileAttackerCount() const { return x34_data.x14_maxProjectileAttackerCount; }
static CTeamAiRole* GetTeamAiRole(CStateManager& mgr, TUniqueId mgrId, TUniqueId aiId);
static void ResetTeamAiRole(EAttackType type, CStateManager& mgr, TUniqueId mgrId, TUniqueId aiId, bool clearRole);
static bool CanAcceptAttacker(EAttackType type, CStateManager& mgr, TUniqueId mgrId, TUniqueId aiId);

View File

@ -1307,10 +1307,10 @@ CEntity* ScriptLoader::LoadWarWasp(CStateManager& mgr, CInputStream& in, int pro
CActorParameters actorParms = LoadActorParameters(in);
CPatterned::EColliderType collider = CPatterned::EColliderType(in.readBool());
CDamageInfo damageInfo1(in);
CAssetId weaponDesc = in.readUint32Big();
CDamageInfo damageInfo2(in);
CAssetId particle = in.readUint32Big();
u32 w1 = in.readUint32Big();
CAssetId projectileWeapon = in.readUint32Big();
CDamageInfo projectileDamage(in);
CAssetId projectileVisorParticle = in.readUint32Big();
u32 projectileVisorSfx = in.readUint32Big();
const CAnimationParameters& aParms = pInfo.GetAnimationParameters();
FourCC animType = g_ResFactory->GetResourceTypeById(aParms.GetACSFile());
@ -1320,7 +1320,8 @@ CEntity* ScriptLoader::LoadWarWasp(CStateManager& mgr, CInputStream& in, int pro
CAnimRes res(aParms.GetACSFile(), aParms.GetCharacter(), scale, aParms.GetInitialAnimation(), true);
CModelData mData(res);
return new MP1::CWarWasp(mgr.AllocateUniqueId(), name, info, xf, std::move(mData), pInfo, flavor, collider,
damageInfo1, actorParms, weaponDesc, damageInfo2, particle, w1);
damageInfo1, actorParms, projectileWeapon, projectileDamage, projectileVisorParticle,
projectileVisorSfx);
}
CEntity* ScriptLoader::LoadSpacePirate(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) {
@ -2657,30 +2658,31 @@ CEntity* ScriptLoader::LoadEyeball(CStateManager& mgr, CInputStream& in, int pro
CPatternedInfo pInfo(in, pair.second);
CActorParameters actParms = LoadActorParameters(in);
float f1 = in.readFloatBig();
float f2 = in.readFloatBig();
float attackDelay = in.readFloatBig();
float attackStartTime = in.readFloatBig();
CAssetId wpsc(in);
CDamageInfo dInfo(in);
CAssetId partId1(in);
CAssetId partId2(in);
CAssetId texture1(in);
CAssetId texture2(in);
u32 w1 = in.readUint32Big();
u32 w2 = in.readUint32Big();
u32 w3 = in.readUint32Big();
u32 w4 = in.readUint32Big();
u32 w5 = in.readUint32Big();
CAssetId beamContactFxId(in);
CAssetId beamPulseFxId(in);
CAssetId beamTextureId(in);
CAssetId beamGlowTextureId(in);
u32 anim0 = in.readUint32Big();
u32 anim1 = in.readUint32Big();
u32 anim2 = in.readUint32Big();
u32 anim3 = in.readUint32Big();
u32 beamSfx = in.readUint32Big();
if (g_ResFactory->GetResourceTypeById(pInfo.GetAnimationParameters().GetACSFile()) != SBIG('ANCS'))
return nullptr;
bool b1 = in.readBool();
bool attackDisabled = in.readBool();
CModelData mData(CAnimRes(pInfo.GetAnimationParameters().GetACSFile(), pInfo.GetAnimationParameters().GetCharacter(),
scale, pInfo.GetAnimationParameters().GetInitialAnimation(), true));
return new MP1::CEyeball(mgr.AllocateUniqueId(), name, flavor, info, xf, std::move(mData), pInfo, f1, f2, wpsc, dInfo,
partId1, partId2, texture1, texture2, w1, w2, w3, w4, w5, b1, actParms);
return new MP1::CEyeball(mgr.AllocateUniqueId(), name, flavor, info, xf, std::move(mData), pInfo, attackDelay,
attackStartTime, wpsc, dInfo, beamContactFxId, beamPulseFxId, beamTextureId,
beamGlowTextureId, anim0, anim1, anim2, anim3, beamSfx, attackDisabled, actParms);
}
CEntity* ScriptLoader::LoadRadialDamage(CStateManager& mgr, CInputStream& in, int propCount, const CEntityInfo& info) {

2
hecl

@ -1 +1 @@
Subproject commit d4a0f17336f19906a6c4f2ed83fd34945f017593
Subproject commit 296d8733c21e7e9276af44cdafdd63f44856975b