📄 monsterai.pas
字号:
end;
//debugout.lines.add('[' + TimeToStr(Now) + '] ' + 'Safety Wall OK >>' + IntToStr(tn.Count));
dmg[6] := 0;
end;
$85: //僯儏乕儅
begin
if ts.Data.Range1 >= 4 then miss := true;
//debugout.lines.add('[' + TimeToStr(Now) + '] ' + 'Pneuma OK');
dmg[6] := 0;
end;
end;
end;
Inc(i1);
end;
if crit then dmg[5] := 10 else dmg[5] := 0; //僋儕僥傿僇儖僠僃僢僋
//VIT儃乕僫僗偲偐寁嶼
j := ((tc.Param[2] div 2) + (tc.Param[2] * 3 div 10));
k := ((tc.Param[2] div 2) + (tc.Param[2] * tc.Param[2] div 150 - 1));
if j > k then k := j;
if tc.Skill[33].Tick > Tick then begin //僄儞僕僃儔僗
k := k * tc.Skill[33].Effect1 div 100;
end;
dmg[1] := ATK1 + Random(ATK2 - ATK1 + 1);
if (ts.Stat2 and 1) = 1 then dmg[1] := dmg[1] * 75 div 100;
//僆乕僩_僶乕僒乕僋
if (tc.Skill[146].Lv <> 0) and (tc.HP * 100 / tc.MAXHP <= 25) then dmg[0] := (dmg[1] * (100 - (tc.DEF1 * word(tc.Skill[6].Data.Data2[10]) div 100)) div 100 - k) * ts.ATKPer div 100
else dmg[0] := (dmg[1] * (100 - tc.DEF1) div 100 - k) * ts.ATKPer div 100;
if Race = 1 then dmg[0] := dmg[0] - tc.DEF3; //DP
if dmg[0] < 0 then dmg[0] := 1;
//if SkillPer <> 0 then dmg[0] := dmg[0] * SkillPer div 100; //Skill%
//dmg[0] := dmg[0] * ElementTable[AElement][ts.Data.Element] div 100; //懏惈憡惈曗惓
//僇乕僪曗惓
// Colus, 20040129: The race reduction shield cards are direct values, not 100-val.
//dmg[0] := dmg[0] * (100-tc.DamageFixR[1][ts.Data.Race] )div 100;
// Added elemental property reduction cards...
//dmg[0] := dmg[0] * (100-tc.DamageFixE[1][ts.Element] )div 100;
// Colus, 20040127: The race reduction shield cards are direct values, not 100-val.
// 20040129: Couldn't do it this way. Must change the card data instead...
dmg[0] := dmg[0] * (100 - tc.DamageFixR[1][ts.Data.Race]) div 100;
dmg[0] := dmg[0] * (100 - tc.DamageFixE[1][0]) div 100;
// Moving element determination to the separate skills...
//MOVING IT BACK!
// Determine element based on status/armor type...
if tc.Stat1 = 2 then i := 21 // Frozen? Water 1
else if tc.Stat1 = 1 then i := 22 // Stone? Earth 1
else if tc.ArmorElement <> 0 then i := tc.ArmorElement // PC's armor type
else i := 1;
dmg[0] := dmg[0] * ElementTable[ts.Element mod 20][i] div 100; // Damage modifier based on elements}
if (tc.Skill[78].Tick > Tick) then dmg[0] := dmg[0] * 2; // Lex Aeterna effect
//dmg[0] := dmg[0] * tc.DEFFixE[ts.Data.Element mod 20] div 100;
{//Auto Gaurd
if ((miss = False) and (tc.Skill[249].Tick > Tick)) then begin
miss := boolean(Random(100) <= tc.Skill[249].Effect1);
if (miss = True) then begin
tc.MSkill := 249;
WFIFOW( 0, $011a);
WFIFOW( 2, tc.MSkill);
WFIFOW( 4, tc.MUseLV);
WFIFOL( 6, tc.ID);
WFIFOL(10, tc.ID);
WFIFOB(14, 1);
SendBCmd(tm, tc.Point, 15);
SendCSkillAtk1(tm, tc, ts, Tick, 0, 1, 6);
tc.MTick := Tick + 3000;
end;
end; }
//Dragonology
if (tc.Skill[284].Lv <> 0) and (ts.Data.Race = 9) then begin
dmg[0] := (dmg[0] - dmg[0] * tc.Skill[284].Data.Data1[tc.Skill[284].Lv]) div 100;
end;
//Providence
if (tc.Skill[256].Tick > Tick) and ((ts.Data.Race = 1) or (ts.Data.Race = 6) or (ts.Data.Race = 8)) then begin
i := (dmg[0] * tc.Skill[256].Data.Data2[tc.Skill[256].Lv]) div 100;
dmg[0] := dmg[0] - i;
end;
{if tc.Skill[61].Tick > Tick then begin //AC
tc.AMode := 8;
tc.ATarget := ts.ID;
DamageCalc1(tm, tc, ts, Tick, 0, 0, 0, 20);
if dmg[0] < 0 then dmg[0] := 0; //懏惈峌寕偱偺夞暅偼枹幚憰
//僷働憲怣
WFIFOW( 0, $008a);
WFIFOL( 2, tc.ID);
WFIFOL( 6, tc.ATarget);
WFIFOL(10, timeGetTime());
WFIFOL(14, tc.aMotion);
WFIFOL(18, ts.Data.dMotion);
WFIFOW(22, dmg[0]); //僟儊乕僕
WFIFOW(24, 1); //暘妱悢
WFIFOB(26, 0); //0=扨峌寕 8=暋悢 10=僋儕僥傿僇儖
WFIFOW(27, 0); //媡庤
SendBCmd(tm, ts.Point, 29);
DamageProcess1(tm, tc, ts, dmg[0], Tick);
StatCalc1(tc, ts, Tick);
tc.Skill[61].Tick := Tick;
tc.AMode := 0;
dmg[0] := 0;
dmg[5] := 11;
end else if avoid then begin
dmg[0] := 0;
dmg[5] := 11;
end else if not miss then begin
//峌寕柦拞
if dmg[0] <> 0 then begin
if tc.Skill[157].Tick > Tick then begin //僄僱儖僊乕僐乕僩
if (tc.SP * 100 / tc.MAXSP) < 1 then tc.SP := 0;
if tc.SP > 0 then begin
i := 1;
if (tc.SP * 100 / tc.MAXSP) > 20 then i := 2;
if (tc.SP * 100 / tc.MAXSP) > 40 then i := 3;
if (tc.SP * 100 / tc.MAXSP) > 60 then i := 4;
if (tc.SP * 100 / tc.MAXSP) > 80 then i := 5;
dmg[0] := dmg[0] - ((dmg[0] * i * 6) div 100);
tc.SP := tc.SP - (tc.MAXSP * (i + 1) * 5) div 1000;
end;
end else if (tc.Skill[257].Tick > Tick) then begin //Defender
i := (dmg[0] * tc.Skill[257].Data.Data2[tc.Skill[257].Lv]) div 100;
dmg[0] := dmg[0] - i;
tc.MSkill := 257;
WFIFOW( 0, $011a);
WFIFOW( 2, tc.MSkill);
WFIFOW( 4, tc.MUseLV);
WFIFOL( 6, tc.ID);
WFIFOL(10, ID);
WFIFOB(14, 1);
end else begin
tc.Skill[257].Tick := Tick;
tc.Skill[157].Tick := Tick;
SendCStat1(tc, 0, 7, tc.SP);
end;
tc.MMode := 0;
tc.MTick := Tick;
tc.MTarget := 0;
tc.MPoint.X := 0;
tc.MPoint.Y := 0;
end;
end else begin
//峌寕儈僗
dmg[0] := 0;
end;}
//偙偙偱惎偺偐偗傜岠壥傪擖傟傞(枹幚憰)
if dmg[0] > 16000 then dmg[0] := 16000;
dmg[4] := 1;
end;
//debugout.lines.add('[' + TimeToStr(Now) + '] ' + Format('REV %d%% %d(%d-%d)', [dmg[6], dmg[0], dmg[1], dmg[2]]));
end;
//------------------------------------------------------------------------------
procedure SendMSkillAttack(tm:TMap; tc:TChara; ts:TMob; Tick:cardinal; k:integer);
begin
//R 01de <skill ID>.w <src ID>.l <dst ID>.l <server tick>.l <src speed>.l <dst speed>.l <param1>.l <param2>.w <param3>.w <type>.B
// Moved Lex Aeterna calc up here. It is display only (don't reset the tick here)
// Damage should be correct when it gets here. Commented.
//if (tc.Skill[78].Tick > Tick) then k := k * 2; // Lex Aeterna effect
// Colus, 20040129: If you aren't going to use DamageProcess3 for mob skills,
// then you need to have a check here so that you don't run into negative HP.
// Likewise you need to send the correct packets for updates, etc., right?
if tc.HP - dmg[0] > 0 then tc.HP := tc.HP - dmg[0]; //Subtract Damage.
if tc.HP < 0 then tc.HP := 0;
WFIFOW( 0, $01de);
WFIFOW( 2, ts.MSkill);
WFIFOL( 4, ts.ID);
WFIFOL( 8, tc.ID);
WFIFOL(12, Tick);
//WFIFOL(16, tc.aMotion);
//WFIFOL(20, ts.Data.dMotion);
WFIFOL(16, ts.Data.dMotion);
WFIFOL(20, tc.aMotion);
WFIFOL(24, dmg[0]);
WFIFOW(28, ts.MLevel);
WFIFOW(30, k);
WFIFOB(32, 8);
//else WFIFOB(32, 8);
//if ts.Stat1 = 5 then dmg := dmg * 2; //儗僢僋僗_僄乕僥儖僫
SendBCmd(tm, tc.Point, 33);
end;
//------------------------------------------------------------------------------
// The Original monster cast time, it has much since evolved
{procedure MonsterCastTime(tm:Tmap; ts:TMob; Tick:cardinal);
var
//tl :TSkillDB;
tc :TChara;
j :integer;
begin
tc := ts.AData;
//with Skill[ts.MSKill] do begin
j := tc.Skill[ts.MSKill].Data.CastTime1 + tc.Skill[ts.MSKill].Data.CastTime2 * ts.MSKill;
if j < tl.CastTime3 then j := tl.CastTime3;
ts.MTick := Tick + cardinal(j);
//j := j * tc.MCastTimeFix div 100;
if (j > 0) then begin
//Send Packets
WFIFOW( 0, $013e);
WFIFOL( 2, ts.ID);
WFIFOL( 6, ts.ATarget);
WFIFOW(10, 0);
WFIFOW(12, 0);
WFIFOW(14, ts.MSKill); //SkillID
WFIFOL(16, tc.Skill[ts.MSKill].Data.Element); //Element
WFIFOL(20, j);
SendBCmd(tm, ts.Point, 24);
ts.MMode := 1;
ts.ATick := Tick + cardinal(j);
end else begin
//塺彞側偟
ts.MMode := 1;
ts.ATick := Tick;
end;
end;
}
//------------------------------------------------------------------------------
procedure LoadMonsterAIData(tm:TMap; ts:TMob; Tick:cardinal);
var
tsAI2 :TMobAIDBFusion;
m :integer;
sl :TStringList;
begin
sl := TStringList.Create;
sl.Delimiter := ',';
sl.Clear;
ts.SkillWaitTick := Tick;
ts.Data.SkillCount := 0;
{
Monster Data: RAYDRIC BERSERK_ST NPC_DARKNESSATTACK 3 200 0 7500 0 0 0
Monster Data: RAYDRIC RUSH_ST NPC_EMOTION 1 15 0 10000 0 0 0
Monster Data: RAYDRIC BERSERK_ST SM_MAGNUM 6 50 1500 10000 NO_DISPEL 0 0
Monster Data: RAYDRIC BERSERK_ST SM_MAGNUM 6 1000 1500 10000 NO_DISPEL IF_ENEMYCOUNT 2
Monster Data: RAYDRIC BERSERK_ST BS_MAXIMIZE 1 50 1000 40000 0 0 0
Monster Data: RAYDRIC RUSH_ST BS_MAXIMIZE 1 50 1000 40000 0 0 0
Monster Data: RAYDRIC BERSERK_ST SM_MAGNUM 6 150 1500 10000 NO_DISPEL IF_HP 30
Monster Data: RAYDRIC BERSERK_ST BS_MAXIMIZE 1 150 1000 40000 IF_HP 30 0
}
{Possible If's
IF_COMRADECONDITION
IF_COMRADEHP
IF_CONDITION
IF_ENEMYCOUNT
IF_HIDING
IF_MAGICLOCKED
IF_RANGEATTACKED
IF_RUDEATTACK
IF_SKILLUSE
IF_SLAVENUM
}
//j := MobAIDBFusion.IndexOf(ts.Number);
//k := j;
//j := MobAIDBFusion.IndexOf(ts.Name);
//debugout.lines.add('[' + TimeToStr(Now) + '] ' + ts.Name);
for m := 0 to MobAIDBFusion.Count do begin
if MobAIDBFusion.IndexOf(m) <> -1 then begin
//while (j > 0) do begin
//tsAI2 := MobAIDBFusion.IndexOf(j)] as TMobAIDBFusion;
tsAI2 := MobAIDBFusion.Objects[MobAIDBFusion.IndexOf(m)] as TMobAIDBFusion;
//debugout.lines.add('[' + TimeToStr(Now) + '] ' + IntToStr(j));
if (ts.Data.ID = tsAI2.ID) then begin
sl.Add(IntToStr(m));
ts.Data.SkillLocations := sl.DelimitedText;
ts.Data.SkillCount := ts.Data.SkillCount + 1;
//debugout.lines.add('[' + TimeToStr(Now) + '] ' + 'Monster Data: ' + tsAI2.Name + ' ' + tsAI2.Status + ' ' + tsAI2.SkillID + ' ' + IntToStr(tsAI2.SkillLV) + ' ' + IntToStr(tsAI2.Percent) + ' ' + IntToStr(tsAI2.Cast_Time) + ' ' + IntToStr(tsAI2.Cool_Time) + ' ' + tsAI2.Dispel + ' ' + tsAI2.IfState + ' ' + tsAI2.IfCond );
//debugout.lines.add('[' + TimeToStr(Now) + '] ' + '----------------------------');
//debugout.lines.add('[' + TimeToStr(Now) + '] ' + 'Skill: ' + tsAI2.SkillID);
//debugout.lines.add('[' + TimeToStr(Now) + '] ' + 'Requires monster is in ' + tsAI2.Status + ' status');
if tsAI2.Dispel = 'NO_DISPEL' then begin
// debugout.lines.add('[' + TimeToStr(Now) + '] ' + 'Cannot be broken when attacked.');
ts.NoDispel := true;
end else
// debugout.lines.add('[' + TimeToStr(Now) + '] ' + 'Can be broken when attacked.');
ts.NoDispel := true;
///////////If Conditions Begin////////////////
if tsAI2.IfState = 'IF_COMRADECONDITION' then begin
// debugout.lines.add('[' + TimeToStr(Now) + '] ' + 'Skill Has Comrade Condition, ' + tsAI2.IfCond);
end;
if tsAI2.IfState = 'IF_COMRADEHP' then begin
// debugout.lines.add('[' + TimeToStr(Now) + '] ' +
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -