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

📄 main.pas

📁 RO模拟器!!适合玩仙境传说的玩家们呦~
💻 PAS
📖 第 1 页 / 共 5 页
字号:
	//Repeat until Spawn Point chosen.
	repeat
		ts.Point.X := ts.Point1.X + Random(ts.Point2.X + 1) - (ts.Point2.X div 2);
		ts.Point.Y := ts.Point1.Y + Random(ts.Point2.Y + 1) - (ts.Point2.Y div 2);
		if (ts.Point.X < 0) or (ts.Point.X > tm.Size.X - 2) or (ts.Point.Y < 0) or (ts.Point.Y > tm.Size.Y - 2) then begin
			if ts.Point.X < 0 then ts.Point.X := 0;
			if ts.Point.X > tm.Size.X - 2 then ts.Point.X := tm.Size.X - 2;
			if ts.Point.Y < 0 then ts.Point.Y := 0;
			if ts.Point.Y > tm.Size.Y - 2 then ts.Point.Y := tm.Size.Y - 2;
		end;
	until ( (tm.gat[ts.Point.X, ts.Point.Y] <> 1) and (tm.gat[ts.Point.X, ts.Point.Y] <> 5) );
	{ChrstphrR  2004/04/27 - This spawning code is pretty common...
	could it be made into a function call and spare everyone the complexity?
	... and is this an efficient algorithm for picking a random point?
	}

	ts.Dir := Random(8);
	ts.HP := ts.Data.HP;
	if ts.Data.isDontMove then
		ts.MoveWait := $FFFFFFFF
	else
		ts.MoveWait := Tick + 5000 + Cardinal(Random(10000));
	ts.Speed := ts.Data.Speed;
	ts.ATarget := 0;
	ts.ARangeFlag := false;
	ts.ATKPer := 100;
	ts.DEFPer := 100;
	ts.DmgTick := 0;
	ts.Status := 'IDLE_ST';
	if ts.Data.Loaded = false then LoadMonsterAIData(tm, ts, Tick);
	for j := 0 to 31 do begin
		ts.EXPDist[j].CData := nil;
		ts.EXPDist[j].Dmg := 0;
	end;
	if ts.Data.MEXP <> 0 then begin
		for j := 0 to 31 do begin
			ts.MVPDist[j].CData := nil;
			ts.MVPDist[j].Dmg := 0;
		end;
		ts.MVPDist[0].Dmg := ts.Data.HP * 30 div 100; //FA偵30%壛嶼
	end;

	tm.Block[ts.Point.X div 8][ts.Point.Y div 8].Mob.AddObject(ts.ID, ts);

	//Notify Nearby Characters that Monster has spawned
	for j := ts.Point.Y div 8 - 2 to ts.Point.Y div 8 + 2 do begin
		for i := ts.Point.X div 8 - 2 to ts.Point.X div 8 + 2 do begin
			//廃傝偺恖偵捠抦
			for k := 0 to tm.Block[i][j].CList.Count - 1 do begin
				tc := tm.Block[i][j].CList.Objects[k] as TChara;
				if tc = nil then continue;
				if (abs(ts.Point.X - tc.Point.X) < 16) and (abs(ts.Point.Y - tc.Point.Y) < 16) then begin
					SendMData(tc.Socket, ts);
				end;
			end;//for k1
		end;//for i1
	end;//for j1

	if (MonsterMob = true) then begin
		k := SlaveDBName.IndexOf(ts.Data.Name);
		if (k <> -1) then begin
			ts.isLeader := true;
		end;
	end;
end;//proc TFrmMain.MonsterSpawn()
//------------------------------------------------------------------------------

{Spawn Slave Monster}
procedure TFrmMain.MobSpawn(tm:TMap; ts:TMob; Tick:cardinal);
var
	i, j, k, h, m : Integer;
	tc            : TChara;
	ts1           : TMob;
	tss           : TSlaveDB;

begin

	if (MonsterMob = true) then begin
		k := SlaveDBName.IndexOf(ts.Data.Name);
		if (k <> -1) then begin
			ts.isLeader := true;
			tss := SlaveDBName.Objects[k] as TSlaveDB;
			if ts.Data.Name = tss.Name then begin

				h := tss.TotalSlaves;
				ts.SlaveCount := h;

				repeat
					for i := 0 to 4 do begin
						if (tss.Slaves[i] <> -1) and (h <> 0) then begin
							ts1 := TMob.Create;
							ts1.Data := MobDBName.Objects[tss.Slaves[i]] as TMobDB;
							ts1.ID := NowMobID;
							Inc(NowMobID);
							ts1.Name := ts1.Data.JName;
							ts1.JID := ts1.Data.ID;
							ts1.LeaderID := ts.ID;
							ts1.Data.isLink := false;
							ts1.Status := 'IDLE_ST';
							ts1.Map := ts.Map;
							ts1.Point.X := ts.Point.X;
							ts1.Point.Y := ts.Point.Y;
							ts1.Dir := ts.Dir;
							ts1.HP := ts1.Data.HP;
							if ts.Data.Speed < ts1.Data.Speed then begin
								ts1.Speed := ts.Data.Speed;
							end else begin
								ts1.Speed := ts1.Data.Speed;
							end;
							ts1.SpawnDelay1 := $7FFFFFFF;
							ts1.SpawnDelay2 := 0;
							ts1.SpawnType := 0;
							ts1.SpawnTick := 0;
							if ts1.Data.isDontMove then
								ts1.MoveWait := $FFFFFFFF
							else
								ts1.MoveWait := timeGetTime();
							ts1.ATarget := 0;
							ts1.ATKPer := 100;
							ts1.DEFPer := 100;
							ts1.DmgTick := 0;
							ts1.Element := ts1.Data.Element;
							ts1.isActive := false;
							for j := 0 to 31 do begin
								ts1.EXPDist[j].CData := nil;
								ts1.EXPDist[j].Dmg := 0;
							end;
							if ts1.Data.MEXP <> 0 then begin
								for j := 0 to 31 do begin
									ts1.MVPDist[j].CData := nil;
									ts1.MVPDist[j].Dmg := 0;
								end;
								ts1.MVPDist[0].Dmg := ts1.Data.HP * 30 div 100; //FA偵30%壛嶼
							end;
							ts1.isSummon := true;
							ts1.isSlave  := true;
							tm.Mob.AddObject(ts1.ID, ts1);
							tm.Block[ts1.Point.X div 8][ts1.Point.Y div 8].Mob.AddObject(ts1.ID, ts1);

							for j := ts1.Point.Y div 8 - 2 to ts1.Point.Y div 8 + 2 do begin
								for m := ts1.Point.X div 8 - 2 to ts1.Point.X div 8 + 2 do begin
									//廃傝偺恖偵捠抦
									for k := 0 to tm.Block[m][j].CList.Count - 1 do begin
										tc := tm.Block[m][j].CList.Objects[k] as TChara;
										if tc = nil then continue;
										if (abs(ts1.Point.X - tc.Point.X) < 16) and (abs(ts1.Point.Y - tc.Point.Y) < 16) then begin
											SendMData(tc.Socket, ts1);
											SendBCmd(tm,ts1.Point,41,tc,False);
										end;
									end;
								end;
							end;
							h := h - 1;
						end;
					end;
				until (h <= 0);

			end;
		end;
	end;

end;
//------------------------------------------------------------------------------
procedure TFrmMain.MonsterDie(tm:TMap; tc:TChara; ts:TMob; Tick:cardinal);
var
	//Variable Declarations
	k,i,j,m,n:integer;
	total:cardinal;
    bonus:integer;
	mvpid:integer;
	mvpitem:boolean;
	mvpcheck:integer;
	i1,j1,k1:integer;
	L : Cardinal;
	w : Cardinal;
	TgtFlag:boolean;
	DropFlag:boolean;
	delcnt:integer;

	//Class Usage
	tc1:TChara;     {Player}
	ts1:TMob;       {Monster}
	tn:TNPC;        {NPC}
	td:TItemDB;     {Reads the Item Database}
	tpaDB:TStringList;
	tpa:TParty;     {Party Class}
	tg   : TGuild;    {Guild Glass}
	tgc  : TCastle;
	tt   : TTerritoryDB;
	tn1  : TNPC;
	ge   : Cardinal;

	//String Declarations
	str  : string;
	str2 : string;

begin
	UpdateMonsterDead(tm, ts, 1);
	{WFIFOW( 0, $0080);
	WFIFOL( 2, ts.ID);
	WFIFOB( 6, 1);
	SendBCmd(tm, ts.Point, 7);}

	delcnt := 0;                      // mf
	repeat                            // mf
		delcnt := delcnt + 1;           // mf
	until (DelPointX[delcnt] = 0) or (delcnt >= 999);      // mf
	DelPointX[delcnt] := ts.Point.X;  // mf
	DelPointY[delcnt] := ts.Point.Y;  // mf
	DelID[delcnt] := ts.ID;           // mf
	DelWait[delcnt] := ts.DeadWait;   // mf

	ts.HP := 0;
	ts.pcnt := 0;

	ts.Stat1 :=0;
	ts.Stat2 :=0;
	ts.nStat := 0;
	ts.Element := ts.Data.Element;
	ts.BodyTick := 0;
	for i := 0 to 4 do
		ts.HealthTick[i] := 0;
	ts.isLooting := False;
	ts.Status := 'DEAD_ST';


	ts.SpawnTick := Tick;

	n := tm.Block[ts.Point.X div 8][ts.Point.Y div 8].Mob.IndexOf(ts.ID);
	if n = -1 then Exit;//safe 2004/04/26

	if ts.isSlave then begin
		ts1 := tm.Mob.IndexOfObject(ts.LeaderID) as TMob;
		if (ts1 <> nil) then begin
			if (ts1.SlaveCount - 1 <= 0) then begin
				ts1.SlaveCount := 0;
			end else begin
				ts1.SlaveCount := ts1.SlaveCount - 1;
			end;
		end;
	end;

	if (ts.isEmperium) then begin

		j := GuildList.IndexOf(tc.GuildID);
		m := TerritoryList.IndexOf(ts.Map);
		if (j <> -1) and (m <> -1) then begin
			tg := GuildList.Objects[j] as TGuild;
			tt := TerritoryList.Objects[m] as TTerritoryDB;
			str := GlobalGMsg;

			str := StringReplace(str, '$charaname', tc.Name, [rfReplaceAll]);
			str := StringReplace(str, '$mapname', ts.Map, [rfReplaceAll]);
			str := StringReplace(str, '$castlename', tt.TerritoryName, [rfReplaceAll]);
			str := StringReplace(str, '$guildname', tg.Name, [rfReplaceAll]);
			str := StringReplace(str, '$guildmaster', tg.MasterName, [rfReplaceAll]);
		end else begin
			str := MapGMsg;
		end;

		str2 :='blue' + MapGMsg;
		//str := StringReplace(str, '$charaname', tc.Name, [rfReplaceAll]);
		//str := StringReplace(str, '$mapname', ts.Map, [rfReplaceAll]);
		//str := StringReplace(str, '$guildname', tg.Name, [rfReplaceAll]);
		//str := StringReplace(str, '$guildmaster', tg.MasterName, [rfReplaceAll]);

		w := Length(str) + 4;
		WFIFOW(0, $009a);
		WFIFOW(2, w);
		WFIFOS(4, str, w - 4);

		for l := 0 to CharaName.Count - 1 do begin
			tc1 := CharaName.Objects[l] as TChara;
			if tc1.Login = 2 then tc1.Socket.SendBuf(buf, w);
		end;

		w := Length(str) + 4;
		WFIFOW(0, $009a);
		WFIFOW(2, w);
		WFIFOS(4, str2, w - 4);

		for l := 0 to tm.CList.Count - 1 do begin
			tc1 := tm.CList.Objects[l] as TChara;
			if (tc1.Login = 2) then tc1.Socket.SendBuf(buf, w);
		end;

		if (EmpList.Count > 0) then begin
			k := EmpList.IndexOf(ts.Map);
			if (k > - 1) then begin
				EmpList.Objects[k].Free;
				EmpList.Delete(k);
			end;
		end;

		if (CastleList.Count > 0) then begin
			m := CastleList.IndexOf(ts.Map);
			if (m > - 1) then begin
				CastleList.Objects[m].Free;
				CastleList.Delete(m);
			end;
		end;

		{Colus, 20040113: Set territory for the guild (not done in real RO!  BAH!}
		{I will replace this with something that parses the guild bases in
		ClaimGuildCastle.}
		//tg.Agit := tm.Name;

		ClaimGuildCastle(tc.GuildID,ts.Map);
		EnableGuildKafra(ts.Map,'Kafra Service',0);

		for l := 0 to CharaName.Count - 1 do begin
			tc1 := CharaName.Objects[l] as TChara;
			if (tc1.Map = tm.Name) AND (tc1.Login = 2) AND
			   ((tc1.GuildID = 0) OR (tc1.GuildID <> tc.GuildID))then begin
				SendCLeave(tc1, 2);
				tc1.tmpMap := tc1.SaveMap;
				tc1.Map := tc1.SaveMap;
				tc1.Point := tc1.SavePoint;
				MapMove(tc1.Socket, tc1.Map, tc1.Point);
			end;
		end;
	end;


	if (ts.NPCID > 0) then begin
		tn := tm.NPC.IndexOfObject(ts.NPCID) as TNPC;
		tc1 := TChara.Create;
		tc1.TalkNPCID := 0;
		tc1.ScriptStep := tn.ScriptInitMS;
		tc1.AMode := 3;
		tc1.AData := tn;
		tc1.Login := 0;
		NPCScript(tc1,0,1);
		tc1.Free;
		ts.NPCID := 0;
	end;

	ts.LeaderID := 0;

	tm.Block[ts.Point.X div 8][ts.Point.Y div 8].Mob.Delete(n);


	for j1 := ts.Point.Y div 8 - 2 to ts.Point.Y div 8 + 2 do begin
		for i1 := ts.Point.X div 8 - 2 to ts.Point.X div 8 + 2 do begin
			for k1 := 0 to tm.Block[i1][j1].CList.Count - 1 do begin
				tc1 := tm.Block[i1][j1].CList.Objects[k1] as TChara;
				if ((tc1.AMode = 1) or (tc1.AMode = 2)) and (tc1.ATarget = ts.ID) then begin
					tc1.AMode := 0;
					tc1.ATarget := 0;
				end;
				if (tc1.MMode > 0) and (tc1.MTarget = ts.ID) then begin
					tc1.MMode := 0;
					tc1.MTarget := 0;
				end;
			end;//for k1
		end;//for i1
	end;//for j1

	//宱尡抣暘攝張棟
	n := 32;
	total := 0;
	for i := 0 to 31 do begin
		if ts.EXPDist[i].CData = nil then begin
			n := i;
			break;
		end;
		tc1 := ts.EXPDist[i].CData;
		if (tc1.Login = 2) and (tc1.Sit <> 1) and (tc1.Map = tm.Name) then begin
			//儘僌傾僂僩偟偰偄傞丄巰傫偱偄傞丄暿偺儅僢僾偵偄傞丄偄偢傟偐偺応崌宱尡抣偼擖傜側偄
			Inc(total, ts.EXPDist[i].Dmg);
		end;
	end;


	mvpid := -1;

	if ts.Data.MEXP > 0 then begin
		mvpcheck := 0;
		for i := 0 to 31 do begin
			if ts.MVPDist[i].CData = nil then break;
			tc1 := ts.MVPDist[i].CData;
			if (tc1.Login = 2) and (tc1.Sit <> 1) and (tc1.Map = tm.Name) then begin
				//儘僌傾僂僩偟偰偄傞丄巰傫偱偄傞丄暿偺儅僢僾偵偄傞丄偄偢傟偐偺応崌MVP懳徾偵側傜側偄
				if mvpcheck < ts.MVPDist[i].Dmg then begin
					mvpid := i;
					mvpcheck := ts.MVPDist[i].Dmg;
				end;
			end;
		end;

		if mvpid <> -1 then begin
			tc1 := ts.MVPDist[mvpid].CData;
			//MVP昞帵
			WFIFOW(0, $010c);
			WFIFOL(2, tc1.ID);
			SendBCmd(tm, tc1.Point, 6);
			//MVP僠僃僢僋
			mvpitem := false;
			GetMVPItem(tc1, ts, mvpitem);
			{if ts.Data.MEXPPer <= Random(10000) then begin
				for i := 0 to 2 do begin
					if ts.Data.MVPItem[i].Per > cardinal(Random(10000)) then begin
						//MVP傾僀僥儉妉摼
						td := ItemDB.IndexOfObject(ts.Data.MVPItem[i].ID) as TItemDB;

						if tc1.MaxWeight >= tc1.Weight + td.Weight then begin
							j := SearchCInventory(tc1, td.ID, td.IEquip);
							if j <> 0 then begin
								//MVP傾僀僥儉僎

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -