447 lines
13 KiB
Plaintext
447 lines
13 KiB
Plaintext
|
|
/*
|
|||
|
|
文件名:FatalismStone.nut
|
|||
|
|
路径:Dps_A/ProjectClass/FatalismStone/FatalismStone.nut
|
|||
|
|
创建日期:2025-06-22 12:54
|
|||
|
|
文件用途:
|
|||
|
|
*/
|
|||
|
|
|
|||
|
|
|
|||
|
|
class FatalismStone_Stone {
|
|||
|
|
//编号
|
|||
|
|
Id = 0;
|
|||
|
|
//类型
|
|||
|
|
StoneType = 0;
|
|||
|
|
//洗练度
|
|||
|
|
CultivationDegree = 0;
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
//特殊 ! 石头的储存数据大小
|
|||
|
|
Size = 8;
|
|||
|
|
|
|||
|
|
constructor(FatalismStoneID = 0) {
|
|||
|
|
Id = FatalismStoneID;
|
|||
|
|
CultivationDegree = MathClass.Rand(1, 100);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Blob2Hex(buf) {
|
|||
|
|
local str = "";
|
|||
|
|
for (local i = 0; i< buf.len(); i++) {
|
|||
|
|
str += format("%02X", buf[i]);
|
|||
|
|
}
|
|||
|
|
return str;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Serialize() {
|
|||
|
|
local B = blob(0);
|
|||
|
|
|
|||
|
|
B.writen(Id, 'i'); //写入ID
|
|||
|
|
B.writen(CultivationDegree, 'i'); //写入洗练值
|
|||
|
|
|
|||
|
|
return Blob2Hex(B);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function Deserialize(Data) {
|
|||
|
|
local Buf = FatalismStone_Stone();
|
|||
|
|
Buf.Id = Data.readn('i');
|
|||
|
|
Buf.CultivationDegree = Data.readn('i');
|
|||
|
|
if (Buf.Id == 0) return Buf;
|
|||
|
|
Buf.StoneType = ProjectInitFuncMap.P_FatalismStone.GetStoneData(Buf.Id)["stone type"];
|
|||
|
|
return Buf;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function SerializeTable(Obj) {
|
|||
|
|
local T = {
|
|||
|
|
id = Obj.Id,
|
|||
|
|
cultivationDegree = Obj.CultivationDegree
|
|||
|
|
};
|
|||
|
|
return T;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
class FatalismStone {
|
|||
|
|
|
|||
|
|
//总格子数
|
|||
|
|
GridCount = 77;
|
|||
|
|
//总穿戴数
|
|||
|
|
WearCount = 6;
|
|||
|
|
|
|||
|
|
//属性数据位数
|
|||
|
|
AttrCount = 2;
|
|||
|
|
|
|||
|
|
//魂石Lst
|
|||
|
|
FatalismStoneLst = null;
|
|||
|
|
|
|||
|
|
constructor() {
|
|||
|
|
local PoolObj = MysqlPool.GetInstance();
|
|||
|
|
PoolObj.SetBaseConfiguration("127.0.0.1", 3306, "game", "uu5!^%jg");
|
|||
|
|
//连接池大小
|
|||
|
|
PoolObj.PoolSize = 10;
|
|||
|
|
//初始化
|
|||
|
|
PoolObj.Init();
|
|||
|
|
|
|||
|
|
//读取pvf的魂石相关数据
|
|||
|
|
InitFatalismStoneData();
|
|||
|
|
|
|||
|
|
//注册客户端收包
|
|||
|
|
RegisterClient();
|
|||
|
|
//注册调试命令
|
|||
|
|
RegisterDebugCmd();
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
SelectSql("CREATE TABLE `zyk`.`fatalismstone` ( `cid` int(250) NOT NULL, `data` varbinary(10240) NULL, `wearpack` varbinary(1024) NULL, PRIMARY KEY (`cid`));", []);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
//通过数组生成魂石序列化数据
|
|||
|
|
function GenerateSerializeData(StoneList) {
|
|||
|
|
local Str = "0x";
|
|||
|
|
foreach(Stone in StoneList) {
|
|||
|
|
Str += Stone.Serialize();
|
|||
|
|
}
|
|||
|
|
return Str;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//通过数据反序列化魂石列表 数据 序列化个数
|
|||
|
|
function GenerateDeserializeData(Data, Count) {
|
|||
|
|
local BData = Sq_Point2Blob(Data.C_Object, FatalismStone_Stone.Size * Count);
|
|||
|
|
local DataArr = [];
|
|||
|
|
|
|||
|
|
//一直读到最后
|
|||
|
|
while (!BData.eos()) {
|
|||
|
|
DataArr.push(FatalismStone_Stone.Deserialize(BData));
|
|||
|
|
}
|
|||
|
|
return DataArr;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//给指定玩家新增魂石
|
|||
|
|
function AddFatalismStone(SUser, FatalismStoneID) {
|
|||
|
|
local CID = SUser.GetCID();
|
|||
|
|
local Ret = SelectSql("select data from zyk.fatalismstone where cid = " + CID, ["binary"]);
|
|||
|
|
//获得玩家魂石数据
|
|||
|
|
local DataArr = GenerateDeserializeData(Ret[0][0], GridCount * 3);
|
|||
|
|
//获取魂石属性
|
|||
|
|
local info = GetStoneData(FatalismStoneID);
|
|||
|
|
//根据页数分割
|
|||
|
|
local Offset = (info["stone type"] * GridCount);
|
|||
|
|
|
|||
|
|
local DataBuffer = DataArr.slice(Offset);
|
|||
|
|
//找到第一个空格子
|
|||
|
|
local Index = null;
|
|||
|
|
foreach(Pos, Obj in DataBuffer) {
|
|||
|
|
if (Obj.Id == 0) {
|
|||
|
|
Index = Pos;
|
|||
|
|
break;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
if (Index == null) {
|
|||
|
|
SUser.SendNotiPacketMessage("您的魂石背包已满!", 8);
|
|||
|
|
return false;
|
|||
|
|
}
|
|||
|
|
//添加魂石
|
|||
|
|
DataArr[Offset + Index] = FatalismStone_Stone(FatalismStoneID);
|
|||
|
|
local backpackBinary = GenerateSerializeData(DataArr);
|
|||
|
|
SelectSql("update zyk.fatalismstone set data = (" + backpackBinary + ") where cid = " + CID, ["int"]);
|
|||
|
|
FlushPlayerFatalismStoneBackpack(SUser);
|
|||
|
|
return true;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
//给指定玩家刷新魂石背包
|
|||
|
|
function FlushPlayerFatalismStoneBackpack(SUser) {
|
|||
|
|
local Ret = SelectSql("select data,wearpack from zyk.fatalismstone where cid = " + SUser.GetCID(), ["binary", "binary"]);
|
|||
|
|
//背包数量*背包类型数量全部使用默认的构造石头填充会是0
|
|||
|
|
local BackPackArr = array(GridCount * 3, FatalismStone_Stone());
|
|||
|
|
local WearArr = array(WearCount, FatalismStone_Stone());
|
|||
|
|
//没有初始化背包的时候先初始化背包
|
|||
|
|
if (Ret.len() == 0) {
|
|||
|
|
local backpackBinary = GenerateSerializeData(BackPackArr);
|
|||
|
|
local wearBinary = GenerateSerializeData(WearArr);
|
|||
|
|
SelectSql("insert into zyk.fatalismstone(cid,data,wearpack) values(" + SUser.GetCID() + ",(" + backpackBinary + "),(" + wearBinary + "))", ["int"]);
|
|||
|
|
} else {
|
|||
|
|
BackPackArr = GenerateDeserializeData(Ret[0][0], GridCount * 3);
|
|||
|
|
WearArr = GenerateDeserializeData(Ret[0][1], WearCount);
|
|||
|
|
}
|
|||
|
|
SUser.SendJso({
|
|||
|
|
op = 21000002,
|
|||
|
|
BackPackData = BackPackArr.map(FatalismStone_Stone.SerializeTable),
|
|||
|
|
WearData = WearArr.map(FatalismStone_Stone.SerializeTable)
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function RegisterClient() {
|
|||
|
|
//查询魂石背包数据
|
|||
|
|
ClientSocketPackFuncMap.rawset(21000001, function(SUser, Jso) {
|
|||
|
|
FlushPlayerFatalismStoneBackpack(SUser);
|
|||
|
|
}.bindenv(this));
|
|||
|
|
|
|||
|
|
//交换魂石位置
|
|||
|
|
ClientSocketPackFuncMap.rawset(21000003, function(SUser, Jso) {
|
|||
|
|
local OldType = Jso.oldtype;
|
|||
|
|
local OldIndex = Jso.oldpos;
|
|||
|
|
|
|||
|
|
local NewType = Jso.newtype;
|
|||
|
|
local NewIndex = Jso.newpos;
|
|||
|
|
|
|||
|
|
|
|||
|
|
local Ret = SelectSql("select data,wearpack from zyk.fatalismstone where cid = " + SUser.GetCID(), ["binary", "binary"]);
|
|||
|
|
local BackPackArr = GenerateDeserializeData(Ret[0][0], GridCount * 3);
|
|||
|
|
local WearArr = GenerateDeserializeData(Ret[0][1], WearCount);
|
|||
|
|
|
|||
|
|
//如果有魂石要移动到穿戴栏 需要检测魂石的类型是否与穿戴栏符合
|
|||
|
|
// if (OldType == -1 || NewType == -1) {
|
|||
|
|
// if(OldType == -1){
|
|||
|
|
// local OldStone = WearArr[OldIndex];
|
|||
|
|
// if(OldStone.Id != 0){
|
|||
|
|
// local Info = GetStoneData(OldStone.Id);
|
|||
|
|
// if(Info["stone type"] != NewType){
|
|||
|
|
// SUser.SendNotiPacketMessage("该魂石无法穿戴在当前位置", 8);
|
|||
|
|
// return;
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// if(NewType == -1){
|
|||
|
|
// local NewStone = BackPackArr[NewIndex];
|
|||
|
|
// if(NewStone.Id != 0){
|
|||
|
|
// local Info = GetStoneData(NewStone.Id);
|
|||
|
|
// if(Info["stone type"] != OldType){
|
|||
|
|
// SUser.SendNotiPacketMessage("该魂石无法穿戴在当前位置", 8);
|
|||
|
|
// return;
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
//如果Type等于-1 说明是穿戴的魂石的槽位
|
|||
|
|
local OldTemp, NewTemp;
|
|||
|
|
if (OldType == -1) {
|
|||
|
|
OldTemp = WearArr[OldIndex];
|
|||
|
|
} else {
|
|||
|
|
OldTemp = BackPackArr[OldType * GridCount + OldIndex];
|
|||
|
|
}
|
|||
|
|
if (NewType == -1) {
|
|||
|
|
NewTemp = WearArr[NewIndex];
|
|||
|
|
} else {
|
|||
|
|
NewTemp = BackPackArr[NewType * GridCount + NewIndex];
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
// //比对两个魂石的槽位类型
|
|||
|
|
// local ComparisonType;
|
|||
|
|
// if (NewType == -1) {
|
|||
|
|
// ComparisonType = NewIndex + 1;
|
|||
|
|
// } else {
|
|||
|
|
// ComparisonType = (NewType + 1);
|
|||
|
|
// }
|
|||
|
|
// print("旧类型: " + OldTemp.StoneType + "\n 新类型: " + ComparisonType);
|
|||
|
|
// print("旧ID: " + OldTemp.Id + "\n 新ID: " + NewTemp.Id);
|
|||
|
|
// if (OldTemp.StoneType != ComparisonType) {
|
|||
|
|
// SUser.SendNotiPacketMessage("该魂石无法穿戴在当前位置", 8);
|
|||
|
|
// return;
|
|||
|
|
// }
|
|||
|
|
|
|||
|
|
//交换数据
|
|||
|
|
if (OldType == -1) {
|
|||
|
|
WearArr[OldIndex] = NewTemp;
|
|||
|
|
} else {
|
|||
|
|
BackPackArr[OldType * GridCount + OldIndex] = NewTemp;
|
|||
|
|
}
|
|||
|
|
if (NewType == -1) {
|
|||
|
|
WearArr[NewIndex] = OldTemp;
|
|||
|
|
} else {
|
|||
|
|
BackPackArr[NewType * GridCount + NewIndex] = OldTemp;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
//序列化数据
|
|||
|
|
local backpackBinary = GenerateSerializeData(BackPackArr);
|
|||
|
|
local wearBinary = GenerateSerializeData(WearArr);
|
|||
|
|
|
|||
|
|
|
|||
|
|
//更新数据库
|
|||
|
|
SelectSql("update zyk.fatalismstone set data = (" + backpackBinary + "),wearpack = (" + wearBinary + ") where cid = " + SUser.GetCID(), ["int"]);
|
|||
|
|
|
|||
|
|
//发送数据
|
|||
|
|
SUser.SendJso({
|
|||
|
|
op = 21000002,
|
|||
|
|
BackPackData = BackPackArr.map(FatalismStone_Stone.SerializeTable),
|
|||
|
|
WearData = WearArr.map(FatalismStone_Stone.SerializeTable)
|
|||
|
|
});
|
|||
|
|
}.bindenv(this));
|
|||
|
|
|
|||
|
|
|
|||
|
|
Cb_User_Insert_Item_Leave_Func["宿命魂石"] <- function(args) {
|
|||
|
|
local SUser = User(NativePointer(args[0]).readPointer());
|
|||
|
|
local InvenObj = SUser.GetInven();
|
|||
|
|
local idx = args.pop();
|
|||
|
|
if (idx > 0) {
|
|||
|
|
local inven_item = InvenObj.GetSlot(1, idx);
|
|||
|
|
local item_id = inven_item.GetIndex();
|
|||
|
|
if (item_id >= 200625000 && item_id< 200626000) {
|
|||
|
|
local Ret = AddFatalismStone(SUser, item_id - 200625000);
|
|||
|
|
//删除原道具
|
|||
|
|
Timer.SetTimeOut(function() {
|
|||
|
|
inven_item.Delete();
|
|||
|
|
SUser.SendUpdateItemList(1, 0, idx);
|
|||
|
|
}, 100);
|
|||
|
|
//如果满了就发邮件
|
|||
|
|
if (!Ret) {
|
|||
|
|
local T = {};
|
|||
|
|
T.rawset(item_id, 1);
|
|||
|
|
SUser.SendMail(T, {
|
|||
|
|
Title = "系统",
|
|||
|
|
Text = "由于你的魂石包裹已满, 请留出足够的空间来接收道具."
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
SUser.SendItemSpace(0);
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}.bindenv(this);
|
|||
|
|
|
|||
|
|
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
function RegisterDebugCmd() {
|
|||
|
|
Gm_InputFunc_Handle["给魂石"] <- function(SUser, CmdString) {
|
|||
|
|
local count = -1;
|
|||
|
|
local pos = 0;
|
|||
|
|
local handler = [];
|
|||
|
|
do {
|
|||
|
|
local start = pos;
|
|||
|
|
pos = CmdString.find(" ", pos + 1);
|
|||
|
|
if (pos != null) {
|
|||
|
|
handler.append(CmdString.slice(start + 1, pos));
|
|||
|
|
} else
|
|||
|
|
handler.append(CmdString.slice(start + 1));
|
|||
|
|
count = count + 1
|
|||
|
|
} while (pos != null)
|
|||
|
|
|
|||
|
|
//得到空格数量
|
|||
|
|
if (count == 1) {
|
|||
|
|
AddFatalismStone(SUser, handler[1].tointeger());
|
|||
|
|
}
|
|||
|
|
}.bindenv(this);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function InitFatalismStoneData() {
|
|||
|
|
Script();
|
|||
|
|
FatalismStoneLst = {};
|
|||
|
|
ScriptData.GetFileData("fatalismstone/fatalismstone.lst", function(DataTable, Data) {
|
|||
|
|
while (!Data.Eof()) {
|
|||
|
|
local Id = Data.Get();
|
|||
|
|
local Path = Data.Get();
|
|||
|
|
FatalismStoneLst.rawset(Id, Path);
|
|||
|
|
}
|
|||
|
|
}.bindenv(this));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
function GetStoneData(Index) {
|
|||
|
|
if (FatalismStoneLst.rawin(Index)) {
|
|||
|
|
//还是路径就读取数据
|
|||
|
|
if (typeof FatalismStoneLst[Index] == "string") {
|
|||
|
|
FatalismStoneLst[Index] = ScriptData.GetFileData("fatalismstone/" + FatalismStoneLst[Index], function(DataTable, Data) {
|
|||
|
|
DataTable.Attribute <- {};
|
|||
|
|
while (!Data.Eof()) {
|
|||
|
|
local Key = Data.Get();
|
|||
|
|
if (Key == "[rarity]" || Key == "[stone type]" || Key == "[move wav]" || Key == "[front effect]" || Key == "[back effect]") {
|
|||
|
|
DataTable[Key.slice(1, -1)] <- Data.Get();
|
|||
|
|
} else if (Key == "[icon]") {
|
|||
|
|
DataTable.icon <- {
|
|||
|
|
img = Data.Get(),
|
|||
|
|
index = Data.Get()
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
});
|
|||
|
|
}
|
|||
|
|
return FatalismStoneLst[Index];
|
|||
|
|
} else error("没有ID为: " + Index + " 的魂石数据!");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
//执行数据库命令
|
|||
|
|
function SelectSql(Sql, Type) {
|
|||
|
|
local SqlObj = MysqlPool.GetInstance().GetConnect();
|
|||
|
|
local Ret = SqlObj.Select(Sql, Type);
|
|||
|
|
//把连接还池子
|
|||
|
|
MysqlPool.GetInstance().PutConnect(SqlObj);
|
|||
|
|
return Ret;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
|
|||
|
|
|
|||
|
|
ProjectInitFuncMap.P_FatalismStone <- FatalismStone();
|
|||
|
|
|
|||
|
|
print("文件加载!");
|