📄 main.pas
字号:
//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 + -