したがって、chara.txtのスキル部分を書きかえるか
Database.pasの
//***スキルデバッグ用***
if sl.Count = 1 then begin
for i := 1 to 53 do begin
を
//***スキルデバッグ用***
if sl.Count = 1 then begin
for i := 1 to 141 do begin
//--------------------------------------------------------------------------
$0197: //GMコマンド /resetstate /resetskill(将来的にはGMチェックを入れる)
begin
RFIFOW(2, w);
if w = 0 then begin// Resetstate(ステータス再分配)の処理
//パラメータ6個を全て1にする
for i := 0 to 5 do begin
tc.ParamBase[i] := 1;
end;
// + 激 し く 自 動 鷹 + ここで鷹が付いているかチェックするべき
if random(1000) <= tc.Param[5] * 3 then begin //確率チェック
if (tc.JobLV + 9) div 10 >= tc.Skill[129].Lv then begin
dmg[0] := (JobLV + 9) div 10;
end else begin
dmg[0] := Skill[129].lv;
end;
//一時的にdmg[0]を段数変数に使用
if tc.Skill[128].Lv <> 0 then begin //スチールクロウ補正
dmg[7] := tc.Skill[128].Data.Data1[Skill[128].Lv] * 2;
end else begin
dmg[7] := 0;
end;
tc.MSkill := 129;
tc.MMode :=0;
dmg[7] := dmg[7] + (tc.Param[4] div 10 + tc.Param[3] div 2) * 2 + 80;
dmg[7] := dmg[7] * dmg[0];
dmg[7] := dmg[7]; //属性相性補正
//無属性吸収はあり得ないので鷹ダメージ保持
SendCSkillAtk(tm, tc, ts, Tick, dmg[7] * ElementTable[0][ts.Data.Element] div 100, dmg[0]);
xy := ts.Point;
//ダメージ算出2@巻き込みダメージ
for j1 := xy.Y div 8 - 2 to xy.Y div 8 + 2 do begin
for i1 := xy.X div 8 - 2 to xy.X div 8 + 2 do begin
k1 := 0;
while (k1 >= 0) and (k1 < tm.Block[i1][j1].Mob.Count) do begin
ts1 := tm.Block[i1][j1].Mob.Objects[k1] as TMob;
if (ts <> ts1) and (abs(ts1.Point.X - xy.X) <= 1) and (abs(ts1.Point.Y - xy.Y) <= 1) then begin
//無属性吸収はあり得ないので鷹ダメージ保持
SendCSkillAtk(tm, tc, ts1, Tick, dmg[7] * ElementTable[0][ts1.Data.Element] div 100, dmg[0]);
//ダメージ処理
DamageProcess1(tm, tc, ts1, dmg[7] * ElementTable[0][ts1.Data.Element], Tick);
end;
if ts1.HP <> 0 then Inc(k1);
end;
end;
end;
dmg[7] := dmg[7] * ElementTable[0][ts.Data.Element] div 100; //実ダメージに戻す
end;
//自動鷹終わり
//ダメージ算出
for j1 := xy.Y div 8 - 2 to xy.Y div 8 + 2 do begin
for i1 := xy.X div 8 - 2 to xy.X div 8 + 2 do begin
//for k1 := 0 to tm.Block[i1][j1].Mob.Count - 1 do begin
k1 := 0;
while (k1 >= 0) and (k1 < tm.Block[i1][j1].Mob.Count) do begin
ts1 := tm.Block[i1][j1].Mob.Objects[k1] as TMob;
if (abs(ts1.Point.X - xy.X) <= tl.Range2) and (abs(ts1.Point.Y - xy.Y) <= tl.Range2) then begin
dmg[0] := MATK1 + Random(MATK2 - MATK1 + 1) * MATKFix div 100 * tl.Data1[tc.MUseLV] div 100;
dmg[0] := dmg[0] * (100 - ts1.Data.MDEF) div 100; //MDEF%
dmg[0] := dmg[0] - ts1.Data.Param[3]; //MDEF-
if dmg[0] < 1 then dmg[0] := 1;
dmg[0] := dmg[0] * ElementTable[tl.Element][ts1.Data.Element] div 100;
dmg[0] := dmg[0] * tl.Data2[tc.MUseLV];
if dmg[0] < 0 then dmg[0] := 0; //魔法攻撃での回復は未実装
//パケ送信
SendCSkillAtk(tm, tc, ts1, Tick, dmg[0], tl.Data2[tc.MUseLV]);
//ダメージ処理
DamageProcess1(tm, tc, ts1, dmg[0], Tick);
end;
if ts1.HP <> 0 then Inc(k1);
end;
end;
end;
SkillProcessType := 0;
end;
begin
i :=0; <--追加 〜〜
xy := tc.Point;
for j1 := xy.Y div 8 - 2 to xy.Y div 8 + 2 do begin
for i1 := xy.X div 8 - 2 to xy.X div 8 + 2 do begin
k1 := 0;
while (k1 >= 0) and (k1 < tm.Block[i1][j1].Mob.Count) and (i < 11) do begin
ts1 := tm.Block[i1][j1].Mob.Objects[k1] as TMob;
if (tc.PID = ts1.ATarget) and (abs(ts1.Point.X - tc.Point.X) <= ts1.Data.Range1) and (abs(ts1.Point.Y - tc.Point.Y) <= ts1.Data.Range1) then begin
Inc(i);
end;
Inc(k1);
end;
end;
end; <-- 〜〜ここまで
with ts.Data do begin
//debugout.Lines.Add(inttostr(i)); <-- 追加〜〜
if i > 1 then begin
i := (i - 1) * tc.FLEE1 div 10; <-- ここの1を2に変えればコモド仕様にできます
end else begin
i := 0;
end; <-- 〜〜ここまで
i := i + HIT + HITFix - (tc.FLEE1 + tc.FLEE2) + 80; <--変更 ここで i + を消せば囲まれ補正を消せます
if i < 5 then i := 5;
if i > 100 then i := 100;
■procedure DataLoad();
//------------------------------------------------------------------------------
-//***スキルデバッグ用***
-if sl.Count = 1 then begin
-for i := 1 to 65 do begin
-tc.Skill[i].Lv := tc.Skill[i].Data.MasterLV;
-end;
-for i := 90 to 91 do begin
-tc.Skill[i].Lv := tc.Skill[i].Data.MasterLV;
-end;
-tc.Skill[93].Lv := tc.Skill[93].Data.MasterLV;
-for i := 126 to 141 do begin
-tc.Skill[i].Lv := tc.Skill[i].Data.MasterLV;
-end;
-{
-for i := 142 to 157 do begin //韓国桜井専用
-tc.Skill[i].Lv := tc.Skill[i].Data.MasterLV;
-end;
-}
-end;
//------------------------------------------------------------------------------
Common.pas
----------
【implementation 節】
//--------------------------------------------------------------------------
// 関数定義
+procedure CalcSkill(Socket: TCustomWinSocket; tc:TChara; Tick:cardinal = 0);
//--------------------------------------------------------------------------
+procedure CalcSkill(Socket: TCustomWinSocket; tc:TChara; Tick:cardinal = 0);
+var
+i, j, k:integer;
+b:byte;
+begin
+//スキル送信
+WFIFOW( 0, $010f);
+j := 0;
+for i := 1 to 157 do begin
+WFIFOW( 0+37*j+4, i);
+WFIFOW( 2+37*j+4, tc.Skill[i].Data.SType);
+WFIFOW( 4+37*j+4, 0);
+WFIFOW( 6+37*j+4, tc.Skill[i].Lv);
+if tc.Skill[i].Lv <> 0 then
+WFIFOW( 8+37*j+4, tc.Skill[i].Data.SP[tc.Skill[i].Lv])
+else
+WFIFOW( 8+37*j+4, tc.Skill[i].Data.SP[1]);
+WFIFOW(10+37*j+4, tc.Skill[i].Data.Range);
+WFIFOS(12+37*j+4, tc.Skill[i].Data.IDC, 24);
+b:= 0;
+if (tc.SkillPoint = 0) or (tc.Skill[i].Lv = tc.Skill[i].Data.MasterLV) then begin
+b := 0;
+end else if (((i>=1)and(i<=65)) or (i=90) or (i=91) or (i=93) or ((i>=126)and(i<=141))) then begin
+b := 1;
+for k := 0 to 4 do begin
+if (tc.Skill[i].Data.ReqSkill[k] <> 0) and (tc.Skill[tc.Skill[i].Data.ReqSkill[k]].Lv < tc.Skill[i].Data.ReqLV[k]) then begin
+b := 0;
+continue;
+end;
+end;
+end;
+WFIFOB(36+37*j+4, b);
+Inc(j);
+end;
+WFIFOW( 2, 4+37*j);
+Socket.SendBuf(buf, 4+37*j);
+
+//スキルポイント送信
+WFIFOW( 0, $00b0);
+WFIFOW( 2, $000c);
+WFIFOL( 4, tc.SkillPoint);
+Socket.SendBuf(buf, 8);
+end;
//--------------------------------------------------------------------------
■グローバル
//------------------------------------------------------------------------------
var
+DefaultServerIP:String;
//------------------------------------------------------------------------------
■procedure TfrmMain.FormCreate(Sender: TObject);
//------------------------------------------------------------------------------
var
+wVersionRequired: Word;
+WSData: TWSAData;
+Status: Integer;
+Name: array[0..255] of Char;
+HostEnt: PHostEnt;
+IP: PChar;
//------------------------------------------------------------------------------
【implementation 節】
■procedure TfrmMain.FormCreate(Sender: TObject);
//------------------------------------------------------------------------------
begin
+wVersionRequired := MAKEWORD(1, 1);
+Status := WSAStartup(wVersionRequired, WSData);
+if Status <> 0 then begin
+MessageDlg('This version of WinSock does not support Host->IP feature!!', mterror, [mbOK], 0);
+exit;
+end;
//------------------------------------------------------------------------------
ini := TIniFile.Create(ChangeFileExt(ParamStr(0), '.ini'));
sl.Clear;
ini.ReadSectionValues('Server', sl);
//$01:石化 $02:凍結 $03:ピヨ $04:眠り $06:石化中
for i:=0 to 5 do begin
if Random(100) < tc.SFixPer1[i] then begin
ts.View1 := i+1;
end;
end;
k := 1;
//i: 00:毒 01:呪い 02:沈黙 03:混乱 04:暗闇
//k: $01:毒 $02:呪い $04:沈黙 $08:混乱 $10:暗闇
for i:=0 to 4 do begin
if Random(100) < tc.SFixPer2[i] then begin
ts.View2 := ts.View2 or k;
end;
k := k*2;
end;
外見だけ変えるならこんな感じでいいのかな?
状態1の優先順位ってどうなってんでしょうね。
//追加変数
DamageFixR :array[0..8] of Integer; //種族
DamageFixE :array[0..9] of Integer; //属性
DamageFixS :array[0..2] of Integer; //サイズ
SFixPer1 :array[0..5] of Integer; //状態1
SFixPer2 :array[0..4] of Integer; //状態2
DrainFix :array[0..1] of Integer; //吸収
SplashAttack :boolean; //スプラッシュ
NoJamstone :boolean;
//読み込み部分
for i :=0 to 3 do begin
//XYZZ
j := StrToInt(sl.Strings[36+i]);
//X = 1:種族 2:属性 3:サイズ
case ( j div 1000 ) of
//種族 Y = 0:無, 1:人間, 2:動物, 3:昆虫, 4:植物, 5:魚類, 6:悪魔, 7:竜族, 8:不死
1: DamageFixR[( j mod 1000 ) div 100] := j mod 100;
//属性 Y = 0:無, 1:水, 2:地, 3:火, 4:風, 5:毒, 6:聖, 7:闇, 8:念, 9:不死
2: DamageFixE[( j mod 1000 ) div 100] := j mod 100;
//サイズ Y = 0:小, 1:中, 2:大
3: DamageFixS[( j mod 1000 ) div 100] := j mod 100;
//状態1 Y = 01:石化 02:凍結 03:スタン 04:睡眠 05:LexA? 06:石化前の移行状態
4: SFixPer1[( j mod 1000 ) div 100 -1] := j mod 100;
//状態2 Y = 01:毒 02:呪い 03:沈黙 04:混乱? 05:暗闇
5: SFixPer2[( j mod 1000 ) div 100 -1 ] := j mod 100;
//吸収 Y = 0:HP 1:SP
6: DrainFix[( j mod 1000 ) div 100] := j mod 100;
7: begin //その他
case ( ( j mod 1000 ) div 100 ) of
0: SplashAttack := true;
1: NoJamstone := true;
else //何もしない
end;
end;
else //何もしない
end; // 'case ( j div 1000 )'
end; // 'for i :=0 to 3 do'
j := StrToInt(sl.Strings[36+i]);
//X = 1:種族 2:属性 3:サイズ
if j > 10000 then begin //スキル追加の効果
j := j - 10000;
AddSkill[j div 10] := j mod 10 + 1;
end else begin
case ( j div 1000 ) of
>>206
main.pasのベースExp加算部の
l := ts.Data.EXP * (ts.EXPDist[i].Dmg) div total;
を
l := ts.Data.EXP * cardinal(cardinal(ts.EXPDist[i].Dmg) div total);
って直したらエラーでなくなった気がします・・・
間違ってたらごめんなさい
l := ts.Data.EXP * (ts.EXPDist[i].Dmg) div total;
式の計算は左から行われます。
つまり、まず、敵の経験値に各自の与えたダメージが掛けられ、
その後に全員の与えたダメージの合計(ほんとはMAXHPなんだけど、
途中で死んだ人が与えた分のダメージは除外しないといけないため)
で割られます。
ここで、HPとEXPの高い敵を倒した場合、かけ算が発生した瞬間、
数値が32ビット整数値の限界(4Gか2Gくらい)を超えてエラーになります。
つまり、経験値とMVP経験値の部分をそれぞれ
l := 100 * (ts.EXPDist[i].Dmg) div total;
l := ts.Data.EXP * l div 100;
これに置き換えればエラーがでないはずです。
>>231
取り込んだあとにアドバイスというのも変ですが、そのままのコードであってますよ。
if Skill[112].Tick > Tick the begin
の後にでも、武器による条件分岐をつければいいかと。
使用者の継続時間減少は、SkillEffect()の4,5: //対パーティ時間制限有りスキル の最後の方に追加するしかないかな。
main.pasに
112: //ウェポンパーフェクション
begin
if ((WeaponType[0] = 7) or (WeaponType[0] = 8)) then begin tc1 := tc;
SkillProcessType := 5;
end else begin
WFIFOW( 0, $0110);
WFIFOW( 2, tc.MSkill);
WFIFOW( 4, 0);
WFIFOW( 6, 0);
WFIFOB( 8, 0);
WFIFOB( 9, 6);
Socket.SendBuf(buf, 10);
MMode := 0;
end;
end;
common.pasに
//ウェポンパーフェクション使用時
if Skill[112].Tick > Tick then begin
if ((WeaponType[0] = 7) or (WeaponType[0] = 8)) then begin
ATKFix[0][0] := 100;
ATKFix[0][1] := 100;
ATKFix[0][2] := 100;
end;
end;
common.pasの
if Skill[60].Tick > Tick then ADelay := ADelay * 70 div 100; //ツーハンドクイックン
の下に
if Skill[111].Tick > Tick then begin
if ((WeaponType[0] = 7) or (WeaponType[0] = 8)) then
ADelay := ADelay * 70 div 100; //AR
end;
を追加すればARが使用できます。
攻撃速度のディレイ減少の部分は間違ってるかもしれませんが…
すいません。
if ((WeaponType[0] = 7) or (WeaponType[0] = 8)) then は
if ((WeaponType[0] = 6) or (WeaponType[0] = 7) or (WeaponType[0] = 8)) then
です^^;
片手斧の存在を忘れてました。
end else if Copy(str, 1, 5) = 'icon ' then begin
sl := TStringList.Create;
sl.DelimitedText := Copy(str, 6, 256);
try
if sl.Count <> 2 then Continue;
Val(sl.Strings[0], i, k);
if (k <> 0) or (i < 0) then Continue;
Val(sl.Strings[1], j, k);
if (k <> 0) or (j < 0) then Continue;
WFIFOW(0, $0196);
WFIFOW(2, i);
WFIFOL(4, tc.ID);
WFIFOB(8, j);
Socket.SendBuf(buf, 9);
finally
sl.Free();
end;
end;