void OnDied(Unit* pKiller) { if(pSkarvald != NULL && pSkarvald->IsAlive()) { Emote("See... you... soon.", Text_Yell, 0); pSkarvald->Emote("Pagh! What sort of necromancer lets death stop him? I knew you were worthless!", Text_Yell, 13233); SpawnCreature(CN_DALRONN_GHOST, true); _unit->SetUInt64Value(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); } else if(pSkarvald != NULL && !pSkarvald->IsAlive()) { Emote("There's no... greater... glory.", Text_Yell, 13201); pSkarvaldGhost = GetNearestCreature(CN_SKARVALD_GHOST); if(pSkarvaldGhost != NULL) { pSkarvaldGhost->Despawn(1000, 0); pSkarvaldGhost = NULL; } } ParentClass::OnDied(pKiller); };
void OnReachWP(uint32 iWaypointId, bool bForwards) { if(iWaypointId == 1) { switch(RandomUInt(2)) { case 0: Emote("Life from the lifelessness... death for you.", Text_Yell, 13961); break; case 1: Emote("Nothing is wasted in the process. You will see....", Text_Yell, 13962); break; }; MoonScriptCreatureAI* pAnvil = GetNearestCreature(CN_VOLKHANS_ANVIL); if(pAnvil) _unit->CastSpell(pAnvil->GetUnit(), SPELL_TEMPER, true); else _unit->CastSpell(GetUnit(), SPELL_TEMPER, true); SetCanEnterCombat(true); _unit->GetAIInterface()->AttackReaction(GetNearestPlayer() , 1); // hackfix }; };
void AIUpdate() { if(IsTimerFinished(mNovaTimer)) { switch(RandomUInt(2)) { case 0: Emote("You cannot hide from fate!", Text_Yell, 14163); break; case 1: Emote("Come closer. I will make it quick.", Text_Yell, 14164); break; case 2: Emote("Your flesh cannot hold out for long.", Text_Yell, 14165); break; }; Announce("Loken begins to cast Lightning Nova!"); CastSpellNowNoScheduling(mNova); ResetTimer(mNovaTimer, TIMER_NOVA + (RandomUInt(8) * 1000)); }; if(mSpeech == 4) return; if(GetHealthPercent() <= (100 - (25 * mSpeech))) { switch(mSpeech) { case 1: Emote("You stare blindly into the abyss!", Text_Yell, 14169); break; case 2: Emote("Your ignorance is profound. Can you not see where this path leads?", Text_Yell, 14170); break; case 3: Emote("You cross the precipice of oblivion!", Text_Yell, 14171); break; ++mSpeech; }; }; if(IsTimerFinished(mRespondTimer)) { Emote("My master has shown me the future, and you have no place in it. Azeroth will be reborn in darkness. Yogg-Saron shall be released! The Pantheon shall fall!", Text_Yell, 14161); RemoveTimer(mRespondTimer); RemoveAIUpdateEvent(); }; ParentClass::AIUpdate(); };
void AIUpdate() { if(IsTimerFinished(mRessTimer)) { SetPhase(2); _unit->RemoveFlag(UNIT_FIELD_FLAGS, UNIT_FLAG_NOT_SELECTABLE); _unit->SetUInt32Value(UNIT_FIELD_DISPLAYID, 26351); _unit->SetUInt32Value(UNIT_FIELD_HEALTH,_unit->GetUInt32Value(UNIT_FIELD_MAXHEALTH)); _unit->setDeathState(ALIVE); _unit->WipeTargetList(); _unit->WipeHateList(); Emote("I return! A second chance to carve out your skull!", Text_Yell, 13209); RemoveTimer(mRessTimer); } }
void Merge() { if( mLynx ) { mLynx->Despawn(0, 0); mLynx = NULL; Emote("Spirit, come back to me!", Text_Yell, 12022); } if(CurrentHealth) _unit->SetHealth(CurrentHealth); if(MaxHealth) _unit->SetUInt32Value(UNIT_FIELD_MAXHEALTH, MaxHealth); SetDisplayId(21632); SplitCount++; SetPhase(1); }
LokenAI(Creature* pCreature) : MoonScriptCreatureAI(pCreature) { mInstance = GetInstanceScript(); mNova = AddSpell( LIGHTNING_NOVA, Target_Self, 0, 4.0f, 0 ); AddSpell( ARC_LIGHTNING, Target_RandomPlayer, 25, 0, 6 ); Emote( "I have witnessed the rise and fall of empires. The birth and extinction of entire species. Over countless millennia the foolishness of mortals has remained the only constant. Your presence here confirms this.", Text_Yell, 14160 ); AddEmote( Event_OnCombatStart, "What hope is there for you? None!", Text_Yell, 14162 ); AddEmote( Event_OnTargetDied, "Only mortal...", Text_Yell, 14166 ); AddEmote( Event_OnTargetDied, "I... am... FOREVER!", Text_Yell, 14167 ); AddEmote( Event_OnTargetDied, "What little time you had, you wasted!", Text_Yell, 14168 ); AddEmote( Event_OnDied, "My death... heralds the end of this world.", Text_Yell, 14172 ); mNovaTimer = INVALIDATE_TIMER; mRespondTimer = AddTimer( TIMER_RESPOND ); RegisterAIUpdateEvent( 1000 ); mSpeech = 1; };
void AIUpdate() { ParentClass::AIUpdate(); if( IsTimerFinished( mSummonTime ) ) { MoonScriptCreatureAI *Eagle = NULL; // Spawn 3 Soaring Eagles for(int x=0; x<3; x++) { Eagle = SpawnCreature(CN_SOARING_EAGLE, ( _unit->GetPositionX() + RandomFloat( 12 ) - 10 ), ( _unit->GetPositionY()+ RandomFloat( 12 ) - 15 ), _unit->GetPositionZ(), _unit->GetOrientation(), true); if(Eagle) { Eagle->AggroNearestUnit(); Eagle->SetDespawnWhenInactive(true); } } Eagle = NULL; Emote("Feed, me bruddahs!", Text_Yell, 12019); // Restart the timer ResetTimer( mSummonTime, 120000); } }
KilJaedenAI(Creature* pCreature) : MoonScriptBossAI(pCreature) { SetCanEnterCombat( false ); DelayNextAttack( 11600 ); SetAllowMelee( false ); SetAllowSpell( false ); SetAllowTargeting( false ); SetCanMove( false ); TriggerCooldownOnAllSpells(); SetCanMove( false ); Emote( "The expendible have perished... So be it! Now I shall succeed where Sargeras could not! I will bleed this wretched world and secure my place as the true master of the Burning Legion. The end has come! Let the unraveling of this world commence!", Text_Yell, 12500 ); mStarted = false; RegisterAIUpdateEvent( 100 ); pKJDummy = static_cast<KJDummyAI*>( GetNearestCreature( CN_KIL_JADEN_DUMMY ) ); if( pKJDummy ) pKJDummy->AddEncounterCreature( _unit ); AddPhaseSpell( 1, AddSpell( SOUL_FLAY, Target_Current, 50, 0, 6 ) ); AddPhaseSpell( 1, AddSpell( LEGION_LIGHTNING, Target_RandomPlayer, 25, 2.0f, 8 ) ); AddPhaseSpell( 1, AddSpell( FIRE_BLOOM, Target_RandomPlayer, 20, 0, 10 ) ); };
void OnCombatStart(Unit *pTarget) { Emote("Reckless mortals! None may challenge the Sons of the Living Flame!", Text_Yell, 8035); SetPhase(1); ParentClass::OnCombatStart(pTarget); }
void OnSpawn() { Emote("The Runes of Warding have been destroyed! Hunt down the infidels, my brethren!", Text_Yell, 8039); }
void CreatureTextMgr::LoadCreatureTexts() { mTextMap.clear(); // for reload case mTextRepeatMap.clear(); //reset all currently used temp texts PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_LOAD_CRETEXT); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { barGoLink bar(1); bar.step(); sLog.outString(); sLog.outString(">> Loaded 0 Creature Texts. DB table `creature_texts` is empty."); return; } barGoLink bar(result->GetRowCount()); uint32 TextCount = 0; uint32 CreatureCount = 0; do { bar.step(); Field* fields = result->Fetch(); CreatureTextEntry temp; temp.entry = fields[0].GetUInt32(); temp.group = fields[1].GetUInt8(); temp.id = fields[2].GetUInt8(); temp.text = fields[3].GetString(); temp.type = ChatType(fields[4].GetUInt8()); temp.lang = Language(fields[5].GetUInt8()); temp.probability = fields[6].GetFloat(); temp.emote = Emote(fields[7].GetUInt32()); temp.duration = fields[8].GetUInt32(); temp.sound = fields[9].GetUInt32(); if (temp.sound) { if (!sSoundEntriesStore.LookupEntry(temp.sound)){ sLog.outErrorDb("CreatureTextMgr: Entry %u, Group %u in table `creature_texts` has Sound %u but sound does not exist.", temp.entry, temp.group, temp.sound); temp.sound = 0; } } if (!GetLanguageDescByID(temp.lang)) { sLog.outErrorDb("CreatureTextMgr: Entry %u, Group %u in table `creature_texts` using Language %u but Language does not exist.", temp.entry, temp.group, uint32(temp.lang)); temp.lang = LANG_UNIVERSAL; } if (temp.type >= CHAT_TYPE_ZONE_YELL)//CHAT_TYPE_ZONE_YELL and more will be used later { sLog.outErrorDb("CreatureTextMgr: Entry %u, Group %u in table `creature_texts` has Type %u but this Chat Type does not exist.", temp.entry, temp.group, uint32(temp.type)); temp.type = CHAT_TYPE_SAY; } if (temp.emote) { if (!sEmotesStore.LookupEntry(temp.emote)) { sLog.outErrorDb("CreatureTextMgr: Entry %u, Group %u in table `creature_texts` has Emote %u but emote does not exist.", temp.entry, temp.group, uint32(temp.emote)); temp.emote = EMOTE_ONESHOT_NONE; } } //entry not yet added, add empty TextHolder (list of groups) if (mTextMap.find(temp.entry) == mTextMap.end()) { ++CreatureCount; CreatureTextHolder TextHolder; mTextMap[temp.entry] = TextHolder; } //group not yet added, add empty TextGroup (list of texts) if (mTextMap[temp.entry].find(temp.group) == mTextMap[temp.entry].end()) { CreatureTextGroup TextGroup; mTextMap[temp.entry][temp.group] = TextGroup; } //add the text into our entry's group mTextMap[temp.entry][temp.group].push_back(temp); ++TextCount; } while (result->NextRow()); sLog.outString(); sLog.outString(">> Loaded %u Creature Texts for %u Creatures.", TextCount, CreatureCount); }
void CreatureTextMgr::LoadCreatureTexts() { uint32 oldMSTime = getMSTime(); mTextMap.clear(); // for reload case //all currently used temp texts are NOT reset QueryResult_AutoPtr result = WorldDatabase.Query("SELECT entry, groupid, id, text, type, language, probability, emote, duration, sound, TextRange FROM creature_text"); if (!result) { sLog.outString(">> Loaded 0 ceature texts. DB table `creature_text` is empty."); return; } uint32 textCount = 0; do { Field* fields = result->Fetch(); CreatureTextEntry temp; temp.entry = fields[0].GetUInt32(); temp.group = fields[1].GetUInt8(); temp.id = fields[2].GetUInt8(); temp.text = fields[3].GetString(); temp.type = ChatMsg(fields[4].GetUInt8()); temp.lang = Language(fields[5].GetUInt8()); temp.probability = fields[6].GetFloat(); temp.emote = Emote(fields[7].GetUInt32()); temp.duration = fields[8].GetUInt32(); temp.sound = fields[9].GetUInt32(); temp.TextRange = CreatureTextRange(fields[10].GetUInt8()); if (temp.sound) { if (!sSoundEntriesStore.LookupEntry(temp.sound)) { sLog.outError("CreatureTextMgr: Entry %u, Group %u in table `creature_text` has Sound %u but sound does not exist.", temp.entry, temp.group, temp.sound); temp.sound = 0; } } if (!GetLanguageDescByID(temp.lang)) { sLog.outError("CreatureTextMgr: Entry %u, Group %u in table `creature_text` using Language %u but Language does not exist.", temp.entry, temp.group, uint32(temp.lang)); temp.lang = LANG_UNIVERSAL; } if (temp.type >= MAX_CHAT_MSG_TYPE) { sLog.outError("CreatureTextMgr: Entry %u, Group %u in table `creature_text` has Type %u but this Chat Type does not exist.", temp.entry, temp.group, uint32(temp.type)); temp.type = CHAT_MSG_SAY; } if (temp.emote) { if (!sEmotesStore.LookupEntry(temp.emote)) { sLog.outError("CreatureTextMgr: Entry %u, Group %u in table `creature_text` has Emote %u but emote does not exist.", temp.entry, temp.group, uint32(temp.emote)); temp.emote = EMOTE_ONESHOT_NONE; } } if (temp.TextRange > TEXT_RANGE_WORLD) { sLog.outError("CreatureTextMgr: Entry %u, Group %u, Id %u in table `creature_text` has incorrect TextRange %u.", temp.entry, temp.group, temp.id, temp.TextRange); temp.TextRange = TEXT_RANGE_NORMAL; } // add the text into our entry's group mTextMap[temp.entry][temp.group].push_back(temp); ++textCount; } while (result->NextRow()); sLog.outString(">> Loaded %u creature texts for %lu creatures in %u ms", textCount, mTextMap.size(), GetMSTimeDiffToNow(oldMSTime)); }
void CreatureTextMgr::LoadCreatureTexts() { uint32 oldMSTime = getMSTime(); mTextMap.clear(); // for reload case //all currently used temp texts are NOT reset PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_TEXT); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { TC_LOG_INFO("server.loading", ">> Loaded 0 ceature texts. DB table `creature_text` is empty."); return; } uint32 textCount = 0; do { Field* fields = result->Fetch(); CreatureTextEntry temp; temp.creatureId = fields[0].GetUInt32(); temp.groupId = fields[1].GetUInt8(); temp.id = fields[2].GetUInt8(); temp.text = fields[3].GetString(); temp.type = ChatMsg(fields[4].GetUInt8()); temp.lang = Language(fields[5].GetUInt8()); temp.probability = fields[6].GetFloat(); temp.emote = Emote(fields[7].GetUInt32()); temp.duration = fields[8].GetUInt32(); temp.sound = fields[9].GetUInt32(); temp.BroadcastTextId = fields[10].GetUInt32(); temp.TextRange = CreatureTextRange(fields[11].GetUInt8()); if (temp.sound) { if (!sSoundEntriesStore.LookupEntry(temp.sound)) { TC_LOG_ERROR("sql.sql", "CreatureTextMgr: Entry %u, Group %u in table `creature_text` has Sound %u but sound does not exist.", temp.creatureId, temp.groupId, temp.sound); temp.sound = 0; } } if (!GetLanguageDescByID(temp.lang)) { TC_LOG_ERROR("sql.sql", "CreatureTextMgr: Entry %u, Group %u in table `creature_text` using Language %u but Language does not exist.", temp.creatureId, temp.groupId, uint32(temp.lang)); temp.lang = LANG_UNIVERSAL; } if (temp.type >= MAX_CHAT_MSG_TYPE) { TC_LOG_ERROR("sql.sql", "CreatureTextMgr: Entry %u, Group %u in table `creature_text` has Type %u but this Chat Type does not exist.", temp.creatureId, temp.groupId, uint32(temp.type)); temp.type = CHAT_MSG_SAY; } if (temp.emote) { if (!sEmotesStore.LookupEntry(temp.emote)) { TC_LOG_ERROR("sql.sql", "CreatureTextMgr: Entry %u, Group %u in table `creature_text` has Emote %u but emote does not exist.", temp.creatureId, temp.groupId, uint32(temp.emote)); temp.emote = EMOTE_ONESHOT_NONE; } } if (temp.BroadcastTextId) { if (!sObjectMgr->GetBroadcastText(temp.BroadcastTextId)) { TC_LOG_ERROR("sql.sql", "CreatureTextMgr: Entry %u, Group %u, Id %u in table `creature_text` has non-existing or incompatible BroadcastTextId %u.", temp.creatureId, temp.groupId, temp.id, temp.BroadcastTextId); temp.BroadcastTextId = 0; } } if (temp.TextRange > TEXT_RANGE_WORLD) { TC_LOG_ERROR("sql.sql", "CreatureTextMgr: Entry %u, Group %u, Id %u in table `creature_text` has incorrect TextRange %u.", temp.creatureId, temp.groupId, temp.id, temp.TextRange); temp.TextRange = TEXT_RANGE_NORMAL; } // add the text into our entry's group mTextMap[temp.creatureId][temp.groupId].push_back(temp); ++textCount; } while (result->NextRow()); TC_LOG_INFO("server.loading", ">> Loaded %u creature texts for " SZFMTD " creatures in %u ms", textCount, mTextMap.size(), GetMSTimeDiffToNow(oldMSTime)); }
void AIUpdate() { if( i_drakeCount >= 1) { if( IsTimerFinished(mDrakeTimer) ) { if( b_tenebron == true ) CallTenebron(); else if( b_shadron == true ) CallShadron(); else if( b_vesperon == true ) CallVesperon(); ResetTimer( mDrakeTimer, 45000 ); }; }; if(IsTimerFinished(mTsunamiTimer)) { _unit->SendChatMessage(CHAT_MSG_RAID_BOSS_EMOTE, LANG_UNIVERSAL, "The lava surrounding Sartharion churns!"); uint32 RandomSpeach = rand()%4; switch (RandomSpeach) { case 0: Emote( "Such flammable little insects....", Text_Yell, 14100); break; case 1: Emote( "Your charred bones will litter the floor!", Text_Yell, 14101); break; case 2: Emote( "How much heat can you take?", Text_Yell, 14102); break; case 3: Emote( "All will be reduced to ash!", Text_Yell, 14103); break; }; uint32 RndSide = rand()%2; Creature *Tsunami = NULLCREATURE; for(int i = 0; i < 3; ++i) { switch(RndSide) { case 0: Tsunami = this->GetUnit()->GetMapMgr()->GetInterface()->SpawnCreature(CN_FLAME_TSUNAMI, TSUNAMI_SPAWN[i].positionX, TSUNAMI_SPAWN[i].positionY, TSUNAMI_SPAWN[i].positionZ, TSUNAMI_SPAWN[i].positionO, true, true, NULL, NULL); if( Tsunami != NULL ) Tsunami->GetAIInterface()->MoveTo( TSUNAMI_MOVE[i].positionX, TSUNAMI_MOVE[i].positionY, TSUNAMI_MOVE[i].positionZ, TSUNAMI_MOVE[i].positionO ); break; case 1: Tsunami = this->GetUnit()->GetMapMgr()->GetInterface()->SpawnCreature(CN_FLAME_TSUNAMI, TSUNAMI_SPAWN[i + 3].positionX, TSUNAMI_SPAWN[i + 3].positionY, TSUNAMI_SPAWN[i + 3].positionZ, TSUNAMI_SPAWN[i + 3].positionO, true, true, NULL, NULL); if( Tsunami != NULL ) Tsunami->GetAIInterface()->MoveTo( TSUNAMI_MOVE[i + 3].positionX, TSUNAMI_MOVE[i + 3].positionY, TSUNAMI_MOVE[i + 3].positionZ, TSUNAMI_MOVE[i + 3].positionO ); }; }; ResetTimer(mTsunamiTimer, 32000); }; if( IsTimerFinished(mAddTimer) ) { for(uint32 i = 0; i < 2; ++i) { uint32 j = rand()%8; SpawnCreature(CN_LAVA_BLAZE, LAVA_SPAWNS[j].positionX, LAVA_SPAWNS[j].positionY, LAVA_SPAWNS[j].positionZ, LAVA_SPAWNS[j].positionO, true); }; ResetTimer(mAddTimer, 15000); }; if( IsTimerFinished(mAddTimer) && GetHealthPercent() <= 10 ) // enrage phase { for(uint32 i = 0; i < 6; ++i) { uint32 j = rand()%8; SpawnCreature(CN_LAVA_BLAZE, LAVA_SPAWNS[j].positionX, LAVA_SPAWNS[j].positionY, LAVA_SPAWNS[j].positionZ, LAVA_SPAWNS[j].positionO, true); }; RemoveTimer(mAddTimer); }; ParentClass::AIUpdate(); };
void OnCombatStart(Unit *pTarget) { Emote("Drain... life...", Text_Yell, 12389); SetPhase(1); ParentClass::OnCombatStart(pTarget); }
void ArcScriptCreatureAI::Emote(EmoteDesc* pEmote) { if( pEmote ) Emote(pEmote->mText.c_str(), pEmote->mType, pEmote->mSoundId); }
void OnCombatStart(Unit *pTarget) { Emote("I'll paint my face with your blood!", Text_Yell, 13207); SetPhase(1); ParentClass::OnCombatStart(pTarget); }
void CEmoticon::OnRender() { if(!m_Active) { if(m_WasActive && m_SelectedEmote != -1) Emote(m_SelectedEmote); if(m_WasActive && m_SelectedEyeEmote != -1) EyeEmote(m_SelectedEyeEmote); m_WasActive = false; return; } if(m_pClient->m_Snap.m_SpecInfo.m_Active) { m_Active = false; m_WasActive = false; return; } m_WasActive = true; if (length(m_SelectorMouse) > 170.0f) m_SelectorMouse = normalize(m_SelectorMouse) * 170.0f; float SelectedAngle = GetAngle(m_SelectorMouse) + 2*pi/24; if (SelectedAngle < 0) SelectedAngle += 2*pi; m_SelectedEmote = -1; m_SelectedEyeEmote = -1; if (length(m_SelectorMouse) > 110.0f) m_SelectedEmote = (int)(SelectedAngle / (2*pi) * NUM_EMOTICONS); else if(length(m_SelectorMouse) > 40.0f) m_SelectedEyeEmote = (int)(SelectedAngle / (2*pi) * NUM_EMOTES); CUIRect Screen = *UI()->Screen(); Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h); Graphics()->BlendNormal(); Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(0,0,0,0.3f); DrawCircle(Screen.w/2, Screen.h/2, 190.0f, 64); Graphics()->QuadsEnd(); Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id); Graphics()->QuadsBegin(); for (int i = 0; i < NUM_EMOTICONS; i++) { float Angle = 2*pi*i/NUM_EMOTICONS; if (Angle > pi) Angle -= 2*pi; bool Selected = m_SelectedEmote == i; float Size = Selected ? 80.0f : 50.0f; float NudgeX = 150.0f * cosf(Angle); float NudgeY = 150.0f * sinf(Angle); RenderTools()->SelectSprite(SPRITE_OOP + i); IGraphics::CQuadItem QuadItem(Screen.w/2 + NudgeX, Screen.h/2 + NudgeY, Size, Size); Graphics()->QuadsDraw(&QuadItem, 1); } Graphics()->QuadsEnd(); CServerInfo pServerInfo; Client()->GetServerInfo(&pServerInfo); if((IsDDRace(&pServerInfo) || IsDDNet(&pServerInfo) || IsPlus(&pServerInfo)) && g_Config.m_ClEyeWheel) { Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(1.0,1.0,1.0,0.3f); DrawCircle(Screen.w/2, Screen.h/2, 100.0f, 64); Graphics()->QuadsEnd(); CTeeRenderInfo *pTeeInfo = &m_pClient->m_aClients[m_pClient->m_LocalIDs[g_Config.m_ClDummy]].m_RenderInfo; Graphics()->TextureSet(pTeeInfo->m_Texture); for (int i = 0; i < NUM_EMOTES; i++) { float Angle = 2*pi*i/NUM_EMOTES; if (Angle > pi) Angle -= 2*pi; bool Selected = m_SelectedEyeEmote == i; float NudgeX = 70.0f * cosf(Angle); float NudgeY = 70.0f * sinf(Angle); pTeeInfo->m_Size = Selected ? 64.0f : 48.0f; RenderTools()->RenderTee(CAnimState::GetIdle(), pTeeInfo, i, vec2(-1,0), vec2(Screen.w/2 + NudgeX, Screen.h/2 + NudgeY)); pTeeInfo->m_Size = 64.0f; } Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(0,0,0,0.3f); DrawCircle(Screen.w/2, Screen.h/2, 30.0f, 64); Graphics()->QuadsEnd(); } else m_SelectedEyeEmote = -1; Graphics()->TextureSet(g_pData->m_aImages[IMAGE_CURSOR].m_Id); Graphics()->QuadsBegin(); Graphics()->SetColor(1,1,1,1); IGraphics::CQuadItem QuadItem(m_SelectorMouse.x+Screen.w/2,m_SelectorMouse.y+Screen.h/2,24,24); Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); }
void CEmoticon::OnRender() { if(!m_Active) { if(m_WasActive && m_SelectedEmote != -1) Emote(m_SelectedEmote); m_WasActive = false; return; } m_WasActive = true; int x, y; Input()->MouseRelative(&x, &y); m_SelectorMouse.x += x; m_SelectorMouse.y += y; if (length(m_SelectorMouse) > 140) m_SelectorMouse = normalize(m_SelectorMouse) * 140; float SelectedAngle = GetAngle(m_SelectorMouse) + 2*pi/24; if (SelectedAngle < 0) SelectedAngle += 2*pi; if (length(m_SelectorMouse) > 100) m_SelectedEmote = (int)(SelectedAngle / (2*pi) * 12.0f); CUIRect Screen = *UI()->Screen(); Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h); Graphics()->BlendNormal(); Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(0,0,0,0.3f); DrawCircle(Screen.w/2, Screen.h/2, 160, 64); Graphics()->QuadsEnd(); Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id); Graphics()->QuadsBegin(); for (int i = 0; i < 12; i++) { float Angle = 2*pi*i/12.0; if (Angle > pi) Angle -= 2*pi; bool Selected = m_SelectedEmote == i; float Size = Selected ? 96 : 64; float NudgeX = 120 * cosf(Angle); float NudgeY = 120 * sinf(Angle); RenderTools()->SelectSprite(SPRITE_OOP + i); IGraphics::CQuadItem QuadItem(Screen.w/2 + NudgeX, Screen.h/2 + NudgeY, Size, Size); Graphics()->QuadsDraw(&QuadItem, 1); } Graphics()->QuadsEnd(); Graphics()->TextureSet(g_pData->m_aImages[IMAGE_CURSOR].m_Id); Graphics()->QuadsBegin(); Graphics()->SetColor(1,1,1,1); IGraphics::CQuadItem QuadItem(m_SelectorMouse.x+Screen.w/2,m_SelectorMouse.y+Screen.h/2,24,24); Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); }
bool CChar::Use_Train_ArcheryButte( CItem * pButte, bool fSetup ) { ADDTOCALLSTACK("CChar::Use_Train_ArcheryButte"); // IT_ARCHERY_BUTTE ASSERT(pButte); ITEMID_TYPE AmmoID; if ( GetDist(pButte) < 2 ) // if we are standing right next to the butte, retrieve the arrows/bolts { if ( pButte->m_itArcheryButte.m_AmmoCount == 0 ) { SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_EMPTY); return true; } AmmoID = pButte->m_itArcheryButte.m_AmmoType; CItemBase *pAmmoDef = CItemBase::FindItemBase(AmmoID); if ( pAmmoDef ) { TCHAR *pszMsg = Str_GetTemp(); sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_REM), pAmmoDef->GetName(), (pButte->m_itArcheryButte.m_AmmoCount == 1) ? "" : g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_REMS)); Emote(pszMsg); CItem *pRemovedAmmo = CItem::CreateBase(AmmoID); ASSERT(pRemovedAmmo); pRemovedAmmo->SetAmount(pButte->m_itArcheryButte.m_AmmoCount); ItemBounce(pRemovedAmmo); } // Clear the target pButte->m_itArcheryButte.m_AmmoType = ITEMID_NOTHING; pButte->m_itArcheryButte.m_AmmoCount = 0; return true; } SKILL_TYPE skill = Fight_GetWeaponSkill(); if ( !g_Cfg.IsSkillFlag(skill, SKF_RANGED) ) { SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_WS); return true; } if ( Skill_GetBase(skill) > g_Cfg.m_iSkillPracticeMax ) { SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_SKILL); return true; } // Make sure we have some ammo CItem *pWeapon = m_uidWeapon.ItemFind(); ASSERT(pWeapon); const CItemBase *pWeaponDef = pWeapon->Item_GetDef(); // Determine ammo type CVarDefCont *pVarAmmoType = pWeapon->GetDefKey("AMMOTYPE", true); RESOURCE_ID_BASE rid; LPCTSTR t_Str; if ( pVarAmmoType ) { t_Str = pVarAmmoType->GetValStr(); rid = static_cast<RESOURCE_ID_BASE>(g_Cfg.ResourceGetID(RES_ITEMDEF, t_Str)); } else { rid = pWeaponDef->m_ttWeaponBow.m_idAmmo; } AmmoID = static_cast<ITEMID_TYPE>(rid.GetResIndex()); // If there is a different ammo type on the butte currently, tell us to remove the current type first if ( (pButte->m_itArcheryButte.m_AmmoType != ITEMID_NOTHING) && (pButte->m_itArcheryButte.m_AmmoType != AmmoID) ) { SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_X); return true; } // We need to be correctly aligned with the target before we can use it // For the south facing butte, we need to have the same X value and a Y > 2 // For the east facing butte, we need to have the same Y value and an X > 2 if ( !pButte->IsTopLevel() ) { badalign: SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_P); return true; } int targDistX = GetTopPoint().m_x - pButte->GetTopPoint().m_x; int targDistY = GetTopPoint().m_y - pButte->GetTopPoint().m_y; if ( (pButte->GetID() == ITEMID_ARCHERYBUTTE_S) || (pButte->GetID() == ITEMID_MONGBATTARGET_S) ) { if ( !(targDistX == 0 && targDistY > 2) ) goto badalign; } else { if ( !(targDistY == 0 && targDistX > 2) ) goto badalign; } if ( !CanSeeLOS(pButte, LOS_NB_WINDOWS) ) //we should be able to shoot through a window { SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_BLOCK); return true; } if ( fSetup ) { if ( Skill_GetActive() == NPCACT_TRAINING ) return true; UpdateAnimate(ANIM_ATTACK_WEAPON); m_Act_TargPrv = m_uidWeapon; m_Act_Targ = pButte->GetUID(); Skill_Start(NPCACT_TRAINING); return true; } CVarDefCont *pCont = pWeapon->GetDefKey("AMMOCONT",true); if ( m_pPlayer && AmmoID ) { int iFound = 1; if ( pCont ) { //check for UID CGrayUID uidCont = static_cast<DWORD>(pCont->GetValNum()); CItemContainer *pNewCont = dynamic_cast<CItemContainer*>(uidCont.ItemFind()); if ( !pNewCont ) //if no UID, check for ITEMID_TYPE { t_Str = pCont->GetValStr(); RESOURCE_ID_BASE rContid = static_cast<RESOURCE_ID_BASE>(g_Cfg.ResourceGetID(RES_ITEMDEF, t_Str)); ITEMID_TYPE ContID = static_cast<ITEMID_TYPE>(rContid.GetResIndex()); if ( ContID ) pNewCont = dynamic_cast<CItemContainer*>(ContentFind(rContid)); } if ( pNewCont ) iFound = pNewCont->ContentConsume(RESOURCE_ID(RES_ITEMDEF, AmmoID)); else iFound = ContentConsume(RESOURCE_ID(RES_ITEMDEF, AmmoID)); } else iFound = ContentConsume(RESOURCE_ID(RES_ITEMDEF, AmmoID)); if ( iFound ) { SysMessageDefault(DEFMSG_ITEMUSE_ARCHB_NOAMMO); return(true); } } // OK...go ahead and fire at the target // Check the skill bool fSuccess = Skill_UseQuick(skill, Calc_GetRandLLVal(40)); // determine animation parameters CVarDefCont *pVarAnim = pWeapon->GetDefKey("AMMOANIM", true); CVarDefCont *pVarAnimColor = pWeapon->GetDefKey("AMMOANIMHUE", true); CVarDefCont *pVarAnimRender = pWeapon->GetDefKey("AMMOANIMRENDER", true); ITEMID_TYPE AmmoAnim; DWORD AmmoHue; DWORD AmmoRender; if ( pVarAnim ) { t_Str = pVarAnim->GetValStr(); rid = static_cast<RESOURCE_ID_BASE>(g_Cfg.ResourceGetID(RES_ITEMDEF, t_Str)); AmmoAnim = static_cast<ITEMID_TYPE>(rid.GetResIndex()); } else AmmoAnim = static_cast<ITEMID_TYPE>(pWeaponDef->m_ttWeaponBow.m_idAmmoX.GetResIndex()); AmmoHue = pVarAnimColor ? static_cast<DWORD>(pVarAnimColor->GetValNum()) : 0; AmmoRender = pVarAnimRender ? static_cast<DWORD>(pVarAnimRender->GetValNum()) : 0; pButte->Effect(EFFECT_BOLT, AmmoAnim, this, 16, 0, false, AmmoHue, AmmoRender); pButte->Sound(0x224); // Did we destroy the ammo? const CItemBase *pAmmoDef = NULL; if ( AmmoID ) pAmmoDef = CItemBase::FindItemBase(AmmoID); if ( !fSuccess ) { // Small chance of destroying the ammo if ( pAmmoDef && !Calc_GetRandVal(10) ) { TCHAR *pszMsg = Str_GetTemp(); sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_DEST), pAmmoDef->GetName()); Emote(pszMsg, NULL, true); return true; } static LPCTSTR const sm_Txt_ArcheryButte_Failure[] = { g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_1), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_2), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_3), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_MISS_4) }; Emote(sm_Txt_ArcheryButte_Failure[Calc_GetRandVal(COUNTOF(sm_Txt_ArcheryButte_Failure))]); } else { // Very small chance of destroying another arrow if ( pAmmoDef && !Calc_GetRandVal(50) && pButte->m_itArcheryButte.m_AmmoCount ) { TCHAR *pszMsg = Str_GetTemp(); sprintf(pszMsg, g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_SPLIT), pAmmoDef->GetName()); Emote(pszMsg, NULL, true); return true; } static LPCTSTR const sm_Txt_ArcheryButte_Success[] = { g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_1), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_2), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_3), g_Cfg.GetDefaultMsg(DEFMSG_ITEMUSE_ARCHB_HIT_4) }; Emote(sm_Txt_ArcheryButte_Success[Calc_GetRandVal(COUNTOF(sm_Txt_ArcheryButte_Success))]); } // Update the target if ( AmmoID ) { pButte->m_itArcheryButte.m_AmmoType = AmmoID; pButte->m_itArcheryButte.m_AmmoCount++; } return true; }
void CreatureTextMgr::LoadCreatureTexts() { uint32 oldMSTime = getMSTime(); mTextMap.clear(); // for reload case mTextRepeatMap.clear(); //reset all currently used temp texts PreparedStatement* stmt = WorldDatabase.GetPreparedStatement(WORLD_SEL_CREATURE_TEXT); PreparedQueryResult result = WorldDatabase.Query(stmt); if (!result) { sLog->outString(">> Loaded 0 ceature texts. DB table `creature_texts` is empty."); sLog->outString(); return; } uint32 textCount = 0; uint32 creatureCount = 0; do { Field* fields = result->Fetch(); CreatureTextEntry temp; temp.entry = fields[0].GetUInt32(); temp.group = fields[1].GetUInt8(); temp.id = fields[2].GetUInt8(); temp.text = fields[3].GetString(); temp.type = ChatMsg(fields[4].GetUInt8()); temp.lang = Language(fields[5].GetUInt8()); temp.probability = fields[6].GetFloat(); temp.emote = Emote(fields[7].GetUInt32()); temp.duration = fields[8].GetUInt32(); temp.sound = fields[9].GetUInt32(); if (temp.sound) { if (!sSoundEntriesStore.LookupEntry(temp.sound)){ sLog->outErrorDb("CreatureTextMgr: Entry %u, Group %u in table `creature_texts` has Sound %u but sound does not exist.", temp.entry, temp.group, temp.sound); temp.sound = 0; } } if (!GetLanguageDescByID(temp.lang)) { sLog->outErrorDb("CreatureTextMgr: Entry %u, Group %u in table `creature_texts` using Language %u but Language does not exist.", temp.entry, temp.group, uint32(temp.lang)); temp.lang = LANG_UNIVERSAL; } if (temp.type >= MAX_CHAT_MSG_TYPE) { sLog->outErrorDb("CreatureTextMgr: Entry %u, Group %u in table `creature_texts` has Type %u but this Chat Type does not exist.", temp.entry, temp.group, uint32(temp.type)); temp.type = CHAT_MSG_SAY; } if (temp.emote) { if (!sEmotesStore.LookupEntry(temp.emote)) { sLog->outErrorDb("CreatureTextMgr: Entry %u, Group %u in table `creature_texts` has Emote %u but emote does not exist.", temp.entry, temp.group, uint32(temp.emote)); temp.emote = EMOTE_ONESHOT_NONE; } } //entry not yet added, add empty TextHolder (list of groups) if (mTextMap.find(temp.entry) == mTextMap.end()) ++creatureCount; //add the text into our entry's group mTextMap[temp.entry][temp.group].push_back(temp); ++textCount; } while (result->NextRow()); sLog->outString(">> Loaded %u creature texts for %u creatures in %u ms", textCount, creatureCount, GetMSTimeDiffToNow(oldMSTime)); sLog->outString(); }
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; }
void OnCombatStop(Unit *pTarget) { Emote("It's been a kick, really.", Text_Yell, 12411); ParentClass::OnCombatStop(pTarget); }
void CEmoticon::OnRender() { if(!m_Active) { if(m_WasActive) { if (m_SelectedEmote != -1) Emote(m_SelectedEmote); else if (Client()->IsServerType("ddrace") && m_SelectedEyes != -1) Eyes(m_SelectedEyes); } m_WasActive = false; return; } if(m_pClient->m_Snap.m_SpecInfo.m_Active) { m_Active = false; m_WasActive = false; return; } m_WasActive = true; if (length(m_SelectorMouse) > 170.0f) m_SelectorMouse = normalize(m_SelectorMouse) * 170.0f; float SelectedAngle = GetAngle(m_SelectorMouse) + 2*pi/24; if (SelectedAngle < 0) SelectedAngle += 2*pi; float mouselen = length(m_SelectorMouse); if (mouselen > 110.0f) { m_SelectedEyes = -1; m_SelectedEmote = (int)(SelectedAngle / (2*pi) * NUM_EMOTICONS); } else if (Client()->IsServerType("ddrace") && mouselen > 50.0f && mouselen < 110.0f) // H-Client { m_SelectedEmote = -1; m_SelectedEyes = (int)(SelectedAngle / (2*pi) * NUM_EMOTES); } else { m_SelectedEyes = -1; m_SelectedEmote = -1; } CUIRect Screen = *UI()->Screen(); Graphics()->MapScreen(Screen.x, Screen.y, Screen.w, Screen.h); Graphics()->BlendNormal(); Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(0,0,0,0.3f); DrawCircle(Screen.w/2, Screen.h/2, 190.0f, 64); Graphics()->QuadsEnd(); // H-Client if (Client()->IsServerType("ddrace")) { Graphics()->TextureSet(-1); Graphics()->QuadsBegin(); Graphics()->SetColor(60,60,60,0.3f); DrawCircle(Screen.w/2, Screen.h/2, 110.0f, 64); Graphics()->QuadsEnd(); } // Graphics()->TextureSet(g_pData->m_aImages[IMAGE_EMOTICONS].m_Id); Graphics()->QuadsBegin(); for (int i = 0; i < NUM_EMOTICONS; i++) { float Angle = 2*pi*i/NUM_EMOTICONS; if (Angle > pi) Angle -= 2*pi; bool Selected = m_SelectedEmote == i; float Size = Selected ? 80.0f : 50.0f; float NudgeX = 150.0f * cosf(Angle); float NudgeY = 150.0f * sinf(Angle); RenderTools()->SelectSprite(SPRITE_OOP + i); IGraphics::CQuadItem QuadItem(Screen.w/2 + NudgeX, Screen.h/2 + NudgeY, Size, Size); Graphics()->QuadsDraw(&QuadItem, 1); } Graphics()->QuadsEnd(); if (Client()->IsServerType("ddrace")) { for (int i = 0; i < NUM_EMOTES; i++) { float Angle = 2*pi*i/NUM_EMOTES; if (Angle > pi) Angle -= 2*pi; bool Selected = m_SelectedEyes == i; float Size = Selected ? 80.0f : 50.0f; float NudgeX = 80.0f * cosf(Angle); float NudgeY = 80.0f * sinf(Angle); CTeeRenderInfo teeRenderInfo = m_pClient->m_aClients[m_pClient->m_Snap.m_LocalClientID].m_RenderInfo; teeRenderInfo.m_Size = Size; Graphics()->TextureSet(teeRenderInfo.m_Texture); Graphics()->QuadsBegin(); Graphics()->SetColor(teeRenderInfo.m_ColorBody.r, teeRenderInfo.m_ColorBody.g, teeRenderInfo.m_ColorBody.b, teeRenderInfo.m_ColorBody.a); switch (i) { case EMOTE_PAIN: RenderTools()->SelectSprite(SPRITE_TEE_EYE_PAIN, 0, 0, 0); break; case EMOTE_HAPPY: RenderTools()->SelectSprite(SPRITE_TEE_EYE_HAPPY, 0, 0, 0); break; case EMOTE_SURPRISE: RenderTools()->SelectSprite(SPRITE_TEE_EYE_SURPRISE, 0, 0, 0); break; case EMOTE_ANGRY: RenderTools()->SelectSprite(SPRITE_TEE_EYE_ANGRY, 0, 0, 0); break; default: RenderTools()->SelectSprite(SPRITE_TEE_EYE_NORMAL, 0, 0, 0); break; } vec2 Direction = vec2(-1,0); float BaseSize = teeRenderInfo.m_Size; float EyeScale = BaseSize*0.40f; float h = i == EMOTE_BLINK ? BaseSize*0.15f : EyeScale; float EyeSeparation = (0.075f - 0.010f*absolute(Direction.x))*BaseSize; vec2 Offset = vec2(Direction.x*0.125f, -0.05f+Direction.y*0.10f)*BaseSize; vec2 BodyPos = vec2(Screen.w/2 + NudgeX, Screen.h/2 + NudgeY); IGraphics::CQuadItem Array[2] = { IGraphics::CQuadItem(BodyPos.x-EyeSeparation+Offset.x, BodyPos.y+Offset.y, EyeScale, h), IGraphics::CQuadItem(BodyPos.x+EyeSeparation+Offset.x, BodyPos.y+Offset.y, -EyeScale, h)}; Graphics()->QuadsDraw(Array, 2); Graphics()->QuadsEnd(); } } //Graphics()->QuadsEnd(); Graphics()->TextureSet(g_pData->m_aImages[IMAGE_CURSOR].m_Id); Graphics()->QuadsBegin(); Graphics()->SetColor(1,1,1,1); IGraphics::CQuadItem QuadItem(m_SelectorMouse.x+Screen.w/2,m_SelectorMouse.y+Screen.h/2,24,24); Graphics()->QuadsDrawTL(&QuadItem, 1); Graphics()->QuadsEnd(); }