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

📄 globallists.pas

📁 RO模拟器!!适合玩仙境传说的玩家们呦~
💻 PAS
📖 第 1 页 / 共 2 页
字号:
		end;//if
End;(* Proc TRandList.SetWeight()
*-----------------------------------------------------------------------------*)


(*-----------------------------------------------------------------------------*
Safely casts weight into Objects[] array.
*-----------------------------------------------------------------------------*)
Function  TRandList.AddObject(
					const
						Item		: Cardinal;
						Weight	: Cardinal
					) : Integer;
Begin
	Result := Add(Item);
	PutObject(Result, TObject(Weight));
	Inc(fTotalWeight,Weight);
End;(* Func TRandList.AddObject()
*-----------------------------------------------------------------------------*)


(*-----------------------------------------------------------------------------*

*-----------------------------------------------------------------------------*)
Procedure TRandList.Clear;
Var
	Index : Integer;
Begin
	if Count <> 0 then
	begin
		//CRW Unset Objects -- remember we're just storing Cardinals in there, not
		//"real" objects, otherwise you would be calling
		//Objects[Index].Free; before setting to NIL for safety
		for Index := 0 to Count-1 do
			Objects[Index] := NIL;

		//now call std Clear from ancestor, that resets the Integers[] etc.
		inherited Clear;
	end;
End;(* Proc TRandList.Clear
*-----------------------------------------------------------------------------*)


(*-----------------------------------------------------------------------------*

*-----------------------------------------------------------------------------*)
Procedure	TRandList.Delete(
				Index : Integer
			);
Begin
  //Don't forget to maintain the TotalWeight..
	Dec(fTotalWeight,Weights[Index]);
	//CRW - remove the object, which for these lists, set to NIL because
	// we aren't really storing objects in there, or else we'd Free before this.
	Objects[Index] := NIL;
	inherited Delete(Index);
End;(* Proc TRandList.Delete()
*-----------------------------------------------------------------------------*)


(*-----------------------------------------------------------------------------*
Added here to direct to this class' LoadFromStream 
*-----------------------------------------------------------------------------*)
Procedure TRandList.LoadFromFile(
					const
						Filename : String
					);
Var
	Stream: TStream;
Begin
	Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
	try
		LoadFromStream(Stream);
	finally
		Stream.Free;
	end;
End;(* Proc TRandList.LoadFromFile()
*-----------------------------------------------------------------------------*)




(*-----------------------------------------------------------------------------*
TRandList.LoadFromStream()
-- Assumes you're loading data in the format...
<ItemID>','<Weight>
Any String data that doesn't conform, will be ignored
(i.e., a descriptive header for the data :) )

Based heavily on routines in TStrings, ancestor of TStringList, which
TIntList32 is based on.
*-----------------------------------------------------------------------------*)
Procedure TRandList.LoadFromStream(
						Stream : TStream
					);
Var
	Size	: Integer;
	P			: PChar;
	Start	: PChar;
	S			: String;
	Line	: String;

	ItemID	: Cardinal;
	Weight	: Cardinal;
Begin
	{BeginUpdate;  }
	try
		Size := Stream.Size - Stream.Position;
		SetString(S, NIL, Size);
		P := Pointer(S);
		Stream.Read(P^, Size);
		if P <> NIL then
			begin
			while P^ <> #0 do
				begin
				Start := P;
				//Find <ItemID> Step through until you find EOL or a Comma
				while NOT (P^ IN [#0, #10, #13, #44]) do
					Inc(P);

				SetString(Line, Start, P - Start);
				ItemID := StrToIntDef( Line, 0 );
				Inc(P);

				//String Found, so find <Weight>
				Start := P;
				//search for integer until EOF found (not comma this time)
				while NOT (P^ IN [#0, #10, #13]) do
					Inc(P);
				SetString(Line, Start, P - Start);
				Weight := StrToIntDef( Line, 0 );

				// If EITHER converted integer is Zero, one or both are invalid,
				// so, do not add them if so...
				if (ItemID > 0) AND (Weight > 0) then
					AddObject( ItemID, Weight );
				if P^ = #13 then Inc(P);
				if P^ = #10 then Inc(P);

				end;//while P<>#0
			end;//if P<>NIL
	finally
		{EndUpdate;}
	end;
End;(* Proc TRandList.LoadFromSTream()
*-----------------------------------------------------------------------------*)


(*-----------------------------------------------------------------------------*
"Key" Routine behind this whole class -- generates a random choice in the
list based on the Weighting

*-----------------------------------------------------------------------------*)
Function TRandList.RandomChoice : Cardinal;
Var
	Index		: Integer;
	Tally		: Cardinal;
	Number	: Cardinal;
Begin
	case Distribution of
	distWeighted :
		begin
		//Choice based on TotalWeight.
		Number	:= Random(fTotalWeight);
		Tally		:= 0;
		Index		:= -1;
		//iterate until you get in that 'bucket' where
		repeat
			Inc(Index);
			Inc(Tally,Weights[ Index ]);
		until (Tally > Number);
		Result := Integers[ Index ];
		end;
	distUniform :
		begin
		Result := Integers[ Random(Count) ];
		end;
	else
		Assert(
			Distribution IN [distWeighted, distUniform],
			'TRandList.RandomChoice -- no choice for set Distribution'
		);
		Result := 0;
	end;
End;(* Proc TRandList.RandomChoice
*-----------------------------------------------------------------------------*)




(*-----------------------------------------------------------------------------*
Reads a different format file than the ancestor
*-----------------------------------------------------------------------------*)
Constructor TSummonMobList.Create(
							FileName	: String;
							DistType	: TDistType
						);
Begin
	inherited Create;
	// Always call ancestor's routines first in Create
	//Weil, in this case call our granddaddy's constructor...
	Clear;

	Distribution := DistType;
	LoadFromFile( FileName );

End;(* TSummonMobList.Create()
*-----------------------------------------------------------------------------*)


(*-----------------------------------------------------------------------------*

*-----------------------------------------------------------------------------*)
Destructor TSummonMobList.Destroy;
Begin
	// Always call ancestor's routines after you clean up
	// objects you created as part of this class

	//Ancestor clears out objects and integers cleanly, defer to it.
	inherited;
End;(* T.Destroy
*-----------------------------------------------------------------------------*)


(*-----------------------------------------------------------------------------*

*-----------------------------------------------------------------------------*)
Procedure TSummonMobList.LoadFromFile(
					const
						Filename : String
					);
Var
	Stream: TStream;
Begin
	Stream := TFileStream.Create(FileName, fmOpenRead or fmShareDenyWrite);
	try
		LoadFromStream(Stream);
	finally
		Stream.Free;
	end;
End;(* Proc TSummonMobList.LoadFromFile()
*-----------------------------------------------------------------------------*)


(*-----------------------------------------------------------------------------*
CRW 2004/04/09

We're reading an expanded format of summon_mob.txt
Mob.JNAME,DBWeight,MVPWeight,Mob.ID

This LoadFromStream handles this format, but only reads fields 2 and 4,
DBweight, and Mob.ID

Commas must be present for a line to be read, and the proper format
a number and a number, or the line is ignored.

Blank lines are also ignored, thus making the datafile read a LOT safer from
corrupting what is loaded into the list.

*-----------------------------------------------------------------------------*)
Procedure TSummonMobList.LoadFromStream(
						Stream : TStream
					);
Var
	Size	: Integer;
	P			: PChar;
	Start	: PChar;
	S			: String;
	Line	: String;

	MobID		: Cardinal;
	Weight	: Cardinal;

	//CRW internal call for clarity/brevity
	procedure GetNextToken;
	begin
		Start := P;
		while NOT (P^ IN [#0, #10, #13, #44]) do
			Inc(P);
	end;
	//

Begin
	{BeginUpdate;  }
	try
		Size := Stream.Size - Stream.Position;
		SetString(S, NIL, Size);
		P := Pointer(S);
		Stream.Read(P^, Size);
		if P <> NIL then
			begin
			while P^ <> #0 do
				begin
				//Read past MobID field (not stored)
				GetNextToken;
				Inc(P);

				//Find <DBweight> Step through until you find EOL or a Comma
				GetNextToken;
				SetString(Line, Start, P - Start);
				Weight := StrToIntDef( Line, 0 );
				Inc(P);

				//Read past MVPweight field (not stored)
				GetNextToken;
				Inc(P);

				//Find <MobID>
				GetNextToken;
				SetString(Line, Start, P - Start);
				MobID := StrToIntDef( Line, 0 );

				// If EITHER DBweight or MobID are Zero, one or both are invalid,
				// Do not add them if so...
				if (MobID > 0) AND (Weight > 0) then
					AddObject( MobID, Weight );

				// Clear off remaining chars, until new line/eof, then re-read
				// tokens in next time around the loop.
				// This cleans up stray commas, other junk text, whitespace.
				while NOT (P^ IN [#0, #10, #13]) do
					Inc(P);
				if (P^ = #13) then Inc(P);
				if (P^ = #10) then Inc(P);
				end;//while P<>#0
			end;//if P<>NIL
	finally
		{EndUpdate;}
	end;
End;(* Proc TSummonMobList.LoadFromSTream()
*-----------------------------------------------------------------------------*)






end.

⌨️ 快捷键说明

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