Add Changelog to README; Remove /world announcements
This commit is contained in:
parent
68e7b675ef
commit
ed2fc13217
703
Cargo.lock
generated
703
Cargo.lock
generated
File diff suppressed because it is too large
Load Diff
24
README.md
24
README.md
@ -33,12 +33,13 @@ The bot is able to respond to the following commands, which must be sent via "/t
|
||||
search term.
|
||||
- `admin_access`: Admin-only, prompts the bot to send a trade invite to the sender, after which it
|
||||
will give away and accept any items until the trade ends.
|
||||
- `announce`: Admin-only, sends the announcement message to "/world". This will reset the
|
||||
- `announce`: Admin-only, sends the announcement message to "/region". This will reset the
|
||||
announcement timer to 45 minutes.
|
||||
- `location`: Returns the bot's current town or, if it is not in a town, its current position.
|
||||
- `sort [count (optional)]`: Admin-only, sorts the inventory once or the given number of times.
|
||||
- `pos [x] [y] [z]`: Admin-only, sets the bot's desired position where it will try to stand (must
|
||||
be close to the bot's current position)
|
||||
- `ori [0-360]`: Admin-only, sets the bot's desired orientation (or facing direction)
|
||||
be close to the bot's current position).
|
||||
- `ori [0-360]`: Admin-only, sets the bot's desired orientation (or facing direction).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
@ -94,10 +95,8 @@ position = [0, 0, 0]
|
||||
# Its orientation can be changed in-game with the "ori" command.
|
||||
orientation = 0
|
||||
|
||||
# Optional. Announcements are sent every 45 minutes. Use {location} to insert the bot's current
|
||||
# location. If not set, the bot will not send /world announcements but will still send /region
|
||||
# announcements with usage instructions.
|
||||
announcement = "I love cheese! I am at {location}."
|
||||
# Optional. Announcements are sent every 45 minutes. If not set, the bot will not make announcements.
|
||||
announcement = "I love cheese!"
|
||||
|
||||
# The buy_prices and sell_prices tables are required. The keys are item definition IDs and the
|
||||
# values are the price in coins. You may type in-game "/give_item common.items." and press Tab to
|
||||
@ -143,6 +142,17 @@ podman build . -t trade_bot
|
||||
Then follow the [above](#running) steps with the tag "trade_bot" instead of
|
||||
"git.jeffa.io/jeff/trade_bot".
|
||||
|
||||
## Changelog
|
||||
|
||||
- 9/2/2024:
|
||||
- Added the "location" command.
|
||||
- Removed the "{location}" feature from the announcement message. Announcements are now sent to
|
||||
"/region" so this feature is now used by the "location" command.
|
||||
- Changed announcements to be sent to "/region" instead of "/world". The moderators on the official
|
||||
server have asked for this, so please don't run an old version to circumvent the change.
|
||||
- Removed the "Ouch!" and "That hurt!" messages when the bot is attacked. The moderators have also
|
||||
asked for this.
|
||||
|
||||
## License
|
||||
|
||||
This project is licensed under the GPL-3.0 license. See the [LICENSE](LICENSE) file for details.
|
||||
|
@ -771,8 +771,9 @@
|
||||
primary: Simple(None, "common.abilities.custom.harvester.scythe"),
|
||||
secondary: Simple(None, "common.abilities.custom.harvester.firebreath"),
|
||||
abilities: [
|
||||
Simple(None, "common.abilities.custom.harvester.ensnaringvines"),
|
||||
Simple(None, "common.abilities.custom.harvester.explodingpumpkin"),
|
||||
Simple(None, "common.abilities.custom.harvester.ensnaringvines_sparse"),
|
||||
Simple(None, "common.abilities.custom.harvester.ensnaringvines_dense"),
|
||||
],
|
||||
),
|
||||
// TODO: Allow ability sets to expand other ability sets
|
||||
|
@ -0,0 +1,10 @@
|
||||
SpriteSummon(
|
||||
buildup_duration: 0.9,
|
||||
cast_duration: 0.6,
|
||||
recover_duration: 0.5,
|
||||
sprite: EnsnaringVines,
|
||||
del_timeout: None,
|
||||
summon_distance: (0, 25),
|
||||
sparseness: 0.6,
|
||||
angle: 360,
|
||||
)
|
@ -0,0 +1,10 @@
|
||||
SpriteSummon(
|
||||
buildup_duration: 0.6,
|
||||
cast_duration: 0.4,
|
||||
recover_duration: 0.3,
|
||||
sprite: EnsnaringVines,
|
||||
del_timeout: None,
|
||||
summon_distance: (0, 30),
|
||||
sparseness: 0.8,
|
||||
angle: 360,
|
||||
)
|
@ -1,21 +1,21 @@
|
||||
BasicRanged(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.75,
|
||||
buildup_duration: 1.0,
|
||||
recover_duration: 1.6,
|
||||
projectile: (
|
||||
kind: Explosive(
|
||||
radius: 5,
|
||||
radius: 7.2,
|
||||
min_falloff: 0.6,
|
||||
reagent: Some(Red),
|
||||
terrain: Some((5, Black)),
|
||||
),
|
||||
attack: Some((
|
||||
damage: 37.5,
|
||||
knockback: Some(25),
|
||||
damage: 20,
|
||||
knockback: Some(22),
|
||||
energy: 0,
|
||||
buff: Some((
|
||||
kind: Burning,
|
||||
dur_secs: 5,
|
||||
dur_secs: 4,
|
||||
strength: DamageFraction(0.2),
|
||||
chance: 1.0,
|
||||
)),
|
||||
|
@ -2,18 +2,18 @@ BasicBeam(
|
||||
buildup_duration: 1.4,
|
||||
recover_duration: 0.9,
|
||||
beam_duration: 1.0,
|
||||
damage: 9.0,
|
||||
damage: 5.0,
|
||||
tick_rate: 1.5,
|
||||
range: 20.0,
|
||||
max_angle: 15.0,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Burning,
|
||||
dur_secs: 10.0,
|
||||
strength: DamageFraction(1.0),
|
||||
dur_secs: 3.0,
|
||||
strength: DamageFraction(0.8),
|
||||
chance: 1.0,
|
||||
))),
|
||||
energy_regen: 0,
|
||||
energy_drain: 0,
|
||||
ori_rate: 0.3,
|
||||
ori_rate: 0.7,
|
||||
specifier: Flamethrower,
|
||||
)
|
||||
|
@ -1,19 +1,19 @@
|
||||
BasicMelee(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.9,
|
||||
swing_duration: 0.1,
|
||||
buildup_duration: 1.0,
|
||||
swing_duration: 0.2,
|
||||
hit_timing: 0.5,
|
||||
recover_duration: 1.2,
|
||||
recover_duration: 1.0,
|
||||
melee_constructor: (
|
||||
kind: Slash(
|
||||
damage: 21.0,
|
||||
damage: 15.0,
|
||||
poise: 10.0,
|
||||
knockback: 10.0,
|
||||
energy_regen: 0.0,
|
||||
),
|
||||
range: 4.0,
|
||||
angle: 60.0,
|
||||
range: 4.5,
|
||||
angle: 50.0,
|
||||
multi_target: Some(Normal),
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
ori_modifier: 0.5,
|
||||
)
|
||||
|
@ -7,7 +7,7 @@ BasicMelee(
|
||||
melee_constructor: (
|
||||
kind: Bash(
|
||||
damage: 8,
|
||||
poise: 5,
|
||||
poise: 10,
|
||||
knockback: 0,
|
||||
energy_regen: 0,
|
||||
),
|
||||
|
@ -7,7 +7,7 @@ BasicMelee(
|
||||
melee_constructor: (
|
||||
kind: SonicWave(
|
||||
damage: 10,
|
||||
poise: 100,
|
||||
poise: 75,
|
||||
knockback: 20,
|
||||
energy_regen: 0,
|
||||
),
|
||||
|
@ -1,20 +1,20 @@
|
||||
Shockwave(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 3.0,
|
||||
buildup_duration: 1.2,
|
||||
swing_duration: 0.12,
|
||||
recover_duration: 2.4,
|
||||
damage: 60.0,
|
||||
recover_duration: 1.5,
|
||||
damage: 22.0,
|
||||
poise_damage: 30,
|
||||
knockback: (strength: 30.0, direction: TowardsUp),
|
||||
knockback: (strength: 20.0, direction: TowardsUp),
|
||||
shockwave_angle: 90.0,
|
||||
shockwave_vertical_angle: 90.0,
|
||||
shockwave_speed: 15.0,
|
||||
shockwave_duration: 2.0,
|
||||
shockwave_duration: 1.9,
|
||||
dodgeable: Jump,
|
||||
move_efficiency: 0.0,
|
||||
damage_kind: Crushing,
|
||||
specifier: Ground,
|
||||
ori_rate: 1.0,
|
||||
ori_rate: 0.9,
|
||||
timing: PostBuildup,
|
||||
emit_outcome: true,
|
||||
)
|
||||
|
@ -1,18 +1,18 @@
|
||||
BasicMelee(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.9,
|
||||
buildup_duration: 1.2,
|
||||
swing_duration: 0.3,
|
||||
hit_timing: 0.6,
|
||||
recover_duration: 0.6,
|
||||
recover_duration: 1.2,
|
||||
melee_constructor: (
|
||||
kind: Bash(
|
||||
damage: 45,
|
||||
damage: 18,
|
||||
poise: 30,
|
||||
knockback: 20,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 7.5,
|
||||
range: 5.0,
|
||||
angle: 360,
|
||||
),
|
||||
ori_modifier: 1.0,
|
||||
ori_modifier: 0.75,
|
||||
)
|
||||
|
@ -1,18 +1,18 @@
|
||||
BasicMelee(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 1.6,
|
||||
swing_duration: 0.1,
|
||||
buildup_duration: 1.0,
|
||||
swing_duration: 0.2,
|
||||
hit_timing: 0.6,
|
||||
recover_duration: 1.0,
|
||||
melee_constructor: (
|
||||
kind: Bash(
|
||||
damage: 30.0,
|
||||
damage: 12.0,
|
||||
poise: 25.0,
|
||||
knockback: 15.0,
|
||||
energy_regen: 0.0,
|
||||
),
|
||||
range: 4.0,
|
||||
angle: 45.0,
|
||||
angle: 55.0,
|
||||
),
|
||||
ori_modifier: 0.4,
|
||||
ori_modifier: 0.7,
|
||||
)
|
||||
|
@ -1,28 +1,28 @@
|
||||
BasicRanged(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.825,
|
||||
buildup_duration: 1.0,
|
||||
recover_duration: 0.6,
|
||||
projectile: (
|
||||
kind: Explosive(
|
||||
radius: 2,
|
||||
min_falloff: 0.5,
|
||||
radius: 3,
|
||||
min_falloff: 0.7,
|
||||
reagent: Some(Red),
|
||||
terrain: Some((2, Black))
|
||||
),
|
||||
attack: Some((
|
||||
damage: 13.5,
|
||||
damage: 5.5,
|
||||
energy: 10,
|
||||
buff: Some((
|
||||
kind: Burning,
|
||||
dur_secs: 5,
|
||||
strength: DamageFraction(0.1),
|
||||
dur_secs: 3,
|
||||
strength: DamageFraction(0.3),
|
||||
chance: 0.1,
|
||||
)),
|
||||
)),
|
||||
),
|
||||
projectile_body: Object(BoltFire),
|
||||
projectile_speed: 25,
|
||||
num_projectiles: 8,
|
||||
num_projectiles: 5,
|
||||
projectile_spread: 0.125,
|
||||
move_efficiency: 0.3,
|
||||
)
|
||||
|
@ -1,16 +1,16 @@
|
||||
Shockwave(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.975,
|
||||
buildup_duration: 1.2,
|
||||
swing_duration: 0.1,
|
||||
recover_duration: 0.6,
|
||||
damage: 30,
|
||||
recover_duration: 0.8,
|
||||
damage: 16,
|
||||
poise_damage: 0,
|
||||
knockback: ( strength: 25, direction: Away),
|
||||
knockback: ( strength: 15, direction: Away),
|
||||
shockwave_angle: 360,
|
||||
shockwave_vertical_angle: 90,
|
||||
shockwave_speed: 10,
|
||||
shockwave_duration: 1,
|
||||
dodgeable: Roll,
|
||||
shockwave_speed: 12,
|
||||
shockwave_duration: 1.0,
|
||||
dodgeable: Jump,
|
||||
move_efficiency: 0,
|
||||
damage_kind: Energy,
|
||||
specifier: Fire,
|
||||
|
@ -1,21 +1,21 @@
|
||||
BasicMelee(
|
||||
energy_cost: 0,
|
||||
buildup_duration: 0.6,
|
||||
swing_duration: 0.1,
|
||||
buildup_duration: 0.75,
|
||||
swing_duration: 0.4,
|
||||
hit_timing: 0.5,
|
||||
recover_duration: 0.45,
|
||||
recover_duration: 0.6,
|
||||
melee_constructor: (
|
||||
kind: Bash(
|
||||
damage: 12,
|
||||
damage: 9,
|
||||
poise: 10,
|
||||
knockback: 0,
|
||||
energy_regen: 0,
|
||||
),
|
||||
range: 7.5,
|
||||
angle: 60.0,
|
||||
range: 3.0,
|
||||
angle: 40.0,
|
||||
damage_effect: Some(Buff((
|
||||
kind: Burning,
|
||||
dur_secs: 10.0,
|
||||
dur_secs: 4.0,
|
||||
strength: DamageFraction(0.5),
|
||||
chance: 0.5,
|
||||
))),
|
||||
|
@ -1,24 +1,24 @@
|
||||
BasicAura(
|
||||
buildup_duration: 0.375,
|
||||
cast_duration: 0.5,
|
||||
recover_duration: 0.375,
|
||||
buildup_duration: 0.2,
|
||||
cast_duration: 0.4,
|
||||
recover_duration: 0.2,
|
||||
targets: InGroup,
|
||||
auras: [
|
||||
(
|
||||
kind: Regeneration,
|
||||
strength: 7.5,
|
||||
duration: Some(5),
|
||||
strength: 1,
|
||||
duration: Some(1),
|
||||
category: Magical,
|
||||
),
|
||||
(
|
||||
kind: ProtectingWard,
|
||||
strength: 0.75,
|
||||
duration: Some(5),
|
||||
strength: 0.5,
|
||||
duration: Some(1),
|
||||
category: Magical,
|
||||
),
|
||||
],
|
||||
aura_duration: Some(2),
|
||||
range: 50,
|
||||
aura_duration: Some(1),
|
||||
range: 15,
|
||||
energy_cost: 0,
|
||||
scales_with_combo: false,
|
||||
)
|
||||
|
@ -1,18 +1,18 @@
|
||||
BasicAura(
|
||||
buildup_duration: 0.375,
|
||||
cast_duration: 0.5,
|
||||
recover_duration: 0.375,
|
||||
buildup_duration: 0.2,
|
||||
cast_duration: 0.4,
|
||||
recover_duration: 0.2,
|
||||
targets: OutOfGroup,
|
||||
auras: [
|
||||
(
|
||||
kind: Burning,
|
||||
strength: 0.75,
|
||||
duration: Some(5),
|
||||
strength: 1.2,
|
||||
duration: Some(1),
|
||||
category: Magical,
|
||||
),
|
||||
],
|
||||
aura_duration: Some(2),
|
||||
range: 50,
|
||||
aura_duration: Some(1),
|
||||
range: 15,
|
||||
energy_cost: 0,
|
||||
scales_with_combo: false,
|
||||
)
|
||||
|
@ -1,18 +1,18 @@
|
||||
BasicAura(
|
||||
buildup_duration: 0.375,
|
||||
cast_duration: 0.5,
|
||||
recover_duration: 0.375,
|
||||
buildup_duration: 0.2,
|
||||
cast_duration: 0.4,
|
||||
recover_duration: 0.2,
|
||||
targets: InGroup,
|
||||
auras: [
|
||||
(
|
||||
kind: Hastened,
|
||||
strength: 0.75,
|
||||
duration: Some(5),
|
||||
strength: 0.4,
|
||||
duration: Some(1),
|
||||
category: Magical,
|
||||
),
|
||||
],
|
||||
aura_duration: Some(2),
|
||||
range: 50,
|
||||
aura_duration: Some(1),
|
||||
range: 15,
|
||||
energy_cost: 0,
|
||||
scales_with_combo: false,
|
||||
)
|
||||
|
@ -2,7 +2,7 @@
|
||||
#![enable(implicit_some)]
|
||||
(
|
||||
name: Name("Gnarling Chieftain"),
|
||||
body: RandomWith("gnarling"),
|
||||
body: RandomWith("gnarling_chieftain"),
|
||||
alignment: Alignment(Enemy),
|
||||
loot: LootTable("common.loot_tables.dungeon.gnarling.chieftain"),
|
||||
inventory: (
|
||||
|
@ -3183,6 +3183,9 @@
|
||||
Simple(
|
||||
"common.items.consumable.potion_minor",
|
||||
): "object-potion_minor",
|
||||
Simple(
|
||||
"common.items.consumable.potion_freezing",
|
||||
): "object-potion_freezing",
|
||||
Simple(
|
||||
"common.items.lantern.black_0",
|
||||
): "lantern-black",
|
||||
|
@ -6,10 +6,10 @@ ItemDef(
|
||||
stats: Direct((
|
||||
protection: Some(Normal(3.0)),
|
||||
poise_resilience: Some(Normal(1.0)),
|
||||
energy_max: Some(14.0),
|
||||
energy_max: Some(6.0),
|
||||
)),
|
||||
)),
|
||||
quality: High,
|
||||
quality: Moderate,
|
||||
tags: [
|
||||
Gnarling,
|
||||
SalvageInto(Lifecloth, 1),
|
||||
|
@ -17,5 +17,5 @@ ItemDef(
|
||||
])
|
||||
),
|
||||
quality: Legendary,
|
||||
tags: [],
|
||||
tags: [Charm],
|
||||
)
|
||||
|
@ -17,5 +17,5 @@ ItemDef(
|
||||
])
|
||||
),
|
||||
quality: Legendary,
|
||||
tags: [],
|
||||
tags: [Charm],
|
||||
)
|
||||
|
@ -16,5 +16,5 @@ ItemDef(
|
||||
])
|
||||
),
|
||||
quality: Legendary,
|
||||
tags: [],
|
||||
tags: [Charm],
|
||||
)
|
||||
|
@ -11,7 +11,15 @@ ItemDef(
|
||||
duration: Some(10)
|
||||
),
|
||||
cat_ids: [Natural],
|
||||
))
|
||||
)),
|
||||
Buff((
|
||||
kind: PotionSickness,
|
||||
data: (
|
||||
strength: 0.15,
|
||||
duration: Some(30),
|
||||
),
|
||||
cat_ids: [Natural],
|
||||
)),
|
||||
])
|
||||
),
|
||||
quality: Moderate,
|
||||
|
27
assets/common/items/consumable/potion_freezing.ron
Normal file
27
assets/common/items/consumable/potion_freezing.ron
Normal file
@ -0,0 +1,27 @@
|
||||
ItemDef(
|
||||
legacy_name: "Freezing Potion",
|
||||
legacy_description: "Freezes the user's brain",
|
||||
kind: Consumable(
|
||||
kind: Drink,
|
||||
effects: All([
|
||||
Buff((
|
||||
kind: Frozen,
|
||||
data: (
|
||||
strength: 0.1,
|
||||
duration: Some(30)
|
||||
),
|
||||
cat_ids: [Natural],
|
||||
)),
|
||||
Buff((
|
||||
kind: PotionSickness,
|
||||
data: (
|
||||
strength: 0.15,
|
||||
duration: Some(30),
|
||||
),
|
||||
cat_ids: [Natural],
|
||||
)),
|
||||
])
|
||||
),
|
||||
quality: Moderate,
|
||||
tags: [Potion],
|
||||
)
|
@ -2,6 +2,6 @@ ItemDef(
|
||||
legacy_name: "Green Luna",
|
||||
legacy_description: "The delicate wings flutter faintly.",
|
||||
kind: Glider,
|
||||
quality: High,
|
||||
quality: Moderate,
|
||||
tags: [],
|
||||
)
|
||||
|
@ -8,6 +8,6 @@ ItemDef(
|
||||
flicker_thousandths: 600,
|
||||
),
|
||||
),
|
||||
quality: High,
|
||||
quality: Moderate,
|
||||
tags: [Utility],
|
||||
)
|
||||
|
@ -4,6 +4,7 @@ ItemDef(
|
||||
kind: RecipeGroup(
|
||||
recipes: [
|
||||
"potion_combustion",
|
||||
"potion_freezing",
|
||||
"potion_agility",
|
||||
"potion_minor",
|
||||
"potion_medium",
|
||||
|
@ -1,12 +1,14 @@
|
||||
[
|
||||
// Weapons
|
||||
(5.0, LootTable("common.loot_tables.weapons.tier-1")),
|
||||
// Armor
|
||||
(5.0, LootTable("common.loot_tables.armor.tier-1")),
|
||||
// Misc
|
||||
(3.0, Item("common.items.armor.misc.neck.scratched")),
|
||||
(2.0, Item("common.items.armor.misc.head.wanderers_hat")),
|
||||
(3.0, Item("common.items.armor.misc.head.bamboo_twig")),
|
||||
// Chieftain Mask
|
||||
(1.0, Item("common.items.armor.misc.head.gnarling_mask")),
|
||||
(1, All([
|
||||
All([
|
||||
LootTable("common.loot_tables.armor.tier-1"),
|
||||
LootTable("common.loot_tables.weapons.tier-1"),
|
||||
]),
|
||||
Lottery([
|
||||
(2.0, Nothing),
|
||||
(1.0, Item("common.items.armor.misc.neck.scratched")),
|
||||
(1.0, Item("common.items.armor.misc.head.gnarling_mask")),
|
||||
(1.0, Item("common.items.glider.moth")),
|
||||
]),
|
||||
])),
|
||||
]
|
@ -1,10 +1,13 @@
|
||||
[
|
||||
// Weapons
|
||||
(5.0, LootTable("common.loot_tables.weapons.tier-3")),
|
||||
// Armor
|
||||
(5.0, LootTable("common.loot_tables.armor.tier-3")),
|
||||
// Misc
|
||||
(3.0, Item("common.items.armor.misc.neck.scratched")),
|
||||
(2.0, Item("common.items.lantern.pumpkin")),
|
||||
(1.0, Item("common.items.glider.moth")),
|
||||
(1, All([
|
||||
All([
|
||||
LootTable("common.loot_tables.armor.tier-2"),
|
||||
LootTable("common.loot_tables.weapons.tier-2"),
|
||||
]),
|
||||
Lottery([
|
||||
(3.0, Nothing),
|
||||
(1.0, Item("common.items.lantern.pumpkin")),
|
||||
(1.0, Item("common.items.armor.misc.head.wanderers_hat")),
|
||||
]),
|
||||
])),
|
||||
]
|
@ -1,6 +1,16 @@
|
||||
[
|
||||
// Crafting ingredients
|
||||
(2.4, MultiDrop(Item("common.items.log.wood"), 5, 10)),
|
||||
(0.1, MultiDrop(Item("common.items.log.hardwood"), 1, 2)),
|
||||
(0.5, LootTable("common.loot_tables.weapons.components.secondary.sceptre")),
|
||||
(1, Lottery([
|
||||
(0.7, All([
|
||||
MultiDrop(Item("common.items.log.wood"), 3, 4),
|
||||
MultiDrop(Item("common.items.crafting_ing.twigs"), 1, 2),
|
||||
Lottery([
|
||||
(0.6, MultiDrop(Item("common.items.log.bamboo"), 1, 2)),
|
||||
(0.4, LootTable("common.loot_tables.weapons.components.secondary.sceptre")),
|
||||
]),
|
||||
])),
|
||||
(0.3, All([
|
||||
MultiDrop(Item("common.items.log.wood"), 5, 7),
|
||||
MultiDrop(Item("common.items.crafting_ing.twigs"), 3, 5),
|
||||
])),
|
||||
]))
|
||||
]
|
||||
|
@ -4,7 +4,7 @@
|
||||
// Ingredients
|
||||
(2.0, Item("common.items.crafting_ing.coral_branch")),
|
||||
(0.5, Item("common.items.crafting_ing.pearl")),
|
||||
(0.25, Item("common.items.recipes.unique.seashell_necklace")),
|
||||
(0.5, Item("common.items.recipes.armor.brinestone")),
|
||||
(0.25, Item("common.items.recipes.unique.winged_coronet")),
|
||||
(0.25, Item("common.items.recipes.unique.abyssal_ring")),
|
||||
]),
|
||||
|
@ -1,3 +1,5 @@
|
||||
[
|
||||
(1.0, Item("common.items.recipes.armor.brinestone")),
|
||||
(1.0, Nothing),
|
||||
(1.0, LootTable("common.loot_tables.food.prepared")),
|
||||
(0.5, Item("common.items.recipes.unique.seashell_necklace")),
|
||||
]
|
||||
|
@ -1,5 +1,5 @@
|
||||
[
|
||||
(1.0, LootTable("common.loot_tables.weapons.components.tier-1")),
|
||||
(1.0, LootTable("common.loot_tables.weapons.components.tier-0")),
|
||||
(1.0, LootTable("common.loot_tables.armor.cloth")),
|
||||
(0.5, Item("common.items.recipes.explosives")),
|
||||
]
|
||||
|
@ -1,7 +1,16 @@
|
||||
[
|
||||
(1.0, LootTable("common.loot_tables.weapons.components.tier-0")),
|
||||
(1.0, LootTable("common.loot_tables.weapons.components.tier-1")),
|
||||
(1.0, LootTable("common.loot_tables.armor.cloth")),
|
||||
(0.5, LootTable("common.loot_tables.weapons.components.tier-0")),
|
||||
(0.25, LootTable("common.loot_tables.weapons.tier-0")),
|
||||
(0.25, LootTable("common.loot_tables.armor.tier-0")),
|
||||
(0.25, Item("common.items.armor.misc.head.bamboo_twig")),
|
||||
// Currency
|
||||
(3.0, MultiDrop(Item("common.items.utility.coins"), 25, 50)),
|
||||
// Materials
|
||||
(0.5, MultiDrop(Item("common.items.mineral.ore.veloritefrag"), 5, 10)),
|
||||
// Consumables
|
||||
(2.0, MultiDrop(Item("common.items.consumable.potion_minor"), 2, 5)),
|
||||
// Food
|
||||
(1.0, MultiDrop(LootTable("common.loot_tables.food.prepared"), 1, 2)),
|
||||
(0.2, Item("common.items.recipes.explosives")),
|
||||
(0.5, Item("common.items.recipes.instruments")),
|
||||
(0.2, Item("common.items.recipes.charms")),
|
||||
|
@ -1233,6 +1233,10 @@
|
||||
keyword: "treasure_egg",
|
||||
generic: "Treasure Egg",
|
||||
),
|
||||
gnarling_chieftain: (
|
||||
keyword: "gnarling_chieftain",
|
||||
generic: "Gnarling Chieftain"
|
||||
),
|
||||
)
|
||||
),
|
||||
fish_small: (
|
||||
|
@ -31,6 +31,15 @@
|
||||
],
|
||||
craft_sprite: Some(Anvil),
|
||||
),
|
||||
"potion_freezing": (
|
||||
output: ("common.items.consumable.potion_freezing", 1),
|
||||
inputs: [
|
||||
(Item("common.items.crafting_ing.empty_vial"), 1, false),
|
||||
(Item("common.items.crafting_ing.animal_misc.icy_fang"), 3, false),
|
||||
(Item("common.items.crafting_ing.animal_misc.viscous_ooze"), 1, false),
|
||||
],
|
||||
craft_sprite: Some(Cauldron),
|
||||
),
|
||||
"potion_combustion": (
|
||||
output: ("common.items.consumable.potion_combustion", 1),
|
||||
inputs: [
|
||||
|
@ -24,8 +24,8 @@ loot_tables: [
|
||||
(20.375, true, "common.trading.food"),
|
||||
|
||||
// Recipes
|
||||
(1.0, true, "common.trading.sellable_recipe"),
|
||||
(1.0, false, "common.trading.unsellable_recipe"),
|
||||
(1.8, true, "common.trading.sellable_recipe"),
|
||||
(1.5, false, "common.trading.unsellable_recipe"),
|
||||
|
||||
// Potions
|
||||
//
|
||||
@ -50,5 +50,6 @@ good_scaling: [
|
||||
(Armor, 0.025), // common.items.armor.misc.pants.worker_blue
|
||||
(Tools, 0.015487), // common.items.weapons.staff.starter_staff
|
||||
(Ingredients, 0.034626), // common.items.crafting_ing.leather_scraps
|
||||
(Wood, 0.034626), // common.items.log.wood
|
||||
(Recipe, 0.01), // common.items.recipes
|
||||
])
|
||||
|
@ -1,7 +1,50 @@
|
||||
[
|
||||
// Legendary sceptres
|
||||
// Purple Linen set
|
||||
Set([
|
||||
"common.items.weapons.sceptre.root_evil",
|
||||
"common.items.weapons.sceptre.caduceus",
|
||||
"common.items.armor.cloth_purple.belt",
|
||||
"common.items.armor.cloth_purple.chest",
|
||||
"common.items.armor.cloth_purple.foot",
|
||||
"common.items.armor.cloth_purple.hand",
|
||||
"common.items.armor.cloth_purple.pants",
|
||||
"common.items.armor.cloth_purple.shoulder",
|
||||
]),
|
||||
|
||||
// Green Linen set
|
||||
Set([
|
||||
"common.items.armor.cloth_green.belt",
|
||||
"common.items.armor.cloth_green.chest",
|
||||
"common.items.armor.cloth_green.foot",
|
||||
"common.items.armor.cloth_green.hand",
|
||||
"common.items.armor.cloth_green.pants",
|
||||
"common.items.armor.cloth_green.shoulder",
|
||||
]),
|
||||
|
||||
// Blue Linen set
|
||||
Set([
|
||||
"common.items.armor.cloth_blue.belt",
|
||||
"common.items.armor.cloth_blue.chest",
|
||||
"common.items.armor.cloth_blue.foot",
|
||||
"common.items.armor.cloth_blue.hand",
|
||||
"common.items.armor.cloth_blue.pants",
|
||||
"common.items.armor.cloth_blue.shoulder_0",
|
||||
"common.items.armor.cloth_blue.shoulder_1",
|
||||
]),
|
||||
|
||||
// Worker/starter clothing
|
||||
Set([
|
||||
"common.items.armor.misc.chest.worker_green_0",
|
||||
"common.items.armor.misc.chest.worker_green_1",
|
||||
"common.items.armor.misc.chest.worker_orange_0",
|
||||
"common.items.armor.misc.chest.worker_orange_1",
|
||||
"common.items.armor.misc.chest.worker_purple_0",
|
||||
"common.items.armor.misc.chest.worker_purple_1",
|
||||
"common.items.armor.misc.chest.worker_purple_brown",
|
||||
"common.items.armor.misc.chest.worker_red_0",
|
||||
"common.items.armor.misc.chest.worker_red_1",
|
||||
"common.items.armor.misc.chest.worker_yellow_0",
|
||||
"common.items.armor.misc.chest.worker_yellow_1",
|
||||
"common.items.armor.misc.pants.worker_blue",
|
||||
"common.items.armor.misc.pants.worker_brown",
|
||||
"common.items.armor.misc.foot.sandals",
|
||||
]),
|
||||
]
|
||||
|
@ -6,40 +6,40 @@
|
||||
[
|
||||
// Recipes
|
||||
// Misc Groups
|
||||
(1.0, Item("common.items.recipes.charms")),
|
||||
(1.0, Item("common.items.recipes.explosives")),
|
||||
(1.0, Item("common.items.recipes.gliders")),
|
||||
(1.0, Item("common.items.recipes.instruments")),
|
||||
(1.25, Item("common.items.recipes.charms")),
|
||||
(1.25, Item("common.items.recipes.explosives")),
|
||||
(1.25, Item("common.items.recipes.gliders")),
|
||||
(1.25, Item("common.items.recipes.instruments")),
|
||||
// Equipment
|
||||
(1.0, Item("common.items.recipes.equipment.moderate")),
|
||||
(0.2, Item("common.items.recipes.equipment.advanced")),
|
||||
(0.3, Item("common.items.recipes.equipment.advanced")),
|
||||
// Armors
|
||||
(0.7, Item("common.items.recipes.armor.steel")),
|
||||
(0.7, Item("common.items.recipes.armor.silken")),
|
||||
(0.7, Item("common.items.recipes.armor.scale")),
|
||||
(0.7, Item("common.items.recipes.weapons.steel")),
|
||||
(0.7, Item("common.items.recipes.weapons.hardwood")),
|
||||
(0.4, Item("common.items.recipes.armor.cobalt")),
|
||||
(0.4, Item("common.items.recipes.armor.druid")),
|
||||
(0.4, Item("common.items.recipes.armor.carapace")),
|
||||
(0.4, Item("common.items.recipes.weapons.cobalt")),
|
||||
(0.4, Item("common.items.recipes.weapons.ironwood")),
|
||||
(0.2, Item("common.items.recipes.armor.bloodsteel")),
|
||||
(0.2, Item("common.items.recipes.armor.moonweave")),
|
||||
(0.2, Item("common.items.recipes.armor.primal")),
|
||||
(0.2, Item("common.items.recipes.weapons.bloodsteel")),
|
||||
(0.2, Item("common.items.recipes.weapons.frostwood")),
|
||||
(0.1, Item("common.items.recipes.armor.orichalcum")),
|
||||
(0.1, Item("common.items.recipes.armor.sunsilk")),
|
||||
(0.1, Item("common.items.recipes.armor.dragonscale")),
|
||||
(0.1, Item("common.items.recipes.armor.brinestone")),
|
||||
(0.1, Item("common.items.recipes.weapons.orichalcum")),
|
||||
(0.1, Item("common.items.recipes.weapons.eldwood")),
|
||||
(1.25, Item("common.items.recipes.armor.steel")),
|
||||
(1.25, Item("common.items.recipes.armor.silken")),
|
||||
(1.25, Item("common.items.recipes.armor.scale")),
|
||||
(1.25, Item("common.items.recipes.weapons.steel")),
|
||||
(1.25, Item("common.items.recipes.weapons.hardwood")),
|
||||
(0.65, Item("common.items.recipes.armor.cobalt")),
|
||||
(0.65, Item("common.items.recipes.armor.druid")),
|
||||
(0.65, Item("common.items.recipes.armor.carapace")),
|
||||
(0.65, Item("common.items.recipes.weapons.cobalt")),
|
||||
(0.65, Item("common.items.recipes.weapons.ironwood")),
|
||||
(0.38, Item("common.items.recipes.armor.bloodsteel")),
|
||||
(0.38, Item("common.items.recipes.armor.moonweave")),
|
||||
(0.38, Item("common.items.recipes.armor.primal")),
|
||||
(0.38, Item("common.items.recipes.weapons.bloodsteel")),
|
||||
(0.38, Item("common.items.recipes.weapons.frostwood")),
|
||||
(0.25, Item("common.items.recipes.armor.sunsilk")),
|
||||
(0.25, Item("common.items.recipes.armor.orichalcum")),
|
||||
(0.25, Item("common.items.recipes.armor.dragonscale")),
|
||||
(0.25, Item("common.items.recipes.weapons.orichalcum")),
|
||||
(0.25, Item("common.items.recipes.weapons.eldwood")),
|
||||
(0.25, Item("common.items.recipes.armor.brinestone")),
|
||||
// Unique items
|
||||
(1.0, Item("common.items.recipes.unique.seashell_necklace")),
|
||||
(0.8, Item("common.items.recipes.unique.winged_coronet")),
|
||||
(1.25, Item("common.items.recipes.unique.seashell_necklace")),
|
||||
(0.6, Item("common.items.recipes.unique.winged_coronet")),
|
||||
(0.5, Item("common.items.recipes.unique.troll_hide_pack")),
|
||||
(0.3, Item("common.items.recipes.unique.abyssal_gorget")),
|
||||
(0.1, Item("common.items.recipes.unique.mindflayer_spellbag")),
|
||||
(0.2, Item("common.items.recipes.unique.abyssal_gorget")),
|
||||
(0.15, Item("common.items.recipes.unique.mindflayer_spellbag")),
|
||||
(0.1, Item("common.items.recipes.unique.polaris")),
|
||||
]
|
||||
|
@ -1,3 +1,4 @@
|
||||
announcement = "Beep Boop!"
|
||||
position = [17720.0, 14951.0, 237.0]
|
||||
orientation = 0
|
||||
|
||||
|
106
src/bot.rs
106
src/bot.rs
@ -21,12 +21,11 @@ use veloren_common::{
|
||||
tool::AbilityMap,
|
||||
ChatType, ControllerInputs, Item, Ori, Pos,
|
||||
},
|
||||
outcome::Outcome,
|
||||
time::DayPeriod,
|
||||
trade::{PendingTrade, TradeAction, TradeResult},
|
||||
uid::Uid,
|
||||
uuid::Uuid,
|
||||
DamageSource, ViewDistances,
|
||||
ViewDistances,
|
||||
};
|
||||
use veloren_common_net::sync::WorldSyncExt;
|
||||
|
||||
@ -37,12 +36,10 @@ const COINS: ItemDefinitionId =
|
||||
const CLIENT_TPS: Duration = Duration::from_millis(33);
|
||||
const TRADE_ACTION_DELAY: Duration = Duration::from_millis(300);
|
||||
const ACCOUNCEMENT_DELAY: Duration = Duration::from_mins(45);
|
||||
const OUCH_DELAY: Duration = Duration::from_secs(2);
|
||||
|
||||
/// An active connection to the Veloren server that will attempt to run every time the `tick`
|
||||
/// function is called.
|
||||
pub struct Bot {
|
||||
username: String,
|
||||
position: Pos,
|
||||
orientation: Ori,
|
||||
admins: Vec<String>,
|
||||
@ -63,7 +60,6 @@ pub struct Bot {
|
||||
previous_trade_receipt: Option<Reciept>,
|
||||
last_trade_action: Instant,
|
||||
last_announcement: Instant,
|
||||
last_ouch: Instant,
|
||||
sort_count: u8,
|
||||
}
|
||||
|
||||
@ -140,7 +136,6 @@ impl Bot {
|
||||
let now = Instant::now();
|
||||
|
||||
Ok(Bot {
|
||||
username,
|
||||
position,
|
||||
orientation,
|
||||
admins,
|
||||
@ -157,7 +152,6 @@ impl Bot {
|
||||
previous_trade_receipt: None,
|
||||
last_trade_action: now,
|
||||
last_announcement: now,
|
||||
last_ouch: now,
|
||||
sort_count: 0,
|
||||
announcement,
|
||||
})
|
||||
@ -284,6 +278,11 @@ impl Bot {
|
||||
Some(price_correction_message)
|
||||
}
|
||||
}
|
||||
"location" => {
|
||||
self.send_location_info(&sender)?;
|
||||
|
||||
None
|
||||
}
|
||||
"ori" => {
|
||||
if self.is_user_admin(&sender)? {
|
||||
if let Some(new_rotation) = split_content.next() {
|
||||
@ -366,36 +365,6 @@ impl Bot {
|
||||
);
|
||||
}
|
||||
}
|
||||
VelorenEvent::Outcome(Outcome::ProjectileHit {
|
||||
target: Some(target),
|
||||
..
|
||||
}) => {
|
||||
if let Some(uid) = self.client.uid() {
|
||||
if uid == target && self.last_ouch.elapsed() > OUCH_DELAY {
|
||||
self.client
|
||||
.send_command("say".to_string(), vec!["Ouch!".to_string()]);
|
||||
|
||||
self.last_ouch = Instant::now();
|
||||
}
|
||||
}
|
||||
}
|
||||
VelorenEvent::Outcome(Outcome::HealthChange { info, .. }) => {
|
||||
if let Some(DamageSource::Buff(_)) = info.cause {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
if let Some(uid) = self.client.uid() {
|
||||
if uid == info.target
|
||||
&& info.amount.is_sign_negative()
|
||||
&& self.last_ouch.elapsed() > OUCH_DELAY
|
||||
{
|
||||
self.client
|
||||
.send_command("say".to_string(), vec!["That hurt!".to_string()]);
|
||||
|
||||
self.last_ouch = Instant::now();
|
||||
}
|
||||
}
|
||||
}
|
||||
VelorenEvent::TradeComplete { result, trade } => {
|
||||
let my_party = trade
|
||||
.which_party(self.client.uid().ok_or("Failed to find uid")?)
|
||||
@ -439,47 +408,46 @@ impl Bot {
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn send_location_info(&mut self, target: &Uid) -> Result<(), String> {
|
||||
let player_name = self
|
||||
.find_player_alias(target)
|
||||
.ok_or("Failed to find player alias")?
|
||||
.to_string();
|
||||
let location = self
|
||||
.client
|
||||
.sites()
|
||||
.into_iter()
|
||||
.find_map(|(_, SiteInfoRich { site, .. })| {
|
||||
let x_difference = self.position.0[0] - site.wpos[0] as f32;
|
||||
let y_difference = self.position.0[1] - site.wpos[1] as f32;
|
||||
|
||||
if x_difference.abs() < 100.0 && y_difference.abs() < 100.0 {
|
||||
site.name.clone()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.unwrap_or(format!("{:?}", self.position));
|
||||
|
||||
self.client.send_command(
|
||||
"tell".to_string(),
|
||||
vec![player_name, format!("I am at {location}.")],
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Make the bot's trading and help accouncements
|
||||
///
|
||||
/// Currently, this can make two announcements: one in /region with basic usage instructions
|
||||
/// is always made. If an announcement was provided when the bot was created, it will make it
|
||||
/// in /world.
|
||||
fn handle_announcement(&mut self) -> Result<(), String> {
|
||||
debug!("Making an announcement");
|
||||
|
||||
self.client.send_command(
|
||||
"region".to_string(),
|
||||
vec![format!(
|
||||
"I'm a bot. You can trade with me or check prices: '/tell {} price [search_term]'.",
|
||||
self.username
|
||||
)],
|
||||
);
|
||||
|
||||
if let Some(announcement) = &self.announcement {
|
||||
let announcement = if announcement.contains("{location}") {
|
||||
let location = self
|
||||
.client
|
||||
.sites()
|
||||
.into_iter()
|
||||
.find_map(|(_, SiteInfoRich { site, .. })| {
|
||||
let x_difference = self.position.0[0] - site.wpos[0] as f32;
|
||||
let y_difference = self.position.0[1] - site.wpos[1] as f32;
|
||||
|
||||
if x_difference.abs() < 100.0 && y_difference.abs() < 100.0 {
|
||||
site.name.clone()
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
.unwrap_or(format!("{:?}", self.position));
|
||||
|
||||
announcement.replace("{location}", &location)
|
||||
} else {
|
||||
announcement.clone()
|
||||
};
|
||||
debug!("Making an announcement");
|
||||
|
||||
self.client
|
||||
.send_command("world".to_string(), vec![announcement]);
|
||||
.send_command("region".to_string(), vec![announcement.to_string()]);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
Loading…
Reference in New Issue
Block a user