679 lines
15 KiB
C
679 lines
15 KiB
C
#include <stdio.h>
|
|
#include "common.h"
|
|
#include "mts/mts.h" // for fprintf
|
|
#include "chara/snake/shadow.h"
|
|
#include "libgv/libgv.h"
|
|
#include "libgcl/libgcl.h"
|
|
#include "libhzd/libhzd.h"
|
|
#include "game/game.h"
|
|
|
|
#include "linkvar.h"
|
|
#include "strcode.h"
|
|
|
|
#include "meryl72.h"
|
|
|
|
extern GM_CAMERA GM_Camera;
|
|
extern UnkCameraStruct2 gUnkCameraStruct2_800B7868;
|
|
|
|
int SECTION("overlay.bss") meryl72_800D5274;
|
|
GM_CAMERA SECTION("overlay.bss") meryl72_camera_800D5278;
|
|
int SECTION("overlay.bss") meryl72_800D52F4;
|
|
SVECTOR SECTION("overlay.bss") meryl72_800D52F8;
|
|
|
|
extern void GM_ConfigControlRadarparam(CONTROL *, u_short, u_short, u_short, u_short);
|
|
|
|
void Meryl72ActionMain_800CBC44( Meryl72Work * );
|
|
void s07c_meryl72_unk1_800CBCD8( Meryl72Work * );
|
|
|
|
void s07c_meryl72_unk2_800D0220( void );
|
|
void s07c_meryl72_unk2_800D025C( void );
|
|
|
|
#define EXEC_LEVEL GV_ACTOR_LEVEL4
|
|
|
|
void s07c_meryl72_800C6AF8( Meryl72Work *work )
|
|
{
|
|
int lo, hi;
|
|
|
|
lo = GM_PlayerAddress & 0xFF;
|
|
hi = ( GM_PlayerAddress >> 8 ) & 0xFF;
|
|
|
|
if ( lo == hi && lo != 0xFF )
|
|
{
|
|
work->player_addr = GM_PlayerAddress;
|
|
work->player_pos = GM_PlayerPosition;
|
|
work->player_map = GM_PlayerMap;
|
|
}
|
|
}
|
|
|
|
int RootFlagCheck_800C6B5C( Meryl72Work *work )
|
|
{
|
|
SVECTOR sp10;
|
|
CONTROL *control;
|
|
GV_MSG *msg;
|
|
int i;
|
|
|
|
control = &work->control;
|
|
control->n_messages = GV_ReceiveMessage( control->name, &control->messages );
|
|
|
|
msg = control->messages;
|
|
for ( i = control->n_messages; i > 0; i-- )
|
|
{
|
|
if ( msg->message[0] == GV_StrCode( "ルート変更" ) )
|
|
{
|
|
work->fB0B = msg->message[1];
|
|
|
|
sp10.vx = msg->message[2];
|
|
sp10.vy = msg->message[3];
|
|
sp10.vz = msg->message[4];
|
|
|
|
if ( sp10.vy < 30000 )
|
|
{
|
|
work->param.defends[0] = HZD_GetAddress( work->control.map->hzd, &sp10, -1 );
|
|
}
|
|
else
|
|
{
|
|
work->param.defends[0] = 255;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
msg++;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
MENU_BAR_CONF s07c_dword_800C32E4 = {"MERYL", {31, 191, 95}, {31, 191, 95}};
|
|
|
|
void s07c_meryl72_800C6C48( Meryl72Work *work )
|
|
{
|
|
PARAM *param;
|
|
TARGET *target;
|
|
|
|
param = &work->param;
|
|
target = work->target;
|
|
|
|
if ( param->life != target->life )
|
|
{
|
|
param->life = target->life;
|
|
work->fC36 = 150;
|
|
}
|
|
|
|
if ( param->life < 0 )
|
|
{
|
|
param->life = 0;
|
|
}
|
|
|
|
if ( param->life < param->max_life )
|
|
{
|
|
param->max_life -= 4;
|
|
}
|
|
|
|
MENU_DrawBar2( 28, param->max_life, param->life, GM_SnakeMaxHealth, &s07c_dword_800C32E4 );
|
|
|
|
if ( work->fC36 > 0 )
|
|
{
|
|
work->fC36--;
|
|
}
|
|
else if ( param->life > ( GM_SnakeMaxHealth / 2 ) )
|
|
{
|
|
GM_GameStatus &= ~STATE_SHOW_LIFEBAR;
|
|
}
|
|
}
|
|
|
|
void Meryl72Act_800C6D54( Meryl72Work *work )
|
|
{
|
|
CONTROL *control;
|
|
TARGET *target;
|
|
|
|
control = &work->control;
|
|
|
|
if ( GM_CheckMessage( &work->actor, control->name, HASH_KILL ) )
|
|
{
|
|
GV_DestroyActor( &work->actor );
|
|
return;
|
|
}
|
|
|
|
s07c_meryl72_unk1_800CBCD8( work );
|
|
|
|
GM_ActControl( control );
|
|
GM_ActObject2( &work->body );
|
|
GM_ActObject2( &work->weapon );
|
|
|
|
DG_GetLightMatrix2( &control->mov, work->light );
|
|
|
|
s07c_meryl72_800C6AF8( work );
|
|
RootFlagCheck_800C6B5C( work );
|
|
Meryl72ActionMain_800CBC44( work );
|
|
|
|
target = work->target;
|
|
GM_MoveTarget( target, &control->mov );
|
|
GM_PushTarget( target );
|
|
|
|
s07c_meryl72_800C6C48( work );
|
|
work->fC04++;
|
|
|
|
meryl72_800D52F8 = work->control.mov;
|
|
}
|
|
|
|
SVECTOR s07c_dword_800C32F0 = { 300, 1500, 300, 0 };
|
|
SVECTOR s07c_dword_800C32F8 = { 0, 0, 0, 0 };
|
|
SVECTOR s07c_dword_800C3300 = { 100, 300, 100, 0 };
|
|
SVECTOR s07c_dword_800C3308 = { 100, 0, 0, 0 };
|
|
|
|
void s07c_meryl72_800C6E48( Meryl72Work *work )
|
|
{
|
|
TARGET *target;
|
|
int life;
|
|
int faint;
|
|
|
|
target = work->target;
|
|
life = work->param.life;
|
|
faint = work->param.faint;
|
|
|
|
GM_SetTarget( target, TARGET_FLAG, ENEMY_SIDE, &s07c_dword_800C32F0 );
|
|
GM_Target_8002DCCC( target, 1, -1, life, faint, &s07c_dword_800C32F8 );
|
|
GM_Target_8002DCB4( target, -1, faint, NULL, NULL );
|
|
GM_TargetBody( target, &work->body.objs->objs[1].world );
|
|
|
|
GM_SetTarget( &work->target2, TARGET_POWER | TARGET_TOUCH, PLAYER_SIDE, &s07c_dword_800C3300 );
|
|
GM_Target_8002DCCC( &work->target2, 7, 5, 0, 0, &s07c_dword_800C3308 );
|
|
}
|
|
|
|
void s07c_meryl72_800C6F30( Meryl72Work *work )
|
|
{
|
|
UNK *unk;
|
|
|
|
unk = &work->f8BC;
|
|
GV_ZeroMemory( unk, sizeof(UNK) );
|
|
unk->field_00 = 0;
|
|
unk->field_1A = 450;
|
|
unk->field_1C = 1;
|
|
|
|
work->action = 0;
|
|
work->action2 = 0;
|
|
work->time = 0;
|
|
work->time2 = 0;
|
|
}
|
|
|
|
int s07c_meryl72_800C6F8C( Meryl72Work *work, int name, int map )
|
|
{
|
|
SVECTOR indices;
|
|
CONTROL *control;
|
|
char *pos;
|
|
char *dir;
|
|
OBJECT *body;
|
|
OBJECT *weapon;
|
|
int motion;
|
|
|
|
control = &work->control;
|
|
|
|
if ( GM_InitControl( control, name, map ) < 0 )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
pos = GCL_GetOption( 'p' );
|
|
dir = GCL_GetOption( 'd' );
|
|
GM_ConfigControlString( control, pos, dir );
|
|
GM_ConfigControlAttribute( control, RADAR_ALL_MAP | RADAR_SIGHT | RADAR_VISIBLE );
|
|
GM_ConfigControlInterp( control, 4 );
|
|
control->exclude_flag = 2;
|
|
GM_ConfigControlTrapCheck( control );
|
|
|
|
body = &work->body;
|
|
weapon = &work->weapon;
|
|
|
|
if ( work->stage == 0 )
|
|
{
|
|
motion = MOTION_DATA;
|
|
}
|
|
else
|
|
{
|
|
motion = MOTION_DATA2;
|
|
}
|
|
|
|
GM_InitObject( body, BODY_DATA, BODY_FLAG, motion );
|
|
GM_ConfigObjectJoint( body );
|
|
GM_ConfigMotionControl( body, &work->m_ctrl, motion, work->m_segs1, work->m_segs2, control, work->rots );
|
|
GM_ConfigObjectLight( body, work->light );
|
|
|
|
work->hom = GM_AllocHomingTarget( &work->body.objs->objs[6].world, control );
|
|
|
|
GM_InitObject( weapon, WEAPON_DATA, WEAPON_FLAG, 0 );
|
|
GM_ConfigObjectLight( weapon, work->light );
|
|
GM_ConfigObjectRoot( weapon, body, 4 );
|
|
|
|
indices.vx = 0;
|
|
indices.vy = 6;
|
|
indices.vz = 12;
|
|
indices.pad = 15;
|
|
work->shadow = (GV_ACT *)NewShadow2( control, body, indices, &work->shadow_enable );
|
|
|
|
ML72_SetPutChar_800CB584( work, 2 );
|
|
|
|
if ( work->stage != 0 )
|
|
{
|
|
ML72_SetPutChar_800CB584( work, 4 );
|
|
}
|
|
|
|
s07c_meryl72_800C6F30( work );
|
|
return 0;
|
|
}
|
|
|
|
void s07c_meryl72_800C7194( Meryl72Work *work )
|
|
{
|
|
GCL_ARGS args;
|
|
long data[4];
|
|
|
|
GM_FreeHomingTarget( work->hom );
|
|
GM_FreeControl( &work->control );
|
|
GM_FreeObject( &work->body );
|
|
GM_FreeObject( &work->weapon );
|
|
GM_FreeTarget( work->target );
|
|
GV_DestroyActor( work->shadow );
|
|
|
|
if ( work->fC3C >= 0 )
|
|
{
|
|
args.argc = 1;
|
|
args.argv = data;
|
|
|
|
data[0] = work->target->life;
|
|
GCL_ForceExecProc( work->fC3C, &args );
|
|
}
|
|
}
|
|
|
|
void s07c_meryl72_800C722C( void )
|
|
{
|
|
printf( " type=0x%x\n", gUnkCameraStruct2_800B7868.type );
|
|
printf( " rotate x=%d y=%d z=%d\n",
|
|
gUnkCameraStruct2_800B7868.rotate.vx,
|
|
gUnkCameraStruct2_800B7868.rotate.vy,
|
|
gUnkCameraStruct2_800B7868.rotate.vz );
|
|
printf( " track=%d\n", gUnkCameraStruct2_800B7868.track );
|
|
|
|
memcpy( &meryl72_camera_800D5278, &GM_Camera, sizeof(GM_Camera) );
|
|
|
|
GM_Camera.rotate.vx = 480;
|
|
GM_Camera.field_28 = 2;
|
|
GM_Camera.field_2A = 2;
|
|
GM_Camera.interp = 0;
|
|
GM_Camera.flags |= 0x2;
|
|
}
|
|
|
|
void s07c_meryl72_800C730C(void)
|
|
{
|
|
memcpy( &GM_Camera, &meryl72_camera_800D5278, sizeof(GM_Camera) );
|
|
}
|
|
|
|
void s07c_meryl72_800C7368( void )
|
|
{
|
|
GM_Camera.track = GV_NearExp8( GM_Camera.track, 4000 );
|
|
printf( " track=%d\n", GM_Camera.track );
|
|
}
|
|
|
|
void Meryl72Die_800C73AC( Meryl72Work *work )
|
|
{
|
|
s07c_meryl72_800C7194( work );
|
|
}
|
|
|
|
int s07c_meryl72_800C73CC( Meryl72Work *work )
|
|
{
|
|
PARAM *param;
|
|
int c_root;
|
|
HZD_PAT *pat;
|
|
HZD_PTP *points;
|
|
int i;
|
|
|
|
param = &work->param;
|
|
c_root = param->c_root;
|
|
|
|
pat = work->control.map->hzd->header->routes;
|
|
pat += param->roots[ c_root ];
|
|
|
|
fprintf( 1, "c_root= %d pat %d n_points = %d \n", c_root, (int)pat, pat->n_points );
|
|
|
|
work->n_patrols = pat->n_points;
|
|
if ( work->n_patrols <= 0 )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
points = pat->points;
|
|
for ( i = 0; i < work->n_patrols; i++ )
|
|
{
|
|
work->nodes[ i ].vx = points->x;
|
|
work->nodes[ i ].vy = points->y;
|
|
work->nodes[ i ].vz = points->z;
|
|
work->nodes[ i ].pad = points->command;
|
|
points++;
|
|
|
|
fprintf( 1, "action = 0x%x \n", work->nodes[ i ].pad );
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int s07c_meryl72_800C74E0( char *opt, char *roots )
|
|
{
|
|
int count;
|
|
char *param;
|
|
|
|
count = 0;
|
|
while ( ( param = GCL_GetParamResult() ) )
|
|
{
|
|
*roots++ = GCL_StrToInt( param );
|
|
count++;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
|
|
int s07c_meryl72_800C7538( char *opt, int *voices )
|
|
{
|
|
int count;
|
|
char *param;
|
|
|
|
count = 0;
|
|
while ( ( param = GCL_GetParamResult() ) )
|
|
{
|
|
*voices++ = GCL_StrToInt( param );
|
|
count++;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
int s07c_meryl72_800C7590( Meryl72Work *work )
|
|
{
|
|
char *opt;
|
|
|
|
opt = GCL_GetOption( 'v' );
|
|
if ( opt && s07c_meryl72_800C7538( opt, work->voices ) > 25 )
|
|
{
|
|
fprintf( 0, "Err Err Err Sound Buff Over !!\n" );
|
|
return -1;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
int s07c_meryl72_800C75F0( Meryl72Work *work, char *opt, char *defends )
|
|
{
|
|
SVECTOR zone;
|
|
int count;
|
|
char *param;
|
|
|
|
count = 0;
|
|
while ( ( param = GCL_GetParamResult() ) )
|
|
{
|
|
*defends = GCL_StrToInt( param );
|
|
GCL_StrToSV( param, &zone );
|
|
|
|
if ( zone.vy < 30000 )
|
|
{
|
|
*defends = HZD_GetAddress( work->control.map->hzd, &zone, -1 );
|
|
}
|
|
else
|
|
{
|
|
*defends = 255;
|
|
}
|
|
|
|
printf( " defence zone =%d ", *defends );
|
|
|
|
count++;
|
|
defends++;
|
|
}
|
|
|
|
return count;
|
|
}
|
|
|
|
// unused for now
|
|
const char s07c_aErrnotenoughwork_800D4788[] = "Err not enough work !!\n";
|
|
|
|
int s07c_meryl72_800C76B0( Meryl72Work *work )
|
|
{
|
|
int i;
|
|
char *opt;
|
|
|
|
for ( i = 0; i < 6; i++ )
|
|
{
|
|
work->fC1C[ i ] = -1;
|
|
}
|
|
|
|
i = 0;
|
|
|
|
opt = GCL_GetOption( 'a' );
|
|
while ( opt )
|
|
{
|
|
if ( i >= 6 )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
work->fC1C[ i ] = GCL_StrToInt( opt );
|
|
opt = GCL_GetParamResult();
|
|
i++;
|
|
}
|
|
|
|
return i;
|
|
}
|
|
|
|
int Meryl72GetResources_800C7738( Meryl72Work *work, int arg1, int arg2 )
|
|
{
|
|
char *opt;
|
|
int i;
|
|
CONTROL *control;
|
|
int addr;
|
|
|
|
work->stage = 0;
|
|
|
|
opt = GCL_GetOption( 's' );
|
|
if ( opt )
|
|
{
|
|
work->stage = GCL_StrToInt( opt );
|
|
}
|
|
|
|
work->fB96 = 0;
|
|
|
|
opt = GCL_GetOption( 'c' );
|
|
if ( opt )
|
|
{
|
|
work->fB96 = GCL_StrToInt( opt );
|
|
}
|
|
|
|
if ( s07c_meryl72_800C6F8C( work, arg1, arg2 ) )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if ( s07c_meryl72_800C7590( work ) < 0 )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
if ( s07c_meryl72_800C76B0( work ) < 0 )
|
|
{
|
|
return -1;
|
|
}
|
|
|
|
work->param.fAF8 = 0;
|
|
work->param.roots[0] = 0;
|
|
work->param.c_root = 0;
|
|
|
|
opt = GCL_GetOption( 'r' );
|
|
if ( opt && s07c_meryl72_800C74E0( opt, work->param.roots ) >= 4 )
|
|
{
|
|
fprintf( 0, "Err Err Err Change Root Num Over !!\n" );
|
|
}
|
|
|
|
work->fB58 = 2000;
|
|
work->fB0B = work->param.roots[0];
|
|
work->param.life = GM_SnakeMaxHealth;
|
|
|
|
opt = GCL_GetOption( 'l' );
|
|
if ( opt )
|
|
{
|
|
work->param.life = GCL_StrToInt( opt );
|
|
}
|
|
|
|
if ( work->param.life < 32 )
|
|
{
|
|
work->param.life = 512;
|
|
}
|
|
|
|
work->param.max_life = work->param.life;
|
|
printf( "Meryl life = %d \n", work->param.max_life );
|
|
|
|
work->param.faint = 20;
|
|
|
|
opt = GCL_GetOption( 'f' );
|
|
if ( opt )
|
|
{
|
|
work->param.faint = GCL_StrToInt( opt );
|
|
}
|
|
|
|
work->param.fAF9 = 65;
|
|
|
|
opt = GCL_GetOption( 'b' );
|
|
if ( opt )
|
|
{
|
|
work->param.fAF9 = GCL_StrToInt( opt );
|
|
}
|
|
|
|
work->param.defends[ work->param.c_root ] = 255;
|
|
|
|
opt = GCL_GetOption( 'n' );
|
|
if ( opt && s07c_meryl72_800C75F0( work, opt, work->param.defends ) >= 4 )
|
|
{
|
|
fprintf( 0, "Err Err Err Change Defend Num Over !!\n" );
|
|
}
|
|
|
|
work->param.fAFA = 65;
|
|
|
|
opt = GCL_GetOption( 'a' );
|
|
if ( opt )
|
|
{
|
|
work->param.fAFA = GCL_StrToInt( opt );
|
|
}
|
|
|
|
work->fB0A = 1;
|
|
|
|
if ( s07c_meryl72_800C73CC( work ) < 0 )
|
|
{
|
|
fprintf( 1, "watchar.c : action point Err\n" );
|
|
}
|
|
|
|
if ( GCL_GetOption( 'e' ) )
|
|
{
|
|
work->fC3C = GCL_StrToInt( GCL_GetParamResult() );
|
|
}
|
|
else
|
|
{
|
|
work->fC3C = -1;
|
|
}
|
|
|
|
if ( GCL_GetOption( 'z' ) )
|
|
{
|
|
work->proc_id = GCL_StrToInt( GCL_GetParamResult() );
|
|
}
|
|
else
|
|
{
|
|
work->proc_id = -1;
|
|
}
|
|
|
|
work->target = GM_AllocTarget();
|
|
if ( work->target )
|
|
{
|
|
s07c_meryl72_800C6E48( work );
|
|
}
|
|
|
|
GM_SetCameraCallbackFunc( 1, s07c_meryl72_800C7368 );
|
|
|
|
work->think1 = 0;
|
|
work->think2 = 0;
|
|
work->think3 = 0;
|
|
work->think4 = 0;
|
|
work->count3 = 0;
|
|
work->next_node = 0;
|
|
|
|
work->target_pos = work->nodes[ 0 ];
|
|
work->target_addr = HZD_GetAddress( work->control.map->hzd, &work->target_pos, -1 );
|
|
work->target_map = GM_CurrentMap;
|
|
|
|
work->vision.angle = 2048; //vision length
|
|
work->vision.length = 4000; //vision angle
|
|
work->fB18 = 0;
|
|
work->vision.facedir = 0;
|
|
work->pad.sound = 0;
|
|
work->pad.time = 0;
|
|
work->fB28 = DG_ZeroVector;
|
|
work->subweapon = 0;
|
|
work->fB98 = 0;
|
|
work->fC0A = 0;
|
|
work->fC0C = 0;
|
|
work->fC0E = 0;
|
|
|
|
if ( work->fB96 != 0 )
|
|
{
|
|
work->control.mov = work->nodes[ 3 ];
|
|
}
|
|
else
|
|
{
|
|
work->control.mov = work->nodes[ 0 ];
|
|
}
|
|
|
|
work->fC10[0] = work->fC10[1] = work->fC10[2] = 0;
|
|
|
|
work->fC34 = 0;
|
|
work->fC36 = 0;
|
|
|
|
for ( i = 0; i < 8; i++ )
|
|
{
|
|
work->modetime[ i ] = 0;
|
|
}
|
|
|
|
work->modetime[ 7 ] = 23;
|
|
work->modetime[ 4 ] = -1;
|
|
|
|
control = &work->control;
|
|
GM_ConfigControlRadarparam( control, 0, 4000, 2048, 0 );
|
|
|
|
work->start_pos = work->nodes[ 0 ];
|
|
work->start_map = GM_CurrentMap;
|
|
|
|
addr = HZD_GetAddress( work->control.map->hzd, &control->mov, -1 );
|
|
work->start_addr = addr;
|
|
work->fB60 = addr;
|
|
work->fB4C = addr;
|
|
|
|
work->fB6C = work->start_pos;
|
|
work->fC04 = 0;
|
|
work->fAF4 = 0;
|
|
|
|
s07c_meryl72_unk2_800D025C();
|
|
s07c_meryl72_unk2_800D0220();
|
|
|
|
return 0;
|
|
}
|
|
|
|
void *NewMeryl72_800C7BC4( int arg0, int arg1 )
|
|
{
|
|
Meryl72Work *work;
|
|
|
|
work = GV_NewActor( EXEC_LEVEL, sizeof(Meryl72Work) );
|
|
if (work)
|
|
{
|
|
GV_SetNamedActor( &work->actor, Meryl72Act_800C6D54, Meryl72Die_800C73AC, "meryl72.c" );
|
|
|
|
if ( Meryl72GetResources_800C7738( work, arg0, arg1 ) < 0 )
|
|
{
|
|
GV_DestroyActor( &work->actor );
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
return (void *)work;
|
|
} |