-- TODO : admin char paperdoll body broken : bodyid,bodygumpid = 987 0x03db : body gump id unknown unknown ( GM admin robe) -- TODO : gump.def must be parsed, simple format -- packet handlers for paperdolls (clother and equipment of player, npcs..) -- see also lib.packet.lua and lib.protocol.lua -- see also net.mobile.lua, especially kPacket_Equipped_MOB -- mobileserial : also known as character/player id -- Created 08.03.2008 12:25:56, with GumpStudio & Iris2 Lua Export Plugin -- Exported Iris2 GumpExporter ver 1.0. local playerPaperdoll = {} playerPaperdoll.bSupportsGuiSys2 = true playerPaperdoll.dialogId = 1000001 playerPaperdoll.x = 120 playerPaperdoll.y = 100 playerPaperdoll.Data = "{ page 0 }" .. "{ gumppic 4 4 2000 paperdollpic }" .. "{ button 187 50 2031 2032 1 0 0 btnhelp }" .. "{ button 187 76 2006 2007 1 0 1 btnoptions }" .. "{ text 36 265 0 0 paperdollname }" .. "{ button 84 6 113 113 1 0 2 btnvirtues }" .. "{ button 187 102 2009 2010 1 0 3 btnquit }" .. "{ button 187 130 22453 22455 1 0 4 btnquests }" .. "{ button 187 156 2015 2016 1 0 5 btnskills }" .. "{ button 187 181 22450 22452 1 0 6 btnguild }" .. "{ button 187 205 2021 2022 1 0 7 btnpeace }" .. "{ button 187 233 2027 2028 1 0 8 btnstatus }" .. "{ button 165 210 11060 11060 1 0 9 btnweaponability }" .. "{ gumppictiled 6 84 21 21 9274 miniequipback1 }" .. "{ gumppic 6 84 9028 miniequip1 }" .. "{ gumppictiled 6 107 21 21 9274 miniequipback2 }" .. "{ gumppic 6 107 9028 miniequip2 }" .. "{ gumppictiled 6 130 21 21 9274 miniequipback3 }" .. "{ gumppic 6 130 9028 miniequip3 }" .. "{ gumppictiled 6 153 21 21 9274 miniequipback4 }" .. "{ gumppic 6 153 9028 miniequip4 }" .. "{ gumppictiled 6 176 21 21 9274 miniequipback5 }" .. "{ gumppic 6 176 9028 miniequip5 }".. "{ button 27 200 2002 2002 1 0 10 charprofile }" .. "{ button 44 200 2002 2002 1 0 11 partymanifest }" playerPaperdoll.textline = { [0] = "paperdoll_name", } playerPaperdoll.functions = { -- help [0] = function (widget,mousebutton) if (mousebutton == 1) then Send_RequestHelp() end end, -- options [1] = function (widget,mousebutton) OpenConfigDialog() end, -- virtues [2] = function (widget,mousebutton) if (mousebutton == 1) then GumpReturnMsg(GetPlayerSerial(),kGumpTypeVirtue,1,nil,1, GetPlayerSerial()) -- special case end end, -- quit [3] = function (widget,mousebutton) if (mousebutton == 1) then OpenQuit() end end, -- quests [4] = function (widget,mousebutton) if (mousebutton == 1) then Send_AOSCommand(kPacket_AOS_Command_QuestGumpRequest,gPlayerBodySerial) end end, -- skills [5] = function (widget,mousebutton) if (mousebutton == 1) then ToggleSkill() end end, -- guild [6] = function (widget,mousebutton) if (mousebutton == 1) then Send_AOSCommand(kPacket_AOS_Command_GuildGumpRequest,gPlayerBodySerial) end end, -- peace [7] = function (widget,mousebutton) if (mousebutton == 1) then Send_CombatMode(IsWarModeActive() and gWarmode_Normal or gWarmode_Combat) end end, -- status [8] = function (widget,mousebutton) if (mousebutton == 1) then ToggleStatusAos() end end, -- weaponability [9] = function (widget,mousebutton) if (mousebutton == 1) then -- current equipped weapon local a,b = GetWeaponSpecialsForMobile(GetPlayerMobile()) local mx,my = GetMousePos() if (a) then CreateQuickCastButtonWeaponability(mx-48,my,a) end if (b) then CreateQuickCastButtonWeaponability(mx+16,my,b) end end end, -- character profile [10] = function (widget,mousebutton) if (mousebutton == 1) then Send_RequestCharacterProfile() end end, -- party manifest [11] = function (widget,mousebutton) if (mousebutton == 1) then TogglePartyList() end end, } -- Created 08.03.2008 12:25:56, with GumpStudio & Iris2 Lua Export Plugin -- Exported Iris2 GumpExporter ver 1.0. local npcPaperdoll = {} npcPaperdoll.bSupportsGuiSys2 = true npcPaperdoll.dialogId = 1000002 npcPaperdoll.x = 120 npcPaperdoll.y = 100 npcPaperdoll.Data = "{ page 0 }" .. "{ gumppic 4 4 2001 paperdollpic }" .. "{ text 36 263 0 0 paperdollname }" .. "{ button 187 233 2027 2028 1 0 0 btnstatus }" npcPaperdoll.textline = { [0] = "paperdoll_name", } npcPaperdoll.functions = { -- status [0] = function (widget,mousebutton) if (mousebutton == 1) then OpenHealthbar(widget:GetDialog().uoPaperdoll.mobile) end end } kClientSideGump_Paperdoll_Own = playerPaperdoll -- own paperdoll, including buttons like quest,skills.. kClientSideGump_Paperdoll_Other = npcPaperdoll -- paperdoll of someone else, no buttons -- initial body positon in gump local BodyWidget_x = 9 local BodyWidget_y = 19 gPaperdolls = {} RegisterListener("Hook_WarmodeChange",function () UpdatePaperdollWarPeaceButton() end) function GetPaperDoll (serial) return serial and gPaperdolls[serial] end function UpdatePaperdollWarPeaceButton() local paperdoll = GetPaperDoll(GetPlayerSerial()) local dialog = paperdoll and paperdoll.dialog local widget = dialog and dialog.controls["btnpeace"] if (widget) then if (IsWarModeActive()) then widget:SetButtonGumpIDs(0x7E8,0x7E9,0x7EA) -- normal,pressed,over else widget:SetButtonGumpIDs(0x7E5,0x7E6,0x7E7) -- normal,pressed,over end end end local function GetPaperdollBodyAndBaseID (bodyid) local bodygumpid = nil local base_id = kGumpBaseId_Male --Human-Male Paperdoll if (bodyid == 400 or bodyid == 744 or --Necromancy Transfromed Model bodyid == 987) --GameMaster v2 + GM Robe should be displayed then bodygumpid = hex2num("0x0C") base_id = kGumpBaseId_Male --Human-Savage_Male elseif (bodyid == 183 or bodyid == 185 or bodyid == 750) then bodygumpid = hex2num("0x79") base_id = kGumpBaseId_Male --Human-Female Paperdoll elseif (bodyid == 401 or bodyid == 745) --Necromancy Transfromed Model then bodygumpid = hex2num("0x0D") base_id = kGumpBaseId_Female --Human-Savage_Female elseif (bodyid == 184 or bodyid == 186 or bodyid == 751) then bodygumpid = hex2num("0x78") base_id = kGumpBaseId_Female --Male-Elf Paperdoll elseif (bodyid == 605) then bodygumpid = hex2num("0x0E") base_id = kGumpBaseId_Male --Female-Elf Paperdoll elseif (bodyid == 606) then bodygumpid = hex2num("0x0F") base_id = kGumpBaseId_Female --Lord British elseif (bodyid == 990) then bodygumpid = hex2num("0x3DE") base_id = kGumpBaseId_Male --Blackthorn elseif (bodyid == 991) then bodygumpid = hex2num("0x3DF") base_id = kGumpBaseId_Male --Dupre (wrong paperdoll ?!) elseif (bodyid == 994) then bodygumpid = hex2num("0x3E2") --Player Ghosts elseif (bodyid == 402 or bodyid == 403 or bodyid == 607 or bodyid == 608 or bodyid == 970) then bodygumpid = hex2num("0x3DB") else -- unknown --bodygumpid = hex2num("0x3DF") end return bodygumpid,base_id end -- base_id = kGumpBaseId_Female or kGumpBaseId_Male function GetPaperdollItemGumpID (artid,base_id) local t = GetStaticTileType(artid) if (not t) then return end local animid = t.miAnimID local gumpid = animid + base_id if ((not PreLoadGump(gumpid)) and base_id == kGumpBaseId_Female) then gumpid = animid+kGumpBaseId_Male end -- fallback to male if (GetPaperdollLayerFromTileType(artid) == kLayer_Backpack) then gumpid = animid+kGumpBaseId_Male end -- no female backpack return gumpid end -- Don't call this directly, use RebuildPaperdoll() instead (need to rebuild completely on change because of layerorder) -- item fields : serial artid layer hue (=-1 if not set) local function CreatePaperdollItemWidget(layer, paperdoll, item, base_id, blockedlayers) local dialog = paperdoll.dialog if (paperdoll.bSupportsGuiSys2) then --~ print("TODO : CreatePaperdollItemWidget") if (not blockedlayers[layer]) then item.widget = dialog:CreateChild("UOPaperdollItemWidget",{paperdoll=paperdoll,item=item,base_id=base_id,x=BodyWidget_x,y=BodyWidget_y}) end local side = gLayerOrderPositionAndArtOverwrite[layer] if side then local x,y = unpack(side) item.widget2 = dialog:CreateChild("UOPaperdollItemWidget",{paperdoll=paperdoll,item=item,base_id=base_id,x=x,y=y,useart=true,onsidebar=true}) end return end -- from here on : code for old-guisystem paperdoll -- Fallback to female local gumpid = GetPaperdollItemGumpID(item.artid) if (not gumpid) then print("WARNING : CreatePaperdollItemWidget : unknown gump",item.artid) return -- TODO : dummy gfx type for each layer ? end if (not blockedlayers[layer]) then item.widget = MakeBorderGumpPart(dialog.rootwidget, gumpid, BodyWidget_x, BodyWidget_y, 0, 0, 0, item.hue) PaperdollItemWidgetInit(item.widget,layer,paperdoll,item,base_id) end -- additonal widget in jewelry slot if gLayerOrderPositionAndArtOverwrite[layer] then local x,y = unpack(gLayerOrderPositionAndArtOverwrite[layer]) local minx,miny,maxx,maxy = GetArtVisibleAABB(item.artid + 0x4000) local cx = minx + (maxx - minx)/2 local cy = miny + (maxy - miny)/2 item.widget2 = MakeArtGumpPart( dialog.rootwidget, item.artid, x-cx,y-cy, nil,nil,nil, item.hue) PaperdollItemWidgetInit(item.widget2,layer,paperdoll,item,base_id) end end function PaperdollItemWidgetInit (widget,layer,paperdoll,item,base_id) widget.mbIgnoreMouseOver = false widget.uoPaperdoll = paperdoll widget.item = item widget.onMouseDown = function (widget,mousebutton) end -- TODO : find a cleaner solution to override the mousepick tipp widget.onMouseEnter = function () -- item tooltip (clientside,debuginfos) local name = GetStaticTileTypeName(item.artid) or "" info = sprintf("equipment %s (artid=%04x=%d)",name,item.artid,item.artid) gCurrentRenderer.gMousePickTippOverride = info Client_SetBottomLine(gCurrentRenderer.gMousePickTippOverride) end widget.onMouseLeave = function () gCurrentRenderer.gMousePickTippOverride = false Client_SetBottomLine("") end if (gTooltipSupport) then widget.tooltip_offx = kUOToolTippOffX widget.tooltip_offy = kUOToolTippOffY widget.stylesetname = gGuiDefaultStyleSet widget.on_simple_tooltip = function (widget) local tooltiptext = AosToolTip_GetText(widget.item.serial) or "" return (tooltiptext .. " \n ") or "?" end -- add newline, workaround for tooltip sizecalc bug end end -- destroys old widgets if neccessary local function DestroyPaperdollItemWidgets (paperdoll) if (paperdoll.mobile) then for k,item in pairs(GetMobileEquipmentList(paperdoll.mobile)) do if (item.widget) then item.widget:Destroy() item.widget = nil end if (item.widget2) then item.widget2:Destroy() item.widget2 = nil end end end end -- close dialog and destroys all widgets local function ClosePaperdoll (paperdoll) if (paperdoll and paperdoll.dialog) then NotifyListener("Hook_ClosePaperdoll",paperdoll) DestroyPaperdollItemWidgets(paperdoll) paperdoll.dialog:Destroy() paperdoll.dialog = nil gPaperdolls[paperdoll.mobileserial] = nil -- TODO : send network message ? end end -- ----------------------------------------------- End of local functions ----------------------------- -- rebuild needed on update to have correct layerorder -- paperdoll.bIsPlayer (check if is player or npc) function RebuildPaperdoll (paperdoll) if (not gGumpLoader) then return end local mobile = GetMobile(paperdoll.mobileserial) paperdoll.mobile = mobile paperdoll.bIsPlayer = IsPlayerMobile(mobile) -- create paperdoll dialog for player or mobile if neccessary local dialog = paperdoll.dialog if (not dialog) then if (paperdoll.bIsPlayer) then dialog = GumpParser( playerPaperdoll, true ) else dialog = GumpParser( npcPaperdoll, true ) end -- save paperdolldialog as paperdoll paperdoll.dialog = dialog dialog.uoPaperdoll = paperdoll -- overwrite the onMouseDown function from gumpparser dialog.SendClose = function (widget,returnvalue) ClosePaperdoll(paperdoll) end end -- visually change the Peace/Warmode Button when opening the Paperdoll when in combat mode UpdatePaperdollWarPeaceButton() -- update paperdoll name and color --~ local r,g,b = GetNotorietyColor(paperdoll.mobile and paperdoll.mobile.notoriety or 0) --~ dialog.controls["paperdollname"].gfx:SetCharHeight(gFontDefs["Gump"].size + 2) --~ dialog.controls["paperdollname"].gfx:SetColour( {r,g,b,1.0} ) --~ dialog.controls["paperdollname"].gfx:SetFont(gFontDefs["Gump"].name) --~ dialog.controls["paperdollname"].gfx:SetText(paperdoll.name) local name = paperdoll.name or "Unknown" local sname = string.gsub(name, ",", ",
") dialog.controls["paperdollname"]:SetUOHtml(""..sname.."", true) -- dialog.controls["paperdollname"]:SetText(name) -- remove old item widgets DestroyPaperdollItemWidgets(paperdoll) -- create bodywidget and item widgets if (mobile) then local bodyid = mobile.artid local bodygumpid,base_id = GetPaperdollBodyAndBaseID(bodyid) -- destroy old bodywidget if (dialog.bodywidget) then dialog.bodywidget:Destroy() dialog.bodywidget = nil end local skinhue = mobile.hue if (skinhue >= 0x8000) then skinhue = skinhue - 0x8000 end -- create bodywidget if (bodygumpid) then dialog.bodywidget = dialog:CreateChild("UOImage",{gump_id=bodygumpid,x=BodyWidget_x,y=BodyWidget_y,hue=skinhue}) else --print("Open_Paperdoll : unknown bodyid ",bodyid,sprintf("0x%04x",bodyid)) -- TODO : fallback/default bodyid ? end -- 2d stitching local blockedlayers = {} for blocker,blockedlist in pairs(gPaperdollBlockingLayers) do if GetMobileEquipmentItem(mobile,blocker) then for k,blocked in pairs(blockedlist) do blockedlayers[blocked] = true end end end paperdoll.bSupportsGuiSys2 = true -- preload / bulkload to atlas for index,layer in pairs(gLayerOrder) do local k = gLayerTypeName[layer] local item = GetMobileEquipmentItem(mobile,layer) if (item) then AosToolTip_GetText(item.serial) local gumpid = GetPaperdollItemGumpID(item.artid,base_id) if (gumpid) then PreLoadGump(gumpid) end if gLayerOrderPositionAndArtOverwrite[layer] then PreLoadArt(item.artid + 0x4000) end end end -- create item widgets for index,layer in pairs(gLayerOrder) do local k = gLayerTypeName[layer] local item = GetMobileEquipmentItem(mobile,layer) if (item) then CreatePaperdollItemWidget(layer,paperdoll,item,base_id,blockedlayers) end end end if (mobile and mobile.name ~= paperdoll.name) then mobile.name = paperdoll.name mobile:Update() end NotifyListener("Hook_RebuildPaperdoll",paperdoll) end -- triggered by mobile destruction function DestroyPaperdollByMobileSerial (serial) local paperdoll = gPaperdolls[serial] if (not paperdoll) then return end ClosePaperdoll(paperdoll) end -- called from kPacket_Open_Paperdoll, TogglePlayerPaperdoll and OpenPaperdoll function HandleOpenPaperdoll (paperdoll) paperdoll.mobileserial = paperdoll.serial paperdoll.Close = ClosePaperdoll -- close old paperdoll local oldpaperdoll = gPaperdolls[paperdoll.mobileserial] if (oldpaperdoll) then oldpaperdoll:Close() end -- register paperdoll gPaperdolls[paperdoll.mobileserial] = paperdoll RebuildPaperdoll(paperdoll) end -- toggles the player paperdoll function TogglePlayerPaperdoll () local playermobile = GetPlayerMobile() -- Check if there is a mobile to display if (not playermobile) then -- No mobile to display so provide at least a menu to quit OpenQuit() return end if (playermobile.serial and gPaperdolls[playermobile.serial]) then gPaperdolls[playermobile.serial]:Close() else local paperdoll = {} paperdoll.serial= playermobile.serial paperdoll.name = playermobile.name paperdoll.flag = 0 HandleOpenPaperdoll(paperdoll) end end -- open/reposition the requested paperdoll function OpenPaperdoll (x,y,serial) local p = gPaperdolls[serial] if p then RebuildPaperdoll(p) else local paperdoll = {} local m = GetMobile(serial) paperdoll.serial = serial paperdoll.name = m and m.name or serial paperdoll.flag = 0 HandleOpenPaperdoll(paperdoll) end local p = gPaperdolls[serial] if p.dialog and p.dialog.rootwidget and p.dialog.rootwidget.gfx then p.dialog.rootwidget.gfx:SetPos(x, y) end end