diff --git a/design/maps.py b/design/maps.py index d6e0d1ec..40fcb0b7 100644 --- a/design/maps.py +++ b/design/maps.py @@ -1221,6 +1221,7 @@ "npcs":[ {"id":"transporter","position":[-14,-477]}, {"id":"locksmith","position":[316,-270]}, + {"id":"scrollsmith","position":[606,-1590]}, ], "monsters":[ {"type":"plantoid","boundary":[-1013,-472,-575,-130],"count":4,"grow":True}, #added grow 31/1/2024 diff --git a/design/npcs.py b/design/npcs.py index 818b54d9..e8fed04f 100644 --- a/design/npcs.py +++ b/design/npcs.py @@ -891,6 +891,13 @@ "type":"fullstatic", "name":"Smith", }, + "scrollsmith":{ + "role":"scrollsmith", + "skin":"bsoldier", + "says":"X", + "type":"fullstatic", + "name":"Sir Bob", + }, "transporter":{ "role":"transport", "skin":"spell", diff --git a/design/sprites.py b/design/sprites.py index 28995b2a..74e24840 100644 --- a/design/sprites.py +++ b/design/sprites.py @@ -372,7 +372,7 @@ "columns":4, "matrix":[ [None,"nexus",None,None], - [None,None,None,None], + [None,None,"bsoldier",None], ] }, "military3":{ @@ -1136,4 +1136,4 @@ "ruins":{"file":"/images/tiles/map/ruins.png?v=2"}, "tree":{"file":"/images/tiles/map/tree.png"}, "lights":{"file":"/images/tiles/map/lights.png?v=3","light":"yes"}, # "frames":3,"frame_width":48, -} \ No newline at end of file +} diff --git a/js/functions.js b/js/functions.js index 86b0c44a..ed9af67c 100644 --- a/js/functions.js +++ b/js/functions.js @@ -2953,6 +2953,14 @@ function lock_item(num) return push_deferred("locksmith"); } +function destat_item(num) +{ + if(num===undefined) num=s_item; + socket.emit("destat",{num:num}); + return push_deferred("destat"); +} + + function seal_item(num) { if(num===undefined) num=l_item; @@ -3204,6 +3212,7 @@ function reopen() else if(rendered_target=="dismantler") render_dismantler(); else if(rendered_target=="none") render_none_shrine(); else if(rendered_target=="locksmith") render_locksmith(); + else if(rendered_target=="scrollsmith") render_scrollsmith(); // else if(rendered_target=="secondhands") render_secondhands(); // Manual resets if(inventory) reset_inventory(); @@ -3270,7 +3279,7 @@ function reset_inventory(condition) { if(inventory) { - if(condition && !in_arr(rendered_target,["upgrade","compound","exchange","npc","merchant","craftsman","dismantler","none","locksmith"])) return; + if(condition && !in_arr(rendered_target,["upgrade","compound","exchange","npc","merchant","craftsman","dismantler","none","locksmith","scrollsmith"])) return; render_inventory(true); } } diff --git a/js/game.js b/js/game.js index 5615ba90..27f1d42d 100644 --- a/js/game.js +++ b/js/game.js @@ -2194,6 +2194,15 @@ function init_socket(args) } else if(response=="magiport_failed") ui_log("Magiport failed","gray"),no_no_no(2); else if(response=="revive_failed") ui_log("Revival failed","gray"),no_no_no(1); + else if(response=="scrollsmith_cant") + { + ui_log("Can't destat this item","gray") + } + else if(response=="scrollsmith_success") + { + ui_log("Spent " + data.gold.toLocaleString() + " gold","gray"); + ui_log("De-statted the item","gray"); + } else if(response=="locksmith_cant") { ui_log("Can't lock/unlock this item","gray") @@ -3257,6 +3266,10 @@ function npc_right_click(event){ { render_interaction({auto:true,dialog:"locksmith",skin:"asoldier"}); } + if(this.role=="scrollsmith") + { + render_interaction({auto:true,dialog:"scrollsmith",skin:"bsoldier"}); + } if(this.role=="compound") { render_compound_shrine(1); diff --git a/js/html.js b/js/html.js index 0365b378..8f42c726 100644 --- a/js/html.js +++ b/js/html.js @@ -1,4 +1,4 @@ -var u_item=null,u_scroll=null,u_offering=null,c_items=e_array(3),c_scroll=null,c_offering=null,c_last=0,e_item=null,p_item=null,l_item=null,cr_items=e_array(9),cr_last=0,ds_item=null; +var u_item=null,u_scroll=null,u_offering=null,c_items=e_array(3),c_scroll=null,c_offering=null,c_last=0,e_item=null,p_item=null,l_item=null,s_item=null,cr_items=e_array(9),cr_last=0,ds_item=null; var settings_shown=0; function show_settings() @@ -1142,6 +1142,30 @@ function render_locksmith(mode) if(!inventory) render_inventory(),inventory_opened_for=topleft_npc; } +function render_scrollsmith() +{ + var button="DE-STAT",f="destat_item",shade="shade_chest"; + reset_inventory(1); + topleft_npc="scrollsmith"; rendered_target=topleft_npc; + s_item=null; + var html="
"; + /*html+="
"; + html+="
"; + html+="
"; + //html+="
";*/ + html+="
"; + html+=item_container({shade:shade,cid:'sitem',s_op:0.4,draggable:false,droppable:true}); + html+="
"; + //html+="
"; + /*html+="
"; + html+="
"; + html+="
";*/ + html+="
"+button+"
"; + html+="
"; + $("#topleftcornerui").html(html); + if(!inventory) render_inventory(),inventory_opened_for=topleft_npc; +} + function render_recipe(element,type,name) { last_selector="#recipe-item"; @@ -3741,6 +3765,17 @@ function on_rclick(current) $("#citem"+inum).parent().html(""); $("#litem").html(html); } + else if(topleft_npc=="scrollsmith") + { + var current=character.items[inum],def=null; + if(current) def=G.items[current.name]; + if(!def) return; + if(s_item!==null) return; + s_item=inum; cache_i[inum]=-1; + var html=$("#citem"+inum).all_html(); + $("#citem"+inum).parent().html(""); + $("#sitem").html(html); + } else if(topleft_npc=="upgrade") { var current=character.items[inum],def=null; @@ -4634,6 +4669,11 @@ function render_interaction(type,sub_type,args) html+="Lock - Prevents anything that can destroy an item, selling, upgrading, you name it! Seal - Locks the item in a way that unlocking it takes two days. Unlock - Frees it. Got it? Good. Cost? 250 big ones."; html+="
LOCK
SEAL
UNLOCK
"; } + else if(type=="scrollsmith") + { + html+="De-stat an item. Give you back the scrolls used on the item, as though the item were level 0. Returns the item back to you along with scrolls. Got it? Good. Cost? Depends on the scroll. 10 times the value of the scrolls that will be returned to you."; + html+="
DE-STAT
"; + } else if(type=="crafting") { html+="I can craft or dismantle items for you. Price differs from item to item. Check out my recipes if you are interested!"; diff --git a/node/server.js b/node/server.js index b4fae706..b2bb233c 100644 --- a/node/server.js +++ b/node/server.js @@ -5585,6 +5585,48 @@ function init_io() { resend(player, "reopen+nc+inv"); success_response({ num: num, cevent: true }); }); + + socket.on("destat", function (data) { + var player = players[socket.id]; + if (!player || player.user) { + return fail_response("cant_in_bank"); + } + if (!player.computer && simple_distance(G.maps.desertland.ref.scrollsmith, player) > B.sell_dist) { + return fail_response("distance"); + } + var item = player.items[data.num]; + if (!item) { + return fail_response("no_item"); + } + var def = G.items[item.name]; + if (item.stat_type == null) { + return fail_response("scrollsmith_cant"); + } + var scrolltype = item.stat_type + "scroll"; + if (scrolltype == "mp_costscroll") { + scrolltype = "mpcostscroll"; + } + var scrolldef = G.items[scrolltype]; + if (!scrolldef) { + return fail_response("scrollsmith_cant"); // Just in case there isn't actually an item associated with the scroll... should never happen, though. + } + var needed = [1, 10, 100, 1000, 9999, 9999, 9999]; + var ograde = calculate_item_grade(def, { name: item.name, level: 0 }); + var cost = needed[ograde] * scrolldef.g * 10; + if (player.gold < cost) { + return fail_response("gold_not_enough"); + } + if (!can_add_items(player, list_to_pseudo_items([[needed[ograde], scrolltype]]))) { + return fail_response("inv_size"); + } + player.gold -= cost; + add_item(player, scrolltype, { q: needed[ograde] }); + delete item.stat_type; + socket.emit("game_response", { response: "scrollsmith_success", gold: cost }); + player.citems[data.num] = cache_item(player.items[data.num]); + resend(player, "reopen+nc"); + success_response(); + }); socket.on("locksmith", function (data) { var player = players[socket.id]; var item = player.items[data.item_num];