- //-----------------------------------------------------------------------
- // Sword3 KNpc.cpp
- //-----------------------------------------------------------------------
- #include "KCore.h"
- //#include <crtdbg.h>
- #include "KNpcAI.h"
- #include "KSkills.h"
- #include "KObj.h"
- #include "KObjSet.h"
- #include "KMath.h"
- #include "KPlayer.h"
- #include "KNpc.h"
- #include "GameDataDef.h"
- #include "KSubWorldSet.h"
- #include "KRegion.h"
- #include "KNpcTemplate.h"
- #include "KItemSet.h"
- #ifdef _SERVER
- //#include "KNetServer.h"
- //#include "../MultiServer/Heaven/Interface/iServer.h"
- #include "KPlayerSet.h"
- #include "KSkillManager.h"
- #else
- #include "../../Headers/IClient.h"
- #include "CoreShell.h"
- #include "Scene/KScenePlaceC.h"
- #include "KIme.h"
- #include "../../Represent/iRepresent/iRepresentshell.h"
- #include "ImgRef.h"
- #include "Text.h"
- #endif
- #include "KNpcAttribModify.h"
- #include "CoreUseNameDef.h"
- #include "KSubWorld.h"
- #include "Scene/ObstacleDef.h"
- #include "KThiefSkill.h"
- #ifdef _STANDALONE
- #include "KThiefSkill.cpp"
- #endif
- #ifndef max
- #define max(a,b) (((a) > (b)) ? (a) : (b))
- #endif
- extern KLuaScript *g_pNpcLevelScript;
- #define ATTACKACTION_EFFECT_PERCENT 60 // 发技能动作完成百分之多少才真正发出来
- #define MIN_JUMP_RANGE 0
- #define ACCELERATION_OF_GRAVITY 10
- #define SHOW_CHAT_WIDTH 24
- #define SHOW_CHAT_COLOR 0xffffffff
- #define SHOW_BLOOD_COLOR 0x00ff0000
- #define defMAX_SHOW_BLOOD_TIME 27
- #define defSHOW_BLOOD_MOVE_SPEED 2
- #define SHOW_LIFE_WIDTH 38
- #define SHOW_LIFE_HEIGHT 3
- #define SHOW_SPACE_HEIGHT 5
- //-----------------------------------------------------------------------
- #define GAME_UPDATE_TIME 10
- #define GAME_SYNC_LOSS 100
- #define STAMINA_RECOVER_SCALE 4
- // 区域的宽高(格子单位)
- #define REGIONWIDTH SubWorld[m_SubWorldIndex].m_nRegionWidth
- #define REGIONHEIGHT SubWorld[m_SubWorldIndex].m_nRegionHeight
- // 格子的宽高(像素单位,放大了1024倍)
- #define CELLWIDTH (SubWorld[m_SubWorldIndex].m_nCellWidth << 10)
- #define CELLHEIGHT (SubWorld[m_SubWorldIndex].m_nCellHeight << 10)
- // 当前区域
- #define CURREGION SubWorld[m_SubWorldIndex].m_Region[m_RegionIndex]
- // 相邻区域的索引
- #define LEFTREGIONIDX CURREGION.m_nConnectRegion[2]
- #define RIGHTREGIONIDX CURREGION.m_nConnectRegion[6]
- #define UPREGIONIDX CURREGION.m_nConnectRegion[4]
- #define DOWNREGIONIDX CURREGION.m_nConnectRegion[0]
- #define LEFTUPREGIONIDX CURREGION.m_nConnectRegion[3]
- #define LEFTDOWNREGIONIDX CURREGION.m_nConnectRegion[1]
- #define RIGHTUPREGIONIDX CURREGION.m_nConnectRegion[5]
- #define RIGHTDOWNREGIONIDX CURREGION.m_nConnectRegion[7]
- #define LEFTREGION SubWorld[m_SubWorldIndex].m_Region[LEFTREGIONIDX]
- #define RIGHTREGION SubWorld[m_SubWorldIndex].m_Region[RIGHTREGIONIDX]
- #define UPREGION SubWorld[m_SubWorldIndex].m_Region[UPREGIONIDX]
- #define DOWNREGION SubWorld[m_SubWorldIndex].m_Region[DOWNREGIONIDX]
- #define LEFTUPREGION SubWorld[m_SubWorldIndex].m_Region[LEFTUPREGIONIDX]
- #define LEFTDOWNREGION SubWorld[m_SubWorldIndex].m_Region[LEFTDOWNREGIONIDX]
- #define RIGHTUPREGION SubWorld[m_SubWorldIndex].m_Region[RIGHTUPREGIONIDX]
- #define RIGHTDOWNREGION SubWorld[m_SubWorldIndex].m_Region[RIGHTDOWNREGIONIDX]
- #define CONREGION(x) SubWorld[m_SubWorldIndex].m_Region[CURREGION.m_nConnectRegion[x]]
- #define CONREGIONIDX(x) CURREGION.m_nConnectRegion[x]
- // 当前技能
- //-----------------------------------------------------------------------
- // Npc[0]不在游戏世界中使用,做为一个NpcSet用于添加新的NPC。
- KNpc Npc[MAX_NPC];
- KNpcTemplate * g_pNpcTemplate[MAX_NPCSTYLE][MAX_NPC_LEVEL]; //0,0为起点
- //-----------------------------------------------------------------------
- KNpc::KNpc()
- {
- #ifdef _SERVER
- m_AiSkillRadiusLoadFlag = 0; // 只需要在构造的时候初始化一次
- #endif
- Init();
- }
- void KNpc::Init()
- {
- m_dwID = 0;
- m_Index = 0;
- m_nPlayerIdx = 0;
- m_ProcessAI = 1;
- m_Kind = kind_normal;
- m_Series = series_metal;
- m_Camp = camp_free;
- m_CurrentCamp = camp_free;
- m_Doing = do_stand;
- m_Height = 0;
- m_Frames.nCurrentFrame = 0;
- m_Frames.nTotalFrame = 0;
- m_SubWorldIndex = 0;
- m_RegionIndex = -1;
- m_Experience = 0;
- m_ActiveSkillID = 0;
- m_SkillParam1 = 0;
- m_SkillParam2 = 0;
- #ifndef _SERVER
- m_nChatContentLen = 0;
- m_nCurChatTime = 0;
- m_nChatNumLine = 0;
- m_nChatFontWidth = 0;
- m_nStature = 0;
- #endif
- m_CurrentLife = 100; // Npc的当前生命
- m_CurrentLifeMax = 100; // Npc的当前生命最大值
- m_CurrentLifeReplenish = 0; // Npc的当前生命回复速度
- m_CurrentMana = 100; // Npc的当前内力
- m_CurrentManaMax = 100; // Npc的当前最大内力
- m_CurrentManaReplenish = 0; // Npc的当前内力回复速度
- m_CurrentStamina = 100; // Npc的当前体力
- m_CurrentStaminaMax = 100; // Npc的当前最大体力
- m_CurrentStaminaGain = 0; // Npc的当前体力回复速度
- m_CurrentStaminaLoss = 0; // Npc的当前体力下降速度
- m_CurrentAttackRating = 100; // Npc的当前命中率
- m_CurrentDefend = 10; // Npc的当前防御
- m_CurrentWalkSpeed = 5; // Npc的当前走动速度
- m_CurrentRunSpeed = 10; // Npc的当前跑动速度
- m_CurrentJumpSpeed = 12; // Npc的当前跳跃速度
- m_CurrentJumpFrame = 40; // Npc的当前跳跃时间
- m_CurrentAttackSpeed = 0; // Npc的当前攻击速度
- m_CurrentCastSpeed = 0; // Npc的当前施法速度
- m_CurrentVisionRadius = 40; // Npc的当前视野范围
- m_CurrentAttackRadius = 30; // Npc的当前攻击范围
- m_CurrentHitRecover = 0; // Npc的当前受击回复速度
- m_CurrentAddPhysicsDamage = 0; // Npc的当前物理伤害直接加的点数
- m_Dir = 0; // Npc的方向
- m_JumpStep = 0;
- m_JumpDir = 0;
- m_MapZ = 0; // Npc的高度
- m_HelmType = 1; // Npc的头盔类型
- m_ArmorType = 1; // Npc的盔甲类型
- m_WeaponType = 1; // Npc的武器类型
- m_HorseType = -1; // Npc的骑马类型
- m_bRideHorse = FALSE; // Npc是否骑马
- ZeroMemory(Name, 32); // Npc的名称
- m_NpcSettingIdx = 0; // Npc的设定文件索引
- m_CorpseSettingIdx = 0; // Body的设定文件索引
- ZeroMemory(ActionScript,32);
- m_ActionScriptID = 0;
- m_TrapScriptID = 0;
- m_btRankId = 0;
- m_LifeMax = 100; // Npc的最大生命
- m_LifeReplenish = 0; // Npc的生命回复速度
- m_ManaMax = 100; // Npc的最大内力
- m_ManaReplenish = 0; // Npc的内力回复速度
- m_StaminaMax = 100; // Npc的最大体力
- m_StaminaGain = 0; // Npc的体力回复速度
- m_StaminaLoss = 0; // Npc的体力下降速度
- m_AttackRating = 100; // Npc的命中率
- m_Defend = 10; // Npc的防御
- m_WalkSpeed = 6; // Npc的行走速度
- m_RunSpeed = 10; // Npc的跑动速度
- m_JumpSpeed = 12; // Npc的跳跃速度
- m_AttackSpeed = 0; // Npc的攻击速度
- m_CastSpeed = 0; // Npc的施法速度
- m_VisionRadius = 40; // Npc的视野范围
- m_DialogRadius = 124; // Npc的对话范围
- m_HitRecover = 12; // Npc的受击回复速度
- m_nPeopleIdx = 0;
- m_LoopFrames = 0;
- m_WalkFrame = 12;
- m_RunFrame = 15;
- m_StandFrame = 15;
- m_DeathFrame = 15;
- m_HurtFrame = 10;
- m_AttackFrame = 20;
- m_CastFrame = 20;
- m_SitFrame = 15;
- m_JumpFrame = 40;
- m_AIMAXTime = 25;
- m_NextAITime = 0;
- m_ProcessState = 1;
- m_ReviveFrame = 100;
- m_bExchangeServer = FALSE;
- m_bActivateFlag = FALSE;
- m_FightMode = 0;
- m_OldFightMode = 0;
- #ifdef _SERVER
- m_nNextStatePos = 0;
- m_pDropRate = NULL;
- #endif
- #ifndef _SERVER
- m_SyncSignal = 0;
- m_sClientNpcID.m_dwRegionID = 0;
- m_sClientNpcID.m_nNo = -1;
- m_ResDir = 0;
- m_nPKFlag = 0;
- m_nSleepFlag = 0;
- memset(&m_sSyncPos, 0, sizeof(m_sSyncPos));
- m_nBloodNo = 0;
- m_nBloodAlpha = 0;
- m_nBloodTime = 0;
- m_szBloodNo[0] = 0;
- m_nTongFlag = 0;
- #endif
- m_nLastPoisonDamageIdx = 0;
- m_nLastDamageIdx = 0;
- m_bHaveLoadedFromTemplate = FALSE;
- m_bClientOnly = FALSE;
- }
- ISkill* KNpc::GetActiveSkill()
- {
- _ASSERT(m_ActiveSkillID < MAX_SKILL);
- int nCurLevel = m_SkillList.GetCurrentLevel(m_ActiveSkillID);
- if (nCurLevel > 0)
- return g_SkillManager.GetSkill(m_ActiveSkillID, nCurLevel);
- else
- return NULL;
- };
- void KNpc::SetCurrentCamp(int nCamp)
- {
- m_CurrentCamp = nCamp;
- #ifdef _SERVER
- POINT POff[8] =
- {
- {0, 32},
- {-16, 32},
- {-16, 0},
- {-16, -32},
- {0, -32},
- {16, -32},
- {16, 0},
- {16, 32},
- };
- if (m_RegionIndex < 0)
- return;
- NPC_CHGCURCAMP_SYNC NetCommand;
- NetCommand.ProtocolType = (BYTE)s2c_npcchgcurcamp;
- NetCommand.ID = m_dwID;
- NetCommand.Camp = (BYTE)m_CurrentCamp;
- int nMaxCount = MAX_BROADCAST_COUNT;
- CURREGION.BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX, m_MapY);
- int i;
- for (i = 0; i < 8; i++)
- {
- if (CONREGIONIDX(i) == -1)
- continue;
- CONREGION(i).BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX - POff[i].x, m_MapY - POff[i].y);
- }
- #endif
- }
- void KNpc::SetCamp(int nCamp)
- {
- m_Camp = nCamp;
- #ifdef _SERVER
- POINT POff[8] =
- {
- {0, 32},
- {-16, 32},
- {-16, 0},
- {-16, -32},
- {0, -32},
- {16, -32},
- {16, 0},
- {16, 32},
- };
- if (m_RegionIndex < 0)
- return;
- NPC_CHGCAMP_SYNC NetCommand;
- NetCommand.ProtocolType = (BYTE)s2c_npcchgcamp;
- NetCommand.ID = m_dwID;
- NetCommand.Camp = (BYTE)m_Camp;
- int nMaxCount = MAX_BROADCAST_COUNT;
- CURREGION.BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX, m_MapY);
- int i;
- for (i = 0; i < 8; i++)
- {
- if (CONREGIONIDX(i) == -1)
- continue;
- CONREGION(i).BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX - POff[i].x, m_MapY - POff[i].y);
- }
- #endif
- }
- void KNpc::RestoreCurrentCamp()
- {
- m_CurrentCamp = m_Camp;
- #ifdef _SERVER
- POINT POff[8] =
- {
- {0, 32},
- {-16, 32},
- {-16, 0},
- {-16, -32},
- {0, -32},
- {16, -32},
- {16, 0},
- {16, 32},
- };
- if (m_RegionIndex < 0)
- return;
- NPC_CHGCURCAMP_SYNC NetCommand;
- NetCommand.ProtocolType = (BYTE)s2c_npcchgcurcamp;
- NetCommand.ID = m_dwID;
- NetCommand.Camp = (BYTE)m_CurrentCamp;
- int nMaxCount = MAX_BROADCAST_COUNT;
- CURREGION.BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX, m_MapY);
- int i;
- for (i = 0; i < 8; i++)
- {
- if (CONREGIONIDX(i) == -1)
- continue;
- CONREGION(i).BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX - POff[i].x, m_MapY - POff[i].y);
- }
- #endif
- }
- #define NPC_SHOW_CHAT_TIME 15000
- int IR_IsTimePassed(unsigned int uInterval, unsigned int& uLastTimer);
- void KNpc::Activate()
- {
- // 不存在这个NPC
- if (!m_Index)
- {
- //g_DebugLog("[DEATH] No Index: %d", m_Index);
- return;
- }
- // 切换地图中,不处理
- if (m_bExchangeServer)
- {
- //g_DebugLog("[DEATH] Change Server: %d", m_bExchangeServer);
- return;
- }
- // Check here
- if (m_bActivateFlag)
- {
- m_bActivateFlag = FALSE; // restore flag
- return;
- }
- // m_bActivateFlag = TRUE;
- m_LoopFrames++;
- // Process npc special state, such as curse, etc.
- //g_DebugLog("[DEATH] m_ProcessState: %d", m_ProcessState);
- if (m_ProcessState)
- {
- if (ProcessState())
- return;
- }
- if (m_ProcessAI)
- {
- NpcAI.Activate(m_Index);
- }
- ProcCommand(m_ProcessAI);
- ProcStatus();
- #ifdef _SERVER
- this->m_cDeathCalcExp.Active();
- #endif
- #ifndef _SERVER
- if (m_RegionIndex == -1)
- return;
- // HurtAutoMove();
- int nMpsX, nMpsY;
- m_DataRes.SetAction(m_ClientDoing);
- m_DataRes.SetRideHorse(m_bRideHorse);
- m_DataRes.SetArmor(m_ArmorType);
- m_DataRes.SetHelm(m_HelmType);
- m_DataRes.SetHorse(m_HorseType);
- m_DataRes.SetWeapon(m_WeaponType);
- // 处理技能产生的状态的特效
- m_DataRes.SetState(&m_StateSkillList, &g_NpcResList);
- if (Player[CLIENT_PLAYER_INDEX].m_nIndex == m_Index)
- {
- SubWorld[0].Map2Mps(m_RegionIndex, m_MapX, m_MapY, m_OffX, m_OffY, &nMpsX, &nMpsY);
- m_DataRes.SetPos(m_Index, nMpsX, nMpsY, m_Height, TRUE);
- }
- else
- {
- SubWorld[0].Map2Mps(m_RegionIndex, m_MapX, m_MapY, m_OffX, m_OffY, &nMpsX, &nMpsY);
- m_DataRes.SetPos(m_Index, nMpsX, nMpsY, m_Height, FALSE);
- }
- // client npc 时间计数处理:不往后跳
- if (m_Kind == kind_bird || m_Kind == kind_mouse)
- m_SyncSignal = SubWorld[0].m_dwCurrentTime;
- if (m_nChatContentLen > 0)
- {
- if (IR_GetCurrentTime() - m_nCurChatTime > NPC_SHOW_CHAT_TIME)
- {
- m_nChatContentLen = 0;
- m_nChatNumLine = 0;
- m_nChatFontWidth = 0;
- m_nCurChatTime = 0;
- }
- }
- #endif
- }
- void KNpc::ProcStatus()
- {
- //g_DebugLog("[DEATH] m_bExchangeServer: %d", m_bExchangeServer);
- if (m_bExchangeServer)
- return;
- switch(m_Doing)
- {
- case do_stand:
- OnStand();
- break;
- case do_run:
- OnRun();
- break;
- case do_walk:
- OnWalk();
- break;
- case do_attack:
- case do_magic:
- OnSkill();
- break;
- case do_sit:
- OnSit();
- break;
- case do_jump:
- OnJump();
- break;
- case do_hurt:
- OnHurt();
- break;
- case do_revive:
- OnRevive();
- break;
- case do_death:
- OnDeath();
- break;
- case do_defense:
- OnDefense();
- break;
- case do_special1:
- OnSpecial1();
- break;
- case do_special2:
- OnSpecial2();
- break;
- case do_special3:
- OnSpecial3();
- break;
- case do_special4:
- OnSpecial4();
- break;
- case do_manyattack:
- OnManyAttack();
- break;
- case do_runattack:
- OnRunAttack();
- break;
- case do_jumpattack:
- OnJumpAttack();
- break;
- case do_idle:
- OnIdle();
- default:
- break;
- }
- }
- void KNpc::ProcCommand(int nAI)
- {
- // CmdKind < 0 表示没有指令 交换地图也不处理
- if (m_Command.CmdKind == do_none || m_bExchangeServer)
- return;
- if (nAI)
- {
- if (m_RegionIndex < 0)
- return;
- switch (m_Command.CmdKind)
- {
- case do_stand:
- DoStand();
- break;
- case do_walk:
- Goto(m_Command.Param_X, m_Command.Param_Y);
- break;
- case do_run:
- RunTo(m_Command.Param_X, m_Command.Param_Y);
- break;
- case do_jump:
- JumpTo(m_Command.Param_X, m_Command.Param_Y);
- break;
- case do_skill:
- if (int nSkillIdx = m_SkillList.FindSame(m_Command.Param_X))
- {
- SetActiveSkill(nSkillIdx);
- DoSkill(m_Command.Param_Y, m_Command.Param_Z);
- }
- else
- {
- DoStand();
- }
- break;
- case do_sit:
- DoSit();
- break;
- case do_defense:
- DoDefense();
- break;
- case do_idle:
- DoIdle();
- break;
- case do_hurt:
- DoHurt(m_Command.Param_X, m_Command.Param_Y, m_Command.Param_Z);
- break;
- // 因为跨地图能把ai设为1
- case do_revive:
- DoStand();
- m_ProcessAI = 1;
- m_ProcessState = 1;
- #ifndef _SERVER
- this->SetInstantSpr(enumINSTANT_STATE_REVIVE);
- #endif
- break;
- }
- }
- else
- {
- switch(m_Command.CmdKind)
- {
- case do_hurt:
- if (m_RegionIndex >= 0)
- DoHurt(m_Command.Param_X, m_Command.Param_Y, m_Command.Param_Z);
- break;
- case do_revive:
- DoStand();
- m_ProcessAI = 1;
- m_ProcessState = 1;
- #ifndef _SERVER
- this->SetInstantSpr(enumINSTANT_STATE_REVIVE);
- #endif
- break;
- default:
- break;
- }
- }
- m_Command.CmdKind = do_none;
- }
- BOOL KNpc::ProcessState()
- {
- int nRet = FALSE;
- if (m_RegionIndex < 0)
- return FALSE;
- if (!(m_LoopFrames % GAME_UPDATE_TIME))
- {
- // 生命、内力、体力变化只由服务器计算
- #ifdef _SERVER
- // 打坐中
- if (m_Doing == do_sit)
- {
- int nLifeAdd = m_CurrentLifeMax * 3 / 1000;
- if (nLifeAdd <= 0)
- nLifeAdd = 1;
- m_CurrentLife += nLifeAdd;
- if (m_CurrentLife > m_CurrentLifeMax)
- m_CurrentLife = m_CurrentLifeMax;
- int nManaAdd = m_CurrentManaMax * 3 / 1000;
- if (nManaAdd <= 0)
- nManaAdd = 1;
- m_CurrentMana += nManaAdd;
- if (m_CurrentMana > m_CurrentManaMax)
- m_CurrentMana = m_CurrentManaMax;
- // if (m_CurrentLife >= m_CurrentLifeMax && m_CurrentMana >= m_CurrentManaMax)
- // this->SendCommand(do_stand);
- }
- // 生命自然回复
- m_CurrentLife += m_CurrentLifeReplenish;
- if (m_CurrentLife > m_CurrentLifeMax)
- m_CurrentLife = m_CurrentLifeMax;
- // 内力自然回复
- m_CurrentMana += m_CurrentManaReplenish;
- if (m_CurrentMana > m_CurrentManaMax)
- m_CurrentMana = m_CurrentManaMax;
- // 体力自然回复
- if (m_Doing == do_run)
- m_CurrentStamina += m_CurrentStaminaGain / STAMINA_RECOVER_SCALE;
- else
- m_CurrentStamina += m_CurrentStaminaGain;
- if (m_CurrentStamina > m_CurrentStaminaMax)
- m_CurrentStamina = m_CurrentStaminaMax;
- #endif
- // 光环技能
- if (m_ActiveAuraID)
- {
- int nLevel = m_SkillList.GetCurrentLevel(m_ActiveAuraID);
- if (nLevel > 0)
- {
- int nMpsX, nMpsY;
- SubWorld[m_SubWorldIndex].Map2Mps(m_RegionIndex, m_MapX, m_MapY, m_OffX, m_OffY, &nMpsX, &nMpsY);
- _ASSERT(m_ActiveAuraID < MAX_SKILL && nLevel < MAX_SKILLLEVEL);
- #ifdef _SERVER
- NPC_SKILL_SYNC SkillCmd;
- SkillCmd.ID = this->m_dwID;
- KSkill * pOrdinSkill = (KSkill *) g_SkillManager.GetSkill(m_ActiveAuraID, nLevel);
- if (pOrdinSkill)
- {
- // if (pOrdinSkill->GetSkillStyle() == SKILL_SS_Missles)
- SkillCmd.nSkillID = pOrdinSkill->GetChildSkillId();
- }
- else
- {
- SkillCmd.nSkillID = 0;
- }
- SkillCmd.nSkillLevel = nLevel;
- SkillCmd.nMpsX = -1;
- SkillCmd.nMpsY = m_dwID;
- SkillCmd.ProtocolType = s2c_castskilldirectly;
- POINT POff[8] =
- {
- {0, 32},
- {-16, 32},
- {-16, 0},
- {-16, -32},
- {0, -32},
- {16, -32},
- {16, 0},
- {16, 32},
- };
- int nMaxCount = MAX_BROADCAST_COUNT;
- CURREGION.BroadCast(&SkillCmd, sizeof(SkillCmd), nMaxCount, m_MapX, m_MapY);
- int i;
- for (i = 0; i < 8; i++)
- {
- if (CONREGIONIDX(i) == -1)
- continue;
- CONREGION(i).BroadCast(&SkillCmd, sizeof(SkillCmd), nMaxCount, m_MapX - POff[i].x, m_MapY - POff[i].y);
- }
- #endif
- KSkill * pOrdinSkill1 = (KSkill *) g_SkillManager.GetSkill(m_ActiveAuraID, nLevel);
- int nChildSkillId = 0;
- if (pOrdinSkill1)
- {
- nChildSkillId = pOrdinSkill1->GetChildSkillId();
- KSkill * pOrdinSkill2 = (KSkill *) g_SkillManager.GetSkill(nChildSkillId, nLevel);
- if (pOrdinSkill2)
- {
- pOrdinSkill2->Cast(m_Index, nMpsX, nMpsY);
- }
- }
- }
- }
- }
- #ifdef _SERVER
- // 物理护盾
- if (m_PhysicsArmor.nTime)
- {
- m_PhysicsArmor.nTime--;
- }
- else
- {
- m_PhysicsArmor.nValue[0] = 0;
- }
- // 冰护盾
- if (m_ColdArmor.nTime)
- {
- m_ColdArmor.nTime--;
- }
- else
- {
- m_ColdArmor.nValue[0] = 0;
- }
- // 火护盾
- if (m_FireArmor.nTime)
- {
- m_FireArmor.nTime--;
- }
- else
- {
- m_FireArmor.nValue[0] = 0;
- }
- // 毒护盾
- if (m_PoisonArmor.nTime)
- {
- m_PoisonArmor.nTime--;
- }
- else
- {
- m_PoisonArmor.nValue[0] = 0;
- }
- // 电护盾
- if (m_LightArmor.nTime)
- {
- m_LightArmor.nTime--;
- }
- else
- {
- m_LightArmor.nValue[0] = 0;
- }
- // 魔法盾
- if (m_ManaShield.nTime)
- {
- m_ManaShield.nTime--;
- }
- else
- {
- m_ManaShield.nValue[0] = 0;
- }
- // m_PowerState; // 怒火状态
- //中毒状态
- if (m_PoisonState.nTime > 0)
- {
- m_PoisonState.nTime--;
- if (m_PoisonState.nValue[1] == 0)
- {
- m_PoisonState.nValue[1] = 1;
- }
- if (!(m_PoisonState.nTime % m_PoisonState.nValue[1]))
- {
- CalcDamage(m_nLastPoisonDamageIdx, m_PoisonState.nValue[0], m_PoisonState.nValue[0], damage_poison, FALSE, FALSE, TRUE);
- }
- }
- // 冰冻状态
- if (m_FreezeState.nTime > 0)
- {
- m_FreezeState.nTime--;
- if (m_FreezeState.nTime & 1)
- {
- nRet = TRUE;
- }
- }
- // 燃烧状态
- if (m_BurnState.nTime > 0)
- {
- m_BurnState.nTime--;
- if (m_BurnState.nValue[1] == 0)
- {
- m_BurnState.nValue[1] = 1;
- }
- if (!(m_BurnState.nTime % m_BurnState.nValue[1]))
- {
- CalcDamage(m_Index, m_BurnState.nValue[0], m_BurnState.nValue[0], damage_fire, TRUE, FALSE);
- }
- }
- // 混乱状态
- if (m_ConfuseState.nTime > 0)
- {
- m_ConfuseState.nTime--;
- if (m_ConfuseState.nTime <= 0)
- {
- m_CurrentCamp = m_Camp;
- }
- }
- // 眩晕状态
- if (m_StunState.nTime > 0)
- {
- m_StunState.nTime--;
- nRet = TRUE;
- }
- // 补血状态
- if (m_LifeState.nTime > 0)
- {
- m_LifeState.nTime--;
- if (!(m_LifeState.nTime % GAME_UPDATE_TIME))
- {
- m_CurrentLife += m_LifeState.nValue[0];
- if (m_CurrentLife > m_CurrentLifeMax)
- {
- m_CurrentLife = m_CurrentLifeMax;
- }
- }
- }
- // 补MANA状态
- if (m_ManaState.nTime > 0)
- {
- m_ManaState.nTime--;
- if (!(m_ManaState.nTime % GAME_UPDATE_TIME))
- {
- m_CurrentMana += m_ManaState.nValue[0];
- if (m_CurrentMana > m_CurrentManaMax)
- {
- m_CurrentMana = m_CurrentManaMax;
- }
- }
- }
- // 醉酒状态
- if (m_DrunkState.nTime > 0)
- {
- m_DrunkState.nTime--;
- }
- #endif
- #ifndef _SERVER
- bool bAdjustColorId = false;
- if (m_FreezeState.nTime > 0)
- {
- if (SubWorld[0].m_dwCurrentTime & 1)
- nRet = TRUE;
- m_DataRes.SetAdjustColorId(KNpcRes::adjustcolor_freeze);
- bAdjustColorId = true;
- }
- if (m_StunState.nTime > 0)
- {
- m_DataRes.SetAdjustColorId(KNpcRes::adjustcolor_stun);
- nRet = TRUE;
- bAdjustColorId = true;
- }
- if (m_PoisonState.nTime > 0)
- {
- // m_PoisonState.nTime--;
- m_DataRes.SetAdjustColorId(KNpcRes::adjustcolor_poison);
- bAdjustColorId = true;
- }
- // 燃烧状态
- if (m_BurnState.nTime > 0)
- {
- // m_BurnState.nTime--;
- m_DataRes.SetAdjustColorId(KNpcRes::adjustcolor_burn);
- bAdjustColorId = true;
- }
- // 混乱状态
- if (m_ConfuseState.nTime > 0)
- {
- // m_ConfuseState.nTime--;
- m_DataRes.SetAdjustColorId(KNpcRes::adjustcolor_confuse);
- bAdjustColorId = true;
- }
- if (!bAdjustColorId)
- m_DataRes.SetAdjustColorId(KNpcRes::adjustcolor_physics);
- #endif
- KStateNode* pNode;
- pNode = (KStateNode *)m_StateSkillList.GetHead();
- while(pNode)
- {
- KStateNode* pTempNode = pNode;
- pNode = (KStateNode *)pNode->GetNext();
- if (pTempNode->m_LeftTime == -1) // 被动技能
- continue;
- if (pTempNode->m_LeftTime == 0)
- {
- int i;
- for (i = 0; i < MAX_SKILL_STATE; i++)
- {
- if (pTempNode->m_State[i].nAttribType)
- ModifyAttrib(m_Index, &pTempNode->m_State[i]);
- }
- _ASSERT(pTempNode != NULL);
- pTempNode->Remove();
- delete pTempNode;
- #ifdef _SERVER
- UpdateNpcStateInfo();
- BroadCastState();
- #endif
- pTempNode = NULL;
- continue;
- }
- else
- pTempNode->m_LeftTime --;
- }
- return nRet;
- }
- void KNpc::DoDeath(int nMode/* = 0*/)
- {
- // _ASSERT(m_Doing != do_death);
- // do_death == 10
- //g_DebugLog("[DEATH] m_Doing: %d", m_Doing);
- _ASSERT(m_RegionIndex >= 0);
- if (m_RegionIndex < 0)
- return;
- if (m_Doing == do_death)
- return;
- if (IsPlayer() && !m_FightMode) // 城镇内不会死亡
- {
- m_CurrentLife = 1;
- return;
- }
- #ifndef _SERVER
- if (this->m_Kind == kind_normal)
- this->SetBlood(this->m_CurrentLife);
- #endif
- m_Doing = do_death;
- m_ProcessAI = 0;
- m_ProcessState = 0;
- m_Frames.nTotalFrame = m_DeathFrame;
- m_Frames.nCurrentFrame = 0;
- m_Height = 0;
- #ifdef _SERVER
- int nPlayer = 0;
- // 杀死玩家不得经验
- if (this->m_Kind != kind_player)
- {
- nPlayer = m_cDeathCalcExp.CalcExp();
- }
- //丢物品
- DeathPunish(nMode, nPlayer);
- NPC_DEATH_SYNC NetCommand;
- NetCommand.ProtocolType = (BYTE)s2c_npcdeath;
- NetCommand.ID = m_dwID;
- POINT POff[8] =
- {
- {0, 32},
- {-16, 32},
- {-16, 0},
- {-16, -32},
- {0, -32},
- {16, -32},
- {16, 0},
- {16, 32},
- };
- int nMaxCount = MAX_BROADCAST_COUNT;
- CURREGION.BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX, m_MapY);
- int i;
- for (i = 0; i < 8; i++)
- {
- if (CONREGIONIDX(i) == -1)
- continue;
- CONREGION(i).BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX - POff[i].x, m_MapY - POff[i].y);
- }
- #endif
- #ifndef _SERVER
- m_ClientDoing = cdo_death;
- if (Npc[Player[CLIENT_PLAYER_INDEX].m_nIndex].m_nPeopleIdx == m_Index)
- {
- Npc[Player[CLIENT_PLAYER_INDEX].m_nIndex].m_nPeopleIdx = 0;
- }
- this->m_cGold.ClientClearState();
- #endif
- if (IsPlayer())
- {
- //离队 Not Finish
- }
- }
- void KNpc::OnDeath()
- {
- if (WaitForFrame())
- {
- g_DebugLog("[DEATH] WaitForFrame TRUE");
- m_Frames.nCurrentFrame = m_Frames.nTotalFrame - 1; // 保证不会有重回第一帧的情况
- #ifndef _SERVER
- int nTempX, nTempY;
- KObjItemInfo sInfo;
- SubWorld[m_SubWorldIndex].Map2Mps(m_RegionIndex, m_MapX, m_MapY, m_OffX, m_OffY, &nTempX, &nTempY);
- sInfo.m_nItemID = 0;
- sInfo.m_nItemWidth = 0;
- sInfo.m_nItemHeight = 0;
- sInfo.m_nMoneyNum = 0;
- sInfo.m_nColorID = 0;
- sInfo.m_nMovieFlag = 0;
- sInfo.m_nSoundFlag = 0;
- sInfo.m_szName[0] = 0;
- ObjSet.ClientAdd(0, m_CorpseSettingIdx, 0, m_Dir, 0, nTempX, nTempY, sInfo);
- m_ProcessAI = 1;
- #else
- //如果当间死者为主角,则看有没有死亡脚本,有则运行。
- if (IsPlayer())
- {
- if (Player[m_nPlayerIdx].m_dwDeathScriptId)
- {
- char szNpcIndex[30];
- sprintf(szNpcIndex, "%d", m_nLastDamageIdx);
- Player[m_nPlayerIdx].ExecuteScript(Player[m_nPlayerIdx].m_dwDeathScriptId, "OnDeath", szNpcIndex);
- }
- }
- //如果死者是Npc,而打死他的是主角,并有死亡脚本则运行脚本
- else if (Npc[m_nLastDamageIdx].IsPlayer())
- {
- int nIdx = Npc[m_nLastDamageIdx].m_nPlayerIdx;
- if (nIdx)
- {
- // 执行战斗npc死亡脚本
- if (ActionScript[0])
- {
- char szNpcIndex[30];
- sprintf(szNpcIndex, "%d", m_nLastDamageIdx);
- Player[nIdx].ExecuteScript(ActionScript, "OnDeath", szNpcIndex);
- }
- }
- }
- if (!IsPlayer())
- this->m_cGold.RecoverBackData();
- #endif
- // 重生点
- if (m_Kind != kind_partner)//战斗Npc时
- {
- DoRevive();
- #ifndef _SERVER
- // 客户端把NPC删除
- if (m_Kind != kind_player)
- {
- SubWorld[0].m_WorldMessage.Send(GWM_NPC_DEL, m_Index);
- return;
- }
- #endif
- }
- else // 同伴类?以后再说吧
- {
- // 以后再说Not Finish
- }
- }
- else
- {
- g_DebugLog("[DEATH] WaitForFrame FALSE");
- }
- }
- void KNpc::DoDefense()
- {
- m_ProcessAI = 0;
- }
- void KNpc::OnDefense()
- {
- }
- void KNpc::DoIdle()
- {
- if (m_Doing == do_idle)
- return;
- m_Doing = do_idle;
- }
- void KNpc::OnIdle()
- {
- }
- void KNpc::DoHurt(int nHurtFrames, int nX, int nY)
- {
- _ASSERT(m_RegionIndex >= 0);
- #ifndef _SERVER
- m_DataRes.SetBlur(FALSE);
- #endif
- if (m_RegionIndex < 0)
- return;
- if (m_Doing == do_hurt || m_Doing == do_death)
- return;
- // 受击回复速度已经达到100%了,不做受伤动作
- #ifdef _SERVER
- if (m_CurrentHitRecover >= 100)
- return;
- #define MIN_HURT_PERCENT 50
- if (!g_RandPercent(MIN_HURT_PERCENT + m_CurrentHitRecover * (100 - MIN_HURT_PERCENT) / 100))
- {
- return;
- }
- #endif
- m_Doing = do_hurt;
- m_ProcessAI = 0;
- #ifdef _SERVER
- m_Frames.nTotalFrame = m_HurtFrame * (100 - m_CurrentHitRecover) / 100;
- #else
- m_ClientDoing = cdo_hurt;
- m_Frames.nTotalFrame = nHurtFrames;
- m_nHurtDesX = nX;
- m_nHurtDesY = nY;
- if (m_Height > 0)
- {
- // 临时记录下来做为高度变化,在OnHurt中使用
- m_nHurtHeight = m_Height;
- }
- else
- {
- m_nHurtHeight = 0;
- }
- #endif
- if (m_Frames.nTotalFrame == 0)
- m_Frames.nTotalFrame = 1;
- m_Frames.nCurrentFrame = 0;
- #ifdef _SERVER // 向周围9个Region广播发技能
- NPC_HURT_SYNC NetCommand;
- NetCommand.ProtocolType = (BYTE)s2c_npchurt;
- NetCommand.ID = m_dwID;
- NetCommand.nFrames = m_Frames.nTotalFrame;
- GetMpsPos(&NetCommand.nX, &NetCommand.nY);
- POINT POff[8] =
- {
- {0, 32},
- {-16, 32},
- {-16, 0},
- {-16, -32},
- {0, -32},
- {16, -32},
- {16, 0},
- {16, 32},
- };
- int nMaxCount = MAX_BROADCAST_COUNT;
- CURREGION.BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX, m_MapY);
- int i;
- for (i = 0; i < 8; i++)
- {
- if (CONREGIONIDX(i) == -1)
- continue;
- CONREGION(i).BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX - POff[i].x, m_MapY - POff[i].y);
- }
- #endif
- }
- void KNpc::OnHurt()
- {
- if (m_RegionIndex < 0)
- {
- g_DebugLog("[error]%s Region Index < 0 when hurt", Name);
- return;
- }
- int nX, nY;
- GetMpsPos(&nX, &nY);
- #ifdef _SERVER
- m_Height = 0;
- #endif
- #ifndef _SERVER
- m_Height = m_nHurtHeight * (m_Frames.nTotalFrame - m_Frames.nCurrentFrame - 1) / m_Frames.nTotalFrame;
- nX = nX + (m_nHurtDesX - nX) * m_Frames.nCurrentFrame / m_Frames.nTotalFrame;
- nY = nY + (m_nHurtDesY - nY) * m_Frames.nCurrentFrame / m_Frames.nTotalFrame;
- int nOldRegion = m_RegionIndex;
- //SetPos(nX, nY);
- CURREGION.DecRef(m_MapX, m_MapY, obj_npc);
- int nRegion, nMapX, nMapY, nOffX, nOffY;
- nRegion = -1;
- nMapX = nMapY = nOffX = nOffY = 0;
- SubWorld[m_SubWorldIndex].Mps2Map(nX, nY, &nRegion, &nMapX, &nMapY, &nOffX, &nOffY);
- if (nRegion == -1)
- {
- SubWorld[0].m_Region[nOldRegion].RemoveNpc(m_Index);
- m_dwRegionID = 0;
- }
- else if (nOldRegion != nRegion)
- {
- m_RegionIndex = nRegion;
- m_MapX = nMapX;
- m_MapY = nMapY;
- m_OffX = nOffX;
- m_OffY = nOffY;
- SubWorld[0].NpcChangeRegion(SubWorld[0].m_Region[nOldRegion].m_RegionID, SubWorld[0].m_Region[m_RegionIndex].m_RegionID, m_Index);
- m_dwRegionID = SubWorld[0].m_Region[m_RegionIndex].m_RegionID;
- }
- if (nRegion >= 0)
- CURREGION.AddRef(m_MapX, m_MapY, obj_npc);
- #endif
- if (WaitForFrame())
- {
- g_DebugLog("[DEATH]On Hurt Finished");
- DoStand();
- m_ProcessAI = 1;
- }
- }
- void KNpc::DoSpecial1()
- {
- DoBlurAttack();
- }
- void KNpc::OnSpecial1()
- {
- if (WaitForFrame() &&m_Frames.nTotalFrame != 0)
- {
- #ifndef _SERVER
- m_DataRes.SetBlur(FALSE);
- #endif
- DoStand();
- m_ProcessAI = 1;
- }
- else if (IsReachFrame(ATTACKACTION_EFFECT_PERCENT))
- {
- KSkill * pSkill = (KSkill*)GetActiveSkill();
- if (pSkill)
- {
- int nChildSkill = pSkill->GetChildSkillId();
- int nChildSkillLevel = pSkill->m_ulLevel;
- if (nChildSkill > 0)
- {
- KSkill * pChildSkill = (KSkill*)g_SkillManager.GetSkill(nChildSkill, nChildSkillLevel);
- if (pChildSkill)
- {
- pChildSkill->Cast(m_Index, m_SkillParam1, m_SkillParam2);
- }
- }
- }
- if (m_Frames.nTotalFrame == 0)
- {
- m_ProcessAI = 1;
- }
- }
- }
- void KNpc::DoSpecial2()
- {
- }
- void KNpc::OnSpecial2()
- {
- if (WaitForFrame() &&m_Frames.nTotalFrame != 0)
- {
- #ifndef _SERVER
- m_DataRes.SetBlur(FALSE);
- #endif
- DoStand();
- m_ProcessAI = 1;
- }
- else if (IsReachFrame(ATTACKACTION_EFFECT_PERCENT))
- {
- ISkill * pSkill = GetActiveSkill();
- eSkillStyle eStyle = (eSkillStyle)pSkill->GetSkillStyle();
- switch(eStyle)
- {
- case SKILL_SS_Thief:
- {
- ( (KThiefSkill*)pSkill )->OnSkill(this);
- }
- break;
- }
- if (m_Frames.nTotalFrame == 0)
- {
- m_ProcessAI = 1;
- }
- }
- }
- void KNpc::DoSpecial3()
- {
- }
- void KNpc::OnSpecial3()
- {
- }
- void KNpc::DoSpecial4()
- {
- }
- void KNpc::OnSpecial4()
- {
- }
- void KNpc::DoStand()
- {
- m_Frames.nTotalFrame = m_StandFrame;
- if (m_Doing == do_stand)
- {
- return;
- }
- else
- {
- m_Doing = do_stand;
- m_Frames.nCurrentFrame = 0;
- GetMpsPos(&m_DesX, &m_DesY);
- #ifndef _SERVER
- if (m_FightMode)
- m_ClientDoing = cdo_fightstand;
- else if (g_Random(6) != 1)
- {
- m_ClientDoing = cdo_stand;
- }
- else
- {
- m_ClientDoing = cdo_stand1;
- }
- m_DataRes.StopSound();
- #endif
- }
- }
- void KNpc::OnStand()
- {
- if (WaitForFrame())
- {
- #ifndef _SERVER
- if (m_FightMode)
- {
- m_ClientDoing = cdo_fightstand;
- }
- else if (g_Random(6) != 1)
- {
- m_ClientDoing = cdo_stand;
- }
- else
- {
- m_ClientDoing = cdo_stand1;
- }
- #endif
- }
- }
- void KNpc::DoRevive()
- {
- if (m_RegionIndex < 0)
- {
- g_DebugLog("[error]%s Region Index < 0 when dorevive", Name);
- return;
- }
- if (m_Doing == do_revive)
- {
- return;
- }
- else
- {
- m_Doing = do_revive;
- m_ProcessAI = 0;
- m_ProcessState = 0;
- ClearStateSkillEffect();
- ClearNormalState();
- #ifdef _SERVER
- if (IsPlayer())
- return;
- m_Frames.nTotalFrame = m_ReviveFrame;
- SubWorld[m_SubWorldIndex].m_Region[m_RegionIndex].DecRef(m_MapX, m_MapY, obj_npc);
- SubWorld[m_SubWorldIndex].NpcChangeRegion(m_RegionIndex, VOID_REGION, m_Index); // spe 03/06/28
- m_Frames.nCurrentFrame = 0;
- #else
- // 客户端
- if (IsPlayer())
- {
- KSystemMessage Msg;
- Msg.byConfirmType = SMCT_UI_RENASCENCE;
- Msg.byParamSize = 0;
- Msg.byPriority = 255;
- Msg.eType = SMT_PLAYER;
- sprintf(Msg.szMessage, MSG_NPC_DEATH, Name);
- CoreDataChanged(GDCNI_SYSTEM_MESSAGE, (unsigned int)&Msg, NULL);
- }
- m_Frames.nTotalFrame = m_DeathFrame;
- m_ClientDoing = cdo_death;
- #endif
- }
- }
- void KNpc::OnRevive()
- {
- #ifdef _SERVER
- if (!IsPlayer() && WaitForFrame())
- {
- Revive();
- }
- #else // 客户端
- m_Frames.nCurrentFrame = m_Frames.nTotalFrame - 1;
- #endif
- }
- void KNpc::DoRun()
- {
- _ASSERT(m_RegionIndex >= 0);
- if (m_CurrentRunSpeed)
- m_Frames.nTotalFrame = (m_RunFrame * m_RunSpeed) / m_CurrentRunSpeed;
- else
- m_Frames.nTotalFrame = m_RunFrame;
- #ifndef _SERVER
- if (m_FightMode)
- {
- m_ClientDoing = cdo_fightrun;
- }
- else
- {
- m_ClientDoing = cdo_run;
- }
- #endif
- if (IsPlayer())
- {
- /* if (!Cost(attrib_stamina, m_CurrentStaminaLoss))
- {
- DoWalk();
- return;
- }*/
- }
- #ifdef _SERVER
- NPC_RUN_SYNC NetCommand;
- NetCommand.ProtocolType = (BYTE)s2c_npcrun;
- NetCommand.ID = m_dwID;
- NetCommand.nMpsX = m_DesX;
- NetCommand.nMpsY = m_DesY;
- POINT POff[8] =
- {
- {0, 32},
- {-16, 32},
- {-16, 0},
- {-16, -32},
- {0, -32},
- {16, -32},
- {16, 0},
- {16, 32},
- };
- int nMaxCount = MAX_BROADCAST_COUNT;
- CURREGION.BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX, m_MapY);
- int i;
- for (i = 0; i < 8; i++)
- {
- if (CONREGIONIDX(i) == -1)
- continue;
- CONREGION(i).BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX - POff[i].x, m_MapY - POff[i].y);
- }
- #endif
- if (m_Doing == do_run)
- {
- return;
- }
- m_Doing = do_run;
- m_Frames.nCurrentFrame = 0;
- }
- void KNpc::OnRun()
- {
- WaitForFrame();
- ServeMove(m_CurrentRunSpeed);
- }
- void KNpc::DoSit()
- {
- _ASSERT(m_RegionIndex >= 0);
- if (m_Doing == do_sit)
- {
- // DoStand();
- return;
- }
- m_Doing = do_sit;
- #ifdef _SERVER // 向周围9个Region广播发技能
- NPC_SIT_SYNC NetCommand;
- NetCommand.ProtocolType = (BYTE)s2c_npcsit;
- NetCommand.ID = m_dwID;
- POINT POff[8] =
- {
- {0, 32},
- {-16, 32},
- {-16, 0},
- {-16, -32},
- {0, -32},
- {16, -32},
- {16, 0},
- {16, 32},
- };
- int nMaxCount = MAX_BROADCAST_COUNT;
- CURREGION.BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX, m_MapY);
- int i;
- for (i = 0; i < 8; i++)
- {
- if (CONREGIONIDX(i) == -1)
- continue;
- CONREGION(i).BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX - POff[i].x, m_MapY - POff[i].y);
- }
- #endif
- #ifndef _SERVER
- m_ClientDoing = cdo_sit;
- #endif
- m_Frames.nTotalFrame = m_SitFrame;
- m_Frames.nCurrentFrame = 0;
- }
- void KNpc::OnSit()
- {
- // 体力换内力(没有设定)
- if (WaitForFrame())
- {
- m_Frames.nCurrentFrame = m_Frames.nTotalFrame - 1;
- }
- }
- void KNpc::DoSkill(int nX, int nY)
- {
- _ASSERT(m_RegionIndex >= 0);
- if (m_Doing == do_skill)
- return;
- // 非战斗状态不能发技能
- if (IsPlayer())
- {
- if (!m_FightMode)
- return;
- #ifdef _SERVER
- if (m_nPlayerIdx > 0)
- Player[m_nPlayerIdx].m_ItemList.Abrade(enumAbradeAttack);
- #endif
- }
- ISkill * pSkill = GetActiveSkill();
- if(pSkill)
- {
- eSkillStyle eStyle = (eSkillStyle)pSkill->GetSkillStyle();
- if (m_SkillList.CanCast(m_ActiveSkillID, SubWorld[m_SubWorldIndex].m_dwCurrentTime)
- && pSkill->CanCastSkill(m_Index, nX, nY)
- &&
- ( m_Kind != kind_player
- || Cost(pSkill->GetSkillCostType(), pSkill->GetSkillCost(this))
- )
- )
- {
- /*------------------------------------------------------------------------------------
- 发技能时,当需指定目标对象时,传至Skill.Cast的两个参数第一个参数为-1,第二个为Npc index
- 在S2C时,第二个参数必须由Server的NpcIndex转为NpcdwID参出去。
- 在C收到该指令时,将NpcdwID转为本机的NpcIndex
- -------------------------------------------------------------------------------------*/
- #ifdef _SERVER // 向周围9个Region广播发技能
- NPC_SKILL_SYNC NetCommand;
- NetCommand.ProtocolType = (BYTE)s2c_skillcast;
- NetCommand.ID = m_dwID;
- NetCommand.nSkillID = m_ActiveSkillID;
- NetCommand.nSkillLevel = m_SkillList.GetCurrentLevel(m_ActiveSkillID);
- if (nY <= 0 )
- {
- DoStand();
- return;
- }
- NetCommand.nMpsX = nX;
- if (nX == -1) //m_nDesX == -1 means attack someone whose id is DesY , and if m_nDesX == -2 means attack at somedir
- {
- NetCommand.nMpsY = Npc[nY].m_dwID;
- if (0 == NetCommand.nMpsY || Npc[nY].m_SubWorldIndex != m_SubWorldIndex)
- return;
- }
- else
- {
- NetCommand.nMpsY = nY;
- }
- m_SkillParam1 = nX;
- m_SkillParam2 = nY;
- m_DesX = nX;
- m_DesY = nY;
- POINT POff[8] =
- {
- {0, 32},
- {-16, 32},
- {-16, 0},
- {-16, -32},
- {0, -32},
- {16, -32},
- {16, 0},
- {16, 32},
- };
- int nMaxCount = MAX_BROADCAST_COUNT;
- CURREGION.BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX, m_MapY);
- int i;
- for (i = 0; i < 8; i++)
- {
- if (CONREGIONIDX(i) == -1)
- continue;
- CONREGION(i).BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX - POff[i].x, m_MapY - POff[i].y);
- }
- #endif
- if (eStyle == SKILL_SS_Missles
- || eStyle == SKILL_SS_Melee
- || eStyle == SKILL_SS_InitiativeNpcState
- || eStyle == SKILL_SS_PassivityNpcState)
- {
- DoOrdinSkill((KSkill *) pSkill, nX, nY);
- }
- else
- {
- switch(eStyle)
- {
- case SKILL_SS_Thief:
- {
- ((KThiefSkill*)pSkill)->DoSkill(this, nX, nY);
- }break;
- default:
- return;
- }
- }
- }
- else
- {
- m_nPeopleIdx = 0;
- m_nObjectIdx = 0;
- DoStand();
- }
- }
- else
- {
- _ASSERT(pSkill);
- }
- }
- int KNpc::DoOrdinSkill(KSkill * pSkill, int nX, int nY)
- {
- _ASSERT(pSkill);
- #ifndef _SERVER
- m_DataRes.StopSound();
- int x, y, tx, ty;
- SubWorld[m_SubWorldIndex].Map2Mps(m_RegionIndex, m_MapX, m_MapY, m_OffX, m_OffY, &x, &y);
- if (nY < 0)
- return 0;
- if (nX < 0)
- {
- if (nX != -1)
- return 0;
- if (nY >= MAX_NPC || Npc[nY].m_dwID == 0 || Npc[nY].m_SubWorldIndex != m_SubWorldIndex)
- return 0;
- Npc[nY].GetMpsPos(&tx, &ty);
- }
- else
- {
- tx = nX;
- ty = nY;
- }
- m_SkillParam1 = nX;
- m_SkillParam2 = nY;
- m_DesX = nX;
- m_DesY = nY;
- m_Dir = g_GetDirIndex(x, y, tx, ty);
- if (pSkill->GetPreCastEffectFile()[0])
- m_DataRes.SetSpecialSpr((char *)pSkill->GetPreCastEffectFile());
- if (IsPlayer())
- pSkill->PlayPreCastSound(m_nSex,x, y);
- if (pSkill->IsNeedShadow())
- m_DataRes.SetBlur(TRUE);
- else
- m_DataRes.SetBlur(FALSE);
- #endif
- CLIENTACTION ClientDoing = pSkill->GetActionType();
- #ifndef _SERVER
- if (ClientDoing >= cdo_count)
- m_ClientDoing = cdo_magic;
- else if (ClientDoing != cdo_none)
- m_ClientDoing = ClientDoing;
- #endif
- if (pSkill->GetSkillStyle() == SKILL_SS_Melee)
- {
- if (CastMeleeSkill(pSkill) == FALSE)
- {
- m_nPeopleIdx = 0;
- m_nObjectIdx = 0;
- m_ProcessAI = 1;
- DoStand();
- return 1 ;
- }
- }
- //物理技能的技能释放时间与普通技能不同,一个是AttackFrame,一个是CastFrame
- else if (pSkill->IsPhysical())
- {
- if (ClientDoing == cdo_none)
- m_Frames.nTotalFrame = 0;
- else
- m_Frames.nTotalFrame = m_AttackFrame * 100 / (100 + m_CurrentAttackSpeed);
- #ifndef _SERVER
- if (g_Random(3))
- m_ClientDoing = cdo_attack;
- else
- m_ClientDoing = cdo_attack1;
- #endif
- m_Doing = do_attack;
- }
- else
- {
- if (ClientDoing == cdo_none)
- m_Frames.nTotalFrame = 0;
- else
- m_Frames.nTotalFrame = m_CastFrame * 100 / (m_CurrentCastSpeed + 100);
- m_Doing = do_magic;
- }
- m_ProcessAI = 0;
- m_Frames.nCurrentFrame = 0;
- return 1;
- }
- void KNpc::DoAttack()
- {
- if (m_Doing == do_attack)
- return;
- #ifndef _SERVER
- if (g_Random(2) == 1)
- {
- m_ClientDoing = cdo_attack;
- }
- else
- {
- m_ClientDoing = cdo_attack1;
- }
- #endif
- m_ProcessAI = 0;
- m_Frames.nTotalFrame = m_AttackFrame * 100 / (100 + m_CurrentAttackSpeed);
- m_Frames.nCurrentFrame = 0;
- m_Doing = do_attack;
- }
- BOOL KNpc::CastMeleeSkill(KSkill * pSkill)
- {
- BOOL bSuceess = FALSE;
- _ASSERT(pSkill);
- switch(pSkill->GetMeleeType())
- {
- case Melee_AttackWithBlur:
- {
- bSuceess = DoBlurAttack();
- }break;
- case Melee_Jump:
- {
- if (NewJump(m_DesX, m_DesY))
- {
- DoJump();
- bSuceess = TRUE;
- }
- }break;
- case Melee_JumpAndAttack:
- {
- if (m_DesX < 0 && m_DesY > 0)
- {
- int x, y;
- SubWorld[m_SubWorldIndex].Map2Mps
- (
- Npc[m_DesY].m_RegionIndex,
- Npc[m_DesY].m_MapX,
- Npc[m_DesY].m_MapY,
- Npc[m_DesY].m_OffX,
- Npc[m_DesY].m_OffY,
- &x,
- &y
- );
- m_DesX = x + 1;
- m_DesY = y;
- }
- if (NewJump(m_DesX, m_DesY))
- {
- DoJumpAttack();
- bSuceess = TRUE;
- }
- }break;
- case Melee_RunAndAttack:
- {
- bSuceess = DoRunAttack();
- }break;
- case Melee_ManyAttack:
- {
- bSuceess = DoManyAttack();
- }break;
- default:
- m_ProcessAI = 1;
- break;
- }
- return bSuceess;
- }
- BOOL KNpc::DoBlurAttack()// DoSpecail1
- {
- if (m_Doing == do_special1)
- return FALSE;
- KSkill * pSkill = (KSkill*) GetActiveSkill();
- if (!pSkill)
- return FALSE;
- _ASSERT(pSkill->GetSkillStyle() == SKILL_SS_Melee);
- #ifndef _SERVER
- m_ClientDoing = pSkill->GetActionType();
- m_DataRes.SetBlur(TRUE);
- #endif
- m_Frames.nTotalFrame = m_AttackFrame * 100 / (100 + m_CurrentAttackSpeed);
- m_Frames.nCurrentFrame = 0;
- m_Doing = do_special1;
- return TRUE;
- }
- void KNpc::DoMagic()
- {
- if (m_Doing == do_magic)
- return;
- m_ProcessAI = 0;
- #ifndef _SERVER
- m_ClientDoing = cdo_magic;
- #endif
- m_Frames.nTotalFrame = m_CastFrame * 100 / (m_CurrentCastSpeed + 100);
- m_Frames.nCurrentFrame = 0;
- m_Doing = do_magic;
- }
- void KNpc::OnSkill()
- {
- KSkill * pSkill = NULL;
- if (WaitForFrame() &&m_Frames.nTotalFrame != 0)
- {
- DoStand();
- m_ProcessAI = 1;
- }
- else if (IsReachFrame(ATTACKACTION_EFFECT_PERCENT))
- {
- #ifndef _SERVER
- m_DataRes.SetBlur(FALSE);
- #endif
- if (m_DesX == -1)
- {
- if (m_DesY <= 0)
- goto Label_ProcessAI;
- //此时该角色已经无效时
- if (Npc[m_DesY].m_RegionIndex < 0)
- goto Label_ProcessAI;
- }
- pSkill =(KSkill*) GetActiveSkill();
- if (pSkill)
- {
- pSkill->Cast(m_Index, m_DesX, m_DesY);
- m_SkillList.SetNextCastTime(m_ActiveSkillID, SubWorld[m_SubWorldIndex].m_dwCurrentTime + pSkill->GetDelayPerCast());
- }
- Label_ProcessAI:
- if (m_Frames.nTotalFrame == 0)
- {
- m_ProcessAI = 1;
- }
- }
- }
- void KNpc::JumpTo(int nMpsX, int nMpsY)
- {
- if (NewJump(nMpsX, nMpsY))
- DoJump();
- else
- {
- RunTo(nMpsX, nMpsY);
- }
- }
- void KNpc::RunTo(int nMpsX, int nMpsY)
- {
- if (NewPath(nMpsX, nMpsY))
- DoRun();
- }
- void KNpc::Goto(int nMpsX, int nMpsY)
- {
- if (NewPath(nMpsX, nMpsY))
- DoWalk();
- }
- void KNpc::DoWalk()
- {
- _ASSERT(m_RegionIndex >= 0);
- if (m_CurrentWalkSpeed)
- m_Frames.nTotalFrame = (m_WalkFrame * m_WalkSpeed) / m_CurrentWalkSpeed + 1;
- else
- m_Frames.nTotalFrame = m_WalkFrame;
- #ifdef _SERVER // Server端的代码
- NPC_WALK_SYNC NetCommand;
- NetCommand.ProtocolType = (BYTE)s2c_npcwalk;
- NetCommand.ID = m_dwID;
- NetCommand.nMpsX = m_DesX;
- NetCommand.nMpsY = m_DesY;
- POINT POff[8] =
- {
- {0, 32},
- {-16, 32},
- {-16, 0},
- {-16, -32},
- {0, -32},
- {16, -32},
- {16, 0},
- {16, 32},
- };
- int nMaxCount = MAX_BROADCAST_COUNT;
- CURREGION.BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX, m_MapY);
- int i;
- for (i = 0; i < 8; i++)
- {
- if (CONREGIONIDX(i) == -1)
- continue;
- CONREGION(i).BroadCast(&NetCommand, sizeof(NetCommand), nMaxCount, m_MapX - POff[i].x, m_MapY - POff[i].y);
- }
- #endif
- if (m_Doing == do_walk)
- {
- return;
- }
- m_Doing = do_walk;
- m_Frames.nCurrentFrame = 0;
- #ifndef _SERVER
- if (m_FightMode)
- {
- m_ClientDoing = cdo_fightwalk;
- }
- else
- {
- m_ClientDoing = cdo_walk;
- }
- #endif
- }
- void KNpc::DoPlayerTalk(char * szTalk)
- {
- #ifdef _SERVER
- _ASSERT(m_RegionIndex >= 0);
- int nTalkLen = strlen(szTalk);
- if (!nTalkLen) return;
- BYTE * pNetCommand = new BYTE[nTalkLen + 6 + 1];
- pNetCommand[0] = (BYTE)s2c_playertalk;
- *(DWORD *)(pNetCommand + 1) = m_dwID;
- pNetCommand[5] = nTalkLen;
- strcpy((char*)(pNetCommand + 6), szTalk);
- pNetCommand[nTalkLen + 6 ] = ' ';
- POINT POff[8] =
- {
- {0, 32},
- {-16, 32},
- {-16, 0},
- {-16, -32},
- {0, -32},
- {16, -32},
- {16, 0},
- {16, 32},
- };
- int nMaxCount = MAX_BROADCAST_COUNT;
- CURREGION.BroadCast(pNetCommand, nTalkLen + 6 + 1, nMaxCount, m_MapX, m_MapY);
- int i;
- for (i = 0; i < 8; i++)
- {
- if (CONREGIONIDX(i) == -1)
- continue;
- CONREGION(i).BroadCast(pNetCommand, nTalkLen + 6 + 1, nMaxCount, m_MapX - POff[i].x, m_MapY - POff[i].y);
- }
- if (pNetCommand)
- {
- delete [] pNetCommand;
- }
- #endif
- }
- void KNpc::OnPlayerTalk()
- {
- }
- void KNpc::OnWalk()
- {
- #ifndef _SERVER
- // 处理客户端的动画换帧等……
- #endif
- WaitForFrame();
- ServeMove(m_CurrentWalkSpeed);
- }
- int KNpc::GetSkillLevel(int nSkillId)
- {
- int nIndex = m_SkillList.FindSame(nSkillId);
- if (nIndex)
- {
- return m_SkillList.m_Skills[nIndex].SkillLevel;
- }
- else
- {
- return 0;
- }
- }
- void KNpc::ModifyAttrib(int nAttacker, void* pData)
- {
- if (pData != NULL)
- g_NpcAttribModify.ModifyAttrib(this, pData);
- }
- #ifdef _SERVER
- void KNpc::CalcDamage(int nAttacker, int nMin, int nMax, DAMAGE_TYPE nType, BOOL bIsMelee, BOOL bDoHurt /* TRUE */, BOOL bReturn /* = FALSE */)
- {
- if (m_Doing == do_death || m_RegionIndex < 0)
- return;
- if (nMin + nMax <= 0)
- return;
- int nRes = 0;
- int nDamageRange = nMax - nMin;
- int nDamage = 0;
- if (nDamageRange < 0)
- {
- nDamage = nMax + g_Random(-nDamageRange);
- }
- else
- nDamage = nMin + g_Random(nMax - nMin);
- // 第一步,统计抗性,并计算吸收伤害
- switch(nType)
- {
- case damage_physics:
- nRes = m_CurrentPhysicsResist;
- if (nRes > m_CurrentPhysicsResistMax)
- {
- nRes = m_CurrentPhysicsResistMax;
- }
- if (nRes > MAX_RESIST)
- {
- nRes = MAX_RESIST;
- }
- g_DebugLog("[数值]%s受到%d点原始物理伤害,物理抗性%d,物理盾%d", Name, nDamage, nRes, m_PhysicsArmor.nValue[0]);
- m_PhysicsArmor.nValue[0] -= nDamage;
- if (m_PhysicsArmor.nValue[0] < 0)
- {
- nDamage = -m_PhysicsArmor.nValue[0];
- m_PhysicsArmor.nValue[0] = 0;
- m_PhysicsArmor.nTime = 0;
- }
- else
- {
- nDamage = 0;
- }
- if (bIsMelee)
- {
- nMax = m_CurrentMeleeDmgRetPercent;
- }
- else
- {
- nMax = m_CurrentRangeDmgRetPercent;
- }
- break;
- case damage_cold:
- nRes = m_CurrentColdResist;
- if (nRes > m_CurrentColdResistMax)
- {
- nRes = m_CurrentColdResistMax;
- }
- if (nRes > MAX_RESIST)
- {
- nRes = MAX_RESIST;
- }
- g_DebugLog("[数值]%s受到%d点原始冰伤害,冰抗性%d,冰盾%d", Name, nDamage, nRes, m_ColdArmor.nValue[0]);
- m_ColdArmor.nValue[0] -= nDamage;
- if (m_ColdArmor.nValue[0] < 0)
- {
- nDamage = -m_ColdArmor.nValue[0];
- m_ColdArmor.nValue[0] = 0;
- m_ColdArmor.nTime = 0;
- }
- else
- {
- nDamage = 0;
- }
- nMax = m_CurrentRangeDmgRetPercent;
- break;
- case damage_fire:
- nRes = m_CurrentFireResist;
- if (nRes > m_CurrentFireResistMax)
- {
- nRes = m_CurrentFireResistMax;
- }
- if (nRes > MAX_RESIST)
- {
- nRes = MAX_RESIST;
- }
- g_DebugLog("[数值]%s受到%d点原始火伤害,火抗性%d,火盾%d", Name, nDamage, nRes, m_FireArmor.nValue[0]);
- m_FireArmor.nValue[0] -= nDamage;
- if (m_FireArmor.nValue[0] < 0)
- {
- nDamage = -m_FireArmor.nValue[0];
- m_FireArmor.nValue[0] = 0;
- m_FireArmor.nTime = 0;
- }
- else
- {
- nDamage = 0;
- }
- nMax = m_CurrentRangeDmgRetPercent;
- break;
- case damage_light:
- nRes = m_CurrentLightResist;
- if (nRes > m_CurrentLightResistMax)
- {
- nRes = m_CurrentLightResistMax;
- }
- if (nRes > MAX_RESIST)
- {
- nRes = MAX_RESIST;
- }
- g_DebugLog("[数值]%s受到%d点原始电伤害,电抗性%d,电盾%d", Name, nDamage, nRes, m_LightArmor.nValue[0]);
- m_LightArmor.nValue[0] -= nDamage;
- if (m_LightArmor.nValue[0] < 0)
- {
- nDamage = -m_LightArmor.nValue[0];
- m_LightArmor.nValue[0] = 0;
- m_LightArmor.nTime = 0;
- }
- else
- {
- nDamage = 0;
- }
- nMax = m_CurrentRangeDmgRetPercent;
- break;
- case damage_poison:
- g_DebugLog("[数值]%s受到%d点原始毒伤害", Name, nDamage);
- nRes = m_CurrentPoisonResist;
- if (nRes > m_CurrentPoisonResistMax)
- {
- nRes = m_CurrentPoisonResistMax;
- }
- if (nRes > MAX_RESIST)
- {
- nRes = MAX_RESIST;
- }
- g_DebugLog("[数值]%s受到%d点原始毒伤害,毒抗性%d,毒盾%d", Name, nDamage, nRes, m_PoisonArmor.nValue[0]);
- m_PoisonArmor.nValue[0] -= nDamage;
- if (m_PoisonArmor.nValue[0] < 0)
- {
- nDamage = -m_PoisonArmor.nValue[0];
- m_PoisonArmor.nValue[0] = 0;
- m_PoisonArmor.nTime = 0;
- }
- else
- {
- nDamage = 0;
- }
- nMax = m_CurrentRangeDmgRetPercent;
- m_nLastPoisonDamageIdx = nAttacker;
- break;
- case damage_magic:
- g_DebugLog("[数值]%s受到%d点原始魔法伤害", Name, nDamage);
- nRes = 0;
- break;
- default:
- nRes = 0;
- break;
- }
- if (!nDamage)
- return;
- // 第二步判断是否有魔法盾存在
- g_DebugLog("[数值]%s魔法盾吸收比例:%d", Name, m_ManaShield.nValue[0]);
- if (m_ManaShield.nValue[0])
- {
- int nManaDamage = nDamage * m_ManaShield.nValue[0] / 100;
- m_CurrentMana -= nManaDamage;
- if (m_CurrentMana < 0)
- {
- nDamage -= m_CurrentMana;
- m_CurrentMana = 0;
- m_ManaShield.nValue[0] = 0;
- m_ManaShield.nTime = 0;
- }
- else
- {
- nDamage -= nManaDamage;
- }
- }
- nDamage = nDamage * (100 - nRes) / 100;
- g_DebugLog("[数值]%s实际伤害:%d", Name, nDamage);
- // 反弹伤害
- if (nAttacker > 0 && bReturn == FALSE)
- {
- if (bIsMelee)
- {
- nMin = m_CurrentMeleeDmgRet;
- nMin += nDamage * nMax / 100;
- Npc[nAttacker].CalcDamage(m_Index, nMin, nMin, damage_magic, FALSE, FALSE, TRUE);
- }
- else
- {
- nMin = m_CurrentRangeDmgRet;
- nMin += nDamage * nMax / 100;
- Npc[nAttacker].CalcDamage(m_Index, nMin, nMin, damage_magic, FALSE, FALSE, TRUE);
- }
- g_DebugLog("[数值]%s返回伤害%d", Name, nMin);
- }
- // PK处理,伤害乘一个系数
- if (this->m_Kind == kind_player && Npc[nAttacker].m_Kind == kind_player)
- nDamage = nDamage * NpcSet.m_nPKDamageRate / 100;
- m_nLastDamageIdx = nAttacker;
- if (m_Kind != kind_player && Npc[nAttacker].m_Kind == kind_player && Npc[nAttacker].m_nPlayerIdx > 0)
- m_cDeathCalcExp.AddDamage(Npc[nAttacker].m_nPlayerIdx, (m_CurrentLife - nDamage > 0 ? nDamage : m_CurrentLife));
- m_CurrentLife -= nDamage;
- if (nDamage > 0)
- {
- m_CurrentMana += m_CurrentDamage2Mana * nDamage / 100;
- if (m_CurrentMana > m_CurrentManaMax)
- {
- m_CurrentMana = m_CurrentManaMax;
- }
- if (bDoHurt)
- DoHurt();
- }
- if (m_CurrentLife < 0)
- {
- int nMode = DeathCalcPKValue(nAttacker);
- DoDeath(nMode);
- // if 死的是玩家,关闭他的仇杀和切磋状态
- if (m_Kind == kind_player)
- Player[m_nPlayerIdx].m_cPK.CloseAll();
- }
- }
- #endif
- #ifdef _SERVER
- BOOL KNpc::ReceiveDamage(int nLauncher, BOOL bIsMelee, void *pData, BOOL bUseAR, BOOL bDoHurt)
- {
- if (m_Doing == do_death || m_Doing == do_revive)
- return FALSE;
- // 发技能的NPC不存在了,不用算了。
- if (!Npc[nLauncher].m_Index)
- return FALSE;
- if (!pData)
- return FALSE;
- KMagicAttrib *pTemp = NULL;
- pTemp = (KMagicAttrib *)pData;
- int nAr = pTemp->nValue[0];
- pTemp++;
- int nIgnoreAr = pTemp->nValue[0];
- pTemp++;
- if (bUseAR)
- {
- if (!CheckHitTarget(nAr, m_CurrentDefend, nIgnoreAr))
- {
- g_DebugLog("[数值]%s闪过攻击", Name);
- return FALSE;
- }
- }
- /*
- if (m_Doing != do_death)
- DoHurt(m_HurtFrame);//Question ?*/
- int nLife = m_CurrentLife;
- // 磨损
- CalcDamage(nLauncher, pTemp->nValue[0], pTemp->nValue[2], damage_physics, bIsMelee, bDoHurt);
- pTemp++;
- CalcDamage(nLauncher, pTemp->nValue[0], pTemp->nValue[2], damage_cold, bIsMelee, bDoHurt);
- if (m_FreezeState.nTime <= 0)
- {
- m_FreezeState.nTime = pTemp->nValue[1] * (100 - m_CurrentFreezeTimeReducePercent) / 100;
- }
- pTemp++;
- CalcDamage(nLauncher, pTemp->nValue[0], pTemp->nValue[2], damage_fire, bIsMelee, bDoHurt);
- pTemp++;
- CalcDamage(nLauncher, pTemp->nValue[0], pTemp->nValue[2], damage_light, bIsMelee, bDoHurt);
- pTemp++;
- CalcDamage(nLauncher, pTemp->nValue[0], pTemp->nValue[0], damage_poison, bIsMelee, bDoHurt);
- if (m_PoisonState.nTime == 0)
- {
- m_PoisonState.nTime = pTemp->nValue[1];
- m_PoisonState.nValue[0] = pTemp->nValue[0];
- m_PoisonState.nValue[1] = pTemp->nValue[2];
- }
- else
- {
- int d1, d2, t1, t2, c1, c2;
- d1 = m_PoisonState.nValue[0];
- d2 = pTemp->nValue[0];
- t1 = m_PoisonState.nTime;
- t2 = pTemp->nValue[1];
- c1 = m_PoisonState.nValue[1];
- c2 = pTemp->nValue[2];
- if (c1 > 0 && c2 > 0 && d1 > 0 && d2 > 0)
- {
- m_PoisonState.nValue[0] = ((c1 + c2) * d1 / c1 + (c1 + c2) * d2 / c2) / 2;
- m_PoisonState.nTime = (t1 * d1 * c2 + t2 *d2 * c1) /(d1 * c2 + d2 * c1);
- m_PoisonState.nValue[1] = (c1 + c2) / 2;
- }
- }
- m_PoisonState.nTime = m_PoisonState.nTime * (100 - m_CurrentPoisonTimeReducePercent) / 100;
- pTemp++;
- CalcDamage(nLauncher, pTemp->nValue[0], pTemp->nValue[2], damage_magic, bIsMelee, bDoHurt);
- m_nPeopleIdx = nLauncher;
- if (IsPlayer() && (m_CurrentLife - nLife < 0))
- {
- if (m_nPlayerIdx > 0)
- {
- Player[m_nPlayerIdx].m_ItemList.Abrade(enumAbradeDefend);
- }
- }
- return TRUE;
- }
- #endif
- void KNpc::SetImmediatelySkillEffect(int nLauncher, void *pData, int nDataNum)
- {
- if (!pData || !nDataNum)
- return;
- KMagicAttrib* pTemp = (KMagicAttrib *)pData;
- _ASSERT(nDataNum <= MAX_SKILL_STATE);
- for (int i = 0; i < nDataNum; i++)
- {
- ModifyAttrib(nLauncher, pTemp);
- pTemp++;
- }
- }
- void KNpc::AppendSkillEffect(BOOL bIsPhysical, BOOL bIsMelee, void *pSrcData, void *pDesData)
- {
- int nMinDamage = m_PhysicsDamage.nValue[0] + m_CurrentAddPhysicsDamage;
- int nMaxDamage = m_PhysicsDamage.nValue[2] + m_CurrentAddPhysicsDamage;
- KMagicAttrib* pTemp = (KMagicAttrib *)pSrcData;
- KMagicAttrib* pDes = (KMagicAttrib *)pDesData;
- // Get AR_p
- if (pTemp->nAttribType == magic_attackrating_p)
- {
- pDes->nAttribType = magic_attackrating_v;
- pDes->nValue[0] = m_CurrentAttackRating + m_AttackRating * pTemp->nValue[0] / 100;
- }
- else
- {
- pDes->nAttribType = magic_attackrating_v;
- pDes->nValue[0] = m_CurrentAttackRating;
- }
- pTemp++;
- pDes++;
- if (pTemp->nAttribType == magic_ignoredefense_p)
- {
- pDes->nAttribType = magic_ignoredefense_p;
- pDes->nValue[0] = pTemp->nValue[0];
- }
- pTemp++;
- pDes++;
- if (pTemp->nAttribType == magic_physicsenhance_p)
- {
- pDes->nAttribType = magic_physicsdamage_v;
- pDes->nValue[0] = nMinDamage * (100 + pTemp->nValue[0]) / 100;
- pDes->nValue[2] = nMaxDamage * (100 + pTemp->nValue[0]) / 100;
- if (IsPlayer())
- {
- if (Player[m_nPlayerIdx].m_ItemList.GetWeaponType() == equip_meleeweapon)
- {
- pDes->nValue[0] += nMinDamage * m_CurrentMeleeEnhance[Player[m_nPlayerIdx].m_ItemList.GetWeaponParticular()] / 100;
- pDes->nValue[2] += nMaxDamage * m_CurrentMeleeEnhance[Player[m_nPlayerIdx].m_ItemList.GetWeaponParticular()] / 100;
- }
- else if (Player[m_nPlayerIdx].m_ItemList.GetWeaponType() == equip_rangeweapon)
- {
- pDes->nValue[0] += nMinDamage * m_CurrentRangeEnhance / 100;
- pDes->nValue[2] += nMaxDamage * m_CurrentRangeEnhance / 100;
- }
- else // 空手
- {
- pDes->nValue[0] += nMinDamage * m_CurrentHandEnhance / 100;
- pDes->nValue[2] += nMaxDamage * m_CurrentHandEnhance / 100;
- }
- }
- }
- else if (pTemp->nAttribType == magic_physicsdamage_v)
- {
- pDes->nAttribType = magic_physicsdamage_v;
- pDes->nValue[0] = pTemp->nValue[0];
- pDes->nValue[2] = pTemp->nValue[2];
- }
- pTemp++;
- pDes++;
- if (pTemp->nAttribType == magic_colddamage_v)
- {
- pDes->nAttribType = magic_colddamage_v;
- pDes->nValue[0] = pTemp->nValue[0];
- pDes->nValue[1] = pTemp->nValue[1] + m_CurrentColdEnhance;
- pDes->nValue[2] = pTemp->nValue[2];
- }
- if (bIsPhysical)
- {
- pDes->nValue[0] += m_CurrentColdDamage.nValue[0];
- pDes->nValue[1] = max(pDes->nValue[1], m_CurrentColdDamage.nValue[1] + m_CurrentColdEnhance);
- pDes->nValue[2] += m_CurrentColdDamage.nValue[2];
- }
- pTemp++;
- pDes++;
- if (pTemp->nAttribType == magic_firedamage_v)
- {
- // How to use FireEnhance???
- pDes->nAttribType = magic_firedamage_v;
- pDes->nValue[0] = pTemp->nValue[0];
- pDes->nValue[2] = pTemp->nValue[2];
- }
- if (bIsPhysical)
- {
- pDes->nValue[0] += m_CurrentFireDamage.nValue[0];
- pDes->nValue[2] += m_CurrentFireDamage.nValue[2];
- }
- pTemp++;
- pDes++;
- if (pTemp->nAttribType == magic_lightingdamage_v)
- {
- pDes->nAttribType = magic_lightingdamage_v;
- pDes->nValue[0] = pTemp->nValue[0] + (pTemp->nValue[2] - pTemp->nValue[0]) * m_CurrentLightEnhance / 100;
- pDes->nValue[2] = pTemp->nValue[2];
- }
- if (bIsPhysical)
- {
- pDes->nValue[0] += m_CurrentLightDamage.nValue[0];
- pDes->nValue[2] += m_CurrentLightDamage.nValue[2];
- }
- pTemp++;
- pDes++;
- if (pTemp->nAttribType == magic_poisondamage_v)
- {
- pDes->nAttribType = magic_poisondamage_v;
- pDes->nValue[0] = pTemp->nValue[0];
- pDes->nValue[1] = pTemp->nValue[1];
- pDes->nValue[2] = pTemp->nValue[2] * (100 - m_CurrentPoisonEnhance) / 100;
- if (pDes->nValue[2] <= 0)
- pDes->nValue[2] = 1;
- }
- if (bIsPhysical)
- {
- // 合成毒伤害
- g_NpcAttribModify.MixPoisonDamage(pDes, &m_CurrentPoisonDamage);
- }
- pTemp++;
- pDes++;
- if (pTemp->nAttribType == magic_magicdamage_v)
- {
- pDes->nAttribType = magic_magicdamage_v;
- pDes->nValue[0] = pTemp->nValue[0];
- pDes->nValue[2] = pTemp->nValue[2];
- }
- }
- void KNpc::ServeMove(int MoveSpeed)
- {
- if (m_Doing != do_walk && m_Doing != do_run && m_Doing != do_hurt && m_Doing != do_runattack)
- return;
- if (MoveSpeed <= 0)
- return;
- if (MoveSpeed >= SubWorld[m_SubWorldIndex].m_nCellWidth)
- {
- MoveSpeed = SubWorld[m_SubWorldIndex].m_nCellWidth - 1;
- }
- #ifndef _SERVER
- if (m_RegionIndex < 0 || m_RegionIndex >= 9)
- {
- g_DebugLog("[zroc]Npc(%d)ServerMove RegionIdx = %d", m_Index, m_RegionIndex);
- _ASSERT(0);
- DoStand();
- return;
- }
- #else
- _ASSERT(m_RegionIndex >= 0);
- if (m_RegionIndex < 0)
- return;
- #endif
- int x, y;
- SubWorld[m_SubWorldIndex].Map2Mps(m_RegionIndex, m_MapX, m_MapY, 0, 0, &x, &y);
- x = (x << 10) + m_OffX;
- y = (y << 10) + m_OffY;
- int nRet = m_PathFinder.GetDir(x, y, m_Dir, m_DesX, m_DesY, MoveSpeed, &m_Dir);
- #ifndef _SERVER
- if(nRet == 1)
- {
- x = g_DirCos(m_Dir, 64) * MoveSpeed;
- y = g_DirSin(m_Dir, 64) * MoveSpeed;
- }
- else if (nRet == 0)
- {
- DoStand();
- return;
- }
- else if (nRet == -1)
- {
- SubWorld[0].m_Region[m_RegionIndex].RemoveNpc(m_Index);
- SubWorld[0].m_Region[m_RegionIndex].DecRef(m_MapX, m_MapY, obj_npc);
- m_RegionIndex = -1;
- return;
- }
- else
- {
- return;
- }
- #endif
- #ifdef _SERVER
- if(nRet == 1)
- {
- x = g_DirCos(m_Dir, 64) * MoveSpeed;
- y = g_DirSin(m_Dir, 64) * MoveSpeed;
- }
- else
- {
- DoStand();
- return;
- }
- #endif
- int nOldRegion = m_RegionIndex;
- int nOldMapX = m_MapX;
- int nOldMapY = m_MapY;
- int nOldOffX = m_OffX;
- int nOldOffY = m_OffY;
- m_OffX += x;
- m_OffY += y;
- // 处理NPC的坐标变幻
- // CELLWIDTH、CELLHEIGHT、OffX、OffY均是放大了1024倍
- if (!m_bClientOnly)
- CURREGION.DecRef(m_MapX, m_MapY, obj_npc);
- if (m_OffX < 0)
- {
- m_MapX--;
- m_OffX += CELLWIDTH;
- }
- else if (m_OffX > CELLWIDTH)
- {
- m_MapX++;
- m_OffX -= CELLWIDTH;
- }
- if (m_OffY < 0)
- {
- m_MapY--;
- m_OffY += CELLHEIGHT;
- }
- else if (m_OffY > CELLHEIGHT)
- {
- m_MapY++;
- m_OffY -= CELLHEIGHT;
- }
- if (m_MapX < 0)
- {
- m_RegionIndex = LEFTREGIONIDX;
- m_MapX += REGIONWIDTH;
- }
- else if (m_MapX >= REGIONWIDTH)
- {
- m_RegionIndex = RIGHTREGIONIDX;
- m_MapX -= REGIONWIDTH;
- }
- if (m_RegionIndex >= 0)
- {
- if (m_MapY < 0)
- {
- m_RegionIndex = UPREGIONIDX;
- m_MapY += REGIONHEIGHT;
- }
- else if (m_MapY >= REGIONHEIGHT)
- {
- m_RegionIndex = DOWNREGIONIDX;
- m_MapY -= REGIONHEIGHT;
- }
- if (!m_bClientOnly && m_RegionIndex >= 0)
- CURREGION.AddRef(m_MapX, m_MapY, obj_npc);
- }
- if (m_RegionIndex == -1) // 不可能移动到-1 Region,如果出现这种情况,恢复原坐标
- {
- m_RegionIndex = nOldRegion;
- m_MapX = nOldMapX;
- m_MapY = nOldMapY;
- m_OffX = nOldOffX;
- m_OffY = nOldOffY;
- CURREGION.AddRef(m_MapX, m_MapY, obj_npc);
- return;
- }
- if (nOldRegion != m_RegionIndex)
- {
- #ifdef _SERVER
- SubWorld[m_SubWorldIndex].NpcChangeRegion(nOldRegion, m_RegionIndex, m_Index);
- if (IsPlayer())
- {
- SubWorld[m_SubWorldIndex].PlayerChangeRegion(nOldRegion, m_RegionIndex, m_nPlayerIdx);
- if (m_nPlayerIdx > 0)
- {
- Player[m_nPlayerIdx].m_ItemList.Abrade(enumAbradeMove);
- }
- }
- #else
- SubWorld[0].NpcChangeRegion(SubWorld[0].m_Region[nOldRegion].m_RegionID, SubWorld[0].m_Region[m_RegionIndex].m_RegionID, m_Index);
- m_dwRegionID = SubWorld[0].m_Region[m_RegionIndex].m_RegionID;
- #endif
- }
- }
- void KNpc::ServeJump(int nSpeed)
- {
- _ASSERT(m_RegionIndex >= 0);
- if (m_RegionIndex < 0)
- return;
- if (!(m_Doing == do_jump || m_Doing == do_jumpattack))
- return;
- if (nSpeed <= 0)
- return;
- if (nSpeed >= SubWorld[m_SubWorldIndex].m_nCellWidth)
- {
- nSpeed = SubWorld[m_SubWorldIndex].m_nCellWidth - 1;
- }
- m_OffX += g_DirCos(m_JumpDir, 64) * nSpeed;
- m_OffY += g_DirSin(m_JumpDir, 64) * nSpeed;
- // s = vt - a * t * t / 2
- m_Height = (m_JumpFirstSpeed * m_Frames.nCurrentFrame - ACCELERATION_OF_GRAVITY * m_Frames.nCurrentFrame * m_Frames.nCurrentFrame / 2) / 8;
- if (m_Height < 0)
- m_Height = 0;
- int nOldRegion = m_RegionIndex;
- int nOldMapX = m_MapX;
- int nOldMapY = m_MapY;
- int nOldOffX = m_OffX;
- int nOldOffY = m_OffY;
- CURREGION.DecRef(m_MapX, m_MapY, obj_npc);
- if (m_OffX < 0)
- {
- m_MapX--;
- m_OffX += CELLWIDTH;
- }
- else if (m_OffX > CELLWIDTH)
- {
- m_MapX++;
- m_OffX -= CELLWIDTH;
- }
- if (m_OffY < 0)
- {
- m_MapY--;
- m_OffY += CELLHEIGHT;
- }
- else if (m_OffY > CELLHEIGHT)
- {
- m_MapY++;
- m_OffY -= CELLHEIGHT;
- }
- if (m_MapX < 0)
- {
- m_RegionIndex = LEFTREGIONIDX;
- m_MapX += REGIONWIDTH;
- }
- else if (m_MapX >= REGIONWIDTH)
- {
- m_RegionIndex = RIGHTREGIONIDX;
- m_MapX -= REGIONWIDTH;
- }
- if (m_RegionIndex >= 0)
- {
- if (m_MapY < 0)
- {
- m_RegionIndex = UPREGIONIDX;
- m_MapY += REGIONHEIGHT;
- }
- else if (m_MapY >= REGIONHEIGHT)
- {
- m_RegionIndex = DOWNREGIONIDX;
- m_MapY -= REGIONHEIGHT;
- }
- if (m_RegionIndex >= 0)
- CURREGION.AddRef(m_MapX, m_MapY, obj_npc);
- }
- if (m_RegionIndex == -1) // 不可能移动到-1 Region,如果出现这种情况,恢复原坐标
- {
- m_RegionIndex = nOldRegion;
- m_MapX = nOldMapX;
- m_MapY = nOldMapY;
- m_OffX = nOldOffX;
- m_OffY = nOldOffY;
- CURREGION.AddRef(m_MapX, m_MapY, obj_npc);
- return;
- }
- if (nOldRegion != m_RegionIndex)
- {
- #ifdef _SERVER
- SubWorld[m_SubWorldIndex].NpcChangeRegion(nOldRegion, m_RegionIndex, m_Index);
- if (IsPlayer())
- {
- SubWorld[m_SubWorldIndex].PlayerChangeRegion(nOldRegion, m_RegionIndex, m_nPlayerIdx);
- if (m_nPlayerIdx > 0)
- {
- Player[m_nPlayerIdx].m_ItemList.Abrade(enumAbradeMove);
- }
- }
- #else
- if (m_RegionIndex >= 0)
- {
- SubWorld[0].NpcChangeRegion(SubWorld[0].m_Region[nOldRegion].m_RegionID, SubWorld[0].m_Region[m_RegionIndex].m_RegionID, m_Index);
- m_dwRegionID = SubWorld[0].m_Region[m_RegionIndex].m_RegionID;
- }
- #endif
- }
- }
- void KNpc::SendCommand(NPCCMD cmd,int x,int y, int z)
- {
- m_Command.CmdKind = cmd;
- m_Command.Param_X = x;
- m_Command.Param_Y = y;
- m_Command.Param_Z = z;
- }
- BOOL KNpc::NewPath(int nMpsX, int nMpsY)
- {
- m_DesX = nMpsX;
- m_DesY = nMpsY;
- return TRUE;
- }
- BOOL KNpc::NewJump(int nMpsX, int nMpsY)
- {
- _ASSERT(m_CurrentJumpSpeed > 0);
- if (m_CurrentJumpSpeed <= 0)
- return FALSE;
- int nX, nY;
- GetMpsPos(&nX, &nY);
- if (nX == nMpsX && nY == nMpsY)
- return FALSE;
- int nDir = g_GetDirIndex(nX, nY, nMpsX, nMpsY);
- int nMaxLength = m_CurrentJumpSpeed * m_CurrentJumpFrame;
- int nWantLength = g_GetDistance(nX, nY, nMpsX, nMpsY);
- int nSin = g_DirSin(nDir, 64);
- int nCos = g_DirCos(nDir, 64);
- if (nWantLength > nMaxLength)
- {
- m_DesX = nX + ((nMaxLength * nCos) >> 10);
- m_DesY = nY + ((nMaxLength * nSin) >> 10);
- nWantLength = nMaxLength;
- }
- else if (nWantLength <= MIN_JUMP_RANGE)
- {
- m_DesX = nMpsX;
- m_DesY = nMpsY;
- return FALSE;
- }
- m_JumpStep = nWantLength / m_CurrentJumpSpeed;
- int nTestX = 0;
- int nTestY = 0;
- int nSuccessStep = 0;
- for (int i = 1; i < m_JumpStep + 1; i++)
- {
- nTestX = nX + ((m_CurrentJumpSpeed * nCos * i) >> 10);
- nTestY = nY + ((m_CurrentJumpSpeed * nSin * i) >> 10);
- int nBarrier = SubWorld[m_SubWorldIndex].GetBarrier(nTestX, nTestY);
- if (Obstacle_NULL == nBarrier)
- {
- nSuccessStep = i;
- }
- if (Obstacle_Normal == nBarrier || Obstacle_Fly == nBarrier)
- {
- if (nSuccessStep <= MIN_JUMP_RANGE / m_CurrentJumpSpeed)
- {
- return FALSE;
- }
- m_DesX = nX + ((m_CurrentJumpSpeed * nCos * nSuccessStep) >> 10);
- m_DesY = nY + ((m_CurrentJumpSpeed * nSin * nSuccessStep) >> 10);
- m_JumpStep = nSuccessStep;
- break;
- }
- int nTrap = SubWorld[m_SubWorldIndex].GetTrap(nTestX, nTestY);
- if (nTrap)
- {
- if (i <= MIN_JUMP_RANGE / m_CurrentJumpSpeed)
- {
- return FALSE;
- }
- m_DesX = nX + ((m_CurrentJumpSpeed * nCos * i) >> 10);
- m_DesY = nY + ((m_CurrentJumpSpeed * nSin * i) >> 10);
- m_JumpStep = i;
- break;
- }
- }
- m_JumpDir = nDir;
- return TRUE;
- }
- void KNpc::SelfDamage(int nDamage)
- {
- m_CurrentLife -= nDamage;
- if (m_CurrentLife <= 0)
- {
- m_CurrentLife = 1;
- }
- }
- BOOL KNpc::Cost(NPCATTRIB nType, int nCost, BOOL bOnlyCheckCanCast)
- {
- if (!IsPlayer())
- return TRUE;
- int *pSource = NULL;
- switch(nType)
- {
- case attrib_mana:
- pSource = &m_CurrentMana;
- break;
- case attrib_life:
- pSource = &m_CurrentLife;
- break;
- case attrib_stamina:
- pSource = &m_CurrentStamina;
- break;
- default:
- break;
- }
- if (pSource)
- {
- if (*pSource < nCost)
- {
- #ifndef _SERVER
- KSystemMessage Msg;
- Msg.byConfirmType = SMCT_NONE;
- Msg.byParamSize = 0;
- Msg.byPriority = 1;
- Msg.eType = SMT_NORMAL;
- switch(nType)
- {
- case attrib_mana:
- g_StrCpyLen(Msg.szMessage, MSG_NPC_NO_MANA, sizeof(Msg.szMessage));
- break;
- case attrib_life:
- g_StrCpyLen(Msg.szMessage, MSG_NPC_NO_LIFE, sizeof(Msg.szMessage));
- break;
- case attrib_stamina:
- g_StrCpyLen(Msg.szMessage, MSG_NPC_NO_STAMINA, sizeof(Msg.szMessage));
- break;
- default:
- break;
- }
- CoreDataChanged(GDCNI_SYSTEM_MESSAGE, (unsigned int)&Msg, NULL);
- #endif