8 Commits

5 changed files with 441 additions and 14 deletions

View File

@@ -321,6 +321,18 @@ quest biolog_system begin
return true
end
function show_status_dialog()
say_title("Biolog Research")
say(biolog_system.get_status_text())
say("")
if not biolog_system.is_complete() and pc.getqf("biolog_stage") > 0 then
local stage = biolog_system.get_stage(pc.getqf("biolog_stage"))
say_item_vnum(stage.item_vnum)
say_reward(string.format("Submitted: %d / %d", pc.getqf("biolog_submitted"), stage.item_count))
end
end
function is_target_mob(stage_index, race)
local stage = biolog_system.get_stage(stage_index)
if not stage then
@@ -368,27 +380,24 @@ quest biolog_system begin
biolog_system.refresh_tracker()
end
when button or info begin
say_title("Biolog Research")
say(biolog_system.get_status_text())
say("")
if not biolog_system.is_complete() then
local stage = biolog_system.get_stage(pc.getqf("biolog_stage"))
say_item_vnum(stage.item_vnum)
say_reward(string.format("Submitted: %d / %d", pc.getqf("biolog_submitted"), stage.item_count))
when button begin
if pc.getqf("remote_submit") != 0 then
pc.setqf("remote_submit", 0)
biolog_system.submit_sample()
else
biolog_system.show_status_dialog()
end
end
when info begin
biolog_system.show_status_dialog()
end
when 20084.chat."Biolog Research" begin
say_title("Biolog Research")
say(biolog_system.get_status_text())
say("")
biolog_system.show_status_dialog()
if not biolog_system.is_complete() and pc.getqf("biolog_stage") > 0 then
local stage = biolog_system.get_stage(pc.getqf("biolog_stage"))
say_item_vnum(stage.item_vnum)
say_reward(string.format("Submitted: %d / %d", pc.getqf("biolog_submitted"), stage.item_count))
say_reward(string.format("Inventory: %d x %s", pc.count_item(stage.item_vnum), item_name(stage.item_vnum)))
say("")

View File

@@ -53,6 +53,7 @@ collect_herb_lv25.quest
collect_herb_lv4.quest
collect_herb_lv7.quest
biolog_system.quest
teleport_system.quest
couple_ring.quest
cube.quest
deviltower_zone.quest

View File

@@ -0,0 +1,336 @@
quest teleport_system begin
state start begin
function get_base_slot_count()
return 3
end
function get_vip_slot_count()
return 5
end
function get_cooldown_seconds()
return 30
end
function has_vip_slots()
return pc.get_premium_remain_sec(PREMIUM_GOLD) > 0
end
function get_max_slot_count()
if teleport_system.has_vip_slots() then
return teleport_system.get_vip_slot_count()
end
return teleport_system.get_base_slot_count()
end
function get_restricted_maps()
return {
[71] = true,
[72] = true,
[73] = true,
[104] = true,
[113] = true,
[200] = true,
[208] = true,
[301] = true,
}
end
function is_map_restricted(map_index)
if map_index == nil or map_index <= 0 then
return true
end
if map_index > 10000 then
return true
end
return teleport_system.get_restricted_maps()[map_index] == true
end
function can_use_now()
if false == pc.can_warp() then
return false, "Teleport is blocked right now."
end
local map_index = pc.get_map_index()
if pc.in_dungeon() or teleport_system.is_map_restricted(map_index) then
return false, "You cannot use teleport on this map."
end
if pc.getqf("cooldown_end") > get_time() then
return false, "Teleport is on cooldown."
end
return true, ""
end
function get_saved_map(slot)
return pc.getqf("slot_" .. slot .. "_map")
end
function get_saved_x(slot)
return pc.getqf("slot_" .. slot .. "_x")
end
function get_saved_y(slot)
return pc.getqf("slot_" .. slot .. "_y")
end
function has_saved_slot(slot)
return teleport_system.get_saved_map(slot) > 0
and teleport_system.get_saved_x(slot) > 0
and teleport_system.get_saved_y(slot) > 0
end
function get_saved_slot_count()
local count = 0
for slot = 1, teleport_system.get_vip_slot_count() do
if teleport_system.has_saved_slot(slot) then
count = count + 1
end
end
return count
end
function clear_slot(slot)
pc.setqf("slot_" .. slot .. "_map", 0)
pc.setqf("slot_" .. slot .. "_x", 0)
pc.setqf("slot_" .. slot .. "_y", 0)
end
function get_empire_preset(id)
local empire = pc.get_empire()
local presets = {
[1] = {
name = "First Village",
coords = {
[1] = { x = 474300, y = 954800 },
[2] = { x = 63800, y = 166400 },
[3] = { x = 959900, y = 269200 },
},
},
[2] = {
name = "Second Village",
coords = {
[1] = { x = 353100, y = 882900 },
[2] = { x = 145500, y = 240000 },
[3] = { x = 863900, y = 246000 },
},
},
[3] = {
name = "Valley",
coords = {
[1] = { x = 402100, y = 673900 },
[2] = { x = 270400, y = 739900 },
[3] = { x = 321300, y = 808000 },
},
},
[4] = {
name = "Desert",
coords = {
[1] = { x = 217800, y = 627200 },
[2] = { x = 221900, y = 502700 },
[3] = { x = 344000, y = 502500 },
},
},
[5] = {
name = "Sohan",
coords = {
[1] = { x = 434200, y = 290600 },
[2] = { x = 375200, y = 174900 },
[3] = { x = 491800, y = 173600 },
},
},
[6] = {
name = "Fireland",
coords = {
[1] = { x = 599400, y = 756300 },
[2] = { x = 597800, y = 622200 },
[3] = { x = 730700, y = 689800 },
},
},
[7] = {
name = "Devil Tower",
coords = {
[1] = { x = 590500, y = 110500 },
[2] = { x = 590500, y = 110500 },
[3] = { x = 590500, y = 110500 },
},
},
[8] = {
name = "Heavens Cave",
coords = {
[1] = { x = 287800, y = 799700 },
[2] = { x = 275500, y = 800000 },
[3] = { x = 277000, y = 788000 },
},
},
}
local preset = presets[id]
if preset == nil then
return nil
end
local coords = preset.coords[empire]
if coords == nil then
return nil
end
return {
name = preset.name,
x = coords.x,
y = coords.y,
}
end
function start_cooldown()
pc.setqf("cooldown_end", get_time() + teleport_system.get_cooldown_seconds())
end
function refresh_tracker()
send_letter("Teleport System")
q.set_title("Teleport System")
q.set_counter_name("Saved / " .. teleport_system.get_max_slot_count())
q.set_counter_value(teleport_system.get_saved_slot_count())
local cooldown = pc.getqf("cooldown_end") - get_time()
if cooldown > 0 then
q.set_clock("Cooldown", cooldown)
else
q.set_clock_name("")
end
q.start()
end
function show_status_dialog()
local cooldown = pc.getqf("cooldown_end") - get_time()
if cooldown < 0 then
cooldown = 0
end
say_title("Teleport System")
say("Use the HUD teleport button near the minimap.")
say("")
say_reward(string.format("Saved slots: %d / %d", teleport_system.get_saved_slot_count(), teleport_system.get_max_slot_count()))
if cooldown > 0 then
say_reward(string.format("Cooldown: %d seconds", cooldown))
else
say_reward("Cooldown: Ready")
end
end
function handle_save(slot)
if slot < 1 or slot > teleport_system.get_max_slot_count() then
syschat("This slot is locked.")
return
end
local map_index = pc.get_map_index()
if false == pc.can_warp() then
syschat("Teleport is blocked right now.")
return
end
if pc.in_dungeon() or teleport_system.is_map_restricted(map_index) then
syschat("This map cannot be saved.")
return
end
pc.setqf("slot_" .. slot .. "_map", map_index)
pc.setqf("slot_" .. slot .. "_x", pc.get_x())
pc.setqf("slot_" .. slot .. "_y", pc.get_y())
syschat(string.format("Saved current position to slot %d.", slot))
end
function handle_saved_warp(slot)
if slot < 1 or slot > teleport_system.get_max_slot_count() then
syschat("This slot is locked.")
return
end
if not teleport_system.has_saved_slot(slot) then
syschat("This slot is empty.")
return
end
local can_use, err = teleport_system.can_use_now()
if not can_use then
syschat(err)
return
end
local map_index = teleport_system.get_saved_map(slot)
if teleport_system.is_map_restricted(map_index) then
syschat("This saved position is no longer available.")
teleport_system.clear_slot(slot)
return
end
teleport_system.start_cooldown()
pc.warp_local(map_index, teleport_system.get_saved_x(slot), teleport_system.get_saved_y(slot))
end
function handle_preset_warp(preset_id)
local preset = teleport_system.get_empire_preset(preset_id)
if preset == nil then
syschat("Unknown teleport preset.")
return
end
local can_use, err = teleport_system.can_use_now()
if not can_use then
syschat(err)
return
end
teleport_system.start_cooldown()
pc.warp(preset.x, preset.y)
end
function handle_remote_action()
local action = pc.getqf("remote_action")
local arg = pc.getqf("remote_arg")
pc.setqf("remote_action", 0)
pc.setqf("remote_arg", 0)
if action == 1 then
teleport_system.handle_save(arg)
elseif action == 2 then
teleport_system.handle_saved_warp(arg)
elseif action == 3 then
teleport_system.handle_preset_warp(arg)
end
end
when login or enter begin
teleport_system.refresh_tracker()
end
when letter begin
teleport_system.refresh_tracker()
end
when button begin
if pc.getqf("remote_action") != 0 then
teleport_system.handle_remote_action()
teleport_system.refresh_tracker()
return
end
teleport_system.show_status_dialog()
teleport_system.refresh_tracker()
end
when info begin
teleport_system.show_status_dialog()
teleport_system.refresh_tracker()
end
end
end

View File

@@ -0,0 +1,46 @@
-- Issue #10: talismans
-- ITEM_TOTEM in a dedicated talisman slot.
-- value0 = element id (1 fire, 2 ice, 3 lightning, 4 wind, 5 earth)
-- applytype0/applyvalue0 carry the actual elemental resistance bonus.
-- refined_vnum + refine_set chain into refine_proto for upgrades.
INSERT INTO item_proto
(vnum, name, locale_name, type, subtype, size, antiflag, flag, wearflag, immuneflag, gold, shop_buy_price,
limittype0, limitvalue0, limittype1, limitvalue1,
applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2,
value0, value1, value2, value3, value4, value5,
socket0, socket1, socket2, refined_vnum, refine_set, magic_pct, specular, socket_pct)
VALUES
(86000, 'talisman_fire_0', 'Fire Talisman +0', 26, 0, 1, 0, 65536, 65536, 0, 0, 0, 1, 30, 0, 0, 35, 5, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 86001, 1000, 0, 0, 0),
(86001, 'talisman_fire_1', 'Fire Talisman +1', 26, 0, 1, 0, 65536, 65536, 0, 0, 0, 1, 30, 0, 0, 35, 10, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 86002, 1001, 0, 0, 0),
(86002, 'talisman_fire_2', 'Fire Talisman +2', 26, 0, 1, 0, 65536, 65536, 0, 0, 0, 1, 30, 0, 0, 35, 15, 0, 0, 0, 0, 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(86010, 'talisman_ice_0', 'Ice Talisman +0', 26, 0, 1, 0, 65536, 65536, 0, 0, 0, 1, 30, 0, 0, 87, 5, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 86011, 1010, 0, 0, 0),
(86011, 'talisman_ice_1', 'Ice Talisman +1', 26, 0, 1, 0, 65536, 65536, 0, 0, 0, 1, 30, 0, 0, 87, 10, 0, 0, 0, 0, 2, 1, 0, 0, 0, 0, 0, 0, 0, 86012, 1011, 0, 0, 0),
(86012, 'talisman_ice_2', 'Ice Talisman +2', 26, 0, 1, 0, 65536, 65536, 0, 0, 0, 1, 30, 0, 0, 87, 15, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(86020, 'talisman_lightning_0', 'Lightning Talisman +0', 26, 0, 1, 0, 65536, 65536, 0, 0, 0, 1, 30, 0, 0, 36, 5, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, 86021, 1020, 0, 0, 0),
(86021, 'talisman_lightning_1', 'Lightning Talisman +1', 26, 0, 1, 0, 65536, 65536, 0, 0, 0, 1, 30, 0, 0, 36, 10, 0, 0, 0, 0, 3, 1, 0, 0, 0, 0, 0, 0, 0, 86022, 1021, 0, 0, 0),
(86022, 'talisman_lightning_2', 'Lightning Talisman +2', 26, 0, 1, 0, 65536, 65536, 0, 0, 0, 1, 30, 0, 0, 36, 15, 0, 0, 0, 0, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(86030, 'talisman_wind_0', 'Wind Talisman +0', 26, 0, 1, 0, 65536, 65536, 0, 0, 0, 1, 30, 0, 0, 38, 5, 0, 0, 0, 0, 4, 0, 0, 0, 0, 0, 0, 0, 0, 86031, 1030, 0, 0, 0),
(86031, 'talisman_wind_1', 'Wind Talisman +1', 26, 0, 1, 0, 65536, 65536, 0, 0, 0, 1, 30, 0, 0, 38, 10, 0, 0, 0, 0, 4, 1, 0, 0, 0, 0, 0, 0, 0, 86032, 1031, 0, 0, 0),
(86032, 'talisman_wind_2', 'Wind Talisman +2', 26, 0, 1, 0, 65536, 65536, 0, 0, 0, 1, 30, 0, 0, 38, 15, 0, 0, 0, 0, 4, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(86040, 'talisman_earth_0', 'Earth Talisman +0', 26, 0, 1, 0, 65536, 65536, 0, 0, 0, 1, 30, 0, 0, 88, 5, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 86041, 1040, 0, 0, 0),
(86041, 'talisman_earth_1', 'Earth Talisman +1', 26, 0, 1, 0, 65536, 65536, 0, 0, 0, 1, 30, 0, 0, 88, 10, 0, 0, 0, 0, 5, 1, 0, 0, 0, 0, 0, 0, 0, 86042, 1041, 0, 0, 0),
(86042, 'talisman_earth_2', 'Earth Talisman +2', 26, 0, 1, 0, 65536, 65536, 0, 0, 0, 1, 30, 0, 0, 88, 15, 0, 0, 0, 0, 5, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);
INSERT INTO refine_proto
(id, cost, prob, vnum0, count0, vnum1, count1, vnum2, count2, vnum3, count3, vnum4, count4)
VALUES
(1000, 50000, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(1001, 125000, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(1010, 50000, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(1011, 125000, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(1020, 50000, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(1021, 125000, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(1030, 50000, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(1031, 125000, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(1040, 50000, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0),
(1041, 125000, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0);

35
sql/issue_9_sashes.sql Normal file
View File

@@ -0,0 +1,35 @@
-- Issue #9: classic sash support
-- value0 = absorb percent
-- subtype = COSTUME_SASH
-- wearflag can stay 0 for ITEM_COSTUME, but WEARABLE_COSTUME_SASH is available if you want parity in tools
-- Sample classic tiers
-- Adjust icon/model names and vnums to your asset pack.
INSERT INTO item_proto
(vnum, name, locale_name, type, subtype, size, antiflag, flag, wearflag, immuneflag, gold, shop_buy_price,
limittype0, limitvalue0, limittype1, limitvalue1,
applytype0, applyvalue0, applytype1, applyvalue1, applytype2, applyvalue2,
value0, value1, value2, value3, value4, value5,
socket0, socket1, socket2, refined_vnum, refine_set, magic_pct, specular, socket_pct)
VALUES
(85000, 'sash_common', 'Common Sash', 28, 2, 2, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0,
0, 0, 0, 0, 0, 0,
5, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0),
(85010, 'sash_rare', 'Rare Sash', 28, 2, 2, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0,
0, 0, 0, 0, 0, 0,
10, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0),
(85020, 'sash_epic', 'Epic Sash', 28, 2, 2, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0,
0, 0, 0, 0, 0, 0,
15, 2, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0),
(85030, 'sash_legendary', 'Legendary Sash', 28, 2, 2, 0, 0, 0, 0, 0, 0,
1, 1, 0, 0,
0, 0, 0, 0, 0, 0,
20, 3, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0);