void GraphicsEntity::SetAnimation( const AnimAction& act, AnimDirection face, AnimDirection move, AnimLength len ) { m_Face = face; m_Move = move; UpdateDir(); RSKMAP_ITERATE( m_Layers ) iter->second->SetAnimation( act, m_Face, m_Move, len ); }
void CGeoThermSmokeProjectile::Update() { UpdateDir(); // NOTE: // speed.w is never changed from its initial value (!), otherwise the // particles would just keep accelerating even when wind == ZeroVector // due to UpVector being added each frame --> if |speed| grows LARGER // than speed.w then newSpeed will be adjusted downward and vice versa CWorldObject::SetVelocity(speed + UpVector); CWorldObject::SetVelocity(speed + XZVector * (wind.GetCurrentWind() / GAME_SPEED)); const float curSpeed = fastmath::sqrt_builtin(speed.SqLength()); const float newSpeed = speed.w * (speed.w / curSpeed); CWorldObject::SetVelocity((dir = (speed / curSpeed)) * newSpeed); CSmokeProjectile::Update(); }
bool CChar::Use_EatQty( CItem * pFood, short iQty ) { ADDTOCALLSTACK("CChar::Use_EatQty"); // low level eat ASSERT(pFood); if ( iQty <= 0 ) return false; if ( iQty > pFood->GetAmount() ) iQty = pFood->GetAmount(); short iRestore = 0; if ( pFood->m_itFood.m_foodval ) iRestore = static_cast<short>(pFood->m_itFood.m_foodval); else iRestore = pFood->Item_GetDef()->GetVolume(); // some food should have more value than other ! if ( iRestore < 1 ) iRestore = 1; short iSpace = Stat_GetMax(STAT_FOOD) - Stat_GetVal(STAT_FOOD); if ( iSpace <= 0 ) return false; if ( iQty > 1 && (iRestore * iQty > iSpace) ) iQty = maximum(1, iSpace / iRestore); switch ( pFood->GetType() ) { case IT_FRUIT: case IT_FOOD: case IT_FOOD_RAW: case IT_MEAT_RAW: if ( pFood->m_itFood.m_poison_skill ) // was the food poisoned? SetPoison(pFood->m_itFood.m_poison_skill * 10, 1 + (pFood->m_itFood.m_poison_skill / 50), this); default: break; } UpdateDir(pFood); EatAnim(pFood->GetName(), iRestore * iQty); pFood->ConsumeAmount(iQty); return true; }
bool CChar::Use_Repair( CItem * pItemArmor ) { ADDTOCALLSTACK("CChar::Use_Repair"); // Attempt to repair the item. // If it is repairable. if ( !pItemArmor || !pItemArmor->Armor_IsRepairable() ) { SysMessageDefault(DEFMSG_REPAIR_NOT); return false; } if ( pItemArmor->IsItemEquipped() ) { SysMessageDefault(DEFMSG_REPAIR_WORN); return false; } if ( !CanUse(pItemArmor, true) ) { SysMessageDefault(DEFMSG_REPAIR_REACH); return false; } // Quickly use arms lore skill, but don't gain any skill until later on int iArmsLoreDiff = Calc_GetRandVal(30); if ( !Skill_UseQuick(SKILL_ARMSLORE, iArmsLoreDiff, false) ) { // apply arms lore skillgain for failure Skill_Experience(SKILL_ARMSLORE, -iArmsLoreDiff); SysMessageDefault(DEFMSG_REPAIR_UNK); return false; } if ( pItemArmor->m_itArmor.m_Hits_Cur >= pItemArmor->m_itArmor.m_Hits_Max ) { SysMessageDefault(DEFMSG_REPAIR_FULL); return false; } m_Act_p = g_World.FindItemTypeNearby(GetTopPoint(), IT_ANVIL, 2, false); if ( !m_Act_p.IsValidPoint() ) { SysMessageDefault(DEFMSG_REPAIR_ANVIL); return false; } CItemBase *pItemDef = pItemArmor->Item_GetDef(); ASSERT(pItemDef); // Use up some raw materials to repair. int iTotalHits = pItemArmor->m_itArmor.m_Hits_Max; int iDamageHits = pItemArmor->m_itArmor.m_Hits_Max - pItemArmor->m_itArmor.m_Hits_Cur; int iDamagePercent = IMULDIV(100, iDamageHits, iTotalHits); size_t iMissing = ResourceConsumePart(&(pItemDef->m_BaseResources), 1, iDamagePercent / 2, true); if ( iMissing != pItemDef->m_BaseResources.BadIndex() ) { // Need this to repair. const CResourceDef *pCompDef = g_Cfg.ResourceGetDef(pItemDef->m_BaseResources.GetAt(iMissing).GetResourceID()); SysMessagef(g_Cfg.GetDefaultMsg(DEFMSG_REPAIR_LACK_1), pCompDef ? pCompDef->GetName() : g_Cfg.GetDefaultMsg(DEFMSG_REPAIR_LACK_2)); return false; } UpdateDir(m_Act_p); UpdateAnimate(ANIM_ATTACK_1H_SLASH); // quarter the skill to make it. // + more damaged items should be harder to repair. // higher the percentage damage the closer to the skills to make it. size_t iRes = pItemDef->m_SkillMake.FindResourceType(RES_SKILL); if ( iRes == pItemDef->m_SkillMake.BadIndex() ) return false; CResourceQty RetMainSkill = pItemDef->m_SkillMake[iRes]; int iSkillLevel = static_cast<int>(RetMainSkill.GetResQty()) / 10; int iDifficulty = IMULDIV(iSkillLevel, iDamagePercent, 100); if ( iDifficulty < iSkillLevel / 4 ) iDifficulty = iSkillLevel / 4; // apply arms lore skillgain now LPCTSTR pszText; Skill_Experience(SKILL_ARMSLORE, iArmsLoreDiff); bool fSuccess = Skill_UseQuick(static_cast<SKILL_TYPE>(RetMainSkill.GetResIndex()), iDifficulty); if ( fSuccess ) { pItemArmor->m_itArmor.m_Hits_Cur = static_cast<WORD>(iTotalHits); pszText = g_Cfg.GetDefaultMsg(DEFMSG_REPAIR_1); } else { /***************************** // not sure if this is working! ******************************/ // Failure if ( !Calc_GetRandVal(6) ) { pszText = g_Cfg.GetDefaultMsg(DEFMSG_REPAIR_2); pItemArmor->m_itArmor.m_Hits_Max--; pItemArmor->m_itArmor.m_Hits_Cur--; } else if ( !Calc_GetRandVal(3) ) { pszText = g_Cfg.GetDefaultMsg(DEFMSG_REPAIR_3); pItemArmor->m_itArmor.m_Hits_Cur--; } else pszText = g_Cfg.GetDefaultMsg( DEFMSG_REPAIR_4 ); iDamagePercent = Calc_GetRandVal(iDamagePercent); // some random amount } ResourceConsumePart(&(pItemDef->m_BaseResources), 1, iDamagePercent / 2, false); if ( pItemArmor->m_itArmor.m_Hits_Cur <= 0 ) pszText = g_Cfg.GetDefaultMsg(DEFMSG_REPAIR_5); TCHAR *pszMsg = Str_GetTemp(); sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_REPAIR_MSG), pszText, pItemArmor->GetName()); Emote(pszMsg); if ( pItemArmor->m_itArmor.m_Hits_Cur <= 0 ) pItemArmor->Delete(); else pItemArmor->UpdatePropertyFlag(AUTOTOOLTIP_FLAG_DURABILITY); return fSuccess; }