· 7 years ago · Nov 01, 2018, 08:14 PM
1<?xml version="1.0" encoding="iso-8859-1"?>
2<!DOCTYPE muclient>
3<!-- Saved on Wednesday, September 26, 2012, 10:16 AM -->
4<!-- MuClient version 4.81 -->
5
6<!-- Plugin "mobs_n_items" generated by Plugin Wizard -->
7
8<muclient>
9
10<plugin
11 name="mobs_n_items"
12 author="Ruthgul"
13 id="8755063a5cf00f3312b113e6"
14 language="Lua"
15 purpose="NPCs and items database"
16 save_state="y"
17 date_written="2012-09-26 10:15:07"
18 date_modified="2013-12-30 07:18:07"
19 requires="4.71"
20 version="1.0"
21 >
22
23<description trim="y">
24
25<![CDATA[
26
27.----------------.
28 | mobs_n_items |
29`----------------'
30
31Implements a database for NPCs and items.
32
33
34** REQUIRES **
35
36- MXP must be ON, to auto-detect NPCs & items [ Client setting: Game, Configure, MXP / Pueblo... > Use MXP / Pueblo: On command (or Yes - always). ]
37- MM GMCP Handler, to auto-detect room & area for items
38- MM_GMCP_Mapper, to search for and speedwalk to rooms
39- Speedwalk_Manager_GMCP_P2, to search for and speedwalk to areas
40
41
42Syntax:
43
44> queries:
45
46* mob where <mob_name> [a:<area_name>] - fuzzy search by mob name
47* item where <item_name> [a:<area_name>] - fuzzy search by item name
48* skill where <skill_name> [a:<area_name>] - search by exact skill name
49
50* mob wheree <mob_name> [a:<area_name>] - search by exact mob name
51* item wheree <item_name> [a:<area_name>] - search by exact item name
52* skill wheree <skill_name> [a:<area_name>] - search by exact skill name
53
54> additions:
55
56* add mxp [on|off] - toggle auto-add mobs and items via MXP (BETA, OFF by default)
57* add mxp 1stock [on|off] - toggle auto-add 1-stock items (BETA, OFF by default)
58* add mxp ground [on|off] - toggle auto-add items on the ground (ON by default)
59
60* add mob <mob_id> n:<name> [l:<long_desc>] - adds a new NPC to the database, <mob_id> must be unique
61* add item <item_id> n:<name> [l:<long_desc>] - adds a new item to the database, <item_id> must be unique
62* add skill <skill_id> n:<name> - adds a new skill to the database, <skill_id> must be unique
63
64* add mob location <mob_id> [a:<area_name>] [r:<room_name_or_number>] - adds a new NPC location to the database
65* add item location <item_id> [a:<area_name>] [m:<mob_id>] [r:<room_name_or_number>] - adds a new item location to the database
66* add trainer <skill_id> <mob_id> - adds a new trainer for the skill
67
68> deletions:
69
70* delete mob <mob_id> - removes an NPC from the database
71* delete item <item_id> - removes an item from the database
72* delete skill <skill_id> - removes a skill from the database
73
74* delete mob location <mob_id> [a:<area_name>] [r:<room_name_or_number>] - removes an NPC's location from the database
75* delete item location <item_id> [a:<area_name>] [m:<mob_id>] [r:<room_name_or_number>] - removes an item's location from the database
76* delete trainer <skill_id> <mob_id> - removes a trainer for the skill from the database
77
78
79Author: Ruthgul
80
81Latest version:
82http://tinyurl.com/mushclient-scripts
83http://dl.dropbox.com/u/65599194/html/Scripts_for_MUSHclient.html
84
85]]>
86
87</description>
88
89</plugin>
90
91
92
93<!-- Aliases -->
94
95<aliases>
96
97<!-- toggles -->
98
99 <alias
100 enabled="y"
101 match="^add[ ]+mxp(|[ ]+(?P<status>(on|off)))$"
102 regexp="y"
103 send_to="12"
104 sequence="100"
105 >
106 <send>toggle_add_mxp("%<status>")
107</send>
108 </alias>
109
110 <alias
111 enabled="y"
112 match="^add[ ]+mxp[ ]+1stock(|[ ]+(?P<status>(on|off)))$"
113 regexp="y"
114 send_to="12"
115 sequence="100"
116 >
117 <send>toggle_add_mxp_1stock("%<status>")
118</send>
119 </alias>
120
121 <alias
122 enabled="y"
123 match="^add[ ]+mxp[ ]+ground(|[ ]+(?P<status>(on|off)))$"
124 regexp="y"
125 send_to="12"
126 sequence="100"
127 >
128 <send>toggle_add_mxp_ground("%<status>")
129</send>
130 </alias>
131
132
133<!-- additions -->
134
135 <alias
136 enabled="y"
137 match="^add mob (?P<id>[^\:]+) n\:(?P<name>[^\:]+)(| l\:(?P<long>[^\:]+))$"
138 regexp="y"
139 send_to="12"
140 sequence="100"
141 >
142 <send>add_mob("%<id>", "%<name>", "%<long>", false)
143</send>
144 </alias>
145
146 <alias
147 enabled="y"
148 match="^add item (?P<id>[^\:]+) n\:(?P<name>[^\:]+)(| l\:(?P<long>[^\:]+))$"
149 regexp="y"
150 send_to="12"
151 sequence="100"
152 >
153 <send>add_item("%<id>", "%<name>", "%<long>", false)
154</send>
155 </alias>
156
157 <alias
158 enabled="y"
159 match="^add skill (?P<id>[^\:]+) n\:(?P<name>[^\:]+)$"
160 regexp="y"
161 send_to="12"
162 sequence="100"
163 >
164 <send>add_skill("%<name>", "%<id>")
165</send>
166 </alias>
167
168
169<!-- ... locations -->
170
171 <alias
172 enabled="y"
173 match="^add mob loc(|ation) (?P<mobid>[^\:]+)(| a\:(?P<area>[^\:]+))(| r\:(?P<room>[^\:]+))$"
174 regexp="y"
175 send_to="12"
176 sequence="100"
177 >
178 <send>add_mob_location("%<mobid>", "%<area>", "%<room>", false)
179</send>
180 </alias>
181
182 <alias
183 enabled="y"
184 match="^add item loc(|ation) (?P<itemid>[^\:]+)(| a\:(?P<area>[^\:]+))(| m\:(?P<mobid>[^\:]+))(| r\:(?P<room>[^\:]+))$"
185 regexp="y"
186 send_to="12"
187 sequence="100"
188 >
189 <send>add_item_location("%<itemid>", "%<area>", "%<mobid>", "%<room>", false)
190</send>
191 </alias>
192
193 <alias
194 enabled="y"
195 match="^add trainer (?P<skillid>[^\:]+) (?P<mobid>[^\:]+)$"
196 regexp="y"
197 send_to="12"
198 sequence="100"
199 >
200 <send>add_skill_trainer("%<skillid>", "%<mobid>")
201</send>
202 </alias>
203
204
205<!-- deletions -->
206
207 <alias
208 enabled="y"
209 match="^del(|ete) mob (?P<id>[^\:]+)$"
210 regexp="y"
211 send_to="12"
212 sequence="100"
213 >
214 <send>del_mob("%<id>")
215</send>
216 </alias>
217
218 <alias
219 enabled="y"
220 match="^del(|ete) item (?P<id>[^\:]+)$"
221 regexp="y"
222 send_to="12"
223 sequence="100"
224 >
225 <send>del_item("%<id>")
226</send>
227 </alias>
228
229 <alias
230 enabled="y"
231 match="^del(|ete) skill (?P<id>[^\:]+)$"
232 regexp="y"
233 send_to="12"
234 sequence="100"
235 >
236 <send>del_skill("%<id>")
237</send>
238 </alias>
239
240
241<!-- ... locations -->
242
243 <alias
244 enabled="y"
245 match="^del(|ete) mob loc(|ation) (?P<mobid>[^\:]+)(| a\:(?P<area>[^\:]+))(| r\:(?P<room>[^\:]+))$"
246 regexp="y"
247 send_to="12"
248 sequence="100"
249 >
250 <send>del_mob_location("%<mobid>", "%<area>", "%<room>")
251</send>
252 </alias>
253
254 <alias
255 enabled="y"
256 match="^del(|ete) item loc(|ation) (?P<itemid>[^\:]+)(| a\:(?P<area>[^\:]+))(| m\:(?P<mobid>[^\:]+))(| r\:(?P<room>[^\:]+))$"
257 regexp="y"
258 send_to="12"
259 sequence="100"
260 >
261 <send>del_item_location("%<itemid>", "%<area>", "%<mobid>", "%<room>")
262</send>
263 </alias>
264
265 <alias
266 enabled="y"
267 match="^del(|ete) trainer (?P<skillid>[^\:]+) (?P<mobid>[^\:]+)$"
268 regexp="y"
269 send_to="12"
270 sequence="100"
271 >
272 <send>del_skill_trainer("%<skillid>", "%<mobid>")
273</send>
274 </alias>
275
276
277<!-- queries -->
278
279 <alias
280 enabled="y"
281 match="^mob wheree (?P<name>[^\:]+)(| a\:(?P<area>[^\:]+))$"
282 regexp="y"
283 send_to="12"
284 sequence="100"
285 >
286 <send>find_npc("%<name>", "%<area>", false)
287</send>
288 </alias>
289
290 <alias
291 enabled="y"
292 match="^mob where (?P<name>[^\:]+)(| a\:(?P<area>[^\:]+))$"
293 regexp="y"
294 send_to="12"
295 sequence="100"
296 >
297 <send>find_npc("%<name>", "%<area>", true)
298</send>
299 </alias>
300
301 <alias
302 enabled="y"
303 match="^item wheree (?P<name>[^\:]+)(| a\:(?P<area>[^\:]+))$"
304 regexp="y"
305 send_to="12"
306 sequence="100"
307 >
308 <send>find_item("%<name>", "%<area>", false)
309</send>
310 </alias>
311
312 <alias
313 enabled="y"
314 match="^item where (?P<name>[^\:]+)(| a\:(?P<area>[^\:]+))$"
315 regexp="y"
316 send_to="12"
317 sequence="100"
318 >
319 <send>find_item("%<name>", "%<area>", true)
320</send>
321 </alias>
322
323 <alias
324 enabled="y"
325 match="^skill wheree (?P<name>[^\:]+)(| a\:(?P<area>[^\:]+))$"
326 regexp="y"
327 send_to="12"
328 sequence="100"
329 >
330 <send>find_skill("%<name>", "%<area>", false)
331</send>
332 </alias>
333
334 <alias
335 enabled="y"
336 match="^skill where (?P<name>[^\:]+)(| a\:(?P<area>[^\:]+))$"
337 regexp="y"
338 send_to="12"
339 sequence="100"
340 >
341 <send>find_skill("%<name>", "%<area>", true)
342</send>
343 </alias>
344
345
346<!-- Plugin help -->
347
348 <alias
349 enabled="y"
350 match="^mobs\_n\_items(|( |\:)help)$"
351 regexp="y"
352 script="OnHelp"
353 >
354 </alias>
355
356</aliases>
357
358
359
360<!-- Triggers -->
361
362<triggers>
363
364 <trigger
365 enabled="y"
366 keep_evaluating="y"
367 match="^[ ]*[0-9]+\) (.+) [0-9]+ [ ]* (?P<amount>(No limit|[0-9\,]+)) [ ]+\[[ ]*[0-9\,]+ (|gp)\]$"
368 regexp="y"
369 send_to="12"
370 sequence="100"
371 >
372 <send>add_item_if_stock("%<amount>")
373</send>
374 </trigger>
375
376</triggers>
377
378
379
380<!-- Scripts -->
381
382<script>
383
384<![CDATA[
385
386require "serialize"
387
388
389-----------------
390-- plugin stuff
391-----------------
392
393function OnPluginInstall()
394 Tell("-- " .. GetPluginInfo(GetPluginID(), 1) .. ": type ")
395 ColourTell("silver", "black", GetPluginInfo(GetPluginID(), 1) .. " help")
396 Note(" to see info about this plugin --")
397
398 -- open databases on disk
399 db = assert(sqlite3.open(GetInfo(66) .. "mm_mobs_n_items.db"))
400
401 create_tables() -- create database structure if necessary
402
403 init_vars()
404end
405
406
407function OnPluginDisconnect ()
408 update_hits()
409end
410
411
412function OnHelp()
413 ColourNote("silver", "black", world.GetPluginInfo(world.GetPluginID(), 3))
414 Note("")
415 ColourNote("silver", "black", "(this version: " .. os.date("%c", GetPluginInfo(GetPluginID(), 14)) .. ")")
416end
417
418
419function plugin_update_url()
420 local t = {
421 "http://dl.dropbox.com/u/65599194/mm-updater/mobs_n_items.xml",
422 }
423 return (table.concat(t, ";"))
424end
425
426
427
428-----------------
429-- config stuff
430-----------------
431
432function init_vars()
433 gmcp_initialized = false
434
435 load_config()
436
437 mobs_locations_cache = {}
438 items_locations_cache = {}
439end
440
441
442function load_config()
443 config = {
444 addMXP = ((GetVariable("addMXP") or "false") == "true"),
445 addMXP1stock = ((GetVariable("addMXP1stock") or "false") == "true"),
446 addMXPground = ((GetVariable("addMXPground") or "true") == "true"),
447 }
448end
449
450
451function toggle_add_mxp(status)
452 config.addMXP = do_toggle(config.addMXP, status)
453 save_config()
454
455 if (config.addMXP) then
456 Note("-- mobs_n_items: will now auto-add mobs and items via MXP --")
457
458 else
459 Note("-- mobs_n_items: will no longer auto-add mobs and items via MXP --")
460
461 -- clear caches
462 mobs_locations_cache = {}
463 items_locations_cache = {}
464 end
465end
466
467
468function toggle_add_mxp_1stock(status)
469 config.addMXP1stock = do_toggle(config.addMXP1stock, status)
470 save_config()
471
472 if (config.addMXP1stock) then
473 Note("-- mobs_n_items: will now auto-add 1-stock shop items via MXP --")
474
475 else
476 Note("-- mobs_n_items: will no longer auto-add 1-stock shop items via MXP --")
477 end
478end
479
480
481function toggle_add_mxp_ground(status)
482 config.addMXPground = do_toggle(config.addMXPground, status)
483 save_config()
484
485 if (config.addMXPground) then
486 Note("-- mobs_n_items: will now auto-add items on the ground via MXP --")
487
488 else
489 Note("-- mobs_n_items: will no longer auto-add items on the ground via MXP --")
490 end
491end
492
493
494function do_toggle(var, status)
495 if (status == "on") then
496 var = true
497 elseif (status == "off") then
498 var = false
499 else
500 var = not var
501 end
502
503 return var
504end
505
506
507function save_config()
508 SetVariable("addMXP", tostring(config.addMXP))
509 SetVariable("addMXP1stock", tostring(config.addMXP1stock))
510 SetVariable("addMXPground", tostring(config.addMXPground))
511
512 SaveState()
513end
514
515
516
517------------------
518-- general stuff
519------------------
520
521function uncapitalize(name)
522 if (not name) then
523 return
524 end
525
526 if (name == "") then
527 return ""
528 end
529
530 local c = string.lower(string.sub(name, 1, 1))
531 if (string.len(name) == 1) then
532 return c
533 end
534
535 local res = c .. string.sub(name, 2, string.len(name))
536 return res
537end
538
539
540function is_in_table(t, item)
541 local res = false
542
543 for i = 1, #t do
544 if (string.upper(t[i]) == string.upper(item)) then
545 -- not case sensitive
546 res = true
547 break
548 end
549 end
550
551 return res
552end
553
554
555
556-------------------
557-- database stuff
558-------------------
559
560function dbcheck(code)
561 if code ~= sqlite3.OK and -- no error
562 code ~= sqlite3.ROW and -- completed OK with another row of data
563 code ~= sqlite3.DONE then -- completed OK, no more rows
564 local err = db:errmsg() -- the rollback will change the error message
565 db:exec("ROLLBACK") -- rollback any transaction to unlock the database
566 error(err, 2) -- show error in caller's context
567 end
568end
569
570
571function fixsql(s)
572 if s then
573 return "'" .. (string.gsub(s, "'", "''")) .. "'" -- replace single quotes with two lots of single quotes
574 else
575 return "NULL"
576 end
577end
578
579
580function create_tables()
581 -- create table
582 dbcheck(db:execute[[
583 PRAGMA foreign_keys = ON;
584 PRAGMA journal_mode = WAL;
585
586 CREATE TABLE IF NOT EXISTS mobs(
587 id INTEGER PRIMARY KEY AUTOINCREMENT,
588 mobid TEXT, -- NPC's unique id
589 name TEXT NOT NULL, -- name of the NPC
590 long_desc TEXT, -- name as it appears in the room
591 date_added DATE,
592 UNIQUE(mobid)
593 );
594
595 CREATE TABLE IF NOT EXISTS mobsloc(
596 id INTEGER PRIMARY KEY AUTOINCREMENT,
597 mobid TEXT NOT NULL, -- NPC's unique id
598 area TEXT, -- name of the area
599 room TEXT, -- name of the room where it pops
600 hits INTEGER, -- times the NPC has been seen in the room
601 date_added DATE
602 );
603
604
605 CREATE TABLE IF NOT EXISTS items(
606 id INTEGER PRIMARY KEY AUTOINCREMENT,
607 itemid TEXT, -- item's unique id
608 name TEXT NOT NULL, -- name of the item
609 long_desc TEXT, -- name as it appears on the ground
610 date_added DATE,
611 UNIQUE(itemid)
612 );
613
614 CREATE TABLE IF NOT EXISTS itemsloc(
615 id INTEGER PRIMARY KEY AUTOINCREMENT,
616 itemid TEXT NOT NULL, -- item's unique id
617 area TEXT, -- name of the area
618 mobid TEXT, -- id of the NPC who carries it, if applicable
619 room TEXT, -- name of the room, if applicable
620 hits INTEGER, -- times the item has been seen in the room
621 date_added DATE
622 );
623
624
625 CREATE TABLE IF NOT EXISTS skills(
626 id INTEGER PRIMARY KEY AUTOINCREMENT,
627 skillid TEXT, -- skill/spell's unique id
628 name TEXT NOT NULL, -- name of the skill or spell
629 date_added DATE,
630 UNIQUE(skillid)
631 );
632
633 CREATE TABLE IF NOT EXISTS skillstrain(
634 id INTEGER PRIMARY KEY AUTOINCREMENT,
635 skillid TEXT NOT NULL, -- skill/spell's unique id
636 mobid TEXT, -- id of the NPC who trains it
637 date_added DATE
638 );
639 ]])
640end
641
642
643
644---------
645-- gmcp
646---------
647
648function OnPluginBroadcast(msg, id, name, text)
649 if (id =="f67c4339ed0591a5b010d05b") then -- GMCP message
650 if (text == "room.info") then -- room.info
651 if (not gmcp_initialized) then
652 gmcp_initialized = true
653 end
654
655 if (config.addMXP) then
656 room = {}
657 room.num = get_gmcp_value("room.info.num")
658 room.zone = get_gmcp_value("room.info.zone")
659 room.name = get_gmcp_value("room.info.name")
660
661 if (not oldzone) then -- first run
662 oldzone = room.zone
663 load_area_hits(room.zone)
664
665 elseif (oldzone ~= room.zone) then -- area changed
666 update_hits()
667 oldzone = room.zone
668 load_area_hits(room.zone)
669 end
670 end
671 end
672 end
673end
674
675
676function get_gmcp_value(name)
677 local res, val
678
679 res, val = CallPlugin("f67c4339ed0591a5b010d05b", "gmcpval", name)
680
681 if (res ~= 0) then
682 val = nil
683 end
684
685 return val
686end
687
688
689
690--------
691-- MXP
692--------
693
694function OnPluginMXPopenTag(name, args, mylist)
695 if (config.addMXP) then
696 if (not entity) then
697 entity = {}
698 end
699
700 if (string.find(name, "get") == 1) then -- item on the ground
701 entity.short, _ = string.match(name, 'get, name="(.+)" desc="(.+)"')
702 entity.type = "item"
703
704 elseif (string.find(name, "shop") == 1) then -- item sold in a shop
705 _, entity.short = string.match(name, 'shop, name=(.+) desc="(.+)"')
706 entity.type = "item"
707
708 -- items in inventory are 'drop, ...'
709
710 elseif (string.find(name, "pers") == 1) then -- NPC or player
711 entity.short, _ = string.match(name, 'pers, name="(.+)" desc="(.+)"')
712 entity.type = "npc"
713
714 else
715-- AppendToNotepad("MXP", "Opening tag: " .. name .. "\r\n\r\n")
716 end
717 end
718end
719
720
721function OnPluginMXPcloseTag(name, text)
722 local ground = false
723 local shop = false
724
725 if (not entity) then
726 entity = {}
727 end
728
729 if (config.addMXP) then
730 if (string.find(name, "get") == 1) then -- item on the ground
731 ground = true
732 entity.long = string.match(name, "get,(.+)")
733
734 elseif (string.find(name, "shop") == 1) then -- iten sold in a shop
735 shop = true
736 entity.long = string.match(name, "shop,(.+)")
737
738 elseif (string.find(name, "pers") == 1) then -- NPC or player
739 entity.long = string.match(name, "pers,(.+)")
740
741 else
742-- AppendToNotepad("mxp", "Closing tag: " .. name .. "\r\n\r\n")
743 end
744
745 if (entity.short) and (entity.long) then
746 if (entity.type == "npc") then
747 add_npc_if_new()
748
749 elseif (entity.type == "item") then
750 if (not shop) -- shop items are added by add_item_if_stock()
751 and ((not ground) or (config.addMXPground)) then -- add items on the ground?
752 add_item_if_new()
753 end
754 end
755 end
756 end
757end
758
759
760function add_npc_if_new()
761 if (gmcp_initialized) and (room) and (entity) then
762 if (not is_player(entity.short, entity.long))
763 and (not is_player_built_area(room.zone)) then
764 local hash = Hash(string.lower(entity.short) .. entity.long .. room.zone)
765
766 if (mobs_locations_cache[hash]) then
767 if (mobs_locations_cache[hash][room.zone .. '|' .. room.name]) then
768 mobs_locations_cache[hash][room.zone .. '|' .. room.name].hits = mobs_locations_cache[hash][room.zone .. '|' .. room.name].hits + 1
769 mobs_locations_cache[hash][room.zone .. '|' .. room.name].changed = true
770
771 else
772 add_mob_location(hash, room.zone, room.name, true)
773 mobs_locations_cache[hash][room.zone .. '|' .. room.name] = {
774 hits = 1,
775 changed = true,
776 }
777 end
778
779 else
780 add_mob(hash, entity.short, entity.long, true)
781 add_mob_location(hash, room.zone, room.name, true)
782 mobs_locations_cache[hash] = {}
783 mobs_locations_cache[hash][room.zone .. '|' .. room.name] = {
784 hits = 1,
785 changed = true,
786 }
787 end
788 end
789
790 entity = nil
791 end
792end
793
794
795function add_item_if_stock(amount)
796-- shop items are checked vs stock, to avoid ading items sold by players
797 if (config.addMXP) then
798-- Note(amount)
799
800 local num = string.gsub(amount, ",", "")
801 num = tonumber(num)
802
803 if (amount == "No limit")
804 or (config.addMXP1stock)
805 or ((num) and (num > 1)) then
806-- Note("add_item_if_stock()")
807 add_item_if_new()
808
809 elseif (num == 1) then
810 entity = nil
811 end
812 end
813end
814
815
816function add_item_if_new()
817 if (gmcp_initialized) and (room) and (entity) then
818 if (not is_player_built_area(room.zone))
819 and (not is_donation(room.num)) then
820 local hash = Hash(entity.short .. entity.long .. room.zone)
821
822 if (items_locations_cache[hash]) then
823 if (items_locations_cache[hash][room.zone .. '|' .. room.name]) then
824 items_locations_cache[hash][room.zone .. '|' .. room.name].hits = items_locations_cache[hash][room.zone .. '|' .. room.name].hits + 1
825 items_locations_cache[hash][room.zone .. '|' .. room.name].changed = true
826
827 else
828 add_item_location(hash, room.zone, "", room.name, true)
829 items_locations_cache[hash][room.zone .. '|' .. room.name] = {
830 hits = 1,
831 changed = true,
832 }
833 end
834
835 else
836 add_item(hash, entity.short, entity.long, true)
837 add_item_location(hash, room.zone, "", room.name, true)
838 items_locations_cache[hash] = {}
839 items_locations_cache[hash][room.zone .. '|' .. room.name] = {
840 hits = 1,
841 changed = true,
842 }
843 end
844 end
845
846 entity = nil
847 end
848end
849
850
851function is_player(short, long)
852 local res = false
853
854 local t = utils.split(short, " ")
855 if (#t == 1) and (short == long) then -- it's a player
856 res = true
857 end
858
859 return res
860end
861
862
863function is_player_built_area(zone)
864 local res = false
865
866 if (string.find(zone, "Clan Hall"))
867 or (string.find(zone, "Player Homes")) then
868 res = true
869 end
870
871 return res
872end
873
874
875function is_donation(uid)
876 local donation_rooms = {
877 ["10440"] = "x", -- Rune
878 ["11424"] = "x", -- Lasler
879 ["28079"] = "x", -- Sigil
880 ["41663"] = "x", -- Tellerium
881 ["61078"] = "x", -- Irda
882 ["63054"] = "x", -- New Rigel
883 ["68037"] = "x", -- Maldra Keep
884 ["73977"] = "x", -- Xaventry
885 ["946210"] = "x", -- Rune Forest
886 }
887
888 return (donation_rooms[uid] == "x")
889end
890
891
892
893-----------------------
894-- read from database
895-----------------------
896
897function load_mob_from_database(id)
898 local mob, loc
899
900 for row in db:nrows(string.format("SELECT * FROM mobs WHERE mobid = %s", fixsql(id))) do
901 mob = {
902 mobid = row.mobid,
903 name = row.name,
904 long_desc = row.long_desc,
905 roomnums = {},
906 locations = {},
907 }
908 end
909
910 for row in db:nrows(string.format("SELECT * FROM mobsloc WHERE mobid = %s", fixsql(id))) do
911 if (tonumber(row.room)) then -- room is a number? => it's a GMCP number
912 mob.roomnums[#mob.roomnums + 1] = tonumber(row.room)
913
914 else -- otherwise, it's a room (+ area) name
915 loc = {
916 area = row.area,
917 room = row.room,
918 hits = row.hits or 0,
919 }
920
921 mob.locations = insert_sorted(mob.locations, loc)
922 end
923 end
924
925 if (mob) and (config.addMXP) then
926 add_mob_to_locations_cache(mob)
927 end
928
929 return mob
930end
931
932
933function load_item_from_database(id)
934 local item
935
936 for row in db:nrows(string.format("SELECT * FROM items WHERE itemid = %s", fixsql(id))) do
937 item = {
938 itemid = row.itemid,
939 name = row.name,
940 long_desc = row.long_desc,
941 locations = {},
942 }
943 end
944
945 for row in db:nrows(string.format("SELECT * FROM itemsloc WHERE itemid = %s", fixsql(id))) do
946 loc = {
947 area = row.area,
948 mobid = row.mobid,
949 room = row.room,
950 hits = row.hits or 0,
951 }
952
953 item.locations = insert_sorted(item.locations, loc)
954 end
955
956 if (item) and (config.addMXP) then
957 add_item_to_locations_cache(item)
958 end
959
960 return item
961end
962
963
964function insert_sorted(locations, aloc)
965-- inserts aloc in the locations table, sorted by hits (reverse order)
966 local inserted = false
967
968 for i = 1, #locations do
969 if (aloc.hits > locations[i].hits) then
970 table.insert(locations, i, aloc)
971 inserted = true
972 break
973 end
974 end
975
976 if (not inserted) then -- append it
977 table.insert(locations, aloc)
978 end
979
980 return locations
981end
982
983
984function load_skill_from_database(id)
985 local skill
986
987 for row in db:nrows(string.format("SELECT * FROM skills WHERE skillid = %s", fixsql(id))) do
988 skill = {
989 skillid = row.skillid,
990 name = row.name,
991 trainers = {},
992 }
993 end
994
995 for row in db:nrows(string.format("SELECT * FROM skillstrain WHERE skillid = %s", fixsql(id))) do
996 skill.trainers[#skill.trainers + 1] = row.mobid
997 end
998
999 return skill
1000end
1001
1002
1003function add_mob_to_locations_cache(mob)
1004 mobs_locations_cache[mob.mobid] = {}
1005
1006 local loc
1007
1008 for i = 1, #mob.locations do
1009 loc = mob.locations[i]
1010
1011 mobs_locations_cache[mob.mobid][(loc.area or "") .. '|' .. (loc.room or "")] = {
1012 hits = loc.hits or 0,
1013 changed = false,
1014 }
1015 end
1016end
1017
1018
1019function add_item_to_locations_cache(item)
1020 items_locations_cache[item.itemid] = {}
1021
1022 local loc
1023
1024 for i = 1, #item.locations do
1025 if (area ~= "") or (room ~= "") then
1026 loc = item.locations[i]
1027
1028 items_locations_cache[item.itemid][(loc.area or "") .. '|' .. (loc.room or "")] = {
1029 hits = loc.hits or 0,
1030 changed = false,
1031 }
1032 end
1033 end
1034end
1035
1036
1037function load_area_hits(zone)
1038 load_mobs_hits(zone)
1039 load_items_hits(zone)
1040end
1041
1042
1043function load_mobs_hits(zone)
1044 -- mobs_n_items: loading mobs locations hits for the area... --
1045
1046 mobs_locations_cache = {}
1047
1048 for row in db:nrows(string.format("SELECT * FROM mobsloc WHERE area = %s", fixsql(zone))) do
1049 if (not mobs_locations_cache[row.mobid]) then
1050 mobs_locations_cache[row.mobid] = {}
1051 end
1052
1053 mobs_locations_cache[row.mobid][(row.area or "") .. '|' .. (row.room or "")] = {
1054 hits = row.hits or 0,
1055 changed = false,
1056 }
1057 end
1058end
1059
1060
1061function load_items_hits(zone)
1062 Note("-- mobs_n_items: loading items locations hits for the area... --")
1063
1064 items_locations_cache = {}
1065
1066 for row in db:nrows(string.format("SELECT * FROM itemsloc WHERE area = %s", fixsql(zone))) do
1067 if (row.area ~= "") or (row.room ~= "") then
1068 if (not items_locations_cache[row.itemid]) then
1069 items_locations_cache[row.itemid] = {}
1070 end
1071
1072 items_locations_cache[row.itemid][(row.area or "") .. '|' .. (row.room or "")] = {
1073 hits = row.hits or 0,
1074 changed = false,
1075 }
1076 end
1077 end
1078end
1079
1080
1081
1082------------------------------
1083-- add NPCs / items / skills
1084------------------------------
1085
1086function add_mob(mobid, name, long_desc, auto)
1087 local mob = load_mob_from_database(mobid)
1088
1089 if (mob) then
1090 if (name == mob.name) and (long_desc == mob.long_desc) then
1091 if (not auto) then
1092 ColourNote("red", "black", "-- mobs_n_items: the NPC #" .. mobid .. " is already in my db --")
1093 end
1094
1095 mobid = nil
1096
1097 else
1098 update_mob_database_info(mobid, name, long_desc)
1099 end
1100
1101 else
1102 save_mob_to_database(mobid, name, long_desc)
1103 end
1104
1105 return mobid
1106end
1107
1108
1109function add_item(itemid, name, long_desc, auto)
1110 local item = load_item_from_database(itemid)
1111
1112 if (item) then
1113 if (name == item.name) and (long_desc == item.long_desc) then
1114 if (not auto) then
1115 ColourNote("red", "black", "-- mobs_n_items: the item #" .. itemid .. " is already in my db --")
1116 end
1117
1118 itemid = nil
1119
1120 else
1121 update_item_database_info(itemid, name, long_desc)
1122 end
1123
1124 else
1125 save_item_to_database(itemid, name, long_desc)
1126 end
1127
1128 return itemid
1129end
1130
1131
1132function add_skill(name, skillid)
1133 local skill = load_skill_from_database(skillid)
1134
1135 if (skill) then
1136 if (name == skill.name) then
1137-- ColourNote("red", "black", "-- mobs_n_items: the skill/spell #" .. skillid .. " is already in my db --")
1138 skillid = nil
1139
1140 else
1141 update_skill_database_info(skillid, name)
1142 end
1143
1144 else
1145 save_skill_to_database(skillid, name)
1146 end
1147
1148 return skillid
1149end
1150
1151
1152function save_mob_to_database(mobid, name, long_desc)
1153 db:exec("BEGIN TRANSACTION;")
1154
1155 dbcheck(db:execute(string.format(
1156 "INSERT INTO mobs(mobid, name, long_desc, date_added) VALUES(%s, %s, %s, DATETIME('NOW'));",
1157 fixsql(mobid),
1158 fixsql(name),
1159 fixsql(long_desc)
1160 )))
1161
1162 db:exec("COMMIT;")
1163
1164 Note("-- mobs_n_items: added NPC #" .. mobid .. ": " .. name .. " to db --")
1165end
1166
1167
1168function save_item_to_database(itemid, name, long_desc)
1169 db:exec("BEGIN TRANSACTION;")
1170
1171 dbcheck(db:execute(string.format(
1172 "INSERT INTO items(itemid, name, long_desc, date_added) VALUES(%s, %s, %s, DATETIME('NOW'));",
1173 fixsql(itemid),
1174 fixsql(name),
1175 fixsql(long_desc)
1176 )))
1177
1178 db:exec("COMMIT;")
1179
1180 Note("-- mobs_n_items: added item #" .. itemid .. ": " .. name .. " to db --")
1181end
1182
1183
1184function save_skill_to_database(skillid, name)
1185 db:exec("BEGIN TRANSACTION;")
1186
1187 dbcheck(db:execute(string.format(
1188 "INSERT INTO skills(skillid, name, date_added) VALUES(%s, %s, DATETIME('NOW'));",
1189 fixsql(skillid),
1190 fixsql(name)
1191 )))
1192
1193 db:exec("COMMIT;")
1194
1195 Note("-- mobs_n_items: added skill #" .. skillid .. ": " .. name .. " to db --")
1196end
1197
1198
1199
1200---------------------------------
1201-- update NPCs / items / skills
1202---------------------------------
1203
1204function update_mob_database_info(mobid, name, long_desc)
1205 db:exec("BEGIN TRANSACTION;")
1206
1207 dbcheck(db:execute(string.format(
1208 "UPDATE mobs SET name = %s, long_desc = %s WHERE mobid = %s;",
1209 fixsql(name),
1210 fixsql(long_desc),
1211 fixsql(mobid)
1212 )))
1213
1214 db:exec("COMMIT;")
1215
1216 Note("-- mobs_n_items: updated db info for NPC #" .. mobid .. ": " .. name .. " --")
1217end
1218
1219
1220function update_item_database_info(itemid, name, long_desc)
1221 db:exec("BEGIN TRANSACTION;")
1222
1223 dbcheck(db:execute(string.format(
1224 "UPDATE items SET name = %s, long_desc = %s WHERE itemid = %s;",
1225 fixsql(name),
1226 fixsql(long_desc),
1227 fixsql(itemid)
1228 )))
1229
1230 db:exec("COMMIT;")
1231
1232 Note("-- mobs_n_items: updated db info for item #" .. itemid .. ": " .. name .. " --")
1233end
1234
1235
1236function update_skill_database_info(skillid, name)
1237 db:exec("BEGIN TRANSACTION;")
1238
1239 dbcheck(db:execute(string.format(
1240 "UPDATE skills SET name = %s WHERE skillid = %s;",
1241 fixsql(name),
1242 fixsql(skillid)
1243 )))
1244
1245 db:exec("COMMIT;")
1246
1247 Note("-- mobs_n_items: updated db info for skill #" .. skillid .. ": " .. name .. " --")
1248end
1249
1250
1251
1252---------------------------------
1253-- delete NPCs / items / skills
1254---------------------------------
1255
1256function del_mob(mobid)
1257 local mob = load_mob_from_database(mobid)
1258
1259 if (mob) then
1260 del_mob_from_database(mobid)
1261
1262 else
1263 ColourNote("red", "black", "-- mobs_n_items: the NPC #" .. mobid .. " isn't in my db --")
1264 end
1265end
1266
1267
1268function del_item(itemid)
1269 local item = load_item_from_database(itemid)
1270
1271 if (item) then
1272 del_item_from_database(itemid)
1273
1274 else
1275 ColourNote("red", "black", "-- mobs_n_items: the item #" .. itemid .. " isn't in my db --")
1276 end
1277end
1278
1279
1280function del_skill(skillid)
1281 local skill = load_skill_from_database(skillid)
1282
1283 if (skill) then
1284 del_skill_from_database(skillid)
1285
1286 else
1287 ColourNote("red", "black", "-- mobs_n_items: the skill/spell #" .. skillid .. " isn't in my db --")
1288 end
1289end
1290
1291
1292function del_mob_from_database(mobid)
1293 db:exec("BEGIN TRANSACTION;")
1294
1295 -- delete NPC
1296 dbcheck(db:execute(string.format(
1297 "DELETE FROM mobs WHERE mobid = %s;",
1298 fixsql(mobid)
1299 )))
1300
1301 -- delete locations
1302 dbcheck(db:execute(string.format(
1303 "DELETE FROM mobsloc WHERE mobid = %s;",
1304 fixsql(mobid)
1305 )))
1306
1307 db:exec("COMMIT;")
1308
1309 Note("-- mobs_n_items: removed NPC #" .. mobid .. " from db --")
1310end
1311
1312
1313function del_item_from_database(itemid)
1314 db:exec("BEGIN TRANSACTION;")
1315
1316 -- delete item
1317 dbcheck(db:execute(string.format(
1318 "DELETE FROM items WHERE itemid = %s;",
1319 fixsql(itemid)
1320 )))
1321
1322 -- delete locations
1323 dbcheck(db:execute(string.format(
1324 "DELETE FROM itemsloc WHERE itemid = %s;",
1325 fixsql(itemid)
1326 )))
1327
1328 db:exec("COMMIT;")
1329
1330 Note("-- mobs_n_items: removed item #" .. itemid .. " from db --")
1331end
1332
1333
1334function del_skill_from_database(skillid)
1335 db:exec("BEGIN TRANSACTION;")
1336
1337 -- delete skill
1338 dbcheck(db:execute(string.format(
1339 "DELETE FROM skills WHERE skillid = %s;",
1340 fixsql(skillid)
1341 )))
1342
1343 -- delete trainers
1344 dbcheck(db:execute(string.format(
1345 "DELETE FROM skillstrain WHERE skillid = %s;",
1346 fixsql(skillid)
1347 )))
1348
1349 db:exec("COMMIT;")
1350
1351 Note("-- mobs_n_items: removed skill #" .. skillid .. " from db --")
1352end
1353
1354
1355
1356------------------
1357-- add locations
1358------------------
1359
1360function add_mob_location(mobid, area, room, auto)
1361 local res = {}
1362
1363 if (tonumber(room)) or (area ~= "") then
1364 for row in db:nrows(string.format("SELECT * FROM mobsloc WHERE mobid = %s", fixsql(mobid))) do
1365 if (string.upper(room) == string.upper(row.room))
1366 and (string.upper(area) == string.upper(row.area)) then
1367 res[#res + 1] = row.mobid
1368 end
1369 end
1370
1371 if (#res > 0) then
1372 if (not auto) then
1373 ColourNote("red", "black", "-- mobs_n_items: the NPC location is already in my db --")
1374 end
1375
1376 else
1377 save_mob_location_to_database(mobid, area, room, 1)
1378 end
1379
1380 else
1381 ColourNote("red", "black", "-- mobs_n_items: please provide either a room #, or [an] area [+ room] name[s] --")
1382 end
1383end
1384
1385
1386function add_item_location(itemid, area, mobid, room, auto)
1387 local res = {}
1388
1389 if (mobid) or (tonumber(room)) or (area ~= "") then
1390 for row in db:nrows(string.format("SELECT * FROM itemsloc WHERE itemid = %s", fixsql(itemid))) do
1391 if (mobid == row.mobid)
1392 and (string.upper(area) == string.upper(row.area))
1393 and (string.upper(room) == string.upper(row.room)) then
1394 res[#res + 1] = row.itemid
1395 end
1396 end
1397
1398 if (#res > 0) then
1399 if (not auto) then
1400 ColourNote("red", "black", "-- mobs_n_items: the item location is already in my db --")
1401 end
1402
1403 else
1404 save_item_location_to_database(itemid, area, mobid, room, 1)
1405 end
1406
1407 else
1408 ColourNote("red", "black", "-- mobs_n_items: please provide either a npc_id, or a room #, or [an] area [+ room] name[s] --")
1409 end
1410end
1411
1412
1413function add_skill_trainer(skillid, mobid)
1414 local res = {}
1415
1416 if (tonumber(skillid)) then -- sanity check, is it a # or a name?
1417 if (tonumber(mobid)) then
1418 for row in db:nrows(string.format("SELECT * FROM skillstrain WHERE skillid = %s", fixsql(skillid))) do
1419 if (mobid == row.mobid) then
1420 res[#res + 1] = row.skillid
1421 end
1422 end
1423
1424 if (#res > 0) then
1425-- ColourNote("red", "black", "-- mobs_n_items: the skill/spell trainer is already in my db --")
1426
1427 else
1428 save_skill_trainer_to_database(skillid, mobid)
1429 end
1430
1431 else -- mobid is not a number
1432 ColourNote("red", "black", "-- mobs_n_items: please provide an npc_id --")
1433 end
1434
1435 else -- skillid is not a number
1436 ColourNote("yellow", "black", "-- mobs_n_items: skill_id must be a number! --")
1437 end
1438end
1439
1440
1441function save_mob_location_to_database(mobid, area, room, hits)
1442 db:exec("BEGIN TRANSACTION;")
1443
1444 dbcheck(db:execute(string.format(
1445 "INSERT INTO mobsloc(mobid, area, room, hits, date_added) VALUES(%s, %s, %s, %i, DATETIME('NOW'));",
1446 fixsql(mobid),
1447 fixsql(area),
1448 fixsql(room),
1449 hits
1450 )))
1451
1452 db:exec("COMMIT;")
1453
1454 Note("-- mobs_n_items: added location for mob #" .. mobid .. " to db --")
1455end
1456
1457
1458function save_item_location_to_database(itemid, area, mobid, room, hits)
1459 db:exec("BEGIN TRANSACTION;")
1460
1461 dbcheck(db:execute(string.format(
1462 "INSERT INTO itemsloc(itemid, area, mobid, room, hits, date_added) VALUES(%s, %s, %s, %s, %i, DATETIME('NOW'));",
1463 fixsql(itemid),
1464 fixsql(area),
1465 fixsql(mobid),
1466 fixsql(room),
1467 hits
1468 )))
1469
1470 db:exec("COMMIT;")
1471
1472 Note("-- mobs_n_items: added location for item #" .. itemid .. " to db --")
1473end
1474
1475
1476function save_skill_trainer_to_database(skillid, mobid)
1477 db:exec("BEGIN TRANSACTION;")
1478
1479 dbcheck(db:execute(string.format(
1480 "INSERT INTO skillstrain(skillid, mobid, date_added) VALUES(%s, %s, DATETIME('NOW'));",
1481 fixsql(skillid),
1482 fixsql(mobid)
1483 )))
1484
1485 db:exec("COMMIT;")
1486
1487 Note("-- mobs_n_items: added location for skill #" .. skillid .. " to db --")
1488end
1489
1490
1491
1492---------------------
1493-- update locations
1494---------------------
1495
1496function update_hits()
1497 if (config.addMXP) then
1498 update_mobs_hits()
1499 update_items_hits()
1500 end
1501end
1502
1503
1504function update_mobs_hits()
1505 --Note(serialize.save_simple(mobs_locations_cache))
1506
1507 local t
1508
1509 Note("-- mobs_n_items: updating mobs locations hits... --")
1510
1511 db:exec("BEGIN TRANSACTION;")
1512
1513 for mobid, val in pairs(mobs_locations_cache) do
1514 SetStatus("... updating locations hits for mob #" .. mobid .. "...")
1515
1516 for where, hits in pairs(val) do
1517 if (hits.changed) then
1518 t = utils.split(where, "|")
1519 update_mob_locations_database_info(mobid, t[1], t[2], hits.hits)
1520 end
1521 end
1522 end
1523
1524 db:exec("COMMIT;")
1525
1526 SetStatus ("Ready")
1527 Note("... done!")
1528end
1529
1530
1531function update_items_hits()
1532 --Note(serialize.save_simple(items_locations_cache))
1533
1534 local t
1535
1536 Note("-- mobs_n_items: updating items locations hits... --")
1537
1538 db:exec("BEGIN TRANSACTION;")
1539
1540 for itemid, val in pairs(items_locations_cache) do
1541 SetStatus("... updating locations hits for item #" .. itemid .. "...")
1542
1543 for where, hits in pairs(val) do
1544 if (hits.changed) then
1545 t = utils.split(where, "|")
1546 update_item_locations_database_info(itemid, t[1], t[2], hits.hits)
1547 end
1548 end
1549 end
1550
1551 db:exec("COMMIT;")
1552
1553 SetStatus ("Ready")
1554 Note("... done!")
1555end
1556
1557
1558function update_mob_locations_database_info(mobid, area, room, hits)
1559 dbcheck(db:execute(string.format(
1560 "UPDATE mobsloc SET hits = %i WHERE mobid = %s AND area = %s AND room = %s;",
1561 hits,
1562 fixsql(mobid),
1563 fixsql(area),
1564 fixsql(room)
1565 )))
1566end
1567
1568
1569function update_item_locations_database_info(itemid, area, room, hits)
1570 dbcheck(db:execute(string.format(
1571 "UPDATE itemsloc SET hits = %i WHERE itemid = %s AND area = %s AND room = %s;",
1572 hits,
1573 fixsql(itemid),
1574 fixsql(area),
1575 fixsql(room)
1576 )))
1577end
1578
1579
1580
1581---------------------
1582-- delete locations
1583---------------------
1584
1585function del_mob_location(mobid, area, room)
1586 local res = {}
1587
1588 for row in db:nrows(string.format("SELECT * FROM mobsloc WHERE mobid = %s", fixsql(mobid))) do
1589 if (string.upper(room) == string.upper(row.room))
1590 and (string.upper(area) == string.upper(row.area)) then
1591 res[#res + 1] = row.mobid
1592 end
1593 end
1594
1595 if (#res > 0) then
1596 del_mob_location_from_database(mobid, area, room)
1597
1598 else
1599 ColourNote("red", "black", "-- mobs_n_items: the NPC location is not in my db --")
1600 end
1601end
1602
1603
1604function del_item_location(itemid, area, mobid, room)
1605 local res = {}
1606
1607 for row in db:nrows(string.format("SELECT * FROM itemsloc WHERE itemid = %s", fixsql(itemid))) do
1608 if (mobid == row.mobid)
1609 and (string.upper(room) == string.upper(row.room))
1610 and (string.upper(area) == string.upper(row.area)) then
1611 res[#res + 1] = row.mobid
1612 end
1613 end
1614
1615 if (#res > 0) then
1616 del_item_location_from_database(itemid, area, mobid, room)
1617
1618 else
1619 ColourNote("red", "black", "-- mobs_n_items: the item location is not in my db --")
1620 end
1621end
1622
1623
1624function del_skill_trainer(skillid, mobid)
1625 local res = {}
1626
1627 for row in db:nrows(string.format("SELECT * FROM skillstrain WHERE skillid = %s", fixsql(skillid))) do
1628 if (mobid == row.mobid) then
1629 res[#res + 1] = row.mobid
1630 end
1631 end
1632
1633 if (#res > 0) then
1634 del_skill_trainer_from_database(skillid, mobid)
1635
1636 else
1637 ColourNote("red", "black", "-- mobs_n_items: the trainer is not in my db --")
1638 end
1639end
1640
1641
1642function del_mob_location_from_database(mobid, area, room)
1643 db:exec("BEGIN TRANSACTION;")
1644
1645 dbcheck(db:execute(string.format([[
1646 DELETE FROM mobsloc WHERE mobid = %s AND UPPER(area) = %s AND room = %s;
1647 ]], fixsql(mobid),
1648 fixsql(string.upper(area)),
1649 fixsql(room)
1650 )))
1651
1652 db:exec("COMMIT;")
1653
1654 Note("-- mobs_n_items: deleted location for mob #" .. mobid .. " from db --")
1655end
1656
1657
1658function del_item_location_from_database(itemid, area, mobid, room)
1659 db:exec("BEGIN TRANSACTION;")
1660
1661 dbcheck(db:execute(string.format([[
1662 DELETE FROM itemsloc WHERE itemid = %s AND UPPER(area) = %s AND mobid = %s AND room = %s;
1663 ]], fixsql(itemid),
1664 fixsql(string.upper(area)),
1665 fixsql(mobid),
1666 fixsql(room)
1667 )))
1668
1669 db:exec("COMMIT;")
1670
1671 Note("-- mobs_n_items: deleted location for item #" .. itemid .. " from db --")
1672end
1673
1674
1675function del_skill_trainer_from_database(skillid, mobid)
1676 db:exec("BEGIN TRANSACTION;")
1677
1678 dbcheck(db:execute(string.format([[
1679 DELETE FROM skillstrain WHERE skillid = %s AND mobid = %s;
1680 ]], fixsql(skillid),
1681 fixsql(mobid)
1682 )))
1683
1684 db:exec("COMMIT;")
1685
1686 Note("-- mobs_n_items: deleted trainer for skill #" .. skillid .. " from db --")
1687end
1688
1689
1690
1691---------------------
1692-- database queries
1693---------------------
1694
1695local fontcol = "silver"
1696local bgcol = "black"
1697local areacol = "white"
1698local namecol = "palevioletred" -- springgreen
1699local mobcol = fontcol
1700
1701
1702function find_npc(name, area, fuzzy)
1703 local results = {}
1704
1705 local cmd
1706 if (fuzzy) then
1707 name = "%" .. name .. "%"
1708 cmd = "SELECT mobid FROM mobs WHERE UPPER(name) LIKE %s"
1709 else
1710 cmd = "SELECT mobid FROM mobs WHERE UPPER(name) = %s"
1711 end
1712
1713 for row in db:nrows(string.format(cmd, string.upper(fixsql(name)))) do
1714 results[#results + 1] = row.mobid
1715 end
1716
1717 ColourTell("lightgreen", "black", "Results for: '" .. name .. "'")
1718 if (area ~= "") then
1719 ColourNote("lightgreen", "black", " in the area: '" .. area .. "':")
1720 else
1721 ColourNote("lightgreen", "black", ":")
1722 end
1723
1724 for i = 1, #results do
1725 show_npc_info(results[i], area)
1726 end
1727
1728 if (area ~= "") then
1729 ColourTell("lightgreen", "black", "Click ")
1730 Hyperlink("mob wheree " .. name, "[here]", "", "lightgreen", "black", false)
1731 ColourNote("lightgreen", "black", " or type 'mob wheree " .. name .. "' to repeat the search without area restrictions.")
1732 end
1733end
1734
1735
1736function find_item(name, area, fuzzy)
1737 local results = {}
1738
1739 local cmd
1740 if (fuzzy) then
1741 name = "%" .. name .. "%"
1742 cmd = "SELECT itemid FROM items WHERE UPPER(name) LIKE %s"
1743 else
1744 cmd = "SELECT itemid FROM items WHERE UPPER(name) = %s"
1745 end
1746
1747 for row in db:nrows(string.format(cmd, string.upper(fixsql(name)))) do
1748 results[#results + 1] = row.itemid
1749 end
1750
1751 ColourTell("lightgreen", "black", "Results for: '" .. name .. "'")
1752 if (area ~= "") then
1753 ColourNote("lightgreen", "black", " in the area: '" .. area .. "':")
1754 else
1755 ColourNote("lightgreen", "black", ":")
1756 end
1757
1758 for i = 1, #results do
1759 show_item_info(results[i], area)
1760 end
1761
1762 if (area ~= "") then
1763 ColourTell("lightgreen", "black", "Click ")
1764 Hyperlink("item wheree " .. name, "[here]", "", "lightgreen", "black", false)
1765 ColourNote("lightgreen", "black", " or type 'item wheree " .. name .. "' to repeat the search without area restrictions.")
1766 end
1767end
1768
1769
1770function find_skill(name, area, fuzzy)
1771 local results = {}
1772
1773 local cmd
1774 if (fuzzy) then
1775 name = "%" .. name .. "%"
1776 cmd = "SELECT skillid FROM skills WHERE UPPER(name) LIKE %s"
1777 else
1778 cmd = "SELECT skillid FROM skills WHERE UPPER(name) = %s"
1779 end
1780
1781 for row in db:nrows(string.format(cmd, string.upper(fixsql(name)))) do
1782 results[#results + 1] = row.skillid
1783 end
1784
1785 ColourTell("lightgreen", "black", "Trainers for: '" .. name .. "'")
1786 if (area ~= "") then
1787 ColourNote("lightgreen", "black", " in the area: '" .. area .. "':")
1788 else
1789 ColourNote("lightgreen", "black", ":")
1790 end
1791
1792 for i = 1, #results do
1793 show_skill_info(results[i], area)
1794 end
1795
1796 if (area ~= "") then
1797 ColourTell("lightgreen", "black", "Click ")
1798 Hyperlink("skill wheree " .. name, "here", "", "lightgreen", "black", false)
1799 ColourNote("lightgreen", "black", " or type 'skill wheree " .. name .. "' to repeat the search without area restrictions.")
1800 end
1801end
1802
1803
1804function show_npc_info(id, area)
1805 local npc = load_mob_from_database(id)
1806 local previous_area = nil
1807 local area_changed = true
1808
1809 area = Trim(area)
1810
1811 if (npc) then -- npc is in the db
1812 if (area ~= "") then
1813 for i = #npc.locations, 1, -1 do
1814 if (string.lower(area) ~= string.lower(npc.locations[i].area)) then
1815 table.remove(npc.locations, i)
1816 end
1817 end
1818 end
1819
1820 if (#npc.locations > 0) then
1821 Note("")
1822 Tell("npc: ")
1823 ColourTell(namecol, bgcol, npc.name)
1824
1825 Tell(" - id: ")
1826 ColourTell(fontcol, bgcol, npc.mobid)
1827
1828-- Tell(" - long_desc: ")
1829-- ColourTell(fontcol, bgcol, npc.long_desc)
1830
1831 if (area ~= "") then
1832 Tell(" - area: ")
1833 Hyperlink("gate " .. area, area, "", areacol, bgcol, false)
1834
1835-- ColourTell(fontcol, bgcol, area)
1836 end
1837
1838 if (#npc.roomnums > 0) then
1839 for i = 1, #npc.roomnums do
1840 Tell(" - ")
1841 Execute("mapper hyper " .. npc.roomnums[i])
1842 end
1843
1844 else
1845 for i = 1, #npc.locations do
1846 if (area == "") then
1847 if (not previous_area) or (previous_area ~= npc.locations[i].area) then
1848 Tell("\r\n- area: ")
1849 Hyperlink("gate " .. npc.locations[i].area, npc.locations[i].area, "", areacol, bgcol, false)
1850 previous_area = npc.locations[i].area
1851 area_changed = true
1852 else
1853 area_changed = false
1854 end
1855 end
1856
1857 if (npc.locations[i].room ~= "")
1858 and (npc.locations[i].room ~= "?")
1859 and (npc.locations[i].room ~= "-") then
1860 Tell(" - room: ")
1861
1862 if (area ~= "") then
1863 Hyperlink("mapper wheree " .. npc.locations[i].room .. " a:" .. area, npc.locations[i].room, "", fontcol, bgcol, false)
1864 else
1865 Hyperlink("mapper wheree " .. npc.locations[i].room, npc.locations[i].room, "", fontcol, bgcol, false)
1866 end
1867 end
1868
1869 if (npc.locations[i].hits) and (npc.locations[i].hits > 0) then
1870 Tell(" (" .. npc.locations[i].hits .. " hit(s))")
1871 end
1872 end
1873
1874 Note("")
1875 end
1876
1877 end
1878
1879 else
1880 ColourNote("red", "black", "-- mobs_n_items: the NPC " .. id .. " isn't in my db --")
1881 end
1882end
1883
1884
1885function show_item_info(id, area)
1886 local item = load_item_from_database(id)
1887 local previous_area = nil
1888 local area_changed = true
1889
1890 area = Trim(area)
1891
1892 if (item) then -- item is in the db
1893
1894 if (area ~= "") then
1895 for i = #item.locations, 1, -1 do
1896 if (string.lower(area) ~= string.lower(item.locations[i].area)) then
1897 table.remove(item.locations, i)
1898 end
1899 end
1900 end
1901
1902 if (#item.locations > 0) then
1903 Note("")
1904 Tell("item: ")
1905 ColourTell(namecol, bgcol, item.name)
1906
1907 Tell(" - id: ")
1908 ColourTell(fontcol, bgcol, item.itemid)
1909
1910 -- Tell(" - long_desc: ")
1911 -- ColourTell(fontcol, bgcol, item.long_desc)
1912
1913 if (area ~= "") then
1914 Tell("\r\n - area: ")
1915 Hyperlink("gate " .. area, area, "", areacol, bgcol, false)
1916 end
1917
1918 for i = 1, #item.locations do
1919 if (area == "") then
1920 if (not previous_area) or (previous_area ~= item.locations[i].area) then
1921 Tell("\r\n - area: ")
1922 Hyperlink("gate " .. item.locations[i].area, item.locations[i].area, "", areacol, bgcol, false)
1923 previous_area = item.locations[i].area
1924 area_changed = true
1925 else
1926 area_changed = false
1927 end
1928 end
1929
1930 if (item.locations[i].mobid ~= "") then
1931 mob = load_mob_from_database(item.locations[i].mobid)
1932
1933 if (area_changed) then
1934 Tell(" - on mob(s): ")
1935 else
1936 Tell(", ")
1937 end
1938
1939 if (area ~= "") then
1940 Hyperlink("mob wheree " .. mob.name .. " a:" .. area, mob.name, "", mobcol, bgcol, false)
1941 elseif (item.locations[i].area) then
1942 Hyperlink("mob wheree " .. mob.name .. " a:" .. item.locations[i].area, mob.name, "", mobcol, bgcol, false)
1943 else
1944 Hyperlink("mob wheree " .. mob.name, mob.name, "", mobcol, bgcol, false)
1945 end
1946
1947 elseif (item.locations[i].room ~= "") then
1948 Tell(" - in room: ")
1949 if (area ~= "") then
1950 Hyperlink("mapper wheree " .. item.locations[i].room .. " a:" .. area, item.locations[i].room, "", fontcol, bgcol, false)
1951 else
1952 Hyperlink("mapper wheree " .. item.locations[i].room, item.locations[i].room, "", fontcol, bgcol, false)
1953 end
1954
1955 if (item.locations[i].hits) and (item.locations[i].hits > 0) then
1956 Tell(" (" .. item.locations[i].hits .. " hit(s))")
1957 end
1958 end
1959 end
1960
1961 Note("")
1962 end
1963
1964 else
1965 ColourNote("red", "black", "mobs_n_items: the item " .. id .. " isn't in my db --")
1966 end
1967end
1968
1969
1970function show_skill_info(id, area)
1971 local skill = load_skill_from_database(id)
1972
1973 area = Trim(area)
1974
1975 if (skill) then -- skill is in the db
1976 Note("")
1977 Tell("skill: ")
1978 ColourTell(namecol, bgcol, skill.name)
1979
1980 Tell(" - id: ")
1981 ColourTell(fontcol, bgcol, skill.skillid)
1982
1983 if (area ~= "") then
1984 Tell(" - area: ")
1985 Hyperlink("gate " .. area, area, "", areacol, bgcol, false)
1986 end
1987
1988 local trainer
1989
1990-- Note(serialize.save_simple(skill))
1991
1992 if (area ~= "") then
1993 for i = #skill.trainers, 1, -1 do
1994 trainer = load_mob_from_database(skill.trainers[i])
1995
1996-- Note(serialize.save_simple(trainer))
1997
1998 if (#trainer.locations > 0) then
1999 if (string.lower(area) ~= string.lower(trainer.locations[1].area)) then -- trainer isn't in the chosen area
2000 table.remove(skill.trainers, i)
2001 end
2002
2003 else -- we don't know where the trainer is
2004 table.remove(skill.trainers, i)
2005 end
2006 end
2007 end
2008
2009 if (#skill.trainers > 0) then
2010 Tell(", trained by:")
2011 end
2012
2013 for i = 1, #skill.trainers do
2014 trainer = load_mob_from_database(skill.trainers[i])
2015
2016-- Note(serialize.save_simple(trainer))
2017
2018 if (i == 1) then
2019 Tell(" ")
2020 else
2021 Tell(", ")
2022 end
2023
2024 if (area ~= "") then
2025 Hyperlink("mob wheree " .. trainer.name .. " a:" .. area, trainer.name, "", fontcol, bgcol, false)
2026 else
2027 Hyperlink("mob wheree " .. trainer.name, trainer.name, "", fontcol, bgcol, false)
2028 Tell(" in " .. trainer.locations[1].area)
2029 end
2030 end
2031 Note("")
2032
2033 else
2034 ColourNote("red", "black", "mobs_n_items: the skill " .. id .. " isn't in my db --")
2035 end
2036end
2037
2038
2039function get_npc_areas(mob_name)
2040 local sname = fixsql(string.upper(mob_name))
2041 local mob_ids = {}
2042
2043-- Note(sname)
2044
2045 for row in db:nrows(string.format("SELECT mobid FROM mobs WHERE UPPER(name) = %s", sname)) do
2046 mob_ids[#mob_ids + 1] = row.mobid
2047 end -- finding rooms
2048
2049-- Note(serialize.save_simple(mob_ids))
2050
2051 local t = {}
2052
2053 for i = 1, #mob_ids do
2054 for row in db:nrows(string.format("SELECT area FROM mobsloc WHERE mobid = %s", fixsql(mob_ids[i]))) do
2055 t[#t + 1] = row.area
2056 end
2057 end
2058
2059-- Note(serialize.save_simple(t))
2060
2061 return table.concat(t, ";")
2062end
2063
2064
2065function get_item_areas(item_name)
2066 local sname = fixsql(string.upper(item_name))
2067-- Note(sname)
2068
2069 local item_ids = {}
2070
2071 for row in db:nrows(string.format("SELECT itemid FROM items WHERE UPPER(name) = %s", sname)) do
2072 item_ids[#item_ids + 1] = row.itemid
2073 end -- finding rooms
2074
2075-- Note(serialize.save_simple(item_ids))
2076
2077 local t = {}
2078
2079 for i = 1, #item_ids do
2080 for row in db:nrows(string.format("SELECT area FROM itemsloc WHERE itemid = %s", fixsql(item_ids[i]))) do
2081 t[#t + 1] = row.area
2082 end
2083 end
2084
2085-- Note(serialize.save_simple(t))
2086
2087 return table.concat(t, ";")
2088end
2089
2090
2091]]>
2092
2093</script>
2094
2095</muclient>