function onSetHp_appendage_monster(appendage, hp, attacker)
{
local parentObj = appendage.getParent();
if(!parentObj) return hp;
local newHpDamage = parentObj.getHp() - hp;
if(newHpDamage <= 0) return hp;
// ====== CONFIGURATION ======
local DAMAGE_INTERVAL = 50; // 毫秒伤害触发间隔
local ACTUAL_DAMAGE_MULTIPLIER = 5; // 实际伤害倍数
local DISPLAY_DAMAGE_MULTIPLIER = 5; // 显示伤害倍数
local DISPLAY_INTERVAL = 1000; // 毫秒汇总显示一次
// ===========================
local currTime = appendage.getTimer().Get();
// 检查当前存在哪些状态
local hasPoison = sq_IsValidActiveStatus(parentObj, ACTIVESTATUS_POISON);
local hasBurn = sq_IsValidActiveStatus(parentObj, ACTIVESTATUS_BURN);
local hasBleeding = sq_IsValidActiveStatus(parentObj, ACTIVESTATUS_BLEEDING);
local hasShock = sq_IsValidActiveStatus(parentObj, ACTIVESTATUS_LIGHTNING);
local hasStone = sq_IsValidActiveStatus(parentObj, ACTIVESTATUS_STONE);
// 检查是否有中毒或烧伤
local hasPoisonOrBurn = hasPoison || hasBurn;
// === Poison ===
if(!attacker && hasPoison)
{
if(appendage.getVar("poisonAtkTime") == null)
appendage.setVar("poisonAtkTime", sq_GetGlobalIntVector());
if(appendage.getVar("poisonDamageTotal") == null)
appendage.setVar("poisonDamageTotal", sq_GetGlobalIntVector());
if(appendage.getVar("poisonDisplayTime") == null)
appendage.setVar("poisonDisplayTime", sq_GetGlobalIntVector());
local lastPoisonAtkTime = appendage.getVar("poisonAtkTime").getInt(0);
local poisonDamageTotal = appendage.getVar("poisonDamageTotal").getInt(0);
local lastPoisonDisplay = appendage.getVar("poisonDisplayTime").getInt(0);
if(currTime - lastPoisonAtkTime > DAMAGE_INTERVAL)
{
appendage.getVar("poisonAtkTime").setInt(0, currTime);
local obj = sq_GetCNRDObjectToSQRCharacter(sq_getMyCharacter());
local actualPoisonDamage = newHpDamage * ACTUAL_DAMAGE_MULTIPLIER;
hp -= applyAddHpDamage(obj, actualPoisonDamage);
local displayPoisonDamage = newHpDamage * DISPLAY_DAMAGE_MULTIPLIER;
poisonDamageTotal += displayPoisonDamage;
appendage.getVar("poisonDamageTotal").setInt(0, poisonDamageTotal);
}
if(currTime - lastPoisonDisplay >= DISPLAY_INTERVAL)
{
appendage.getVar("poisonDisplayTime").setInt(0, currTime);
if(poisonDamageTotal > 0)
{
local obj = sq_GetCNRDObjectToSQRCharacter(sq_getMyCharacter());
local x = parentObj.getXPos();
local y = parentObj.getYPos() - parentObj.getZPos() - (parentObj.getObjectHeight()/2) - 50;
sq_BinaryStartWrite();
sq_BinaryWriteByte(0);
sq_BinaryWriteByte(1);
sq_BinaryWriteWord(x);
sq_BinaryWriteWord(y);
sq_BinaryWriteDword(poisonDamageTotal);
sq_SendChangeSkillEffectPacket(obj, 169);
appendage.getVar("poisonDamageTotal").setInt(0, 0);
}
}
}
// === Burn ===
if(!attacker && hasBurn)
{
if(appendage.getVar("burnAtkTime") == null)
appendage.setVar("burnAtkTime", sq_GetGlobalIntVector());
if(appendage.getVar("burnDamageTotal") == null)
appendage.setVar("burnDamageTotal", sq_GetGlobalIntVector());
if(appendage.getVar("burnDisplayTime") == null)
appendage.setVar("burnDisplayTime", sq_GetGlobalIntVector());
local lastBurnAtkTime = appendage.getVar("burnAtkTime").getInt(0);
local burnDamageTotal = appendage.getVar("burnDamageTotal").getInt(0);
local lastBurnDisplay = appendage.getVar("burnDisplayTime").getInt(0);
if(currTime - lastBurnAtkTime > DAMAGE_INTERVAL)
{
appendage.getVar("burnAtkTime").setInt(0, currTime);
local obj = sq_GetCNRDObjectToSQRCharacter(sq_getMyCharacter());
local actualBurnDamage = newHpDamage * ACTUAL_DAMAGE_MULTIPLIER;
hp -= applyAddHpDamage(obj, actualBurnDamage);
local displayBurnDamage = newHpDamage * DISPLAY_DAMAGE_MULTIPLIER;
burnDamageTotal += displayBurnDamage;
appendage.getVar("burnDamageTotal").setInt(0, burnDamageTotal);
}
if(currTime - lastBurnDisplay >= DISPLAY_INTERVAL)
{
appendage.getVar("burnDisplayTime").setInt(0, currTime);
// 中毒和烧伤同时存在时,不显示烧伤
if(burnDamageTotal > 0 && !hasPoison) // 只有没有中毒时才显示烧伤
{
local obj = sq_GetCNRDObjectToSQRCharacter(sq_getMyCharacter());
local x = parentObj.getXPos();
local y = parentObj.getYPos() - parentObj.getZPos() - (parentObj.getObjectHeight()/2) - 50;
sq_BinaryStartWrite();
sq_BinaryWriteByte(0);
sq_BinaryWriteByte(1);
sq_BinaryWriteWord(x);
sq_BinaryWriteWord(y);
sq_BinaryWriteDword(burnDamageTotal);
sq_SendChangeSkillEffectPacket(obj, 169);
}
// 清除累计伤害
appendage.getVar("burnDamageTotal").setInt(0, 0);
}
}
// === Bleeding ===
if(!attacker && hasBleeding)
{
// 如果有中毒或烧伤,就不处理出血的显示
if(!hasPoisonOrBurn) // 只有没有中毒和烧伤时才处理出血
{
if(appendage.getVar("bleedAtkTime") == null)
appendage.setVar("bleedAtkTime", sq_GetGlobalIntVector());
if(appendage.getVar("bleedDisplayTime") == null)
appendage.setVar("bleedDisplayTime", sq_GetGlobalIntVector());
local lastBleedAtkTime = appendage.getVar("bleedAtkTime").getInt(0);
local lastBleedDisplay = appendage.getVar("bleedDisplayTime").getInt(0);
if(currTime - lastBleedAtkTime > 50)
{
appendage.getVar("bleedAtkTime").setInt(0, currTime);
local obj = sq_GetCNRDObjectToSQRCharacter(sq_getMyCharacter());
local bleedDamage = newHpDamage;
hp -= applyAddHpDamage(obj, bleedDamage);
if(currTime - lastBleedDisplay > 500)
{
appendage.getVar("bleedDisplayTime").setInt(0, currTime);
local x = parentObj.getXPos();
local y = parentObj.getYPos() - parentObj.getZPos() - (parentObj.getObjectHeight()/2) - 50;
local obj = sq_GetCNRDObjectToSQRCharacter(sq_getMyCharacter());
sq_BinaryStartWrite();
sq_BinaryWriteByte(0);
sq_BinaryWriteByte(1);
sq_BinaryWriteWord(x);
sq_BinaryWriteWord(y);
sq_BinaryWriteDword(bleedDamage);
sq_SendChangeSkillEffectPacket(obj, 169);
}
}
}
}
// === Shock ===
if(!attacker && hasShock)
{
// 如果有中毒或烧伤,就不处理感电的显示
if(!hasPoisonOrBurn) // 只有没有中毒和烧伤时才处理感电
{
if(appendage.getVar("shockAtkTime") == null)
appendage.setVar("shockAtkTime", sq_GetGlobalIntVector());
if(appendage.getVar("shockDisplayTime") == null)
appendage.setVar("shockDisplayTime", sq_GetGlobalIntVector());
local lastShockAtkTime = appendage.getVar("shockAtkTime").getInt(0);
local lastShockDisplay = appendage.getVar("shockDisplayTime").getInt(0);
if(currTime - lastShockAtkTime > 50)
{
appendage.getVar("shockAtkTime").setInt(0, currTime);
local obj = sq_GetCNRDObjectToSQRCharacter(sq_getMyCharacter());
local shockDamage = newHpDamage;
hp -= applyAddHpDamage(obj, shockDamage);
if(currTime - lastShockDisplay > 500)
{
appendage.getVar("shockDisplayTime").setInt(0, currTime);
local x = parentObj.getXPos();
local y = parentObj.getYPos() - parentObj.getZPos() - (parentObj.getObjectHeight()/2) - 50;
local obj = sq_GetCNRDObjectToSQRCharacter(sq_getMyCharacter());
sq_BinaryStartWrite();
sq_BinaryWriteByte(0);
sq_BinaryWriteByte(1);
sq_BinaryWriteWord(x);
sq_BinaryWriteWord(y);
sq_BinaryWriteDword(shockDamage);
sq_SendChangeSkillEffectPacket(obj, 169);
}
}
}
}
// === Stone ===
if(!attacker && hasStone)
{
// 如果有中毒或烧伤,就不处理石化的显示
if(!hasPoisonOrBurn) // 只有没有中毒和烧伤时才处理石化
{
if(appendage.getVar("stoneAtkTime") == null)
appendage.setVar("stoneAtkTime", sq_GetGlobalIntVector());
if(appendage.getVar("stoneDisplayTime") == null)
appendage.setVar("stoneDisplayTime", sq_GetGlobalIntVector());
local lastStoneAtkTime = appendage.getVar("stoneAtkTime").getInt(0);
local lastStoneDisplay = appendage.getVar("stoneDisplayTime").getInt(0);
if(currTime - lastStoneAtkTime > 50)
{
appendage.getVar("stoneAtkTime").setInt(0, currTime);
local obj = sq_GetCNRDObjectToSQRCharacter(sq_getMyCharacter());
local stoneDamage = newHpDamage;
hp -= applyAddHpDamage(obj, stoneDamage);
if(currTime - lastStoneDisplay > 500)
{
appendage.getVar("stoneDisplayTime").setInt(0, currTime);
local x = parentObj.getXPos();
local y = parentObj.getYPos() - parentObj.getZPos() - (parentObj.getObjectHeight()/2) - 50;
local obj = sq_GetCNRDObjectToSQRCharacter(sq_getMyCharacter());
sq_BinaryStartWrite();
sq_BinaryWriteByte(0);
sq_BinaryWriteByte(1);
sq_BinaryWriteWord(x);
sq_BinaryWriteWord(y);
sq_BinaryWriteDword(newHpDamage);
sq_SendChangeSkillEffectPacket(obj, 169);
}
}
}
}
return hp;
}