⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 monsterai.pas

📁 RO模拟器!!适合玩仙境传说的玩家们呦~
💻 PAS
📖 第 1 页 / 共 5 页
字号:
						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 + -