diff --git a/call_handlers/firefly_stuff.lua b/call_handlers/firefly_stuff.lua index eaa5dc4..f96b8da 100644 --- a/call_handlers/firefly_stuff.lua +++ b/call_handlers/firefly_stuff.lua @@ -66,4 +66,15 @@ function FireflyCallHandler:add_goblin_citizen_command(session, response) return true end +function FireflyCallHandler:market(session, response, source_entity) + validator.expect_argument_types({'Entity'}, source_entity) + validator.expect.matching_player_id(session.player_id, source_entity) + + local market_component = source_entity:get_component("swamp_goblins:market") + if market_component then + return market_component:create_shop() + end + return false +end + return FireflyCallHandler \ No newline at end of file diff --git a/components/market/market.lua b/components/market/market.lua new file mode 100644 index 0000000..81e9f29 --- /dev/null +++ b/components/market/market.lua @@ -0,0 +1,82 @@ +local GoblinMarketComponent = class() + +function GoblinMarketComponent:initialize() + self._sv._restock_timer = nil +end + +function GoblinMarketComponent:post_activate() + self.json = radiant.entities.get_json(self) +end + + +function GoblinMarketComponent:create_shop() + local player_id = radiant.entities.get_player_id(self._entity) + local population = stonehearth.population:get_population(player_id) + local city_tier = population:get_city_tier() or 0 + if city_tier < 1 then + city_tier = 1 + end + city_tier = "tier_" .. city_tier + local info = radiant.resources.load_json(self.json[city_tier]).shop_info + local shop_name = radiant.entities.get_entity_data(self._entity, 'stonehearth:catalog').display_name + info.name = shop_name or info.name + info.title = shop_name or info.title + + local shop = stonehearth.shop:create_shop(player_id, info.name, info.inventory) + + local bulletin = stonehearth.bulletin_board:post_bulletin(player_id) + :set_ui_view('StonehearthShopBulletinDialog') + :set_callback_instance(self) + :set_sticky(true) + :set_data({ + shop = shop, + title = info.title, + opened_callback = '_on_opened', + closed_callback = '_on_closed' + }) + self.shop = shop + self.bulletin = bulletin + + local commands_component = self._entity:get_component("stonehearth:commands") + commands_component:set_command_enabled('swamp_goblins:commands:market',false) +end + +function GoblinMarketComponent:destroy() + self:close_shop() + if self._sv._restock_timer then + self._sv._restock_timer:destroy() + self._sv._restock_timer = nil + end +end + +function GoblinMarketComponent:_on_opened() + radiant.effects.run_effect(self._entity, 'emote_count') +end + +function GoblinMarketComponent:_on_closed() + self:close_shop() + self._sv._restock_timer = stonehearth.calendar:set_persistent_timer('shopkeeper restocking', '1d', function() + self:open_shop() + end) + radiant.effects.run_effect(self._entity, 'stonehearth:effects:spawn_entity') +end + +function GoblinMarketComponent:open_shop() + local commands_component = self._entity:get_component("stonehearth:commands") + commands_component:set_command_enabled('swamp_goblins:commands:market',true) + self._entity:get_component('render_info'):set_model_variant("default") +end + +function GoblinMarketComponent:close_shop() + self._entity:get_component('render_info'):set_model_variant("closed") + if self.shop then + stonehearth.shop:destroy_shop(self.shop) + self.shop = nil + end + if self.bulletin then + stonehearth.bulletin_board:remove_bulletin(self.bulletin) + self.bulletin = nil + end +end + +return GoblinMarketComponent \ No newline at end of file diff --git a/data/commands/market/market.json b/data/commands/market/market.json new file mode 100644 index 0000000..b2ef1fb --- /dev/null +++ b/data/commands/market/market.json @@ -0,0 +1,12 @@ +{ + "type": "command", + "name": "market", + "display_name": "i18n(swamp_goblins:data.commands.market.display_name)", + "description": "i18n(swamp_goblins:data.commands.market.description)", + "disabled_description": "i18n(swamp_goblins:data.commands.market.disabled_description)", + "icon": "/stonehearth/data/commands/call_trader/call_trader.png", + "ordinal": 9, + "action": "call", + "function": "swamp_goblins:market", + "args": [] +} \ No newline at end of file diff --git a/entities/decoration/goblin_market/closed.qb b/entities/decoration/goblin_market/closed.qb new file mode 100644 index 0000000..9274141 Binary files /dev/null and b/entities/decoration/goblin_market/closed.qb differ diff --git a/entities/decoration/goblin_market/goblin_market.json b/entities/decoration/goblin_market/goblin_market.json new file mode 100644 index 0000000..9654067 --- /dev/null +++ b/entities/decoration/goblin_market/goblin_market.json @@ -0,0 +1,55 @@ +{ + "type": "entity", + "mixins": "file(goblin_market_ghost.json)", + "components": { + "stonehearth:entity_forms": { + "iconic_form": "file(goblin_market_iconic.json)", + "ghost_form": "file(goblin_market_ghost.json)", + "placeable_on_ground": true + }, + "destination": { + "region": [ + { + "min": {"x": -2, "y": 0, "z": -1 }, + "max": {"x": 4, "y": 2, "z": 2 } + } + ] + }, + "region_collision_shape": { + "region": [ + { + "min": {"x": -2, "y": 0, "z": -1 }, + "max": {"x": 4, "y": 2, "z": 2 } + } + ] + }, + "stonehearth:commands": { + "commands": [ + "swamp_goblins:commands:market" + ] + }, + "swamp_goblins:market": { + "tier_1":"swamp_goblins/data/gm/campaigns/trader/arcs/encounters/tier_1_shops/firefly_shop_1.json", + "tier_2":"swamp_goblins/data/gm/campaigns/trader/arcs/encounters/tier_2_shops/firefly_shop_2.json", + "tier_3":"swamp_goblins/data/gm/campaigns/trader/arcs/encounters/tier_3_shops/firefly_shop_3.json" + } + }, + "entity_data": { + "stonehearth:net_worth": { + "value_in_gold": 28, + "rarity": "uncommon", + "shop_info": { + "buyable": true, + "sellable": true, + "shopkeeper_level": 2, + "shopkeeper_type": "caravan" + } + }, + "stonehearth:appeal": { + "appeal": 18 + }, + "stonehearth:item_quality": { + "variable_quality": true + } + } +} diff --git a/entities/decoration/goblin_market/goblin_market.png b/entities/decoration/goblin_market/goblin_market.png new file mode 100644 index 0000000..1f5d98f Binary files /dev/null and b/entities/decoration/goblin_market/goblin_market.png differ diff --git a/entities/decoration/goblin_market/goblin_market.qb b/entities/decoration/goblin_market/goblin_market.qb new file mode 100644 index 0000000..0741f67 Binary files /dev/null and b/entities/decoration/goblin_market/goblin_market.qb differ diff --git a/entities/decoration/goblin_market/goblin_market_ghost.json b/entities/decoration/goblin_market/goblin_market_ghost.json new file mode 100644 index 0000000..828a8e4 --- /dev/null +++ b/entities/decoration/goblin_market/goblin_market_ghost.json @@ -0,0 +1,40 @@ +{ + "mixins": "stonehearth:mixins:placed_object", + "components": { + "render_info": { + "animation_table": "stonehearth:skeletons:humanoid:female", + "scale": 0.09 + }, + "effect_list": { + "default": "stonehearth/data/rigs/entities/humans/effects/sitting_idle.json" + }, + "model_variants": { + "default": { + "models": [ + "file(goblin_market.qb)", + "file(open.qb)", + "file(trader.qb)" + ] + }, + "closed": { + "models": [ + "file(goblin_market.qb)", + "file(closed.qb)" + ] + } + }, + "mob": { + "model_origin": { "x": -0.05, "y": 0, "z": 0 }, + "region_origin": { "x": 0.5, "y": 0, "z": 0.5 } + } + }, + "entity_data": { + "stonehearth:catalog": { + "display_name": "i18n(swamp_goblins:entities.decoration.goblin_market.display_name)", + "description": "i18n(stonehearth:entities.furniture.blue_market_stall.blue_market_stall_ghost.description)", + "icon": "file(goblin_market.png)", + "category": "decoration", + "material_tags": ["firefly_made", "wood","decoration","cloth","crafted","utility","stockpile_decoration"] + } + } +} \ No newline at end of file diff --git a/entities/decoration/goblin_market/goblin_market_iconic.json b/entities/decoration/goblin_market/goblin_market_iconic.json new file mode 100644 index 0000000..a670109 --- /dev/null +++ b/entities/decoration/goblin_market/goblin_market_iconic.json @@ -0,0 +1,22 @@ +{ + "mixins": "stonehearth:mixins:item_properties", + "type": "entity", + "components": { + "model_variants": { + "default": { + "models": [ + "file(goblin_market_iconic.qb)" + ] + } + }, + "mob": { + "model_origin": { "x": 0, "y": 0, "z": 0 } + } + }, + "entity_data": { + "stonehearth:catalog": { + "is_item": true, + "category": "decoration" + } + } +} \ No newline at end of file diff --git a/entities/decoration/goblin_market/goblin_market_iconic.qb b/entities/decoration/goblin_market/goblin_market_iconic.qb new file mode 100644 index 0000000..251d1b7 Binary files /dev/null and b/entities/decoration/goblin_market/goblin_market_iconic.qb differ diff --git a/entities/decoration/goblin_market/open.qb b/entities/decoration/goblin_market/open.qb new file mode 100644 index 0000000..3177603 Binary files /dev/null and b/entities/decoration/goblin_market/open.qb differ diff --git a/entities/decoration/goblin_market/trader.qb b/entities/decoration/goblin_market/trader.qb new file mode 100644 index 0000000..2549880 Binary files /dev/null and b/entities/decoration/goblin_market/trader.qb differ diff --git a/jobs/bonesmith/recipes/decorations/goblin_market_recipe.json b/jobs/bonesmith/recipes/decorations/goblin_market_recipe.json new file mode 100644 index 0000000..c613af1 --- /dev/null +++ b/jobs/bonesmith/recipes/decorations/goblin_market_recipe.json @@ -0,0 +1,34 @@ +{ + "type": "recipe", + "effort": 44, + "work_units": 15, + "recipe_name": "i18n(swamp_goblins:entities.decoration.goblin_market.display_name)", + "description": "i18n(stonehearth:entities.furniture.blue_market_stall.blue_market_stall_ghost.description)", + "flavor": "i18n(stonehearth:jobs.carpenter.recipes.blue_market_stall_recipe.flavor)", + "portrait": "/swamp_goblins/entities/decoration/goblin_market/goblin_market.png", + "workshop": "swamp_goblins:bonesmith:workbench", + "level_requirement": 3, + "ingredients": [ + { + "material": "wood resource", + "count": 1 + }, + { + "material": "fiber resource", + "count": 1 + }, + { + "uri": "swamp_goblins:decoration:certificate", + "count": 1 + }, + { + "uri": "swamp_goblins:decoration:potted_cattail", + "count": 1 + } + ], + "produces": [ + { + "item": "swamp_goblins:decoration:goblin_market" + } + ] +} \ No newline at end of file diff --git a/jobs/bonesmith/recipes/recipes.json b/jobs/bonesmith/recipes/recipes.json index ad58b9a..600b97a 100644 --- a/jobs/bonesmith/recipes/recipes.json +++ b/jobs/bonesmith/recipes/recipes.json @@ -198,6 +198,9 @@ }, "wall_mask": { "recipe": "file(decorations/wall_mask_recipe.json)" + }, + "goblin_market": { + "recipe": "file(decorations/goblin_market_recipe.json)" } } }, diff --git a/locales/en.json b/locales/en.json index 05f2f1b..8c0c947 100644 --- a/locales/en.json +++ b/locales/en.json @@ -72,6 +72,11 @@ "display_name":"Open the Goblinpedia", "description":"Click to read it" }, + "market":{ + "display_name":"Shop", + "description":"Opens a trading window", + "disabled_description":"Waiting a new trader" + }, "music":{ "display_name":"Play Music", "description":"Will call someone to play this instrument", @@ -813,8 +818,11 @@ "description": "Commemorative totem, resembling someone from the clan", "flavor": "Don't worry, it is not made from real skulls, just white paint" }, + "goblin_market": { + "display_name": "Firefly Bazaar" + }, "goblin_market_stall": { - "display_name": "Firefly Market Stall" + "display_name": "Trading Stall" }, "mini_fountain": { "display_name": "Mini Fountain", diff --git a/manifest.json b/manifest.json index 6826617..d4150f8 100644 --- a/manifest.json +++ b/manifest.json @@ -121,6 +121,7 @@ "commands:enable_egg_spot": "file(data/commands/enable_egg_spot)", "commands:cancel_egg_spot": "file(data/commands/enable_egg_spot/cancel_egg_spot.json)", "commands:goblinpedia": "file(data/commands/goblinpedia)", + "commands:market": "file(data/commands/market)", "commands:travel": "file(data/commands/travel)", "commands:music": "file(data/commands/music)", @@ -164,6 +165,7 @@ "decoration:big_firefly_essense": "file(entities/decoration/big_firefly_essense)", "decoration:certificate": "file(entities/decoration/certificate)", "decoration:fiber_rug": "file(entities/decoration/fiber_rug)", + "decoration:goblin_market": "file(entities/decoration/goblin_market)", "decoration:goblin_market_stall": "file(entities/decoration/goblin_market_stall)", "decoration:goblin_large_totem": "file(entities/decoration/goblin_large_totem)", "decoration:goblin_small_totem": "file(entities/decoration/goblin_small_totem)", @@ -770,6 +772,10 @@ "add_goblin_citizen_command": { "controller": "file(call_handlers/firefly_stuff.lua)", "endpoint": "server" + }, + "market": { + "controller": "file(call_handlers/firefly_stuff.lua)", + "endpoint": "server" } }, "components": { @@ -778,6 +784,7 @@ "firefly_goblin": "file(components/firefly_goblin/firefly_goblin.lua)", "firefly": "file(components/firefly/firefly_component.lua)", "lay_egg_spot": "file(components/lay_egg_spot/lay_egg_spot.lua)", + "market": "file(components/market/market.lua)", "monster_spawner": "file(components/monster_spawner/monster_spawner_component.lua)", "music": "file(components/music/music.lua)", "replace_with_on_world_gen":"file(components/replace_with_on_world_gen/replace_with_on_world_gen.lua)", @@ -820,6 +827,10 @@ "weather_scripts:foggy": "file(data/weather/foggy/foggy.lua)" }, "object_commands":{ + "market":[ + "_on_opened", + "_on_closed" + ], "warrior_hearth":[ "_spawn_wave", "_declined" diff --git a/swamp_goblins_server.lua b/swamp_goblins_server.lua index 63d735b..d79d000 100644 --- a/swamp_goblins_server.lua +++ b/swamp_goblins_server.lua @@ -1,8 +1,10 @@ swamp_goblins = {} -print("Swamp Goblins Mod version 20.4.2") +print("Swamp Goblins Mod version 20.4.7") --[[ +move default market stall to earthmaster + non blue skin trait swamp zilla @@ -16,8 +18,6 @@ vine cobblestone wall waves: boss, bunnies, orcs, kobolds, ogres -add visible goblin trader - and goblin market import hearthlings/goblins to the other kingdom mosquito model diff --git a/update_log.txt b/update_log.txt index c218238..957b61f 100644 --- a/update_log.txt +++ b/update_log.txt @@ -1,6 +1,7 @@ Additions: Stone chest, with space for 48 items Immigrant orcs can also be beast tamers (defaults were worker and footman only) +Firefly bazaar, works the same way as market stalls, but only summon goblins traders Changes: Slightly better hunting, goblins only detects possible targets in a 48 blocks range (instead of default 64) and darts will slow critters way more, for a longer time, and do more damage. This should help with faster hunting and less chasing.