По порядку.
0393 | COMMAND_SET_CHAR_ANIM_SPEEDОписание0393: set_char_anim_speed 215@ anim "POOL_SHORT_SHOT" to 248@
COMMAND_SET_CHAR_ANIM_SPEED
Порядок действийНаходим в клампе анимацию (CAnimBlendAssociation) по заданому имени. Если нашли - устанавливаем нужную скорость.
Код опкодаcase COMMAND_SET_CHAR_ANIM_SPEED:
this->CollectParameters(1);
CPed *ped = CPools::ms_pPedPool->AtHandle(ScriptParams[0].i);
this->ReadTextLabelFromScript(text, 24);
CAnimBlendAssociation *assoc = RpAnimBlendClumpGetAssociation(ped->m_pRwClump, text);
this->CollectParameters(1);
if ( assoc )
assoc->m_fSpeed = ScriptParams[0].f;
return OR_CONTINUE;
04ED | REQUEST_ANIMATIONОписание04ED: request_animation "LOWRIDER"
REQUEST_ANIMATION
Порядок действийНаходим индекс файла анимации по названию, загружаем ресурс, добавляем в менеджер управления скриптовыми ресурсами.
Код опкодаcase COMMAND_REQUEST_ANIMATION:
this->ReadTextLabelFromScript(text, 16);
animResourceIndex = CAnimManager::GetAnimationBlockIndex(text);
CStreaming::RequestModel(animResourceIndex + 25575, 4); // 25575 - базовый индекс для файлов анимаций, 4 = MISSION_REQUIRED
CTheScripts::ScriptResourceManager->AddToResourceManager(animResourceIndex, 1, this);
return OR_CONTINUE;
04EE | HAS_ANIMATION_LOADEDОписание04EE: has_animation_loaded "LOWRIDER"
HAS_ANIMATION_LOADED
Порядок действийНаходим блок анимации по названию, проверяем статус загрузки.
Код опкодаcase COMMAND_HAS_ANIMATION_LOADED:
this->ReadTextLabelFromScript(text, 16);
if ( CAnimManager::GetAnimationBlock(text)->bLoaded != 1 )
this->UpdateCompareFlag(false);
else
this->UpdateCompareFlag(true);
return OR_CONTINUE;
04EF | REMOVE_ANIMATIONОписание04EF: remove_animation "LOWRIDER"
REMOVE_ANIMATION
Порядок действийНаходим индекс файла анимации по названию, удаляем из менеджера управления скриптовыми ресурсами, выгружаем ресурс.
Код опкодаcase COMMAND_REMOVE_ANIMATION:
this->ReadTextLabelFromScript(text, 16);
animResourceIndex = CAnimManager::GetAnimationBlockIndex(text);
if (!CTheScripts::ScriptResourceManager->RemoveFromResourceManager(animResourceIndex, 1, this))
return OR_CONTINUE;
CStreaming::SetMissionDoesntRequireAnim(animResourceIndex); // вызывает CStreaming::SetMissionDoesntRequireModel(animResourceIndex + 25575)
return OR_CONTINUE;
0611 | IS_CHAR_PLAYING_ANIMОписание0611: is_char_playing_anim 2@ anim "LRGIRL_IDLE_TO_L0"
IS_CHAR_PLAYING_ANIM
Порядок действийПроверяем наличие в клампе анимации (CAnimBlendAssociation) с заданым именем.
Код опкодаcase COMMAND_IS_CHAR_PLAYING_ANIM:
this->CollectParameters(1);
CPed *ped = CPools::ms_pPedPool->AtHandle(ScriptParams[0].i);
this->ReadTextLabelFromScript(text, 24);
if (RpAnimBlendClumpGetAssociation(ped->m_pRwClump, text))
this->UpdateCompareFlag(true);
else
this->UpdateCompareFlag(false);
return OR_CONTINUE;
0612 | SET_CHAR_ANIM_PLAYING_FLAGОписание0612: set_char_anim_playing_flag 66@ anim "SHP_HANDSUP_SCR" to 0
SET_CHAR_ANIM_PLAYING_FLAG
Порядок действийПолучаем в клампе анимацию (CAnimBlendAssociation) с заданым именем, устанавливаем или убираем флаг проигрывания.
Код опкодаcase COMMAND_SET_CHAR_ANIM_PLAYING_FLAG:
this->CollectParameters(1);
CPed *ped = CPools::ms_pPedPool->AtHandle(ScriptParams[0].i);
this->ReadTextLabelFromScript(text, 24);
CAnimBlendAssociation *assoc = RpAnimBlendClumpGetAssociation(ped->m_pRwClump, text);
this->CollectParameters(1);
if (assoc) {
if (ScriptParams[0].s)
assoc->m_clumpAssoc.m_nFlags.bPlaying = true;
else
assoc->m_clumpAssoc.m_nFlags.bPlaying = false;
}
return OR_CONTINUE;
Опкоды 0605, 0812, 088A, 0A1A проигрывают анимацию.0605 | TASK_PLAY_ANIMОписание0605: task_play_anim -1 anim "M_SMKLEAN_LOOP" ifp "LOWRIDER" framedelta 4.0 loop 1 lockX 0 lockY 0 lockF 0 time -1
TASK_PLAY_ANIM
0812 | TASK_PLAY_ANIM_NON_INTERRUPTABLE Анимация не может быть прерванаОписание0812: task_play_anim_non_interruptable -1 anim "LRGIRL_IDLELOOP" ifp "LOWRIDER" framedelta 4.0 loop 0 lockX 0 lockY 0 lockF 0 time -1
TASK_PLAY_ANIM_NON_INTERRUPTABLE
088A | TASK_PLAY_ANIM_WITH_FLAGS Дополнительные настройки для анимацииОписание088A: task_play_anim_with_flags 34@ anim "RAIL_FALL" ifp "SWAT" framedelta 8.0 loop 0 lockX 0 lockY 0 lockF 1 time -1 disable_force 0 disable_lockZ 1
TASK_PLAY_ANIM_WITH_FLAGS
0A1A | TASK_PLAY_ANIM_SECONDARY Анимация верхних частей телаОписание0A1A: task_play_anim_secondary 88@ anim "HIKER_POSE_L" ifp "MISC" framedelta 4.0 loop 0 lockX 0 lockY 0 lockF 1 time -1
TASK_PLAY_ANIM_SECONDARY
Все опкоды вызывают специальную, "общую" функцию PlayAnimScriptCommand.
this->PlayAnimScriptCommand(opcodeId);
return OR_CONTINUE;
void CRunningScript::PlayAnimScriptCommand(int opcodeId) {
char animName[24];
char fileName[16];
bool lockZ = false;
bool interruptable = true;
this->CollectParameters(1);
int pedHandle = ScriptParams[0].i;
this->ReadTextLabelFromScript(animName, 24);
this->ReadTextLabelFromScript(fileName, 16);
switch (opcodeId) {
case COMMAND_TASK_PLAY_ANIM:
case COMMAND_TASK_PLAY_ANIM_SECONDARY:
this->CollectParameters(6);
break;
case COMMAND_TASK_PLAY_ANIM_NON_INTERRUPTABLE:
interruptable = false;
this->CollectParameters(6);
break;
case COMMAND_TASK_PLAY_ANIM_WITH_FLAGS:
this->CollectParameters(8);
interruptable = ScriptParams[6].i != 0;
lockZ = ScriptParams[7].i != 0;
break;
}
float frameDelta = ScriptParams[0].f;
int loop = ScriptParams[1].i;
int lockLastX = ScriptParams[2].i;
int lockLastY = ScriptParams[3].i;
int lockLastFrame = ScriptParams[4].i;
int time = ScriptParams[5].i;
int flags = 0x10;
if (loop || time > 0 && !lockLastFrame)
flags = 0x12;
if (lockLastX)
flags |= 0x40;
if (lockLastY)
flags |= 0x80;
if (!lockLastFrame)
flags |= 8;
if (opcodeId == COMMAND_TASK_PLAY_ANIM_SECONDARY)
flags |= 0x400;
bool isActiveSequence = false;
if (CTaskSequences::ms_iActiveSequence >= 0)
isActiveSequence = true;
CTaskSimpleRunNamedAnim *taskAnim = new CTaskSimpleRunNamedAnim(animName, fileName, flags, frameDelta, time, !interruptable, isActiveSequence, lockZ, 0);
if (opcodeId == COMMAND_TASK_PLAY_ANIM_SECONDARY) {
CTaskSimpleAffectSecondaryBehaviour *affectSecondaryBehaviour = new CTaskSimpleAffectSecondaryBehaviour(1, 4, taskAnim);
this->GivePedScriptedTask(pedHandle, taskAnim, opcodeId);
}