int StateControl_Raptor(struct entity_s *ent, struct ss_animation_s *ss_anim) { character_command_p cmd = &ent->character->cmd; character_state_p state = &ent->character->state; uint16_t current_state = Anim_GetCurrentState(ss_anim); ent->character->rotate_speed_mult = 1.0f; ss_anim->anim_frame_flags = ANIM_NORMAL_CONTROL; state->sprint = 0x00; state->crouch = 0x00; state->attack = 0x00; switch(current_state) { case TR_STATE_RAPTOR_STAY: // -> 2 -> 3 -> 4 -> 6 -> 8 if(state->dead) { Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_RAPTOR_DEAD1, 0, NULL); } else if(cmd->action) { ss_anim->target_state = TR_STATE_RAPTOR_STAY_ATTACK; } else if(cmd->jump) { ss_anim->target_state = TR_STATE_RAPTOR_JUMP_ATTACK; } else if(cmd->move[0] < 0) { ss_anim->target_state = TR_STATE_RAPTOR_ARRRR; } else if(cmd->move[0] > 0) { ss_anim->target_state = (cmd->shift) ? (TR_STATE_RAPTOR_WALK) : (TR_STATE_RAPTOR_RUN); } else { ss_anim->target_state = TR_STATE_RAPTOR_STAY; } break; case TR_STATE_RAPTOR_WALK: // -> 1 ent->dir_flag = ENT_MOVE_FORWARD; if(!state->dead && cmd->shift && (cmd->move[0] > 0)) { ss_anim->target_state = TR_STATE_RAPTOR_WALK; } else { ss_anim->target_state = TR_STATE_RAPTOR_STAY; } break; case TR_STATE_RAPTOR_RUN: // -> 1 -> 7 ent->dir_flag = ENT_MOVE_FORWARD; if(state->dead) { Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_RAPTOR_DEAD2, 0, NULL); } else if(cmd->action) { ss_anim->target_state = TR_STATE_RAPTOR_RUN_ATTACK; } else if(!cmd->shift && (cmd->move[0] > 0)) { ss_anim->target_state = TR_STATE_RAPTOR_RUN; } else { ss_anim->target_state = TR_STATE_RAPTOR_STAY; } break; case TR_STATE_RAPTOR_JUMP_ATTACK: case TR_STATE_RAPTOR_RUN_ATTACK: case TR_STATE_RAPTOR_STAY_ATTACK: state->attack = 0x01; break; case TR_STATE_RAPTOR_DEAD: state->dead = 0x02; break; }; return 0; }
int StateControl_Wolf(struct entity_s *ent, struct ss_animation_s *ss_anim) { character_command_p cmd = &ent->character->cmd; character_state_p state = &ent->character->state; uint16_t current_state = Anim_GetCurrentState(ss_anim); ent->character->rotate_speed_mult = 1.0f; ent->dir_flag = ENT_STAY; ss_anim->anim_frame_flags = ANIM_NORMAL_CONTROL; state->sprint = 0x00; state->crouch = 0x00; state->attack = 0x00; state->can_attack = 0x00; if(!state->dead && (ent->character->target_id != ENTITY_ID_NONE)) { entity_p target = World_GetEntityByID(ent->character->target_id); if(target && Room_IsInNearRoomsList(ent->self->room, target->self->room)) { float pos[3], *v = ent->bf->bone_tags[ent->character->bone_head].current_transform + 12; Mat4_vec3_mul_macro(pos, ent->transform.M4x4, v); pos[0] -= target->obb->centre[0]; pos[1] -= target->obb->centre[1]; pos[2] -= target->obb->centre[2]; if((pos[2] > -target->obb->extent[2]) && (pos[2] < target->obb->extent[2]) && (pos[0] * pos[0] + pos[1] * pos[1] < 400.0f * 400.0f)) { state->can_attack = 0x01; } } } switch(current_state) { case TR_STATE_WOLF_STAY:// 1 // -> 2 -> 7 -> 8 -> 9 cmd->rot[0] = 0; if(state->dead) { Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_WOLF_DEAD1, 0, NULL); } else if(cmd->move[0] > 0) { ss_anim->target_state = TR_STATE_WOLF_WALK; ent->dir_flag = ENT_MOVE_FORWARD; } else if(cmd->shift) { ss_anim->target_state = TR_STATE_WOLF_STAY_CROUCH; } else if(cmd->action) { ss_anim->target_state = TR_STATE_WOLF_WOOOO; } else if(cmd->move[0] < 0) { ss_anim->target_state = TR_STATE_WOLF_IDLE; } else { ent->dir_flag = ENT_MOVE_FORWARD; } break; case TR_STATE_WOLF_STAY_CROUCH:// 9 // -> 1 -> 3 -> 5 -> 7 -> 12 if(state->dead) { Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_WOLF_DEAD1, 0, NULL); } else if(cmd->move[0] > 0) { ent->dir_flag = ENT_MOVE_FORWARD; ss_anim->target_state = (cmd->shift) ? (TR_STATE_WOLF_CROUCH) : (TR_STATE_WOLF_RUN); } else if(cmd->action) { cmd->rot[0] = 0; ss_anim->target_state = TR_STATE_WOLF_STAY_ATTACK; } else if(cmd->jump) { cmd->rot[0] = 0; ss_anim->target_state = TR_STATE_WOLF_WOOOO; } else if(cmd->shift) { ss_anim->target_state = TR_STATE_WOLF_STAY_CROUCH; } else { ent->dir_flag = ENT_MOVE_FORWARD; ss_anim->target_state = TR_STATE_WOLF_STAY; } break; case TR_STATE_WOLF_WALK:// 2 // -> 1 -> 5 if(state->dead) { Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_WOLF_DEAD1, 0, NULL); } else if(cmd->move[0] > 0) { ent->dir_flag = ENT_MOVE_FORWARD; ss_anim->target_state = (cmd->shift) ? (TR_STATE_WOLF_WALK) : (TR_STATE_WOLF_CROUCH); } else { ent->dir_flag = ENT_MOVE_FORWARD; ss_anim->target_state = TR_STATE_WOLF_STAY; } break; case TR_STATE_WOLF_RUN:// 3 // -> 6 -> 9 -> 10 if(state->dead) { Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_WOLF_DEAD1, 0, NULL); } else if(cmd->action) { ss_anim->target_state = TR_STATE_WOLF_JUMP_ATTACK; } else if(cmd->move[0] > 0) { ent->dir_flag = ENT_MOVE_FORWARD; ss_anim->target_state = (cmd->shift) ? (TR_STATE_WOLF_RUN) : (TR_STATE_WOLF_CROUCH); } else if(cmd->roll) { ent->dir_flag = ENT_MOVE_FORWARD; ss_anim->target_state = TR_STATE_WOLF_RUN_RIGHT; } else { ent->dir_flag = ENT_MOVE_FORWARD; ss_anim->target_state = TR_STATE_WOLF_STAY_CROUCH; } break; case TR_STATE_WOLF_CROUCH:// 5 // -> 3 -> 9 -> 12 if(state->dead) { Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_WOLF_DEAD1, 0, NULL); } else if(cmd->action) { cmd->rot[0] = 0; ent->dir_flag = ENT_MOVE_FORWARD; ss_anim->target_state = TR_STATE_WOLF_JUMP_ATTACK; } else if(cmd->move[0] > 0) { ent->dir_flag = ENT_MOVE_FORWARD; ss_anim->target_state = (cmd->shift) ? (TR_STATE_WOLF_CROUCH) : (TR_STATE_WOLF_RUN); } else { cmd->rot[0] = 0; ent->dir_flag = ENT_MOVE_FORWARD; ss_anim->target_state = TR_STATE_WOLF_STAY_CROUCH; } break; case TR_STATE_WOLF_STAY_ATTACK:// 12 state->attack = 0x01; break; case TR_STATE_WOLF_JUMP_ATTACK:// 6 // -> 3 ent->dir_flag = ENT_MOVE_FORWARD; state->attack = 0x01; if(state->dead) { Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_WOLF_DEAD3, 0, NULL); } else if(cmd->action) { ss_anim->target_state = TR_STATE_WOLF_JUMP_ATTACK; } else { ss_anim->target_state = TR_STATE_WOLF_RUN; } break; case TR_STATE_WOLF_WOOOO:// 7 cmd->rot[0] = 0; break; case TR_STATE_WOLF_IDLE:// 8 // -> 1 cmd->rot[0] = 0; ent->no_move = 0x01; if(state->dead) { Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_WOLF_DEAD1, 0, NULL); } else if(cmd->move[0] > 0) { ent->dir_flag = ENT_MOVE_FORWARD; ss_anim->target_state = TR_STATE_WOLF_STAY; } else { ss_anim->target_state = TR_STATE_WOLF_IDLE; } break; case TR_STATE_WOLF_RUN_RIGHT:// 10 if(state->dead) { Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_WOLF_DEAD2, 0, NULL); } else { cmd->rot[0] = -1; ent->dir_flag = ENT_MOVE_FORWARD; } break; case TR_STATE_WOLF_DEAD:// 11 state->dead = 0x01; if(ss_anim->model->animations[ss_anim->current_animation].max_frame <= ss_anim->current_frame + 1) { state->dead = 0x02; state->ragdoll = 0x01; } break; default: cmd->rot[0] = 0; break; }; return 0; }
int StateControl_Crocodile(struct entity_s *ent, struct ss_animation_s *ss_anim) { character_command_p cmd = &ent->character->cmd; character_state_p state = &ent->character->state; skeletal_model_p sm = ss_anim->model; uint16_t current_state = Anim_GetCurrentState(ss_anim); ent->character->rotate_speed_mult = 1.0f; ss_anim->anim_frame_flags = ANIM_NORMAL_CONTROL; state->sprint = 0x00; state->crouch = 0x00; state->attack = 0x00; switch(ent->move_type) { case MOVE_ON_WATER: ent->move_type = MOVE_UNDERWATER; case MOVE_UNDERWATER: sm = World_GetModelByID(TR_MODEL_CROCODILE_UW_TR1); if(sm && ss_anim->model->id != TR_MODEL_CROCODILE_UW_TR1) { ss_anim->model = sm; Anim_SetAnimation(ss_anim, TR_ANIMATION_CROCODILE_UW_FLOW, 0); } break; case MOVE_ON_FLOOR: sm = World_GetModelByID(TR_MODEL_CROCODILE_OF_TR1); if(sm && ss_anim->model->id != TR_MODEL_CROCODILE_OF_TR1) { ss_anim->model = sm; Anim_SetAnimation(ss_anim, TR_ANIMATION_CROCODILE_OF_STAY, 0); } break; } if(ss_anim->model->id == TR_MODEL_CROCODILE_UW_TR1) { ent->character->parameters.param[PARAM_AIR] = 1000; ent->character->parameters.maximum[PARAM_AIR] = 1000; switch(current_state) { case TR_STATE_CROCODILE_UW_FLOW: // -> 2 if(state->dead) { Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_CROCODILE_UW_DEAD, 0, NULL); } else if(cmd->action) { ss_anim->next_state = TR_STATE_CROCODILE_UW_ATTACK; } else { ss_anim->next_state = TR_STATE_CROCODILE_UW_FLOW; } break; case TR_STATE_CROCODILE_UW_ATTACK: // -> 1 state->attack = 0x01; ent->dir_flag = ENT_MOVE_FORWARD; if(!state->dead && cmd->action) { ss_anim->next_state = TR_STATE_CROCODILE_UW_ATTACK; } else { ss_anim->next_state = TR_STATE_CROCODILE_UW_FLOW; } break; case TR_STATE_CROCODILE_DEAD: state->dead = 0x02; break; }; } else if(ss_anim->model->id == TR_MODEL_CROCODILE_OF_TR1) { switch(current_state) { case TR_STATE_CROCODILE_STAY: // -> 2 -> 3 -> 4 -> 5 if(state->dead) { Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_CROCODILE_OF_DEAD, 0, NULL); } else if(cmd->action) { ss_anim->next_state = TR_STATE_CROCODILE_ATTACK; } else if(cmd->move[0] > 0) { ss_anim->next_state = (cmd->shift) ? (TR_STATE_CROCODILE_WALK) : (TR_STATE_CROCODILE_RUN); } else if(cmd->roll) { ss_anim->next_state = TR_STATE_CROCODILE_RUN_RIGHT; } else { ss_anim->next_state = TR_STATE_CROCODILE_STAY; } break; case TR_STATE_CROCODILE_WALK: // -> 1 -> 2 ent->dir_flag = ENT_MOVE_FORWARD; if(!state->dead && (cmd->move[0] > 0)) { ss_anim->next_state = (cmd->shift) ? (TR_STATE_CROCODILE_WALK) : (TR_STATE_CROCODILE_RUN); } else { ss_anim->next_state = TR_STATE_CROCODILE_STAY; } break; case TR_STATE_CROCODILE_RUN: // -> 1 -> 3 ent->dir_flag = ENT_MOVE_FORWARD; if(!state->dead && (cmd->move[0] > 0)) { ss_anim->next_state = (cmd->shift) ? (TR_STATE_CROCODILE_WALK) : (TR_STATE_CROCODILE_RUN); } else { ss_anim->next_state = TR_STATE_CROCODILE_STAY; } break; case TR_STATE_CROCODILE_RUN_RIGHT: ent->dir_flag = ENT_MOVE_FORWARD; cmd->rot[0] = -1; if(!state->dead && cmd->roll) { ss_anim->next_state = TR_STATE_CROCODILE_RUN_RIGHT; } else { ss_anim->next_state = TR_STATE_CROCODILE_WALK; } break; case TR_STATE_CROCODILE_ATTACK: state->attack = 0x01; break; case TR_STATE_CROCODILE_DEAD: state->dead = 0x02; break; }; } return 0; }
///@TODO: move here TickEntity with Inversing entity state... see carefully heavy irregular cases void Trigger_DoCommands(trigger_header_p trigger, struct entity_s *entity_activator) { if(trigger && entity_activator) { bool has_non_continuos_triggers = false; for(trigger_command_p command = trigger->commands; command; command = command->next) { switch(command->function) { case TR_FD_TRIGFUNC_UWCURRENT: if(entity_activator->move_type == MOVE_ON_WATER) { if(entity_activator->bf->animations.current_animation != TR_ANIMATION_LARA_ONWATER_DIVE_ALTERNATE) { Entity_SetAnimation(entity_activator, ANIM_TYPE_BASE, TR_ANIMATION_LARA_ONWATER_DIVE_ALTERNATE, 0); entity_activator->move_type = MOVE_UNDERWATER; } } else if(entity_activator->move_type == MOVE_UNDERWATER) { Entity_MoveToSink(entity_activator, command->operands); } break; default: has_non_continuos_triggers = true; break; }; } if(has_non_continuos_triggers) { int activator = TR_ACTIVATOR_NORMAL; // Activator is normal by default. int action_type = TR_ACTIONTYPE_NORMAL; // Action type is normal by default. int mask_mode = TRIGGER_OP_OR; // Activation mask by default. int activator_sector_status = Entity_GetSectorStatus(entity_activator); bool header_condition = true; bool is_heavy = false; // Activator type is LARA for all triggers except HEAVY ones, which are triggered by // some specific entity classes. // entity_activator_type == TR_ACTIVATORTYPE_LARA and // trigger_activator_type == TR_ACTIVATORTYPE_MISC switch(trigger->sub_function) { case TR_FD_TRIGTYPE_HEAVY: case TR_FD_TRIGTYPE_HEAVYANTITRIGGER: case TR_FD_TRIGTYPE_HEAVYSWITCH: is_heavy = true; if((entity_activator->type_flags & ENTITY_TYPE_HEAVYTRIGGER_ACTIVATOR) == 0) { return; } break; } switch(trigger->sub_function) { case TR_FD_TRIGTYPE_TRIGGER: case TR_FD_TRIGTYPE_HEAVY: activator = TR_ACTIVATOR_NORMAL; break; case TR_FD_TRIGTYPE_ANTIPAD: action_type = TR_ACTIONTYPE_ANTI; case TR_FD_TRIGTYPE_PAD: // Check move type for triggering entity. header_condition = (entity_activator->move_type == MOVE_ON_FLOOR); break; case TR_FD_TRIGTYPE_SWITCH: // Set activator and action type for now; conditions are linked with first item in operand chain. activator = TR_ACTIVATOR_SWITCH; action_type = TR_ACTIONTYPE_SWITCH; mask_mode = TRIGGER_OP_XOR; break; case TR_FD_TRIGTYPE_HEAVYSWITCH: // Action type remains normal, as HEAVYSWITCH acts as "heavy trigger" with activator mask filter. activator = TR_ACTIVATOR_SWITCH; mask_mode = TRIGGER_OP_XOR; break; case TR_FD_TRIGTYPE_KEY: // Action type remains normal, as key acts one-way (no need in switch routines). activator = TR_ACTIVATOR_KEY; break; case TR_FD_TRIGTYPE_PICKUP: // Action type remains normal, as pick-up acts one-way (no need in switch routines). activator = TR_ACTIVATOR_PICKUP; break; case TR_FD_TRIGTYPE_COMBAT: // Check weapon status for triggering entity. header_condition = header_condition && (entity_activator->character && (entity_activator->character->weapon_current_state > 0)); break; case TR_FD_TRIGTYPE_DUMMY: case TR_FD_TRIGTYPE_SKELETON: ///@FIXME: Find the meaning later!!! // These triggers are being parsed, but not added to trigger script! action_type = TR_ACTIONTYPE_BYPASS; break; case TR_FD_TRIGTYPE_ANTITRIGGER: case TR_FD_TRIGTYPE_HEAVYANTITRIGGER: action_type = TR_ACTIONTYPE_ANTI; break; case TR_FD_TRIGTYPE_MONKEY: header_condition = header_condition && (entity_activator->move_type == MOVE_MONKEYSWING); break; case TR_FD_TRIGTYPE_CLIMB: header_condition = header_condition && (entity_activator->move_type == MOVE_CLIMBING); break; case TR_FD_TRIGTYPE_TIGHTROPE: // Check state range for triggering entity. header_condition = header_condition && ((entity_activator->state_flags >= TR_STATE_LARA_TIGHTROPE_IDLE) && (entity_activator->state_flags <= TR_STATE_LARA_TIGHTROPE_EXIT)); break; case TR_FD_TRIGTYPE_CRAWLDUCK: // Check state range for triggering entity. header_condition = header_condition && ((entity_activator->state_flags >= TR_ANIMATION_LARA_CROUCH_ROLL_FORWARD_BEGIN) && (entity_activator->state_flags <= TR_ANIMATION_LARA_CRAWL_SMASH_LEFT)); break; } if(!header_condition) { return; } // Now execute operand chain for trigger function! bool first_command = true; int switch_sectorstatus = 0; int switch_event_state = -1; uint32_t switch_mask = 0; entity_p trig_entity = NULL; entity_p switch_entity = NULL; for(trigger_command_p command = trigger->commands; command; command = command->next) { switch(command->function) { case TR_FD_TRIGFUNC_OBJECT: // ACTIVATE / DEACTIVATE object trig_entity = World_GetEntityByID(command->operands); // If activator is specified, first item operand counts as activator index (except // heavy switch case, which is ordinary heavy trigger case with certain differences). if(!trig_entity) { break; } if(first_command && (activator != TR_ACTIVATOR_NORMAL)) { first_command = false; switch(activator) { case TR_ACTIVATOR_SWITCH: if(action_type == TR_ACTIONTYPE_SWITCH) { // Switch action type case. switch_entity = trig_entity; switch_event_state = (trig_entity->trigger_layout & ENTITY_TLAYOUT_EVENT) >> 5; switch_sectorstatus = (trig_entity->trigger_layout & ENTITY_TLAYOUT_SSTATUS) >> 7; switch_mask = (trig_entity->trigger_layout & ENTITY_TLAYOUT_MASK); // Trigger activation mask is here filtered through activator's own mask. switch_mask = (switch_mask == 0) ? (0x1F & trigger->mask) : (switch_mask & trigger->mask); if((switch_event_state == 0) && (switch_sectorstatus == 1)) { Entity_SetSectorStatus(trig_entity, 0); trig_entity->timer = trigger->timer; } else if((switch_event_state == 1) && (switch_sectorstatus == 1)) { // Create statement for antitriggering a switch. Entity_SetSectorStatus(trig_entity, 0); trig_entity->timer = 0.0f; } else { return; } } else /// end if (action_type == TR_ACTIONTYPE_SWITCH) { // Ordinary type case (e.g. heavy switch). switch_sectorstatus = (entity_activator->trigger_layout & ENTITY_TLAYOUT_SSTATUS) >> 7; switch_mask = (entity_activator->trigger_layout & ENTITY_TLAYOUT_MASK); // Trigger activation mask is here filtered through activator's own mask. switch_mask = (switch_mask == 0) ? (0x1F & trigger->mask) : (switch_mask & trigger->mask); if(switch_sectorstatus == 0) { int activation_state = Entity_Activate(trig_entity, entity_activator, switch_mask, mask_mode, trigger->once, trigger->timer); if(trigger->once && (activation_state != ENTITY_TRIGGERING_NOT_READY)) { Entity_SetSectorStatus(entity_activator, 1); switch_sectorstatus = 1; } } else { return; } } break; case TR_ACTIVATOR_KEY: if((Entity_GetLock(trig_entity) == 1) && (Entity_GetSectorStatus(trig_entity) == 0)) { Entity_SetSectorStatus(trig_entity, 1); } else { return; } break; case TR_ACTIVATOR_PICKUP: if(!(trig_entity->state_flags & ENTITY_STATE_ENABLED) && (Entity_GetSectorStatus(trig_entity) == 0)) { Entity_SetSectorStatus(trig_entity, 1); } else { return; } break; }; } else {
int StateControl_TorsoBoss(struct entity_s *ent, struct ss_animation_s *ss_anim) { character_command_p cmd = &ent->character->cmd; character_state_p state = &ent->character->state; uint16_t current_state = Anim_GetCurrentState(ss_anim); ent->character->rotate_speed_mult = 1.0f; ss_anim->anim_frame_flags = ANIM_NORMAL_CONTROL; state->sprint = 0x00; state->crouch = 0x00; state->attack = 0x00; ent->character->rotate_speed_mult = 0.33; switch(current_state) { case TR_STATE_TORSO_BOSS_STAY: // -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 cmd->rot[0] = 0; ent->dir_flag = ENT_MOVE_FORWARD; if(state->dead) { Entity_SetAnimation(ent, ANIM_TYPE_BASE, TR_ANIMATION_TORSO_BOSS_DEAD, 0, NULL); } else if(cmd->action) { ss_anim->target_state = (cmd->shift) ? (TR_STATE_TORSO_BOSS_ATTACK_BIG) : (TR_STATE_TORSO_BOSS_ATTACK); } else if(cmd->jump) { ss_anim->target_state = TR_STATE_TORSO_BOSS_ATTACK_KILL; } else if(cmd->move[1] < 0) { ss_anim->target_state = TR_STATE_TORSO_BOSS_TURN_RIGHT; } else if(cmd->move[1] > 0) { ss_anim->target_state = TR_STATE_TORSO_BOSS_TURN_LEFT; } else if(cmd->move[0] > 0) { ss_anim->target_state = TR_STATE_TORSO_BOSS_MOVE; } else { ss_anim->target_state = TR_STATE_TORSO_BOSS_STAY; } break; case TR_STATE_TORSO_BOSS_MOVE: // -> 1 if(!state->dead && (cmd->move[1] > 0)) { ss_anim->target_state = TR_STATE_TORSO_BOSS_MOVE; } else { ss_anim->target_state = TR_STATE_TORSO_BOSS_STAY; } break; case TR_STATE_TORSO_BOSS_TURN_RIGHT: // -> 1 cmd->rot[0] = 1; if(!state->dead && (cmd->move[1] < 0)) { ss_anim->target_state = TR_STATE_TORSO_BOSS_TURN_RIGHT; } else { ss_anim->target_state = TR_STATE_TORSO_BOSS_STAY; } break; case TR_STATE_TORSO_BOSS_TURN_LEFT: // -> 1 cmd->rot[0] = -1; if(!state->dead && (cmd->move[1] > 0)) { ss_anim->target_state = TR_STATE_TORSO_BOSS_TURN_LEFT; } else { ss_anim->target_state = TR_STATE_TORSO_BOSS_STAY; } break; case TR_STATE_TORSO_BOSS_ATTACK_KILL: case TR_STATE_TORSO_BOSS_ATTACK: case TR_STATE_TORSO_BOSS_ATTACK_BIG: case TR_STATE_TORSO_BOSS_ATTACK_JUMP: state->attack = 0x01; cmd->rot[0] = 0; break; case TR_STATE_TORSO_BOSS_DEAD: state->dead = 0x02; break; default: cmd->rot[0] = 0; break; }; return 0; }