From ccdc9cc7dec26c21816128eba30695982e29f6b6 Mon Sep 17 00:00:00 2001 From: lcdr Date: Wed, 1 Nov 2017 10:28:55 +0100 Subject: [PATCH] v2017.11.01 - fixed turret quickbuilds not despawning - fixed survival objects not spawning (survival still needs work though) - fixed not being able to launch rockets using the mouse - implemented minigame achievement mission task type - implemented missions where items are removed on complete --- luserver/commands/misc.py | 6 ++---- luserver/components/char/__init__.py | 5 ++++- luserver/components/char/mission.py | 18 +++++++++++++---- luserver/components/inventory.py | 10 +++++++++- luserver/components/launchpad.py | 8 ++++++-- luserver/components/mission.py | 3 +++ luserver/components/scripted_activity.py | 6 +++--- luserver/components/stats.py | 5 +++++ .../avant_gardens/survival/stromling_mech.py | 5 +++++ .../avant_gardens/survival/world_control.py | 20 ++++++++++++++++--- luserver/scripts/avant_gardens/turret.py | 9 +++++++++ luserver/world.py | 2 ++ runtime/db/init.py | 7 +++++++ runtime/db/scripts.py | 1 + 14 files changed, 87 insertions(+), 18 deletions(-) create mode 100644 luserver/scripts/avant_gardens/survival/stromling_mech.py diff --git a/luserver/commands/misc.py b/luserver/commands/misc.py index 202b6d8..27a7015 100644 --- a/luserver/commands/misc.py +++ b/luserver/commands/misc.py @@ -135,7 +135,7 @@ class HighStats(ChatCommand): sender.stats.max_life = 99 sender.stats.max_armor = 99 sender.stats.max_imagination = 99 - RefillStats.run(args, sender) + sender.stats.refill_stats() class Invisibility(ChatCommand): # not working @@ -196,9 +196,7 @@ class RefillStats(ChatCommand): super().__init__("refillstats") def run(self, args, sender): - sender.stats.life = sender.stats.max_life - sender.stats.armor = sender.stats.max_armor - sender.stats.imagination = sender.stats.max_imagination + sender.stats.refill_stats() class Rules(ChatCommand): def __init__(self): diff --git a/luserver/components/char/__init__.py b/luserver/components/char/__init__.py index 39cdce9..9bf0303 100644 --- a/luserver/components/char/__init__.py +++ b/luserver/components/char/__init__.py @@ -235,7 +235,10 @@ class CharacterComponent(Component, CharActivity, CharCamera, CharMission, CharP if self.gm_flag or is_creation: out.write(c_bit(self.pvp_enabled)) out.write(c_bit(self.show_gm_status)) - out.write(c_ubyte(self.account.gm_level)) + if self.account is None: + out.write(c_ubyte(0)) + else: + out.write(c_ubyte(self.account.gm_level)) out.write(c_bit(False)) out.write(c_ubyte(0)) if self.gm_flag: diff --git a/luserver/components/char/mission.py b/luserver/components/char/mission.py index 6861919..476e5b1 100644 --- a/luserver/components/char/mission.py +++ b/luserver/components/char/mission.py @@ -7,7 +7,7 @@ from ...messages import single from ...world import server from ...math.vector import Vector3 from ..inventory import InventoryType, LootType, Stack -from ..mission import check_prereqs, MissionProgress, MissionState, TaskType +from ..mission import check_prereqs, MissionProgress, MissionState, ObtainItemType, TaskType class CharMission: def __init__(self): @@ -50,6 +50,9 @@ class CharMission: if task_type in (TaskType.UseEmote, TaskType.UseSkill): if parameter not in task.parameter: continue + if task_type == TaskType.MinigameAchievement: + if parameter[0] != task.parameter or parameter[1] < task.target_value: + continue if isinstance(task.target, tuple): if target not in task.target: continue @@ -67,6 +70,9 @@ class CharMission: task.parameter.add(increment) task.value = len(task.parameter) update = increment + elif task.type == TaskType.MinigameAchievement: + task.value = task.target_value + update = task.value else: task.value = min(task.value+increment, task.target_value) update = task.value @@ -95,6 +101,13 @@ class CharMission: self.set_currency(currency=self.currency + mission.rew_currency, position=Vector3.zero, source_type=source_type) self.modify_lego_score(mission.rew_universe_score, source_type=source_type) + for task in mission.tasks: + if task.type == TaskType.ObtainItem and task.parameter == ObtainItemType.RemoveOnComplete: + self.object.inventory.remove_item_from_inv(InventoryType.Max, lot=task.target[0], amount=task.target_value) + + if mission.rew_max_items: + self.object.inventory.set_inventory_size(inventory_type=InventoryType.Items, size=len(self.object.inventory.items)+mission.rew_max_items) + if not mission.is_choice_reward: for lot, amount in mission.rew_items: self.object.inventory.add_item_to_inventory(lot, amount, source_type=source_type) @@ -105,9 +118,6 @@ class CharMission: self.object.stats.max_life += mission.rew_max_life self.object.stats.max_imagination += mission.rew_max_imagination - if mission.rew_max_items: - self.object.inventory.set_inventory_size(inventory_type=InventoryType.Items, size=len(self.object.inventory.items)+mission.rew_max_items) - self.notify_mission(mission_id, mission_state=MissionState.Completed, sending_rewards=False) # No longer required, delete to free memory in db diff --git a/luserver/components/inventory.py b/luserver/components/inventory.py index abcddb6..8711a33 100644 --- a/luserver/components/inventory.py +++ b/luserver/components/inventory.py @@ -324,7 +324,7 @@ class InventoryComponent(Component): assert subkey == 0 assert trade_id == 0 if inventory_type == InventoryType.Max: - inventories = [InventoryType.Items, InventoryType.Models, InventoryType.MissionObjects] + inventories = [InventoryType.Items, InventoryType.Bricks, InventoryType.Models, InventoryType.MissionObjects] else: inventories = [inventory_type] for inventory_type in inventories: @@ -398,6 +398,14 @@ class InventoryComponent(Component): if other_item.item_type == item.item_type and other_item.object_id != item.object_id: self.un_equip_inventory(item_to_unequip=other_item.object_id) break + + # if this is a rocket, check for launchpads nearby, and possibly activate the launch sequence + if item.lot == 6416 and self.object.char.traveling_rocket is None: + for obj in server.world_data.objects.values(): + if hasattr(obj, "launchpad"): + if self.object.physics.position.sq_distance(obj.physics.position) < 25: + obj.launchpad.launch(self.object, item) + break return def un_equip_inventory(self, even_if_dead:bool=False, ignore_cooldown:bool=False, out_success:bool=False, item_to_unequip:c_int64=None, replacement_object_id:c_int64=0): diff --git a/luserver/components/launchpad.py b/luserver/components/launchpad.py index 9631927..4b22e94 100644 --- a/luserver/components/launchpad.py +++ b/luserver/components/launchpad.py @@ -12,6 +12,7 @@ log = logging.getLogger(__name__) class LaunchpadComponent(Component): def __init__(self, obj, set_vars, comp_id): super().__init__(obj, set_vars, comp_id) + self.object.launchpad = self self.target_world = server.db.launchpad_component[comp_id][0] self.default_world_id = server.db.launchpad_component[comp_id][1] self.respawn_point_name = server.db.launchpad_component[comp_id][2] @@ -30,12 +31,15 @@ class LaunchpadComponent(Component): for model in player.inventory.models: if model is not None and model.lot == 6416: - player.char.traveling_rocket = model.module_lots - self.fire_event_client_side(args="RocketEquipped", obj=model, sender=player) + self.launch(player, model) break else: player.char.disp_tooltip("You don't have a rocket!") + def launch(self, player, rocket): + player.char.traveling_rocket = rocket.module_lots + self.fire_event_client_side(args="RocketEquipped", obj=rocket, sender=player) + def fire_event_server_side(self, player, args:str=None, param1:c_int=-1, param2:c_int=-1, param3:c_int=-1, sender_id:c_int64=None): if args == "ZonePlayer": if param2: diff --git a/luserver/components/mission.py b/luserver/components/mission.py index 7ec79d5..4c82bbc 100644 --- a/luserver/components/mission.py +++ b/luserver/components/mission.py @@ -25,6 +25,9 @@ class MissionState: ReadyToComplete = 4 Completed = 8 +class ObtainItemType: + RemoveOnComplete = 2 + from persistent import Persistent class MissionTask(Persistent): diff --git a/luserver/components/scripted_activity.py b/luserver/components/scripted_activity.py index d463a63..2217be0 100644 --- a/luserver/components/scripted_activity.py +++ b/luserver/components/scripted_activity.py @@ -13,11 +13,11 @@ class ScriptedActivityComponent(Component): self.object.scripted_activity = self self._flags["activity_values"] = "activity_flag" self.activity_values = {} - self.comp_id = comp_id + self.activity_id = comp_id if "transfer_world_id" in set_vars: self.transfer_world_id = set_vars["transfer_world_id"] - elif self.comp_id in server.db.activities: - activity = server.db.activities[self.comp_id] + elif self.activity_id in server.db.activities: + activity = server.db.activities[self.activity_id] self.transfer_world_id = activity[0] else: self.transfer_world_id = None diff --git a/luserver/components/stats.py b/luserver/components/stats.py index c926c3c..ab3fee0 100644 --- a/luserver/components/stats.py +++ b/luserver/components/stats.py @@ -139,6 +139,11 @@ class StatsSubcomponent(Component): if self.object.spawner_object is not None: self.object.spawner_object.handle("on_spawned_destruction") + def refill_stats(self): + self.life = self.max_life + self.armor = self.max_armor + self.imagination = self.max_imagination + @broadcast def die(self, client_death:bool=False, spawn_loot:bool=True, death_type:str=None, direction_relative_angle_xz:float=None, direction_relative_angle_y:float=None, direction_relative_force:float=None, kill_type:c_uint=0, killer:GameObject=None, loot_owner:GameObject=0): self.object.handle("on_death", killer, silent=True) diff --git a/luserver/scripts/avant_gardens/survival/stromling_mech.py b/luserver/scripts/avant_gardens/survival/stromling_mech.py new file mode 100644 index 0000000..b0d457f --- /dev/null +++ b/luserver/scripts/avant_gardens/survival/stromling_mech.py @@ -0,0 +1,5 @@ +import luserver.components.script as script + +class ScriptComponent(script.ScriptComponent): + def on_startup(self): + self.object.stats.faction = 4 diff --git a/luserver/scripts/avant_gardens/survival/world_control.py b/luserver/scripts/avant_gardens/survival/world_control.py index d028488..91287e8 100644 --- a/luserver/scripts/avant_gardens/survival/world_control.py +++ b/luserver/scripts/avant_gardens/survival/world_control.py @@ -12,6 +12,7 @@ from luserver.math.quaternion import Quaternion # todo: change this to a separate activity manager script +BASE_SPAWNERS = "Base_MobA", "Base_MobB","Base_MobC" SURVIVAL_MISSIONS = [ (479, 60), (1153, 180), @@ -40,13 +41,20 @@ class ScriptComponent(script.ScriptComponent): player.char.teleport(ignore_y=False, pos=spawn.physics.position, set_rotation=True, x=spawn.physics.rotation.x, y=spawn.physics.rotation.y, z=spawn.physics.rotation.z, w=spawn.physics.rotation.w) def start(self): + if len(self.object.scripted_activity.activity_values) == 1: + self.game_type = "solo" + else: + self.game_type = "team" + server.spawners["Smash_01"].spawner.activate() + for spawner in BASE_SPAWNERS: + server.spawners[spawner].spawner.activate() + self.start_time = time.time() self.tick_handle = self.object.call_later(1, self.tick) self.object.scripted_activity.activity_start() - self.set_network_var("Clear_Scoreboard", LDFDataType.BOOLEAN, True) - self.set_network_var("Start_Wave_Message", LDFDataType.STRING, "Start!") self.set_network_var("wavesStarted", LDFDataType.BOOLEAN, True) - + self.set_network_var("Start_Wave_Message", LDFDataType.STRING, "Start!") + self.set_network_var("Clear_Scoreboard", LDFDataType.BOOLEAN, True) leaderboard = LDF() leaderboard.ldf_set("ADO.Result", LDFDataType.BOOLEAN, True) leaderboard.ldf_set("Result.Count", LDFDataType.INT32, 1) @@ -54,6 +62,7 @@ class ScriptComponent(script.ScriptComponent): for player_id in self.object.scripted_activity.activity_values: player = server.get_object(player_id) + player.stats.refill_stats() self.object.scripted_activity.send_activity_summary_leaderboard_data(game_id=5, info_type=1, leaderboard_data=leaderboard, throttled=False, weekly=False, player=player) def game_over(self, player): @@ -62,6 +71,10 @@ class ScriptComponent(script.ScriptComponent): self.object.cancel_callback(self.tick_handle) self.script_network_vars.clear() + server.spawners["Smash_01"].spawner.destroy() + for spawner in BASE_SPAWNERS: + server.spawners[spawner].spawner.destroy() + for player_id, values in self.object.scripted_activity.activity_values.items(): player = server.get_object(player_id) player.char.request_resurrect() @@ -74,6 +87,7 @@ class ScriptComponent(script.ScriptComponent): for mission_id, time in SURVIVAL_MISSIONS: if player_time > time: player.char.update_mission_task(TaskType.Script, self.object.lot, mission_id=mission_id) + player.char.update_mission_task(TaskType.MinigameAchievement, self.object.scripted_activity.activity_id, ("survival_time_"+self.game_type, 400)) def tick(self): self.set_network_var("Update_Timer", LDFDataType.DOUBLE, time.time()-self.start_time) diff --git a/luserver/scripts/avant_gardens/turret.py b/luserver/scripts/avant_gardens/turret.py index 7fa83b2..ac10a7e 100644 --- a/luserver/scripts/avant_gardens/turret.py +++ b/luserver/scripts/avant_gardens/turret.py @@ -1,5 +1,14 @@ import luserver.components.script as script +from luserver.components.rebuild import RebuildState class ScriptComponent(script.ScriptComponent): + def on_startup(self): + self.die_callback = self.object.call_later(20, self.die_if_not_building) + def complete_rebuild(self, player): self.object.physics.lock_node_rotation(node_name=b"base") + self.object.cancel_callback(self.die_callback) + + def die_if_not_building(self): + if self.object.rebuild.rebuild_state != RebuildState.Building: + self.object.destructible.simply_die() diff --git a/luserver/world.py b/luserver/world.py index fa19516..5306361 100644 --- a/luserver/world.py +++ b/luserver/world.py @@ -22,6 +22,8 @@ class World(Enum): AvantGardens = 1100 AG = AvantGardens AvantGardensSurvival = 1101 + AGSurvival = AvantGardensSurvival + AGS = AvantGardensSurvival SpiderQueenBattle = 1102 BlockYard = 1150 AvantGrove = 1151 diff --git a/runtime/db/init.py b/runtime/db/init.py index bb5cc3d..aca4b85 100644 --- a/runtime/db/init.py +++ b/runtime/db/init.py @@ -127,8 +127,15 @@ class Init: parameter = tuple(int(param_id) for param_id in parameter.split(",")) elif task_type == TaskType.Discover: target = target_group + elif task_type == TaskType.MinigameAchievement: + parameter = target_group elif task_type == TaskType.Flag: target = tuple(int(flag_id) for flag_id in target_group.split(",")) + if task_type == TaskType.ObtainItem: + if not parameter: + parameter = None + else: + parameter = int(parameter) tasks.append((task_type, target, target_value, parameter)) diff --git a/runtime/db/scripts.py b/runtime/db/scripts.py index 7169da7..1cfa5d9 100644 --- a/runtime/db/scripts.py +++ b/runtime/db/scripts.py @@ -15,6 +15,7 @@ SCRIPTS = { 847: "avant_gardens.rusty_steele", 867: "avant_gardens.survival.buff_station", 882: "avant_gardens.survival.world_control", + 901: "avant_gardens.survival.stromling_mech", 946: "gnarled_forest.torch", 947: "gnarled_forest.banana_tree", 952: "general.binoculars",