-- LUA Script - precede every function and global member with lowercase name of script + '_main' -- local pieces = {} local sub = string.sub local rad = math.rad local sin = math.sin local cos = math.cos local mouse_sprite = nil local hand_sprite = nil function piece_init_name(e, name) pieces[e] = {name = name, onBoard = false, sq = ''} mouse_sprite = CreateSprite(LoadImage ( "scriptbank\\examine_stuff\\mouse_cursor.png")) SetSpriteOffset(mouse_sprite, -1 , 1.5) SetSpriteSize (mouse_sprite, -1 , 3) SetSpriteDepth (mouse_sprite, 0) SetSpritePosition (mouse_sprite, 200, 200) hand_sprite = CreateSprite(LoadImage ( "scriptbank\\examine_stuff\\hand.png")) SetSpriteOffset(hand_sprite, -1 , 1.5) SetSpriteSize (hand_sprite, -1 , 3) SetSpriteDepth (hand_sprite, 0) SetSpritePosition (hand_sprite, 200, 200) end function GetPiece(sq) for k, v in pairs(pieces) do if v.sq == sq and v.onBoard then return v.name, k end end return '', nil end function PutPiece(name, sq, x, y, z, ang) for k, v in pairs(pieces) do if v.name == name and not v.onBoard then pieces[k] = {name = name, onBoard = true, sq = sq} CollisionOff(k) SetPosition(k, x, y, z) if sub(name,1,5) == 'White' then SetRotation(k, 0, ang, 0) else SetRotation(k, 0, ang - 180, 0) end CollisionOn(k) return end end end local function HidePiece(sq) for k, v in pairs(pieces) do if v.sq == sq and v.onBoard then CollisionOff(k) Hide(k) pieces[k].onBoard = false return end end end function MovePiece(fromsq, tosq) local name, k = GetPiece(fromsq) -- check for castling if name == 'White King' and fromsq == 'e1' then -- might be castling if tosq == 'g1' then MovePiece('h1', 'f1') elseif tosq == 'c1' then MovePiece('a1', 'd1') end elseif name == 'Black King' and fromsq == 'e8' then -- might be castling if tosq == 'g8' then MovePiece('h8', 'f8') elseif tosq == 'c8' then MovePiece('a8', 'd8') end end -- check for enpassant if name == 'White Pawn' and sub(fromsq, 2, 2) == '5' then -- might be enpassant if sub(fromsq, 1, 1) ~= sub(tosq, 1, 1) then local name, k = GetPiece(tosq) if k == nil then HidePiece(sub(tosq, 1, 1) .. '5') end end elseif name == 'Black Pawn' and sub(fromsq, 2, 2) == '4' then -- might be enpassant if sub(fromsq, 1, 1) ~= sub(tosq, 1, 1) then local name, k = GetPiece(tosq) if k == nil then HidePiece(sub(tosq, 1, 1) .. '4') end end end HidePiece(tosq) CollisionOff(k) local x, y, z, ang = GCGetPos(tosq) SetPosition(k, x, y, z) if sub(name,1,5) == 'White' then SetRotation(k, 0, ang, 0) else SetRotation(k, 0, ang - 180, 0) end CollisionOn(k) pieces[k].sq = tosq end local function Rotate3D (x, y, z, xrot, yrot, zrot) function RotatePoint2D (x, y, Ang) -- Ang in radians local Sa, Ca = sin(Ang), cos(Ang) return x*Ca - y*Sa, x*Sa + y*Ca end local NX, NY, NZ = x, y, z -- X NZ, NY = RotatePoint2D (NZ, NY, -xrot) -- Y NX, NZ = RotatePoint2D (NX, NZ, -yrot) -- Z NY, NX = RotatePoint2D (NY, NX, -zrot) return NX, NY, NZ end local function PlayerLookingAtPiece() local yOff = 31 if GetGamePlayerStatePlayerDucking() == 1 then yOff = 10 end local x, y, z = g_PlayerPosX, g_PlayerPosY + yOff, g_PlayerPosZ local paX, paY, paZ = rad(g_PlayerAngX), rad(g_PlayerAngY), rad(g_PlayerAngZ) local rayX, rayY, rayZ = Rotate3D(0,0,2000,paX, paY, paZ) return IntersectAll(x, y, z, x + rayX, y + rayY, z + rayZ, 0) end local function PlayerLookingAtSquare() local yOff = 31 if GetGamePlayerStatePlayerDucking() == 1 then yOff = 10 end local x, y, z = g_PlayerPosX, g_PlayerPosY + yOff, g_PlayerPosZ local paX, paY, paZ = rad(g_PlayerAngX), rad(g_PlayerAngY), rad(g_PlayerAngZ) local rayX, rayY, rayZ = Rotate3D(0,0,5000,paX, paY, paZ) local obj = IntersectAll(x, y, z, x + rayX, y + rayY, z + rayZ, 0) --while obj and obj ~= 0 and g_boardObject ~= obj do -- IntersectAll(x, y, z, x + rayX, y + rayY, z + rayZ, obj) --end if obj == g_boardObject then return GetSquare(GetIntersectCollisionX(),GetIntersectCollisionZ()) else -- try again ignoring objects obj = IntersectAll(x, y, z, x + rayX, y + rayY, z + rayZ, obj) if obj == g_boardObject then return GetSquare(GetIntersectCollisionX(),GetIntersectCollisionZ()) else return '??' end end end local objects = {} local function ShowSprite(spr) if spr == hand_sprite then SetSpritePosition (mouse_sprite, 200, 200) SetSpritePosition (hand_sprite, 50, 50) else SetSpritePosition (mouse_sprite, 50, 50) SetSpritePosition (hand_sprite, 200, 200) end end local choosePiece = nil local mousePressed = false local frameCounter = 0 local flasherFlag = false local lastPiece = nil local function ProcessPlayer(e, zone) local fp = false if choosePiece == nil then local obj = PlayerLookingAtPiece() for k, v in pairs(objects) do if v.obj == obj then if pieces[k] then Prompt(pieces[k].name) ShowSprite(hand_sprite) if g_MouseClick == 1 then if not mousePressed then choosePiece = k mousePressed = true end else mousePressed = false end end return end end ShowSprite(mouse_sprite) else frameCounter = frameCounter + 1 if frameCounter > 25 then frameCounter = 0 flasherFlag = not flasherFlag end local fromsq = pieces[choosePiece].sq local tosq = PlayerLookingAtSquare() Prompt(fromsq .. tosq) if tosq ~= '??' and tosq ~= fromsq then CollisionOff(choosePiece) local valid, move = GCValidMove(fromsq, tosq) if valid then local x, y, z, ang = GCGetPos(tosq) SetPosition(choosePiece, x, y, z) local _,otherPiece = GetPiece(tosq) if otherPiece ~= nil then if lastPiece and lastPiece ~= otherPiece then Show(lastPiece) end lastPiece = otherPiece if not flasherFlag then Hide(otherPiece) else Show(otherPiece) end else if lastPiece ~= nil then Show(lastPiece) end end end else if lastPiece ~= nil then Show(lastPiece) end CollisionOff(choosePiece) local x, y, z, ang = GCGetPos(fromsq) SetPosition(choosePiece, x, y, z) CollisionOn(choosePiece) end if flasherFlag then Hide(choosePiece) else Show(choosePiece) end if g_MouseClick ~= 1 then mousePressed = false local x, y, z, ang = GCGetPos(fromsq) SetPosition(choosePiece, x, y, z) CollisionOn(choosePiece) Show(choosePiece) if tosq ~= '??' then if lastPiece ~= nil then Show(lastPiece) lastPiece = nil end local valid, move = GCValidMove(fromsq, tosq) if valid then GCMakeMove(fromsq, tosq, move) -- handle promotion if pieces[choosePiece].name == 'White Pawn' then if sub(tosq,2,2) == '8' then pieces[choosePiece].name = 'White Queen' end elseif pieces[choosePiece].name == 'Black Pawn' then if sub(tosq,2,2) == '1' then pieces[choosePiece].name = 'Black Queen' end end end end choosePiece = nil end end end local Trigger_Ent = nil function piece_main(e) local Ent = g_Entity[e] local thisObj = objects[e] if thisObj == nil then objects[e] = {obj = Ent.obj, state = 'steady'} if Trigger_Ent == nil then Trigger_Ent = e end return end if Trigger_Ent == e then ProcessPlayer(e) end end