void Creature::updateWalkAnimation(int totalPixelsWalked) { // update outfit animation if(m_outfit.getCategory() != ThingCategoryCreature) return; int footAnimPhases = getAnimationPhases() - 1; int footDelay = getStepDuration(true) / 3; // Since mount is a different outfit we need to get the mount animation phases if(m_outfit.getMount() != 0) { ThingType *type = g_things.rawGetThingType(m_outfit.getMount(), m_outfit.getCategory()); footAnimPhases = type->getAnimationPhases() - 1; } if(footAnimPhases == 0) m_walkAnimationPhase = 0; else if(m_footStepDrawn && m_footTimer.ticksElapsed() >= footDelay && totalPixelsWalked < 32) { m_footStep++; m_walkAnimationPhase = 1 + (m_footStep % footAnimPhases); m_footStepDrawn = false; m_footTimer.restart(); } else if(m_walkAnimationPhase == 0 && totalPixelsWalked < 32) { m_walkAnimationPhase = 1 + (m_footStep % footAnimPhases); } if(totalPixelsWalked == 32 && !m_walkFinishAnimEvent) { auto self = static_self_cast<Creature>(); m_walkFinishAnimEvent = g_dispatcher.scheduleEvent([self] { if(!self->m_walking || self->m_walkTimer.ticksElapsed() >= self->getStepDuration(true)) self->m_walkAnimationPhase = 0; self->m_walkFinishAnimEvent = nullptr; }, std::min<int>(footDelay, 200)); } }
void Creature::internalDrawOutfit(Point dest, float scaleFactor, bool animateWalk, bool animateIdle, Otc::Direction direction) { // outfit is a real creature if(m_outfit.getCategory() == ThingCategoryCreature) { int animationPhase = animateWalk ? m_walkAnimationPhase : 0; if(isAnimateAlways() && animateIdle) { int ticksPerFrame = 1000 / getAnimationPhases(); animationPhase = (g_clock.millis() % (ticksPerFrame * getAnimationPhases())) / ticksPerFrame; } // xPattern => creature direction int xPattern; if(direction == Otc::NorthEast || direction == Otc::SouthEast) xPattern = Otc::East; else if(direction == Otc::NorthWest || direction == Otc::SouthWest) xPattern = Otc::West; else xPattern = direction; int zPattern = 0; if(m_outfit.getMount() != 0) { auto datType = g_things.rawGetThingType(m_outfit.getMount(), ThingCategoryCreature); dest -= datType->getDisplacement() * scaleFactor; datType->draw(dest, scaleFactor, 0, xPattern, 0, 0, animationPhase); dest += getDisplacement() * scaleFactor; zPattern = 1; } // yPattern => creature addon for(int yPattern = 0; yPattern < getNumPatternY(); yPattern++) { // continue if we dont have this addon if(yPattern > 0 && !(m_outfit.getAddons() & (1 << (yPattern-1)))) continue; auto datType = rawGetThingType(); datType->draw(dest, scaleFactor, 0, xPattern, yPattern, zPattern, animationPhase); if(getLayers() > 1) { Color oldColor = g_painter->getColor(); Painter::CompositionMode oldComposition = g_painter->getCompositionMode(); g_painter->setCompositionMode(Painter::CompositionMode_Multiply); g_painter->setColor(m_outfit.getHeadColor()); datType->draw(dest, scaleFactor, SpriteMaskYellow, xPattern, yPattern, zPattern, animationPhase); g_painter->setColor(m_outfit.getBodyColor()); datType->draw(dest, scaleFactor, SpriteMaskRed, xPattern, yPattern, zPattern, animationPhase); g_painter->setColor(m_outfit.getLegsColor()); datType->draw(dest, scaleFactor, SpriteMaskGreen, xPattern, yPattern, zPattern, animationPhase); g_painter->setColor(m_outfit.getFeetColor()); datType->draw(dest, scaleFactor, SpriteMaskBlue, xPattern, yPattern, zPattern, animationPhase); g_painter->setColor(oldColor); g_painter->setCompositionMode(oldComposition); } } // outfit is a creature imitating an item or the invisible effect } else { ThingType *type = g_things.rawGetThingType(m_outfit.getAuxId(), m_outfit.getCategory()); int animationPhase = 0; int animationPhases = type->getAnimationPhases(); int animateTicks = Otc::ITEM_TICKS_PER_FRAME; // when creature is an effect we cant render the first and last animation phase, // instead we should loop in the phases between if(m_outfit.getCategory() == ThingCategoryEffect) { animationPhases = std::max(1, animationPhases-2); animateTicks = Otc::INVISIBLE_TICKS_PER_FRAME; } if(animationPhases > 1) { if(animateIdle) animationPhase = (g_clock.millis() % (animateTicks * animationPhases)) / animateTicks; else animationPhase = animationPhases-1; } if(m_outfit.getCategory() == ThingCategoryEffect) animationPhase = std::min(animationPhase+1, animationPhases); type->draw(dest - (getDisplacement() * scaleFactor), scaleFactor, 0, 0, 0, 0, animationPhase); } }