void changeAnimation(Entity * entity, size_t layer, ANIM_HANDLE * animation, AnimUseType flags, bool startAtBeginning) { AnimLayer & animlayer = entity->animlayer[layer]; AcquireLastAnim(entity); FinishAnim(entity, animlayer.cur_anim); ANIM_Set(animlayer, animation); animlayer.flags |= flags; if(startAtBeginning) { animlayer.altidx_cur = 0; } }
static void ARX_SPEECH_Release(long i) { if(aspeech[i].exist) { ARX_SOUND_Stop(aspeech[i].sample); if(ValidIOAddress(aspeech[i].io) && aspeech[i].io->animlayer[2].cur_anim) { AcquireLastAnim(aspeech[i].io); aspeech[i].io->animlayer[2].cur_anim = NULL; } aspeech[i].clear(); } }
void ManageCombatModeAnimationsEND() { Entity * io = entities.player(); AnimLayer & layer1 = io->animlayer[1]; AnimLayer & layer3 = io->animlayer[3]; ANIM_HANDLE ** alist = io->anims; if(layer1.cur_anim &&( (layer1.cur_anim == alist[ANIM_BARE_READY]) || (layer1.cur_anim == alist[ANIM_DAGGER_READY_PART_2]) || (layer1.cur_anim == alist[ANIM_DAGGER_READY_PART_1]) || (layer1.cur_anim == alist[ANIM_1H_READY_PART_2]) || (layer1.cur_anim == alist[ANIM_1H_READY_PART_1]) || (layer1.cur_anim == alist[ANIM_2H_READY_PART_2]) || (layer1.cur_anim == alist[ANIM_2H_READY_PART_1]) || (layer1.cur_anim == alist[ANIM_MISSILE_READY_PART_1]) || (layer1.cur_anim == alist[ANIM_MISSILE_READY_PART_2]) ) ) { AimTime = (unsigned long)(arxtime); } if(layer1.flags & EA_ANIMEND) { WeaponType weapontype = ARX_EQUIPMENT_GetPlayerWeaponType(); if(layer1.cur_anim && ( (layer1.cur_anim == io->anims[ANIM_BARE_UNREADY]) || (layer1.cur_anim == io->anims[ANIM_DAGGER_UNREADY_PART_2]) || (layer1.cur_anim == io->anims[ANIM_1H_UNREADY_PART_2]) || (layer1.cur_anim == io->anims[ANIM_2H_UNREADY_PART_2]) || (layer1.cur_anim == io->anims[ANIM_MISSILE_UNREADY_PART_2]) ) ) { AcquireLastAnim(io); layer1.cur_anim = NULL; } switch(weapontype) { case WEAPON_BARE: { // Is Weapon Ready ? In this case go to Fight Wait anim if(layer1.cur_anim == alist[ANIM_BARE_READY]) { if(player.Interface & INTER_NO_STRIKE) { player.Interface &= ~INTER_NO_STRIKE; changeAnimation(io, 1, alist[ANIM_BARE_WAIT], EA_LOOP); } else { changeAnimation(io, 1, alist[ANIM_BARE_STRIKE_LEFT_START + CurrFightPos * 3]); } AimTime = (unsigned long)(arxtime); io->isHit = false; } break; } case WEAPON_DAGGER: // DAGGER ANIMS end if(alist[ANIM_DAGGER_READY_PART_1]) { if(layer1.cur_anim == alist[ANIM_DAGGER_READY_PART_1]) { ARX_EQUIPMENT_AttachPlayerWeaponToHand(); changeAnimation(io, 1, alist[ANIM_DAGGER_READY_PART_2]); } else if(layer1.cur_anim == alist[ANIM_DAGGER_READY_PART_2]) { if(player.Interface & INTER_NO_STRIKE) { player.Interface &= ~INTER_NO_STRIKE; changeAnimation(io, 1, alist[ANIM_DAGGER_WAIT], EA_LOOP); } else { changeAnimation(io, 1, alist[ANIM_DAGGER_STRIKE_LEFT_START + CurrFightPos * 3]); } AimTime = (unsigned long)(arxtime); io->isHit = false; } else if(layer1.cur_anim == alist[ANIM_DAGGER_UNREADY_PART_1]) { ARX_EQUIPMENT_AttachPlayerWeaponToBack(); changeAnimation(io, 1, alist[ANIM_DAGGER_UNREADY_PART_2]); } } break; case WEAPON_1H: // 1H ANIMS end if(alist[ANIM_1H_READY_PART_1]) { if(layer1.cur_anim == alist[ANIM_1H_READY_PART_1]) { ARX_EQUIPMENT_AttachPlayerWeaponToHand(); changeAnimation(io, 1, alist[ANIM_1H_READY_PART_2]); } else if(layer1.cur_anim == alist[ANIM_1H_READY_PART_2]) { if(player.Interface & INTER_NO_STRIKE) { player.Interface &= ~INTER_NO_STRIKE; changeAnimation(io, 1, alist[ANIM_1H_WAIT], EA_LOOP); } else { changeAnimation(io, 1, alist[ANIM_1H_STRIKE_LEFT_START + CurrFightPos * 3]); } AimTime = (unsigned long)(arxtime); io->isHit = false; } else if (layer1.cur_anim == alist[ANIM_1H_UNREADY_PART_1]) { ARX_EQUIPMENT_AttachPlayerWeaponToBack(); changeAnimation(io, 1, alist[ANIM_1H_UNREADY_PART_2]); } } break; case WEAPON_2H: // 2H ANIMS end if(alist[ANIM_2H_READY_PART_1]) { if(layer1.cur_anim == alist[ANIM_2H_READY_PART_1]) { ARX_EQUIPMENT_AttachPlayerWeaponToHand(); changeAnimation(io, 1, alist[ANIM_2H_READY_PART_2]); } else if(layer1.cur_anim == alist[ANIM_2H_READY_PART_2]) { if(player.Interface & INTER_NO_STRIKE) { player.Interface &= ~INTER_NO_STRIKE; changeAnimation(io, 1, alist[ANIM_2H_WAIT], EA_LOOP); } else { changeAnimation(io, 1, alist[ANIM_2H_STRIKE_LEFT_START + CurrFightPos * 3]); } AimTime = (unsigned long)(arxtime); io->isHit = false; } else if(layer1.cur_anim == alist[ANIM_2H_UNREADY_PART_1]) { ARX_EQUIPMENT_AttachPlayerWeaponToBack(); changeAnimation(io, 1, alist[ANIM_2H_UNREADY_PART_2]); } } break; case WEAPON_BOW:// MISSILE Weapon ANIMS end if(alist[ANIM_MISSILE_READY_PART_1]) { if(layer1.cur_anim == alist[ANIM_MISSILE_READY_PART_1]) { ARX_EQUIPMENT_AttachPlayerWeaponToHand(); changeAnimation(io, 1, alist[ANIM_MISSILE_READY_PART_2]); } else if(layer1.cur_anim == alist[ANIM_MISSILE_READY_PART_2]) { if(Player_Arrow_Count() > 0) { if(player.Interface & INTER_NO_STRIKE) { player.Interface &= ~INTER_NO_STRIKE; changeAnimation(io, 1, alist[ANIM_MISSILE_WAIT], EA_LOOP); } else { changeAnimation(io, 1, alist[ANIM_MISSILE_STRIKE_PART_1]); } io->isHit = false; } else { changeAnimation(io, 1, alist[ANIM_MISSILE_WAIT]); } EERIE_LINKEDOBJ_UnLinkObjectFromObject(io->obj, arrowobj); } else if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_PART_1]) { // TODO why no AcquireLastAnim()? ANIM_Set(layer1, alist[ANIM_MISSILE_STRIKE_PART_2]); } else if(layer1.cur_anim == alist[ANIM_MISSILE_STRIKE_PART_2]) { // TODO why no AcquireLastAnim()? ANIM_Set(layer1, alist[ANIM_MISSILE_STRIKE_CYCLE]); } else if(layer1.cur_anim == alist[ANIM_MISSILE_UNREADY_PART_1]) { ARX_EQUIPMENT_AttachPlayerWeaponToBack(); changeAnimation(io, 1, alist[ANIM_MISSILE_UNREADY_PART_2]); } } break; } // Spell casting anims if(alist[ANIM_CAST] && layer1.cur_anim == alist[ANIM_CAST]) { if(alist[ANIM_CAST_END]) { changeAnimation(io, 1, alist[ANIM_CAST_END]); } } else if(alist[ANIM_CAST_END] && layer1.cur_anim == alist[ANIM_CAST_END]) { AcquireLastAnim(io); layer1.cur_anim = NULL; player.doingmagic = 0; if(WILLRETURNTOCOMBATMODE) { player.Interface |= INTER_COMBATMODE; player.Interface |= INTER_NO_STRIKE; ARX_EQUIPMENT_LaunchPlayerReadyWeapon(); WILLRETURNTOCOMBATMODE = false; } } } // Is the shield off ? if(layer3.flags & EA_ANIMEND) { if(io->anims[ANIM_SHIELD_END] && layer3.cur_anim == io->anims[ANIM_SHIELD_END]) { AcquireLastAnim(io); layer3.cur_anim = NULL; } } }
/*! * \brief Main Procedure to draw an animated object * * \param eobj main object data * \param eanim Animation data * \param time Time increment to current animation in Ms * \param io Referrence to Interactive Object (NULL if no IO) */ void PrepareAnim(AnimLayer & layer, AnimationDuration time, Entity *io) { if(layer.flags & EA_PAUSED) time = AnimationDuration_ZERO; if(io && (io->ioflags & IO_FREEZESCRIPT)) time = AnimationDuration_ZERO; if(layer.altidx_cur >= layer.cur_anim->alt_nb) layer.altidx_cur = 0; if(!(layer.flags & EA_EXCONTROL)) layer.ctime += time; layer.flags &= ~EA_ANIMEND; AnimationDuration animTime = layer.cur_anim->anims[layer.altidx_cur]->anim_time; if(layer.ctime > animTime) { if(layer.flags & EA_STOPEND) { layer.ctime = animTime; } AnimationDuration lost = layer.ctime - animTime; if((layer.flags & EA_LOOP) || (io && ((layer.cur_anim == io->anims[ANIM_WALK]) || (layer.cur_anim == io->anims[ANIM_WALK2]) || (layer.cur_anim == io->anims[ANIM_WALK3]) || (layer.cur_anim == io->anims[ANIM_RUN]) || (layer.cur_anim == io->anims[ANIM_RUN2]) || (layer.cur_anim == io->anims[ANIM_RUN3]))) ) { if(!layer.next_anim) { layer.ctime = AnimationDuration(layer.ctime.t % animTime.t); if(io) FinishAnim(io, layer.cur_anim); } else { if(io) { FinishAnim(io, layer.cur_anim); if(io->animBlend.lastanimtime != ArxInstant_ZERO) AcquireLastAnim(io); else io->animBlend.lastanimtime = ArxInstantMs(1); } layer.cur_anim = layer.next_anim; layer.altidx_cur = ANIM_GetAltIdx(layer.next_anim, layer.altidx_cur); layer.next_anim = NULL; ResetAnim(layer); layer.ctime = lost; layer.flags = layer.nextflags; layer.flags &= ~EA_ANIMEND; } } else { if(io && layer.next_anim) { FinishAnim(io, layer.cur_anim); if (io->animBlend.lastanimtime != ArxInstant_ZERO) AcquireLastAnim(io); else io->animBlend.lastanimtime = ArxInstant(1); layer.cur_anim = layer.next_anim; layer.altidx_cur = ANIM_GetAltIdx(layer.next_anim, layer.altidx_cur); layer.next_anim = NULL; ResetAnim(layer); layer.ctime = lost; layer.flags = layer.nextflags; layer.flags &= ~EA_ANIMEND; } else { layer.flags |= EA_ANIMEND; layer.ctime = layer.cur_anim->anims[layer.altidx_cur]->anim_time; } } } if (!layer.cur_anim) return; AnimationDuration tim; if(layer.flags & EA_REVERSE) tim = animTime - layer.ctime; else tim = layer.ctime; EERIE_ANIM * anim = layer.cur_anim->anims[layer.altidx_cur]; layer.currentFrame = anim->nb_key_frames - 2; layer.currentInterpolation = 1.f; for(long i = 1; i < anim->nb_key_frames; i++) { AnimationDuration tcf = anim->frames[i - 1].time; AnimationDuration tnf = anim->frames[i].time; if(tcf == tnf) return; if((tim < tnf && tim >= tcf) || (i == anim->nb_key_frames - 1 && tim == tnf)) { long fr = i - 1; tim -= tcf; float pour = toMsf(tim) / toMsf(tnf - tcf); // Frame Sound Management if(!(layer.flags & EA_ANIMEND) && time != AnimationDuration_ZERO && (anim->frames[fr].sample != -1) && (layer.lastframe != fr)) { Vec3f * position = io ? &io->pos : NULL; if(layer.lastframe < fr && layer.lastframe != -1) { for(long n = layer.lastframe + 1; n <= fr; n++) ARX_SOUND_PlayAnim(anim->frames[n].sample, position); } else { ARX_SOUND_PlayAnim(anim->frames[fr].sample, position); } } // Frame Flags Management if(!(layer.flags & EA_ANIMEND) && time != AnimationDuration_ZERO && (anim->frames[fr].stepSound) && (layer.lastframe != fr)) { if(io && io != entities.player()) { if(layer.lastframe < fr && layer.lastframe != -1) { for(long n = layer.lastframe + 1; n <= fr; n++) { if(anim->frames[n].stepSound) ARX_NPC_NeedStepSound(io, io->pos); } } else if(anim->frames[fr].stepSound) ARX_NPC_NeedStepSound(io, io->pos); } } // Memorize this frame as lastframe. layer.lastframe = fr; layer.currentFrame = fr; layer.currentInterpolation = pour; break; } } }
void stopAnimation(Entity * entity, size_t layer) { AnimLayer & animlayer = entity->animlayer[layer]; AcquireLastAnim(entity); FinishAnim(entity, animlayer.cur_anim); animlayer.cur_anim = NULL; }
/*! * \brief Main Procedure to draw an animated object * * \param eobj main object data * \param eanim Animation data * \param time Time increment to current animation in Ms * \param io Referrence to Interactive Object (NULL if no IO) */ void PrepareAnim(AnimLayer & layer, unsigned long time, Entity *io) { if(layer.flags & EA_PAUSED) time = 0; if(io && (io->ioflags & IO_FREEZESCRIPT)) time = 0; if(layer.altidx_cur >= layer.cur_anim->alt_nb) layer.altidx_cur = 0; if(!(layer.flags & EA_EXCONTROL)) layer.ctime += time; layer.flags &= ~EA_ANIMEND; const long animTime = layer.cur_anim->anims[layer.altidx_cur]->anim_time; if(layer.ctime > animTime) { if(layer.flags & EA_STOPEND) { layer.ctime = animTime; } long lost = layer.ctime - animTime; if((layer.flags & EA_LOOP) || (io && ((layer.cur_anim == io->anims[ANIM_WALK]) || (layer.cur_anim == io->anims[ANIM_WALK2]) || (layer.cur_anim == io->anims[ANIM_WALK3]) || (layer.cur_anim == io->anims[ANIM_RUN]) || (layer.cur_anim == io->anims[ANIM_RUN2]) || (layer.cur_anim == io->anims[ANIM_RUN3]))) ) { if(!layer.next_anim) { long t = animTime; layer.ctime= layer.ctime % t; if(io) FinishAnim(io,layer.cur_anim); } else { if(io) { FinishAnim(io,layer.cur_anim); if(io->animBlend.lastanimtime != 0) AcquireLastAnim(io); else io->animBlend.lastanimtime = 1; } layer.cur_anim=layer.next_anim; layer.altidx_cur=ANIM_GetAltIdx(layer.next_anim,layer.altidx_cur); layer.next_anim=NULL; ResetAnim(layer); layer.ctime = lost; layer.flags=layer.nextflags; layer.flags&=~EA_ANIMEND; } } else { if(io && layer.next_anim) { FinishAnim(io,layer.cur_anim); if (io->animBlend.lastanimtime!=0) AcquireLastAnim(io); else io->animBlend.lastanimtime=1; layer.cur_anim=layer.next_anim; layer.altidx_cur=ANIM_GetAltIdx(layer.next_anim,layer.altidx_cur); layer.next_anim=NULL; ResetAnim(layer); layer.ctime = lost; layer.flags=layer.nextflags; layer.flags&=~EA_ANIMEND; } else { layer.flags |= EA_ANIMEND; layer.ctime = layer.cur_anim->anims[layer.altidx_cur]->anim_time; } } } if (!layer.cur_anim) return; long tim; if(layer.flags & EA_REVERSE) tim = animTime - layer.ctime; else tim = layer.ctime; EERIE_ANIM * anim = layer.cur_anim->anims[layer.altidx_cur]; layer.fr = anim->nb_key_frames - 2; layer.pour = 1.f; for(long i = 1; i < anim->nb_key_frames; i++) { long tcf = (long)anim->frames[i - 1].time; long tnf = (long)anim->frames[i].time; if(tcf == tnf) return; if((tim < tnf && tim >= tcf) || (i == anim->nb_key_frames - 1 && tim == tnf)) { long fr = i - 1; tim -= tcf; float pour = (float)((float)tim/((float)tnf-(float)tcf)); // Frame Sound Management if(!(layer.flags & EA_ANIMEND) && time && (anim->frames[fr].sample != -1) && (layer.lastframe != fr)) { Vec3f * position = io ? &io->pos : NULL; if(layer.lastframe < fr && layer.lastframe != -1) { for(long n = layer.lastframe + 1; n <= fr; n++) ARX_SOUND_PlayAnim(anim->frames[n].sample, position); } else { ARX_SOUND_PlayAnim(anim->frames[fr].sample, position); } } // Frame Flags Management if(!(layer.flags & EA_ANIMEND) && time && (anim->frames[fr].flag > 0) && (layer.lastframe != fr)) { if(io && io != entities.player()) { if(layer.lastframe < fr && layer.lastframe != -1) { for(long n = layer.lastframe + 1; n <= fr; n++) { if(anim->frames[n].flag == 9) ARX_NPC_NeedStepSound(io, io->pos); } } else if(anim->frames[fr].flag == 9) ARX_NPC_NeedStepSound(io, io->pos); } } // Memorize this frame as lastframe. layer.lastframe = fr; layer.fr = fr; layer.pour = pour; break; } } }
/*! * \brief Main Procedure to draw an animated object * * \param eobj main object data * \param eanim Animation data * \param time Time increment to current animation in Ms * \param io Referrence to Interactive Object (NULL if no IO) */ void PrepareAnim(ANIM_USE *eanim, unsigned long time, Entity *io) { if(!eanim) return; if(eanim->flags & EA_PAUSED) time = 0; if(io && (io->ioflags & IO_FREEZESCRIPT)) time = 0; if(eanim->altidx_cur >= eanim->cur_anim->alt_nb) eanim->altidx_cur = 0; if(!(eanim->flags & EA_EXCONTROL)) eanim->ctime += time; eanim->flags &= ~EA_ANIMEND; if((eanim->flags & EA_STOPEND) && eanim->ctime > eanim->cur_anim->anims[eanim->altidx_cur]->anim_time) { eanim->ctime = eanim->cur_anim->anims[eanim->altidx_cur]->anim_time; } if((eanim->flags & EA_LOOP) || (io && ((eanim->cur_anim == io->anims[ANIM_WALK]) || (eanim->cur_anim == io->anims[ANIM_WALK2]) || (eanim->cur_anim == io->anims[ANIM_WALK3]) || (eanim->cur_anim == io->anims[ANIM_RUN]) || (eanim->cur_anim == io->anims[ANIM_RUN2]) || (eanim->cur_anim == io->anims[ANIM_RUN3])))) { if(eanim->ctime > eanim->cur_anim->anims[eanim->altidx_cur]->anim_time) { long lost = eanim->ctime - long(eanim->cur_anim->anims[eanim->altidx_cur]->anim_time); if(!eanim->next_anim) { long t = eanim->cur_anim->anims[eanim->altidx_cur]->anim_time; eanim->ctime= eanim->ctime % t; if(io) FinishAnim(io,eanim->cur_anim); } else { if(io) { FinishAnim(io,eanim->cur_anim); if(io->animBlend.lastanimtime != 0) AcquireLastAnim(io); else io->animBlend.lastanimtime = 1; } eanim->cur_anim=eanim->next_anim; eanim->altidx_cur=ANIM_GetAltIdx(eanim->next_anim,eanim->altidx_cur); eanim->next_anim=NULL; ResetAnim(eanim); eanim->ctime = lost; eanim->flags=eanim->nextflags; eanim->flags&=~EA_ANIMEND; } } } else if (eanim->ctime > eanim->cur_anim->anims[eanim->altidx_cur]->anim_time) { if(io) { long lost = eanim->ctime - eanim->cur_anim->anims[eanim->altidx_cur]->anim_time; if(eanim->next_anim) { FinishAnim(io,eanim->cur_anim); if (io->animBlend.lastanimtime!=0) AcquireLastAnim(io); else io->animBlend.lastanimtime=1; eanim->cur_anim=eanim->next_anim; eanim->altidx_cur=ANIM_GetAltIdx(eanim->next_anim,eanim->altidx_cur); eanim->next_anim=NULL; ResetAnim(eanim); eanim->ctime = lost; eanim->flags=eanim->nextflags; eanim->flags&=~EA_ANIMEND; goto suite; } } eanim->flags |= EA_ANIMEND; eanim->ctime = eanim->cur_anim->anims[eanim->altidx_cur]->anim_time; } suite: if (!eanim->cur_anim) return; long tim; if(eanim->flags & EA_REVERSE) tim = eanim->cur_anim->anims[eanim->altidx_cur]->anim_time - eanim->ctime; else tim = eanim->ctime; eanim->fr = eanim->cur_anim->anims[eanim->altidx_cur]->nb_key_frames - 2; eanim->pour = 1.f; long fr; for(long i = 1; i < eanim->cur_anim->anims[eanim->altidx_cur]->nb_key_frames; i++) { long tcf = (long)eanim->cur_anim->anims[eanim->altidx_cur]->frames[i - 1].time; long tnf = (long)eanim->cur_anim->anims[eanim->altidx_cur]->frames[i].time; if(tcf == tnf) return; if((tim < tnf && tim >= tcf) || (i == eanim->cur_anim->anims[eanim->altidx_cur]->nb_key_frames - 1 && tim == tnf)) { fr = i - 1; tim -= tcf; float pour = (float)((float)tim/((float)tnf-(float)tcf)); // Frame Sound Management if(!(eanim->flags & EA_ANIMEND) && time && (eanim->cur_anim->anims[eanim->altidx_cur]->frames[fr].sample != -1) && (eanim->lastframe != fr)) { Vec3f * position = io ? &io->pos : NULL; if(eanim->lastframe < fr && eanim->lastframe != -1) { for(long n = eanim->lastframe + 1; n <= fr; n++) ARX_SOUND_PlayAnim(eanim->cur_anim->anims[eanim->altidx_cur]->frames[n].sample, position); } else { ARX_SOUND_PlayAnim(eanim->cur_anim->anims[eanim->altidx_cur]->frames[fr].sample, position); } } // Frame Flags Management if(!(eanim->flags & EA_ANIMEND) && time && (eanim->cur_anim->anims[eanim->altidx_cur]->frames[fr].flag > 0) && (eanim->lastframe != fr)) { if(io != entities.player()) { if(eanim->lastframe < fr && eanim->lastframe != -1) { for(long n = eanim->lastframe + 1; n <= fr; n++) { if(eanim->cur_anim->anims[eanim->altidx_cur]->frames[n].flag == 9) ARX_NPC_NeedStepSound(io, &io->pos); } } else if(eanim->cur_anim->anims[eanim->altidx_cur]->frames[fr].flag == 9) ARX_NPC_NeedStepSound(io, &io->pos); } } // Memorize this frame as lastframe. eanim->lastframe = fr; eanim->fr = fr; eanim->pour = pour; break; } } }