mirror of
https://github.com/lcdr/luserver.git
synced 2025-12-19 04:29:56 -06:00
v2016.09.01
This commit is contained in:
13
README.md
13
README.md
@@ -17,17 +17,8 @@ or
|
||||
|
||||
If you don't want to compile the packages yourself, you can download precompiled ones from http://www.lfd.uci.edu/~gohlke/pythonlibs/ .
|
||||
|
||||
##### Bugfixes
|
||||
|
||||
ZEO has some unfixed bugs which you'll need to fix manually:
|
||||
in `<Python installation directory>/Lib/site-packages/ZEO/zrpc/client.py`
|
||||
line 453
|
||||
comment out:
|
||||
|
||||
if socktype != socket.SOCK_STREAM:
|
||||
continue
|
||||
|
||||
and in `<Python installation directory>/Lib/site-packages/ZEO/zrpc/trigger.py`
|
||||
ZEO has an unfixed bug which you'll need to fix manually:
|
||||
in `<Python installation directory>/Lib/site-packages/ZEO/zrpc/trigger.py`
|
||||
line 235
|
||||
change
|
||||
|
||||
|
||||
@@ -16,6 +16,11 @@ from .mission import MissionProgress, MissionState, TaskType
|
||||
|
||||
log = logging.getLogger(__name__)
|
||||
|
||||
class TerminateType:
|
||||
Range = 0
|
||||
User = 1
|
||||
FromInteraction = 2
|
||||
|
||||
class BuildType:
|
||||
BuildNowhere = 0
|
||||
BuildInWorld = 1
|
||||
@@ -230,6 +235,12 @@ class CharacterComponent:
|
||||
del self._v_server.dropped_loot[self.object_id]
|
||||
self.vehicle_id = 0
|
||||
self.online = False
|
||||
self.check_for_leaks()
|
||||
|
||||
def check_for_leaks(self):
|
||||
if self.temp_models:
|
||||
print("Temp Models not empty")
|
||||
print(self.temp_models)
|
||||
|
||||
async def transfer_to_world(self, world, respawn_point_name=None):
|
||||
if respawn_point_name is not None:
|
||||
@@ -261,7 +272,7 @@ class CharacterComponent:
|
||||
if task.type == TaskType.ObtainItem:
|
||||
for item in self.items:
|
||||
if item is not None and item.lot in task.target:
|
||||
mission_progress.increment_task(task, self._v_server, self, increment=item.amount)
|
||||
mission_progress.increment_task(task, self, increment=item.amount)
|
||||
if task.value == task.target_value:
|
||||
break
|
||||
|
||||
@@ -312,6 +323,9 @@ class CharacterComponent:
|
||||
def notify_mission_task(self, address, mission_id:c_int=None, task_mask:c_int=None, updates:(c_ubyte, c_float)=None):
|
||||
pass
|
||||
|
||||
def terminate_interaction(self, address, obj_id_terminator:c_int64=None, type:c_int=None):
|
||||
pass
|
||||
|
||||
def request_use(self, address, is_multi_interact_use:c_bit=None, multi_interact_id:c_uint=None, multi_interact_type:c_int=None, object_id:c_int64=None, secondary:c_bit=False):
|
||||
if not is_multi_interact_use:
|
||||
assert multi_interact_id == 0
|
||||
@@ -334,7 +348,7 @@ class CharacterComponent:
|
||||
if mission.state == MissionState.Active:
|
||||
for task in mission.tasks:
|
||||
if task.type == TaskType.Interact and task.target == obj.lot:
|
||||
mission.increment_task(task, self._v_server, self)
|
||||
mission.increment_task(task, self)
|
||||
|
||||
def get_flag(self, flag_id):
|
||||
return bool(self.flags & (1 << flag_id))
|
||||
@@ -350,7 +364,7 @@ class CharacterComponent:
|
||||
if mission.state == MissionState.Active:
|
||||
for task in mission.tasks:
|
||||
if task.type == TaskType.Flag and flag_id in task.target:
|
||||
mission.increment_task(task, self._v_server, self)
|
||||
mission.increment_task(task, self)
|
||||
|
||||
|
||||
def player_loaded(self, address, player_id:c_int64=None):
|
||||
@@ -454,7 +468,7 @@ class CharacterComponent:
|
||||
self._v_server.mail.send_mail(self.name, "Bug Report: "+selection, body, account.characters.selected())
|
||||
|
||||
def request_smash_player(self, address):
|
||||
self._v_server.send_game_message(self.request_die, unknown_bool=False, death_type="", direction_relative_angle_xz=0, direction_relative_angle_y=0, direction_relative_force=0, killer_id=self.object_id, loot_owner_id=0, address=self.address)
|
||||
self.request_die(None, unknown_bool=False, death_type="", direction_relative_angle_xz=0, direction_relative_angle_y=0, direction_relative_force=0, killer_id=self.object_id, loot_owner_id=0)
|
||||
|
||||
def handle_u_g_c_equip_post_delete_based_on_edit_mode(self, address, inv_item:c_int64=None, items_total:c_int=0):
|
||||
pass
|
||||
|
||||
@@ -15,4 +15,4 @@ class CollectibleComponent:
|
||||
if mission.state == MissionState.Active:
|
||||
for task in mission.tasks:
|
||||
if task.type == TaskType.Collect and task.target == self.lot:
|
||||
mission.increment_task(task, self._v_server, player)
|
||||
mission.increment_task(task, player)
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
import random
|
||||
|
||||
from ..bitstream import c_bit, c_float, c_int, c_int64, c_uint
|
||||
from ..math.vector import Vector3
|
||||
from .comp108 import Comp108Component
|
||||
from .mission import MissionState, TaskType
|
||||
from .stats import StatsSubcomponent
|
||||
@@ -20,6 +19,7 @@ class DestructibleComponent:
|
||||
self.life = self.max_life
|
||||
self.armor = self.max_armor
|
||||
self.imagination = self.max_imagination
|
||||
self.is_smashable = comp[7]
|
||||
|
||||
def serialize(self, out, is_creation):
|
||||
if is_creation:
|
||||
@@ -44,12 +44,6 @@ class DestructibleComponent:
|
||||
loot.append(lot)
|
||||
return loot
|
||||
|
||||
def drop_loot(self, lot, owner):
|
||||
object_id = self._v_server.new_spawned_id()
|
||||
self._v_server.dropped_loot.setdefault(owner.object_id, {})[object_id] = lot
|
||||
self._v_server.send_game_message(owner.drop_client_loot, use_position=True, spawn_position=self.position, final_position=Vector3(self.position.x+(random.random()-0.5)*20, self.position.y, self.position.z+(random.random()-0.5)*20), currency=0, item_template=lot, loot_id=object_id, owner=owner.object_id, source_obj=self.object_id, address=owner.address)
|
||||
|
||||
|
||||
def request_die(self, address, unknown_bool:c_bit=None, death_type:"wstr"=None, direction_relative_angle_xz:c_float=None, direction_relative_angle_y:c_float=None, direction_relative_force:c_float=None, kill_type:c_int=0, killer_id:c_int64=None, loot_owner_id:c_int64=None):
|
||||
if self.armor != 0:
|
||||
self.armor = 0
|
||||
@@ -67,7 +61,7 @@ class DestructibleComponent:
|
||||
if mission.state == MissionState.Active:
|
||||
for task in mission.tasks:
|
||||
if task.type == TaskType.KillEnemy and self.lot in task.target:
|
||||
mission.increment_task(task, self._v_server, killer)
|
||||
mission.increment_task(task, killer)
|
||||
|
||||
# drops
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ class InventoryComponent:
|
||||
if mission.state == MissionState.Active:
|
||||
for task in mission.tasks:
|
||||
if task.type == TaskType.ObtainItem and stack.lot in task.target:
|
||||
mission.increment_task(task, self._v_server, self)
|
||||
mission.increment_task(task, self)
|
||||
|
||||
return stack
|
||||
|
||||
@@ -282,10 +282,14 @@ class InventoryComponent:
|
||||
return
|
||||
|
||||
def move_item_between_inventory_types(self, address, inventory_type_a:c_int=None, inventory_type_b:c_int=None, object_id:c_int64=None, show_flying_loot:c_bit=True, stack_count:c_uint=1, template_id:c_int=-1):
|
||||
assert stack_count == 1
|
||||
source = self.inventory_type_to_inventory(inventory_type_a)
|
||||
for item in source:
|
||||
if item is not None and (item.object_id == object_id or item.lot == template_id):
|
||||
self.add_item_to_inventory(item.lot, item.amount, inventory_type=inventory_type_b, show_flying_loot=show_flying_loot)
|
||||
self.remove_item_from_inv(inventory_type_a, item)
|
||||
break
|
||||
if stack_count == 0:
|
||||
move_stack_count = item.amount
|
||||
else:
|
||||
assert item.amount >= stack_count
|
||||
move_stack_count = stack_count
|
||||
new_item = self.add_item_to_inventory(item.lot, move_stack_count, inventory_type=inventory_type_b, show_flying_loot=show_flying_loot)
|
||||
self.remove_item_from_inv(inventory_type_a, item, amount=move_stack_count)
|
||||
return new_item
|
||||
|
||||
@@ -38,6 +38,23 @@ class MissionState:
|
||||
ReadyToComplete = 4
|
||||
Completed = 8
|
||||
|
||||
def check_prereqs(mission_id, player):
|
||||
player_missions = {mission.id: mission.state for mission in player.missions}
|
||||
prereqs = player._v_server.db.missions[mission_id][1]
|
||||
for prereq_ors in prereqs:
|
||||
for prereq_mission in prereq_ors:
|
||||
if isinstance(prereq_mission, tuple): # prereq requires special mission state
|
||||
prereq_mission, prereq_mission_state = prereq_mission
|
||||
else:
|
||||
prereq_mission_state = MissionState.Completed
|
||||
if prereq_mission in player_missions and player_missions[prereq_mission] == prereq_mission_state:
|
||||
break # an element was found, this prereq_ors is satisfied
|
||||
else:
|
||||
break # no elements found, not satisfied, checking further prereq_ors unnecessary
|
||||
else: # all preconditions satisfied
|
||||
return True
|
||||
return False
|
||||
|
||||
class MissionTask(Persistent):
|
||||
def __init__(self, task_type, target, target_value, parameter):
|
||||
self.type = task_type
|
||||
@@ -64,20 +81,23 @@ class MissionProgress(Persistent):
|
||||
self.tasks = [MissionTask(task_type, target, target_value, parameter) for task_type, target, target_value, parameter in mission_data[2]]
|
||||
self.is_mission = mission_data[3]
|
||||
|
||||
def increment_task(self, task, server, player, increment=1):
|
||||
def increment_task(self, task, player, increment=1):
|
||||
if task.value == task.target_value:
|
||||
return
|
||||
if not self.is_mission and not check_prereqs(self.id, player):
|
||||
return
|
||||
|
||||
task.value = min(task.value+increment, task.target_value)
|
||||
task_index = self.tasks.index(task)
|
||||
server.send_game_message(player.notify_mission_task, self.id, task_mask=1<<(task_index+1), updates=[task.value], address=player.address)
|
||||
player._v_server.send_game_message(player.notify_mission_task, self.id, task_mask=1<<(task_index+1), updates=[task.value], address=player.address)
|
||||
if not self.is_mission:
|
||||
for task in self.tasks:
|
||||
if task.value < task.target_value:
|
||||
break
|
||||
else:
|
||||
self.complete(server, player)
|
||||
self.complete(player)
|
||||
|
||||
def complete(self, server, player):
|
||||
def complete(self, player):
|
||||
self.state = MissionState.Completed
|
||||
|
||||
if self.is_mission:
|
||||
@@ -85,23 +105,23 @@ class MissionProgress(Persistent):
|
||||
else:
|
||||
source_type = LootType.Achievement
|
||||
|
||||
server.send_game_message(player.notify_mission, self.id, mission_state=MissionState.Unavailable, sending_rewards=True, address=player.address)
|
||||
server.send_game_message(player.set_currency, currency=player.currency + self.rew_currency, position=Vector3.zero, source_type=source_type, address=player.address)
|
||||
server.send_game_message(player.modify_lego_score, self.rew_universe_score, source_type=source_type, address=player.address)
|
||||
player._v_server.send_game_message(player.notify_mission, self.id, mission_state=MissionState.Unavailable, sending_rewards=True, address=player.address)
|
||||
player._v_server.send_game_message(player.set_currency, currency=player.currency + self.rew_currency, position=Vector3.zero, source_type=source_type, address=player.address)
|
||||
player._v_server.send_game_message(player.modify_lego_score, self.rew_universe_score, source_type=source_type, address=player.address)
|
||||
|
||||
for lot, amount in self.rew_items:
|
||||
player.add_item_to_inventory(lot, amount, source_type=source_type)
|
||||
|
||||
if self.rew_emote is not None:
|
||||
server.send_game_message(player.set_emote_lock_state, lock=False, emote_id=self.rew_emote, address=player.address)
|
||||
player._v_server.send_game_message(player.set_emote_lock_state, lock=False, emote_id=self.rew_emote, address=player.address)
|
||||
|
||||
player.max_life += self.rew_max_life
|
||||
player.max_imagination += self.rew_max_imagination
|
||||
|
||||
if self.rew_max_items:
|
||||
server.send_game_message(player.set_inventory_size, inventory_type=InventoryType.Items, size=len(player.items)+self.rew_max_items, address=player.address)
|
||||
player._v_server.send_game_message(player.set_inventory_size, inventory_type=InventoryType.Items, size=len(player.items)+self.rew_max_items, address=player.address)
|
||||
|
||||
server.send_game_message(player.notify_mission, self.id, mission_state=MissionState.Completed, sending_rewards=False, address=player.address)
|
||||
player._v_server.send_game_message(player.notify_mission, self.id, mission_state=MissionState.Completed, sending_rewards=False, address=player.address)
|
||||
|
||||
# No longer required, delete to free memory in db
|
||||
|
||||
@@ -121,9 +141,9 @@ class MissionProgress(Persistent):
|
||||
if mission.state == MissionState.Active:
|
||||
for task in mission.tasks:
|
||||
if task.type == TaskType.MissionComplete and self.id in task.target:
|
||||
mission.increment_task(task, server, player)
|
||||
mission.increment_task(task, player)
|
||||
|
||||
server.commit()
|
||||
player._v_server.commit()
|
||||
|
||||
class MissionNPCComponent:
|
||||
def __init__(self, comp_id):
|
||||
@@ -147,18 +167,7 @@ class MissionNPCComponent:
|
||||
break
|
||||
elif offers_mission:
|
||||
log.debug("assessing %i", mission_id)
|
||||
prereqs = self._v_server.db.missions[mission_id][1]
|
||||
for prereq_ors in prereqs:
|
||||
for prereq_mission in prereq_ors:
|
||||
if isinstance(prereq_mission, tuple): # prereq requires special mission state
|
||||
prereq_mission, prereq_mission_state = prereq_mission
|
||||
else:
|
||||
prereq_mission_state = MissionState.Completed
|
||||
if prereq_mission in player_missions and player_missions[prereq_mission] == prereq_mission_state:
|
||||
break # an element was found, this prereq_ors is satisfied
|
||||
else:
|
||||
break # no elements found, not satisfied, checking further prereq_ors unnecessary
|
||||
else: # all preconditions satisfied
|
||||
if check_prereqs(mission_id, player):
|
||||
offer = mission_id
|
||||
|
||||
if offer is not None:
|
||||
@@ -185,7 +194,7 @@ class MissionNPCComponent:
|
||||
assert is_complete
|
||||
for mission_progress in player.missions:
|
||||
if mission_progress.id == mission_id:
|
||||
mission_progress.complete(self._v_server, player)
|
||||
mission_progress.complete(player)
|
||||
break
|
||||
|
||||
def request_linked_mission(self, address, player_id:c_int64=None, mission_id:c_int=None, mission_offered:c_bit=None):
|
||||
|
||||
@@ -19,6 +19,16 @@ class ModularBuildComponent:
|
||||
player = self._v_server.accounts[address].characters.selected()
|
||||
self._v_server.send_game_message(player.start_arranging_with_item, first_time, self.object_id, player.position, source_bag, source_id, source_lot, source_type, target_id, target_lot, target_pos, target_type, address=address)
|
||||
|
||||
def done_arranging_with_item(self, address, new_source_bag:c_int=None, new_source_id:c_int64=None, new_source_lot:c_int=None, new_source_type:c_int=None, new_target_id:c_int64=None, new_target_lot:c_int=None, new_target_type:c_int=None, new_target_pos:Vector3=None, old_item_bag:c_int=None, old_item_id:c_int64=None, old_item_lot:c_int=None, old_item_type:c_int=None):
|
||||
player = self._v_server.accounts[address].characters.selected()
|
||||
for model in player.temp_models.copy():
|
||||
player.move_item_between_inventory_types(None, inventory_type_a=InventoryType.TempModels, inventory_type_b=InventoryType.Models, object_id=model.object_id, stack_count=0)
|
||||
|
||||
def modular_build_move_and_equip(self, address, template_id:c_int=None):
|
||||
player = self._v_server.accounts[address].characters.selected()
|
||||
new_item = player.move_item_between_inventory_types(None, inventory_type_a=InventoryType.TempModels, inventory_type_b=InventoryType.Models, object_id=0, template_id=template_id)
|
||||
player.equip_inventory(None, item_to_equip=new_item.object_id)
|
||||
|
||||
def modular_build_finish(self, address, module_lots:(c_ubyte, c_int)=None):
|
||||
player = self._v_server.accounts[address].characters.selected()
|
||||
for model in player.temp_models.copy():
|
||||
|
||||
@@ -40,5 +40,5 @@ class PetComponent:
|
||||
if mission.state == MissionState.Active:
|
||||
for task in mission.tasks:
|
||||
if task.type == TaskType.TamePet and self.lot in task.target:
|
||||
mission.increment_task(task, self._v_server, player)
|
||||
mission.increment_task(task, player)
|
||||
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import asyncio
|
||||
import time
|
||||
|
||||
from ..bitstream import c_bit, c_float, c_int, c_int64, c_uint
|
||||
from ..math.vector import Vector3
|
||||
from .char import TerminateType
|
||||
from .mission import MissionState, TaskType
|
||||
from .scripted_activity import ScriptedActivityComponent
|
||||
|
||||
@@ -10,6 +12,7 @@ class RebuildState:
|
||||
Completed = 2
|
||||
Resetting = 4
|
||||
Building = 5
|
||||
Incomplete = 6
|
||||
|
||||
class FailReason:
|
||||
NotGiven = 0
|
||||
@@ -22,19 +25,31 @@ class RebuildComponent(ScriptedActivityComponent):
|
||||
super().__init__(comp_id)
|
||||
self.complete_time = self._v_server.db.rebuild_component[comp_id][0]
|
||||
self.smash_time = self._v_server.db.rebuild_component[comp_id][1]
|
||||
|
||||
self.reset_time = self._v_server.db.rebuild_component[comp_id][2]
|
||||
self.imagination_cost = self._v_server.db.rebuild_component[comp_id][3]
|
||||
self.callback_handles = []
|
||||
self.rebuild_start_time = 0
|
||||
self.last_progress = 0
|
||||
self._flags["rebuild_state"] = "rebuild_flag"
|
||||
self._flags["success"] = "rebuild_flag"
|
||||
self._flags["enabled"] = "rebuild_flag"
|
||||
self._flags["rebuild_duration"] = "rebuild_flag"
|
||||
self.rebuild_state = RebuildState.Open
|
||||
self._rebuild_state = RebuildState.Open
|
||||
self.success = False
|
||||
self.enabled = True
|
||||
self.rebuild_duration = 0
|
||||
|
||||
if not hasattr(self, "rebuild_activator_position"):
|
||||
self.rebuild_activator_position = Vector3(self.position)
|
||||
|
||||
@property
|
||||
def rebuild_state(self):
|
||||
return self._rebuild_state
|
||||
|
||||
@rebuild_state.setter
|
||||
def rebuild_state(self, value):
|
||||
player = self._v_server.get_object(self.players[0])
|
||||
self._v_server.send_game_message(self.rebuild_notify_state, self.rebuild_state, value, player=player.object_id, address=player.address)
|
||||
self._rebuild_state = value
|
||||
|
||||
def serialize(self, out, is_creation):
|
||||
super().serialize(out, is_creation)
|
||||
out.write(c_bit(self.rebuild_flag or is_creation))
|
||||
@@ -42,7 +57,7 @@ class RebuildComponent(ScriptedActivityComponent):
|
||||
out.write(c_uint(self.rebuild_state))
|
||||
out.write(c_bit(self.success))
|
||||
out.write(c_bit(self.enabled))
|
||||
out.write(c_float(self.rebuild_duration))
|
||||
out.write(c_float(time.time() - self.rebuild_start_time))
|
||||
out.write(c_uint(0))
|
||||
if is_creation:
|
||||
out.write(c_bit(False))
|
||||
@@ -53,29 +68,36 @@ class RebuildComponent(ScriptedActivityComponent):
|
||||
self.rebuild_flag = False
|
||||
|
||||
def on_use(self, player, multi_interact_id):
|
||||
if self.rebuild_state == RebuildState.Open:
|
||||
assert multi_interact_id is None
|
||||
prev_state = self.rebuild_state
|
||||
self.rebuild_state = RebuildState.Building
|
||||
self.players.append(player.object_id)
|
||||
self.activity_flag = True
|
||||
player.rebuilding = 1
|
||||
self._v_server.send_game_message(self.rebuild_notify_state, prev_state, self.rebuild_state, player=player.object_id, address=player.address)
|
||||
self._v_server.send_game_message(self.enable_rebuild, enable=True, fail=False, success=False, duration=0, user=player.object_id, address=player.address)
|
||||
assert multi_interact_id is None
|
||||
assert self.rebuild_state in (RebuildState.Open, RebuildState.Incomplete)
|
||||
for handle in self.callback_handles:
|
||||
handle.cancel()
|
||||
self.callback_handles.clear()
|
||||
self.players.append(player.object_id)
|
||||
self.activity_flag = True
|
||||
self.rebuild_state = RebuildState.Building
|
||||
player.rebuilding = 1
|
||||
self._v_server.send_game_message(self.enable_rebuild, enable=self.enabled, fail=False, success=self.success, duration=0, user=player.object_id, address=player.address)
|
||||
self.rebuild_start_time = time.time()
|
||||
drain_interval = self.complete_time/self.imagination_cost
|
||||
remaining_cost = int((self.complete_time - self.last_progress) // drain_interval)
|
||||
for i in range(remaining_cost):
|
||||
self.callback_handles.append(asyncio.get_event_loop().call_later(self.last_progress%drain_interval + drain_interval*i, self.drain_imagination, player))
|
||||
self.callback_handles.append(asyncio.get_event_loop().call_later(self.complete_time-self.last_progress, self.complete_rebuild, player))
|
||||
return True
|
||||
|
||||
|
||||
asyncio.get_event_loop().call_later(self.complete_time, self.complete_rebuild, player)
|
||||
return True
|
||||
def drain_imagination(self, player):
|
||||
player.imagination -= 1
|
||||
if player.imagination == 0:
|
||||
self.rebuild_cancel(None, early_release=False, user_id=player.object_id)
|
||||
|
||||
def complete_rebuild(self, player):
|
||||
prev_state = self.rebuild_state
|
||||
self.rebuild_state = RebuildState.Completed
|
||||
self.success = True
|
||||
self.enabled = False
|
||||
self.rebuild_duration = self.complete_time
|
||||
player.rebuilding = 0
|
||||
self._v_server.send_game_message(self.rebuild_notify_state, prev_state, self.rebuild_state, player=player.object_id, address=player.address)
|
||||
self._v_server.send_game_message(self.enable_rebuild, enable=False, fail=False, success=True, duration=0, user=player.object_id, address=player.address)
|
||||
self._v_server.send_game_message(self.enable_rebuild, enable=self.enabled, fail=False, success=self.success, duration=0, user=player.object_id, address=player.address)
|
||||
self._v_server.send_game_message(self.play_f_x_effect, name="BrickFadeUpVisCompleteEffect", effect_type="create", effect_id=507, address=player.address)
|
||||
self._v_server.send_game_message(player.play_animation, animation_id="rebuild-celebrate", play_immediate=False, address=player.address)
|
||||
|
||||
assert len(self.children) == 1
|
||||
@@ -87,16 +109,30 @@ class RebuildComponent(ScriptedActivityComponent):
|
||||
if mission.state == MissionState.Active:
|
||||
for task in mission.tasks:
|
||||
if task.type == TaskType.QuickBuild and task.target == self.lot:
|
||||
mission.increment_task(task, self._v_server, player)
|
||||
mission.increment_task(task, player)
|
||||
|
||||
def smash_rebuild(self):
|
||||
self._v_server.send_game_message(self.die, death_type="", direction_relative_angle_xz=0, direction_relative_angle_y=0, direction_relative_force=10, killer_id=0, broadcast=True)
|
||||
self._v_server.destruct(self)
|
||||
|
||||
def rebuild_cancel(self, address, early_release:c_bit=None, user_id:c_int64=None):
|
||||
pass#self.rebuild_state = RebuildState.Open
|
||||
#self.players.remove(user_id)
|
||||
#self.activity_flag = True
|
||||
player = self._v_server.get_object(user_id)
|
||||
if self.rebuild_state == RebuildState.Building:
|
||||
for handle in self.callback_handles:
|
||||
handle.cancel()
|
||||
self.callback_handles.clear()
|
||||
self.last_progress += time.time() - self.rebuild_start_time
|
||||
self.rebuild_state = RebuildState.Incomplete
|
||||
self.players.remove(user_id)
|
||||
self.activity_flag = True
|
||||
player.rebuilding = 0
|
||||
if early_release:
|
||||
fail_reason = FailReason.CanceledEarly
|
||||
else:
|
||||
fail_reason = FailReason.OutOfImagination
|
||||
self._v_server.send_game_message(self.enable_rebuild, enable=False, fail=True, success=self.success, fail_reason=fail_reason, duration=self.last_progress, user=player.object_id, address=player.address)
|
||||
self.callback_handles.append(asyncio.get_event_loop().call_later(self.reset_time, self.smash_rebuild))
|
||||
self._v_server.send_game_message(player.terminate_interaction, obj_id_terminator=self.object_id, type=TerminateType.FromInteraction, address=player.address)
|
||||
|
||||
def enable_rebuild(self, address, enable:c_bit=None, fail:c_bit=None, success:c_bit=None, fail_reason:c_uint=FailReason.NotGiven, duration:c_float=None, user:c_int64=None):
|
||||
pass
|
||||
|
||||
@@ -123,7 +123,7 @@ class SkillComponent:
|
||||
if mission.state == MissionState.Active:
|
||||
for task in mission.tasks:
|
||||
if task.type == TaskType.UseSkill and skill_id in task.parameter:
|
||||
mission.increment_task(task, self._v_server, self)
|
||||
mission.increment_task(task, self)
|
||||
|
||||
target = self
|
||||
self.picked_target_id = optional_target_id
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
import asyncio
|
||||
import random
|
||||
|
||||
from ..bitstream import c_bit, c_float, c_int, c_int64, c_uint
|
||||
from ..math.vector import Vector3
|
||||
|
||||
class StatsSubcomponent:
|
||||
def __init__(self, comp_id):
|
||||
@@ -16,7 +18,7 @@ class StatsSubcomponent:
|
||||
self.life = self.max_life
|
||||
self.armor = self.max_armor
|
||||
self.imagination = self.max_imagination
|
||||
|
||||
self.is_smashable = False
|
||||
|
||||
@property
|
||||
def max_life(self):
|
||||
@@ -93,12 +95,11 @@ class StatsSubcomponent:
|
||||
out.write(c_float(self.max_imagination))
|
||||
out.write(c_uint(1))
|
||||
out.write(c_int(self.faction))
|
||||
show_smashable_glint = True
|
||||
out.write(c_bit(show_smashable_glint))
|
||||
out.write(c_bit(self.is_smashable))
|
||||
if is_creation:
|
||||
out.write(c_bit(False))
|
||||
out.write(c_bit(False))
|
||||
if show_smashable_glint:
|
||||
if self.is_smashable:
|
||||
out.write(c_bit(False))
|
||||
out.write(c_bit(False))
|
||||
|
||||
@@ -110,5 +111,10 @@ class StatsSubcomponent:
|
||||
if self.spawner is not None:
|
||||
asyncio.get_event_loop().call_later(8, self.spawner.spawn)
|
||||
|
||||
def drop_loot(self, lot, owner):
|
||||
object_id = self._v_server.new_spawned_id()
|
||||
self._v_server.dropped_loot.setdefault(owner.object_id, {})[object_id] = lot
|
||||
self._v_server.send_game_message(owner.drop_client_loot, use_position=True, spawn_position=self.position, final_position=Vector3(self.position.x+(random.random()-0.5)*20, self.position.y, self.position.z+(random.random()-0.5)*20), currency=0, item_template=lot, loot_id=object_id, owner=owner.object_id, source_obj=self.object_id, address=owner.address)
|
||||
|
||||
def die(self, address, client_death:c_bit=False, spawn_loot:c_bit=True, death_type:"wstr"=None, direction_relative_angle_xz:c_float=None, direction_relative_angle_y:c_float=None, direction_relative_force:c_float=None, kill_type:c_uint=0, killer_id:c_int64=None, loot_owner_id:c_int64=0):
|
||||
pass
|
||||
|
||||
@@ -32,7 +32,7 @@ class VendorComponent:
|
||||
player = self._v_server.accounts[address].characters.selected()
|
||||
for item in player.items:
|
||||
if item is not None and item.object_id == item_obj_id:
|
||||
self._v_server.send_game_message(player.set_currency, currency=player.currency + (item.base_value*count)//10, position=Vector3.zero, source_type=source_type, address=player.address)
|
||||
self._v_server.send_game_message(player.set_currency, currency=player.currency + (item.base_value*count)//10, position=Vector3.zero, address=player.address)
|
||||
player.remove_item_from_inv(InventoryType.Items, object_id=item_obj_id, amount=count)
|
||||
break
|
||||
else:
|
||||
|
||||
@@ -59,7 +59,6 @@ component[65] = PropertyVendorComponent,
|
||||
component[67] = LaunchpadComponent,
|
||||
component[104] = RailActivatorComponent,
|
||||
|
||||
|
||||
component_order = list(component.keys())
|
||||
|
||||
def restore_template(*args):
|
||||
@@ -83,8 +82,11 @@ def Template(lot_, conn=None, comps=None, custom_script=None):
|
||||
for component_type, component_id in sorted(comp_ids, key=lambda x: component_order.index(x[0]) if x[0] in component_order else 99999):
|
||||
if component_type == 5:
|
||||
if component_id is None:
|
||||
script = importlib.import_module("luserver.scripts."+custom_script)
|
||||
comp = script.ScriptComponent,
|
||||
if custom_script != "":
|
||||
script = importlib.import_module("luserver.scripts."+custom_script)
|
||||
comp = script.ScriptComponent,
|
||||
else:
|
||||
comp = ScriptComponent,
|
||||
elif component_id in conn.root.script_component:
|
||||
script = importlib.import_module("luserver.scripts."+conn.root.script_component[component_id])
|
||||
comp = script.ScriptComponent,
|
||||
@@ -213,7 +215,7 @@ def Template(lot_, conn=None, comps=None, custom_script=None):
|
||||
if mission.state == MissionState.Active:
|
||||
for task in mission.tasks:
|
||||
if task.type == TaskType.UseEmote and emote_id in task.parameter and task.target == self._v_server.game_objects[target_id].lot:
|
||||
mission.increment_task(task, self._v_server, self)
|
||||
mission.increment_task(task, self)
|
||||
|
||||
|
||||
def play_animation(self, address, animation_id:"wstr"=None, expect_anim_to_exist:c_bit=True, play_immediate:c_bit=None, trigger_on_complete_msg:c_bit=False, priority:c_float=2, f_scale:c_float=1):
|
||||
|
||||
@@ -119,6 +119,7 @@ class GameMessage(Enum):
|
||||
NotifyMission = 254
|
||||
NotifyMissionTask = 255
|
||||
RebuildNotifyState = 336
|
||||
TerminateInteraction = 357
|
||||
RequestUse = 364
|
||||
VendorOpenWindow = 369
|
||||
EmotePlayed = 371
|
||||
@@ -168,9 +169,11 @@ class GameMessage(Enum):
|
||||
StartBuildingWithItem = 1057
|
||||
StartArrangingWithItem = 1061
|
||||
FinishArrangingWithItem = 1062
|
||||
DoneArrangingWithItem = 1063
|
||||
SetBuildMode = 1068
|
||||
SetBuildModeConfirmed = 1073
|
||||
MoveItemBetweenInventoryTypes = 1093
|
||||
ModularBuildMoveAndEquip = 1096
|
||||
ModularBuildFinish = 1097
|
||||
EchoSyncSkill = 1144
|
||||
SyncSkill = 1145
|
||||
|
||||
@@ -102,6 +102,9 @@ class ChatHandling(ServerModule):
|
||||
build_cmd.add_argument("type", type=int)
|
||||
build_cmd.set_defaults(func=self.build_cmd)
|
||||
|
||||
check_for_leaks_cmd = cmds.add_parser("checkforleaks")
|
||||
check_for_leaks_cmd.set_defaults(func=self.check_for_leaks_cmd)
|
||||
|
||||
complete_mission_cmd = cmds.add_parser("completemission")
|
||||
complete_mission_cmd.add_argument("--id", type=int)
|
||||
complete_mission_cmd.set_defaults(func=self.complete_mission_cmd)
|
||||
@@ -119,6 +122,9 @@ class ChatHandling(ServerModule):
|
||||
faction_cmd.add_argument("faction", type=int)
|
||||
faction_cmd.set_defaults(func=self.faction_cmd)
|
||||
|
||||
glow_cmd = cmds.add_parser("glow")
|
||||
glow_cmd.set_defaults(func=self.glow_cmd)
|
||||
|
||||
filelog_cmd = cmds.add_parser("filelog", description="Change which packets are logged to file")
|
||||
filelog_cmd.add_argument("action", choices=("add", "remove", "show"), default="show")
|
||||
filelog_cmd.add_argument("packetname")
|
||||
@@ -280,6 +286,9 @@ class ChatHandling(ServerModule):
|
||||
def build_cmd(self, args, sender):
|
||||
self.server.send_game_message(sender.activate_brick_mode, build_type=args.type, address=sender.address)
|
||||
|
||||
def check_for_leaks_cmd(self, args, sender):
|
||||
sender.check_for_leaks()
|
||||
|
||||
def complete_mission_cmd(self, args, sender):
|
||||
if args.id:
|
||||
for mission in sender.missions:
|
||||
@@ -290,7 +299,7 @@ class ChatHandling(ServerModule):
|
||||
if mission.state == 2:
|
||||
for task_index, task_data in enumerate(self.server.db.missions[mission.id][2]):
|
||||
target_value = task_data[2]
|
||||
mission.increment_task(mission.tasks[task_index], self.server, sender, target_value)
|
||||
mission.increment_task(mission.tasks[task_index], sender, target_value)
|
||||
self.server.commit()
|
||||
|
||||
def dismount_cmd(self, args, sender):
|
||||
@@ -313,6 +322,12 @@ class ChatHandling(ServerModule):
|
||||
elif args.action == "show":
|
||||
print(self.server.file_logged_packets)
|
||||
|
||||
def glow_cmd(self, args, sender):
|
||||
if sender.rebuilding == 0:
|
||||
sender.rebuilding = 1
|
||||
else:
|
||||
sender.rebuilding = 0
|
||||
|
||||
def help_cmd(self, args, sender):
|
||||
print("Please use -h / --help for help.")
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ MODEL_DIMENSIONS[5633] = Vector3(-819.2, 0, -819.2), Vector3(819.2, 13.521, 819.
|
||||
MODEL_DIMENSIONS[5652] = Vector3(-2.5, -2.5, -2.5), Vector3(2.5, 2.5, 2.5)
|
||||
MODEL_DIMENSIONS[8419] = Vector3(-5.2644, 0.0051, -0.5011), Vector3(4.7356, 5.0051, 0.4989)
|
||||
|
||||
DEBUG_INCLUDE_NO_SCRIPT = True
|
||||
DEBUG_INCLUDE_NO_SCRIPT = False
|
||||
|
||||
log = logging.getLogger(__file__)
|
||||
|
||||
|
||||
4
luserver/scripts/avant_gardens/quickbuild_elevator.py
Normal file
4
luserver/scripts/avant_gardens/quickbuild_elevator.py
Normal file
@@ -0,0 +1,4 @@
|
||||
import luserver.components.script as script
|
||||
|
||||
class ScriptComponent(script.ScriptComponent):
|
||||
pass # currently not implemented
|
||||
@@ -17,4 +17,4 @@ class ScriptComponent(script.ScriptComponent):
|
||||
if mission.state == MissionState.Active and mission.id == achievement_id:
|
||||
for task in mission.tasks:
|
||||
if task.type == TaskType.Script and self.lot in task.target:
|
||||
mission.increment_task(task, self._v_server, player)
|
||||
mission.increment_task(task, player)
|
||||
|
||||
@@ -7,4 +7,4 @@ class ScriptComponent(script.ScriptComponent):
|
||||
if mission.state == MissionState.Active and mission.id == self.script_vars["touch_complete_mission_id"]:
|
||||
for task in mission.tasks:
|
||||
if task.type == TaskType.Script and self.lot in task.target:
|
||||
mission.increment_task(task, self._v_server, player)
|
||||
mission.increment_task(task, player)
|
||||
|
||||
14
luserver/scripts/nimbus_station/imagination_statue.py
Normal file
14
luserver/scripts/nimbus_station/imagination_statue.py
Normal file
@@ -0,0 +1,14 @@
|
||||
import asyncio
|
||||
|
||||
import luserver.components.script as script
|
||||
from luserver.components.rebuild import RebuildComponent
|
||||
|
||||
IMAGINATION_POWERUP_LOT = 935
|
||||
SPAWN_AMOUNT = 10
|
||||
SPAWN_INTERVAL = 1.5
|
||||
|
||||
class ScriptComponent(script.ScriptComponent):
|
||||
def complete_rebuild(self, player):
|
||||
RebuildComponent.complete_rebuild(self, player)
|
||||
for i in range(SPAWN_AMOUNT):
|
||||
asyncio.get_event_loop().call_later(i*SPAWN_INTERVAL, self.drop_loot, IMAGINATION_POWERUP_LOT, player)
|
||||
@@ -34,5 +34,5 @@ class ScriptComponent(script.ScriptComponent):
|
||||
for achievement_id in achievements:
|
||||
for mission in player.missions:
|
||||
if mission.id == achievement_id:
|
||||
mission.complete(self._v_server, player)
|
||||
mission.complete(player)
|
||||
break
|
||||
|
||||
@@ -11,5 +11,5 @@ class ScriptComponent(script.ScriptComponent):
|
||||
player.imagination = 6
|
||||
for mission in player.missions:
|
||||
if mission.id == 664:
|
||||
mission.complete(self._v_server, player)
|
||||
mission.complete(player)
|
||||
break
|
||||
|
||||
@@ -116,8 +116,6 @@ class WorldServer(server.Server, pyraknet.replicamanager.ReplicaManager):
|
||||
console_log = packetname not in self.not_console_logged_packets
|
||||
except ValueError:
|
||||
packetname = self.unknown_packetname(data)
|
||||
with open("logs/"+packetname+".bin", "wb") as file:
|
||||
file.write(data)
|
||||
console_log = True
|
||||
|
||||
if console_log:
|
||||
|
||||
@@ -79,7 +79,6 @@ def get_behavior(behavior_id):
|
||||
if behavior_id not in root.behavior:
|
||||
global behavs_accessed
|
||||
behavs_accessed += 1
|
||||
print(behavior_id)
|
||||
if behavior_id not in templates:
|
||||
return None
|
||||
template_id = templates[behavior_id]
|
||||
@@ -311,7 +310,7 @@ if GENERATE_COMPS:
|
||||
root.script_component[id] = script_name
|
||||
|
||||
elif row[1] == 7 and row[2] not in root.destructible_component:
|
||||
faction, faction_list, level, loot_matrix_index, currency_index, life, armor, imagination = cdclient.execute("select faction, factionList, level, LootMatrixIndex, CurrencyIndex, life, armor, imagination from DestructibleComponent where id == %i" % row[2]).fetchone()
|
||||
faction, faction_list, level, loot_matrix_index, currency_index, life, armor, imagination, is_smashable = cdclient.execute("select faction, factionList, level, LootMatrixIndex, CurrencyIndex, life, armor, imagination, isSmashable from DestructibleComponent where id == %i" % row[2]).fetchone()
|
||||
if faction is None:
|
||||
faction = int(faction_list) # fallback, i have no idea why both columns exist in the first place
|
||||
if level is not None and currency_index is not None:
|
||||
@@ -332,7 +331,7 @@ if GENERATE_COMPS:
|
||||
if armor is not None:
|
||||
armor = int(armor)
|
||||
|
||||
root.destructible_component[row[2]] = faction, loot, minvalue, maxvalue, life, armor, imagination
|
||||
root.destructible_component[row[2]] = faction, loot, minvalue, maxvalue, life, armor, imagination, is_smashable
|
||||
|
||||
elif row[1] == 16 and row[2] not in root.vendor_component:
|
||||
comp_row = cdclient.execute("select LootMatrixIndex from VendorComponent where id == %i" % row[2]).fetchone()
|
||||
@@ -344,12 +343,12 @@ if GENERATE_COMPS:
|
||||
root.inventory_component.setdefault(row[2], []).append((comp_row[0], comp_row[1]))
|
||||
|
||||
elif row[1] == 48 and row[2] not in root.rebuild_component:
|
||||
comp_row = cdclient.execute("select complete_time, time_before_smash from RebuildComponent where id == %i" % row[2]).fetchone()
|
||||
comp_row = cdclient.execute("select complete_time, time_before_smash, reset_time, take_imagination from RebuildComponent where id == %i" % row[2]).fetchone()
|
||||
if comp_row is not None:
|
||||
complete_time, smash_time = comp_row
|
||||
complete_time, smash_time, reset_time, take_imagination = comp_row
|
||||
if complete_time is None:
|
||||
complete_time = 0
|
||||
root.rebuild_component[row[2]] = complete_time, smash_time
|
||||
root.rebuild_component[row[2]] = complete_time, smash_time, reset_time, take_imagination
|
||||
|
||||
elif row[1] == 53 and row[2] not in root.package_component:
|
||||
comp_row = cdclient.execute("select LootMatrixIndex from PackageComponent where id == %i" % row[2]).fetchone()
|
||||
|
||||
@@ -94,8 +94,11 @@ def parse_lvl(conn, world_data, lvl_path):
|
||||
config = ldf.from_ldf(config_data)
|
||||
|
||||
custom_script = None
|
||||
if lot != 176 and config.get("custom_script_server") not in (None, ""):
|
||||
custom_script = scripts.SCRIPTS.get(config["custom_script_server"][len("scripts\\"):])
|
||||
if lot != 176 and "custom_script_server" in config:
|
||||
if config["custom_script_server"] == "":
|
||||
custom_script = ""
|
||||
else:
|
||||
custom_script = scripts.SCRIPTS.get(config["custom_script_server"][len("scripts\\"):])
|
||||
|
||||
spawned_vars = {}
|
||||
if "groupID" in config:
|
||||
@@ -135,8 +138,11 @@ def parse_lvl(conn, world_data, lvl_path):
|
||||
spawn_vars = {}
|
||||
|
||||
obj.spawntemplate = config["spawntemplate"]
|
||||
if config.get("custom_script_server") not in (None, ""):
|
||||
spawn_vars["custom_script"] = scripts.SCRIPTS.get(config["custom_script_server"][len("scripts\\"):])
|
||||
if "custom_script_server" in config:
|
||||
if config["custom_script_server"] == "":
|
||||
spawn_vars["custom_script"] = ""
|
||||
else:
|
||||
spawn_vars["custom_script"] = scripts.SCRIPTS.get(config["custom_script_server"][len("scripts\\"):])
|
||||
|
||||
if "attached_path" in config:
|
||||
spawned_vars["attached_path"] = config["attached_path"]
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
# consider converting all to path
|
||||
# consider converting all to path so components using the same script are automatically handled
|
||||
# some paths are removed from the database though
|
||||
|
||||
SCRIPTS = {}
|
||||
SCRIPTS[313] = "general.death_trigger"
|
||||
@@ -34,7 +35,9 @@ SCRIPTS[r"02_server\Map\General\L_TOUCH_MISSION_UPDATE_SERVER.lua"] = "general.t
|
||||
SCRIPTS[r"02_server\Map\NT\L_NT_PARADOXTELE_SERVER.lua"] = "nexus_tower.paradox_teleporter"
|
||||
SCRIPTS[r"ai\AG\L_ACT_SHARK_PLAYER_DEATH_TRIGGER.lua"] = "general.shark_death_trigger"
|
||||
SCRIPTS[r"ai\AG\L_AG_PICNIC_BLANKET.lua"] = "avant_gardens.picnic_blanket"
|
||||
SCRIPTS[r"ai\AG\L_AG_QB_Elevator.lua"] = "avant_gardens.quickbuild_elevator"
|
||||
SCRIPTS[r"ai\AG\L_AG_SHIP_PLAYER_DEATH_TRIGGER.lua"] = "venture_explorer.death_trigger"
|
||||
SCRIPTS[r"ai\AG\L_AG_SHIP_PLAYER_SHOCK_SERVER.lua"] = "venture_explorer.broken_console"
|
||||
SCRIPTS[r"ai\AG\L_AG_SHIP_SHAKE.lua"] = "venture_explorer.ship_shake"
|
||||
SCRIPTS[r"ai\NS\L_NS_JONNY_FLAG_MISSION_SERVER.lua"] = "nimbus_station.johnny_thunder"
|
||||
SCRIPTS[r"ai\NS\L_NS_QB_IMAGINATION_STATUE.lua"] = "nimbus_station.imagination_statue"
|
||||
|
||||
Reference in New Issue
Block a user