Configurable number of segments for Chain Chomp, Pokey, and Wiggler

This commit is contained in:
Arceveti
2021-09-30 15:09:01 -07:00
parent 3a3637723d
commit ff43340b0b
7 changed files with 95 additions and 176 deletions

View File

@@ -123,6 +123,14 @@
// -- SPECIFIC OBJECT SETTINGS --
// Allow for retries on collecting the remaining blue coins from a blue coin switch
#define BLUE_COIN_SWITCH_RETRY
// The number of chain balls the Chain Chomp has. Vanilla is 5.
#define CHAIN_CHOMP_NUM_SEGMENTS 5
// The number of parts Pokey has, including the head. Vanilla is 5, max is 30.
#define POKEY_NUM_SEGMENTS 5
// The number of segments Wiggler has, not including the head. Vanilla is 4.
#define WIGGLER_NUM_SEGMENTS 4
// -- CUTSCENE SKIPS --
// Skip peach letter cutscene

View File

@@ -1282,7 +1282,7 @@
/* Pokey Body Part */
/* oBehParams2ndByte */
#define POKEY_PART_BP_HEAD 0x0
#define POKEY_PART_BP_LOWEST POKEY_NUM_PARTS-0x1
#define POKEY_PART_BP_LOWEST (POKEY_NUM_SEGMENTS - 0x1)
/* Swoop */
/* oAction */

View File

@@ -32,11 +32,8 @@ void bhv_chain_chomp_chain_part_update(void) {
obj_mark_for_deletion(o);
} else if (o->oBehParams2ndByte != CHAIN_CHOMP_CHAIN_PART_BP_PIVOT) {
struct ChainSegment *segment = &o->parentObj->oChainChompSegments[o->oBehParams2ndByte];
// Set position relative to the pivot
o->oPosX = o->parentObj->parentObj->oPosX + segment->posX;
o->oPosY = o->parentObj->parentObj->oPosY + segment->posY;
o->oPosZ = o->parentObj->parentObj->oPosZ + segment->posZ;
vec3_sum(&o->oPosVec, &o->parentObj->parentObj->oPosVec, segment->pos);
} else if (o->parentObj->oChainChompReleaseStatus != CHAIN_CHOMP_NOT_RELEASED) {
cur_obj_update_floor_and_walls();
cur_obj_move_standard(78);
@@ -51,14 +48,14 @@ static void chain_chomp_act_uninitialized(void) {
s32 i;
if (o->oDistanceToMario < 3000.0f) {
segments = mem_pool_alloc(gObjectMemoryPool, 5 * sizeof(struct ChainSegment));
segments = mem_pool_alloc(gObjectMemoryPool, CHAIN_CHOMP_NUM_SEGMENTS * sizeof(struct ChainSegment));
if (segments != NULL) {
// Each segment represents the offset of a chain part to the pivot.
// Segment 0 connects the pivot to the chain chomp itself. Segment
// 1 connects the pivot to the chain part next to the chain chomp
// (chain part 1), etc.
o->oChainChompSegments = segments;
for (i = 0; i <= 4; i++) {
for (i = 0; i < CHAIN_CHOMP_NUM_SEGMENTS; i++) {
chain_segment_init(&segments[i]);
}
@@ -70,7 +67,7 @@ static void chain_chomp_act_uninitialized(void) {
!= NULL) {
// Spawn the non-pivot chain parts, starting from the chain
// chomp and moving toward the pivot
for (i = 1; i <= 4; i++) {
for (i = 1; i < CHAIN_CHOMP_NUM_SEGMENTS; i++) {
spawn_object_relative(i, 0, 0, 0, o, MODEL_METALLIC_BALL, bhvChainChompChainPart);
}
@@ -86,69 +83,31 @@ static void chain_chomp_act_uninitialized(void) {
* part as well as from the pivot.
*/
static void chain_chomp_update_chain_segments(void) {
struct ChainSegment *prevSegment;
struct ChainSegment *segment;
f32 offsetX;
f32 offsetY;
f32 offsetZ;
f32 offset;
f32 segmentVelY;
f32 maxTotalOffset;
s32 i;
if (o->oVelY < 0.0f) {
segmentVelY = o->oVelY;
} else {
segmentVelY = -20.0f;
}
// Segment 0 connects the pivot to the chain chomp itself, and segment i>0
// connects the pivot to chain part i (1 is closest to the chain chomp).
for (i = 1; i <= 4; i++) {
prevSegment = &o->oChainChompSegments[i - 1];
segment = &o->oChainChompSegments[i];
s32 i;
for (i = 1; i < CHAIN_CHOMP_NUM_SEGMENTS; i++) {
struct ChainSegment *prevSegment = &o->oChainChompSegments[i - 1];
struct ChainSegment *segment = &o->oChainChompSegments[i];
// Apply gravity
if ((segment->posY += segmentVelY) < 0.0f) {
segment->posY = 0.0f;
f32 segmentVelY = ((o->oVelY < 0.0f) ? o->oVelY : -20.0f);
segment->pos[1] += segmentVelY;
if (segment->pos[1] < 0.0f) {
segment->pos[1] = 0.0f;
}
// Cap distance to previous chain part (so that the tail follows the
// chomp)
// Cap distance to previous chain part (so that the tail follows the chomp)
Vec3f offset;
vec3_diff(offset, segment->pos, prevSegment->pos);
vec3_normalize_max(offset, o->oChainChompMaxDistBetweenChainParts);
offsetX = segment->posX - prevSegment->posX;
offsetY = segment->posY - prevSegment->posY;
offsetZ = segment->posZ - prevSegment->posZ;
offset = sqrtf(offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ);
// Cap distance to pivot (so that it stretches when the chomp moves far from the wooden post)
vec3_add(offset, prevSegment->pos);
f32 maxTotalDist = o->oChainChompMaxDistFromPivotPerChainPart * (CHAIN_CHOMP_NUM_SEGMENTS - i);
vec3_normalize_max(offset, maxTotalDist);
if (offset > o->oChainChompMaxDistBetweenChainParts) {
offset = o->oChainChompMaxDistBetweenChainParts / offset;
offsetX *= offset;
offsetY *= offset;
offsetZ *= offset;
}
// Cap distance to pivot (so that it stretches when the chomp moves far
// from the wooden post)
offsetX += prevSegment->posX;
offsetY += prevSegment->posY;
offsetZ += prevSegment->posZ;
offset = sqrtf(offsetX * offsetX + offsetY * offsetY + offsetZ * offsetZ);
maxTotalOffset = o->oChainChompMaxDistFromPivotPerChainPart * (5 - i);
if (offset > maxTotalOffset) {
offset = maxTotalOffset / offset;
offsetX *= offset;
offsetY *= offset;
offsetZ *= offset;
}
segment->posX = offsetX;
segment->posY = offsetY;
segment->posZ = offsetZ;
vec3_copy(segment->pos, offset);
}
}
@@ -157,7 +116,8 @@ static void chain_chomp_update_chain_segments(void) {
* distance between chain parts. Restore these values to normal.
*/
static void chain_chomp_restore_normal_chain_lengths(void) {
approach_f32_ptr(&o->oChainChompMaxDistFromPivotPerChainPart, 750.0f / 5, 4.0f);
// approach_f32_ptr(&o->oChainChompMaxDistFromPivotPerChainPart, 750.0f / CHAIN_CHOMP_NUM_SEGMENTS, 4.0f);
approach_f32_ptr(&o->oChainChompMaxDistFromPivotPerChainPart, 150.0f, 4.0f);
o->oChainChompMaxDistBetweenChainParts = o->oChainChompMaxDistFromPivotPerChainPart;
}
@@ -182,8 +142,8 @@ static void chain_chomp_sub_act_turn(void) {
cur_obj_play_sound_2(SOUND_GENERAL_CHAIN_CHOMP2);
o->oSubAction = CHAIN_CHOMP_SUB_ACT_LUNGE;
o->oChainChompMaxDistFromPivotPerChainPart = 900.0f / 5;
// o->oChainChompMaxDistFromPivotPerChainPart = 900.0f / CHAIN_CHOMP_NUM_SEGMENTS;
o->oChainChompMaxDistFromPivotPerChainPart = 180.0f;
o->oForwardVel = 140.0f;
o->oVelY = 20.0f;
o->oGravity = 0.0f;
@@ -227,8 +187,7 @@ static void chain_chomp_sub_act_lunge(void) {
o->oTimer = 0;
} else {
// Turn toward pivot
cur_obj_rotate_yaw_toward(atan2s(o->oChainChompSegments[0].posZ, o->oChainChompSegments[0].posX),
0x1000);
cur_obj_rotate_yaw_toward(atan2s(o->oChainChompSegments[0].pos[2], o->oChainChompSegments[0].pos[0]), 0x1000);
if (o->oChainChompSignedMaxDistBetweenChainParts != 0.0f) {
approach_f32_ptr(&o->oChainChompSignedMaxDistBetweenChainParts, 0.0f, 0.8f);
@@ -392,40 +351,27 @@ static void chain_chomp_act_move(void) {
cur_obj_move_standard(78);
// Segment 0 connects the pivot to the chain chomp itself
o->oChainChompSegments[0].posX = o->oPosX - o->parentObj->oPosX;
o->oChainChompSegments[0].posY = o->oPosY - o->parentObj->oPosY;
o->oChainChompSegments[0].posZ = o->oPosZ - o->parentObj->oPosZ;
vec3_diff(o->oChainChompSegments[0].pos, &o->oPosVec, &o->parentObj->oPosVec);
o->oChainChompDistToPivot =
sqrtf(o->oChainChompSegments[0].posX * o->oChainChompSegments[0].posX
+ o->oChainChompSegments[0].posY * o->oChainChompSegments[0].posY
+ o->oChainChompSegments[0].posZ * o->oChainChompSegments[0].posZ);
o->oChainChompDistToPivot = vec3_mag(o->oChainChompSegments[0].pos);
// If the chain is fully stretched
maxDistToPivot = o->oChainChompMaxDistFromPivotPerChainPart * 5;
maxDistToPivot = o->oChainChompMaxDistFromPivotPerChainPart * CHAIN_CHOMP_NUM_SEGMENTS;
if (o->oChainChompDistToPivot > maxDistToPivot) {
f32 ratio = maxDistToPivot / o->oChainChompDistToPivot;
o->oChainChompDistToPivot = maxDistToPivot;
o->oChainChompSegments[0].posX *= ratio;
o->oChainChompSegments[0].posY *= ratio;
o->oChainChompSegments[0].posZ *= ratio;
vec3_mul_val(o->oChainChompSegments[0].pos, ratio);
if (o->oChainChompReleaseStatus == CHAIN_CHOMP_NOT_RELEASED) {
// Restrict chain chomp position
o->oPosX = o->parentObj->oPosX + o->oChainChompSegments[0].posX;
o->oPosY = o->parentObj->oPosY + o->oChainChompSegments[0].posY;
o->oPosZ = o->parentObj->oPosZ + o->oChainChompSegments[0].posZ;
vec3_sum(&o->oPosVec, &o->parentObj->oPosVec, o->oChainChompSegments[0].pos);
o->oChainChompRestrictedByChain = TRUE;
} else {
// Move pivot like the chain chomp is pulling it along
f32 oldPivotY = o->parentObj->oPosY;
o->parentObj->oPosX = o->oPosX - o->oChainChompSegments[0].posX;
o->parentObj->oPosY = o->oPosY - o->oChainChompSegments[0].posY;
vec3_diff(&o->parentObj->oPosVec, &o->oPosVec, o->oChainChompSegments[0].pos);
o->parentObj->oVelY = o->parentObj->oPosY - oldPivotY;
o->parentObj->oPosZ = o->oPosZ - o->oChainChompSegments[0].posZ;
}
} else {
o->oChainChompRestrictedByChain = FALSE;
@@ -436,7 +382,8 @@ static void chain_chomp_act_move(void) {
// Begin a lunge if mario tries to attack
if (obj_check_attacks(&sChainChompHitbox, o->oAction)) {
o->oSubAction = CHAIN_CHOMP_SUB_ACT_LUNGE;
o->oChainChompMaxDistFromPivotPerChainPart = 900.0f / 5;
// o->oChainChompMaxDistFromPivotPerChainPart = 900.0f / CHAIN_CHOMP_NUM_SEGMENTS;
o->oChainChompMaxDistFromPivotPerChainPart = 180.0f; // ((CHAIN_CHOMP_NUM_SEGMENTS * 180.0f) / CHAIN_CHOMP_NUM_SEGMENTS);
o->oForwardVel = 0.0f;
o->oVelY = 300.0f;
o->oGravity = -4.0f;
@@ -491,8 +438,7 @@ void bhv_wooden_post_update(void) {
// Stay still until mario is done ground pounding
o->oWoodenPostMarioPounding = cur_obj_is_mario_ground_pounding_platform();
} else if ((o->oWoodenPostOffsetY += o->oWoodenPostSpeedY) < -190.0f) {
// Once pounded, if this is the chain chomp's post, release the chain
// chomp
// Once pounded, if this is the chain chomp's post, release the chain chomp
o->oWoodenPostOffsetY = -190.0f;
if (o->parentObj != o) {
play_puzzle_jingle();
@@ -512,7 +458,7 @@ void bhv_wooden_post_update(void) {
o->oWoodenPostTotalMarioAngle += (s16)(o->oAngleToMario - o->oWoodenPostPrevAngleToMario);
if (ABSI(o->oWoodenPostTotalMarioAngle) > 0x30000 && o->oTimer < 200) {
obj_spawn_loot_yellow_coins(o, 5, 20.0f);
set_object_respawn_info_bits(o, 1);
set_object_respawn_info_bits(o, RESPAWN_INFO_TYPE_32);
}
}

View File

@@ -36,15 +36,12 @@ static u8 sPokeyBodyPartAttackHandlers[] = {
/**
* Update function for pokey body part.
* The behavior parameter is the body part's index from 0 to 4, with 0 at the
* top.
* The behavior parameter is the body part's index from POKEY_PART_BP_HEAD to POKEY_PART_BP_LOWEST,
* with POKEY_PART_BP_HEAD at the top.
*/
void bhv_pokey_body_part_update(void) {
// PARTIAL_UPDATE
s16 offsetAngle;
f32 baseHeight;
if (obj_update_standard_actions(3.0f)) {
if (o->parentObj->oAction == POKEY_ACT_UNLOAD_PARTS) {
obj_mark_for_deletion(o);
@@ -79,12 +76,12 @@ void bhv_pokey_body_part_update(void) {
}
//! Pausing causes jumps in offset angle
offsetAngle = o->oBehParams2ndByte * 0x4000 + gGlobalTimer * 0x800;
s16 offsetAngle = o->oBehParams2ndByte * 0x4000 + gGlobalTimer * 0x800;
o->oPosX = o->parentObj->oPosX + coss(offsetAngle) * 6.0f;
o->oPosZ = o->parentObj->oPosZ + sins(offsetAngle) * 6.0f;
// This is the height of the tower beneath the body part
baseHeight = o->parentObj->oPosY
f32 baseHeight = o->parentObj->oPosY
+ (120 * (o->parentObj->oPokeyNumAliveBodyParts - o->oBehParams2ndByte) - 240)
+ 120.0f * o->parentObj->oPokeyBottomBodyPartSize;
@@ -96,18 +93,14 @@ void bhv_pokey_body_part_update(void) {
}
// Only the head has loot coins
if (o->oBehParams2ndByte == 0) {
o->oNumLootCoins = 1;
} else {
o->oNumLootCoins = 0;
}
o->oNumLootCoins = (o->oBehParams2ndByte == POKEY_PART_BP_HEAD);
// If the body part was attacked, then die. If the head was killed,
// then die after a delay.
if (obj_handle_attacks(&sPokeyBodyPartHitbox, o->oAction, sPokeyBodyPartAttackHandlers)) {
o->parentObj->oPokeyNumAliveBodyParts--;
if (o->oBehParams2ndByte == 0) {
if (o->oBehParams2ndByte == POKEY_PART_BP_HEAD) {
o->parentObj->oPokeyHeadWasKilled = TRUE;
// Last minute change to blue coins - not sure why they didn't
// just set it to -1 above
@@ -140,20 +133,19 @@ void bhv_pokey_body_part_update(void) {
}
/**
* When mario gets within range, spawn the 5 body parts and enter the wander
* action.
* When mario gets within range, spawn the POKEY_NUM_SEGMENTS body parts and enter the wander action.
*/
static void pokey_act_uninitialized(void) {
struct Object *bodyPart;
s32 i;
s16 partModel;
if (o->oDistanceToMario < 2000.0f) {
if (o->oDistanceToMario < 4000.0f) {
partModel = MODEL_POKEY_HEAD;
for (i = 0; i < 5; i++) {
for (i = 0; i < POKEY_NUM_SEGMENTS; i++) {
// Spawn body parts at y offsets 480, 360, 240, 120, 0
// behavior param 0 = head, 4 = lowest body part
// behavior param POKEY_PART_BP_HEAD = head, POKEY_PART_BP_LOWEST = lowest body part
bodyPart = spawn_object_relative(i, 0, -i * 120 + 480, 0, o, partModel, bhvPokeyBodyPart);
if (bodyPart != NULL) {
@@ -163,8 +155,8 @@ static void pokey_act_uninitialized(void) {
partModel = MODEL_POKEY_BODY_PART;
}
o->oPokeyAliveBodyPartFlags = 0x1F;
o->oPokeyNumAliveBodyParts = 5;
o->oPokeyAliveBodyPartFlags = BITMASK(POKEY_NUM_SEGMENTS);
o->oPokeyNumAliveBodyParts = POKEY_NUM_SEGMENTS;
o->oPokeyBottomBodyPartSize = 1.0f;
o->oAction = POKEY_ACT_WANDER;
}
@@ -180,9 +172,9 @@ static void pokey_act_wander(void) {
s32 targetAngleOffset;
struct Object *bodyPart;
if (o->oPokeyNumAliveBodyParts == 0) {
if (o->oPokeyNumAliveBodyParts == POKEY_PART_BP_HEAD) {
obj_mark_for_deletion(o);
} else if (o->oDistanceToMario > 2500.0f) {
} else if (o->oDistanceToMario > 4500.0f) {
o->oAction = POKEY_ACT_UNLOAD_PARTS;
o->oForwardVel = 0.0f;
} else {
@@ -195,7 +187,7 @@ static void pokey_act_wander(void) {
o->oForwardVel = 5.0f;
// If a body part is missing, replenish it after 100 frames
if (o->oPokeyNumAliveBodyParts < 5) {
if (o->oPokeyNumAliveBodyParts < POKEY_NUM_SEGMENTS) {
if (o->oTimer > 100) {
// Because the body parts shift index whenever a body part
// is killed, the new part's index is equal to the number

View File

@@ -62,28 +62,23 @@ static f32 sWigglerSpeeds[] = { 2.0f, 40.0f, 30.0f, 16.0f };
* attack.
*/
void bhv_wiggler_body_part_update(void) {
f32 dx;
f32 dy;
f32 dz;
Vec3f d;
f32 dxz;
struct ChainSegment *segment = &o->parentObj->oWigglerSegments[o->oBehParams2ndByte];
f32 posOffset;
cur_obj_scale(o->parentObj->header.gfx.scale[0]);
o->oFaceAnglePitch = segment->pitch;
o->oFaceAngleYaw = segment->yaw;
o->oFaceAnglePitch = segment->angle[0];
o->oFaceAngleYaw = segment->angle[1];
// TODO: What is this for?
posOffset = -37.5f * o->header.gfx.scale[0];
dy = posOffset * coss(o->oFaceAnglePitch) - posOffset;
d[1] = posOffset * coss(o->oFaceAnglePitch) - posOffset;
dxz = posOffset * sins(o->oFaceAnglePitch);
dx = dxz * sins(o->oFaceAngleYaw);
dz = dxz * coss(o->oFaceAngleYaw);
o->oPosX = segment->posX + dx;
o->oPosY = segment->posY + dy;
o->oPosZ = segment->posZ + dz;
d[0] = dxz * sins(o->oFaceAngleYaw);
d[2] = dxz * coss(o->oFaceAngleYaw);
vec3_sum(&o->oPosVec, segment->pos, d);
if (o->oPosY < o->parentObj->oWigglerFallThroughFloorsHeight) {
//! Since position is recomputed each frame, tilting the wiggler up
@@ -91,13 +86,12 @@ void bhv_wiggler_body_part_update(void) {
// the floor
o->oPosY += -30.0f;
cur_obj_update_floor_height();
if (o->oFloorHeight > o->oPosY) // TODO: Check ineq swap
{
if (o->oFloorHeight > o->oPosY) { // TODO: Check ineq swap
o->oPosY = o->oFloorHeight;
}
}
segment->posY = o->oPosY;
segment->pos[1] = o->oPosY;
// Inherit walking animation speed from wiggler
cur_obj_init_animation_with_accel_and_sound(0, o->parentObj->oWigglerWalkAnimSpeed);
@@ -120,27 +114,23 @@ void wiggler_init_segments(void) {
struct ChainSegment *segments;
struct Object *bodyPart;
segments = mem_pool_alloc(gObjectMemoryPool, 4 * sizeof(struct ChainSegment));
segments = mem_pool_alloc(gObjectMemoryPool, WIGGLER_NUM_SEGMENTS * sizeof(struct ChainSegment));
if (segments != NULL) {
// Each segment represents the global position and orientation of each
// object. Segment 0 represents the wiggler's head, and segment i>0
// represents body part i.
o->oWigglerSegments = segments;
for (i = 0; i <= 3; i++) {
for (i = 0; i < WIGGLER_NUM_SEGMENTS; i++) {
chain_segment_init(segments + i);
(segments + i)->posX = o->oPosX;
(segments + i)->posY = o->oPosY;
(segments + i)->posZ = o->oPosZ;
(segments + i)->pitch = o->oFaceAnglePitch;
(segments + i)->yaw = o->oFaceAngleYaw;
vec3_copy((segments + i)->pos, &o->oPosVec);
(segments + i)->angle[0] = o->oFaceAnglePitch;
(segments + i)->angle[1] = o->oFaceAngleYaw;
}
o->header.gfx.animInfo.animFrame = -1;
// Spawn each body part
for (i = 1; i <= 3; i++) {
for (i = 1; i < WIGGLER_NUM_SEGMENTS; i++) {
bodyPart =
spawn_object_relative(i, 0, 0, 0, o, MODEL_WIGGLER_BODY, bhvWigglerBody);
if (bodyPart != NULL) {
@@ -166,9 +156,7 @@ void wiggler_init_segments(void) {
void wiggler_update_segments(void) {
struct ChainSegment *prevBodyPart;
struct ChainSegment *bodyPart;
f32 dx;
f32 dy;
f32 dz;
Vec3f d;
s16 dpitch;
s16 dyaw;
f32 dxz;
@@ -177,33 +165,31 @@ void wiggler_init_segments(void) {
segmentLength = 35.0f * o->header.gfx.scale[0];
for (i = 1; i <= 3; i++) {
for (i = 1; i < WIGGLER_NUM_SEGMENTS; i++) {
prevBodyPart = &o->oWigglerSegments[i - 1];
bodyPart = &o->oWigglerSegments[i];
dx = bodyPart->posX - prevBodyPart->posX;
dy = bodyPart->posY - prevBodyPart->posY;
dz = bodyPart->posZ - prevBodyPart->posZ;
vec3_diff(d, bodyPart->pos, prevBodyPart->pos);
// As the head turns, propagate this rotation backward if the difference
// is more than 45 degrees
dyaw = atan2s(-dz, -dx) - prevBodyPart->yaw;
dyaw = atan2s(-d[2], -d[0]) - prevBodyPart->angle[1];
clamp_s16(&dyaw, -0x2000, 0x2000);
bodyPart->yaw = prevBodyPart->yaw + dyaw;
bodyPart->angle[1] = prevBodyPart->angle[1] + dyaw;
// As the head tilts, propagate the tilt backward
dxz = sqrtf(sqr(dx) + sqr(dz));
dpitch = atan2s(dxz, dy) - prevBodyPart->pitch;
dxz = sqrtf(sqr(d[0]) + sqr(d[2]));
dpitch = atan2s(dxz, d[1]) - prevBodyPart->angle[0];
clamp_s16(&dpitch, -0x2000, 0x2000);
bodyPart->pitch = prevBodyPart->pitch + dpitch;
bodyPart->angle[0] = prevBodyPart->angle[0] + dpitch;
// Set the body part's position relative to the previous body part's
// position, using the current body part's angles. This means that the
// head can rotate up to 45 degrees without the body moving
bodyPart->posY = segmentLength * sins(bodyPart->pitch) + prevBodyPart->posY;
dxz = segmentLength * coss(bodyPart->pitch);
bodyPart->posX = prevBodyPart->posX - dxz * sins(bodyPart->yaw);
bodyPart->posZ = prevBodyPart->posZ - dxz * coss(bodyPart->yaw);
bodyPart->pos[1] = segmentLength * sins(bodyPart->angle[0]) + prevBodyPart->pos[1];
dxz = segmentLength * coss(bodyPart->angle[0]);
bodyPart->pos[0] = prevBodyPart->pos[0] - dxz * sins(bodyPart->angle[1]);
bodyPart->pos[2] = prevBodyPart->pos[2] - dxz * coss(bodyPart->angle[1]);
}
}
@@ -213,8 +199,6 @@ void wiggler_init_segments(void) {
* If attacked by mario, enter either the jumped on or knockback action.
*/
static void wiggler_act_walk(void) {
s16 yawTurnSpeed;
o->oWigglerWalkAnimSpeed = 0.06f * o->oForwardVel;
// Update text if necessary
@@ -260,7 +244,7 @@ static void wiggler_act_walk(void) {
// If moving at high speeds, could overflow. But can't reach such speeds
// in practice
yawTurnSpeed = (s16)(30.0f * o->oForwardVel);
s16 yawTurnSpeed = (s16)(30.0f * o->oForwardVel);
cur_obj_rotate_yaw_toward(o->oWigglerTargetYaw, yawTurnSpeed);
obj_face_yaw_approach(o->oMoveAngleYaw, 2 * yawTurnSpeed);
@@ -437,11 +421,9 @@ void bhv_wiggler_update(void) {
}
// Update segment 0 with data from the wiggler object
o->oWigglerSegments[0].posX = o->oPosX;
o->oWigglerSegments[0].posY = o->oPosY;
o->oWigglerSegments[0].posZ = o->oPosZ;
o->oWigglerSegments[0].pitch = o->oFaceAnglePitch;
o->oWigglerSegments[0].yaw = o->oFaceAngleYaw;
vec3_copy(o->oWigglerSegments[0].pos, &o->oPosVec);
o->oWigglerSegments[0].angle[0] = o->oFaceAnglePitch;
o->oWigglerSegments[0].angle[1] = o->oFaceAngleYaw;
// Update the rest of the segments to follow segment 0
wiggler_update_segments();

View File

@@ -1717,13 +1717,8 @@ s32 cur_obj_follow_path(UNUSED s32 unusedArg) {
}
void chain_segment_init(struct ChainSegment *segment) {
segment->posX = 0.0f;
segment->posY = 0.0f;
segment->posZ = 0.0f;
segment->pitch = 0;
segment->yaw = 0;
segment->roll = 0;
vec3_zero(segment->pos);
vec3_zero(segment->angle);
}
f32 random_f32_around_zero(f32 diameter) {

View File

@@ -9,12 +9,8 @@
// used for chain chomp and wiggler
struct ChainSegment
{
f32 posX;
f32 posY;
f32 posZ;
s16 pitch;
s16 yaw;
s16 roll;
Vec3f pos;
Vec3s angle;
};
#define WATER_DROPLET_FLAG_RAND_ANGLE (1 << 1) // 0x02