summaryrefslogtreecommitdiff
path: root/walkto.py
diff options
context:
space:
mode:
Diffstat (limited to 'walkto.py')
-rw-r--r--walkto.py110
1 files changed, 110 insertions, 0 deletions
diff --git a/walkto.py b/walkto.py
new file mode 100644
index 0000000..a2b0312
--- /dev/null
+++ b/walkto.py
@@ -0,0 +1,110 @@
+import time
+import net.mapserv as mapserv
+import net.charserv as charserv
+import logicmanager
+from net.common import distance
+from utils import extends
+
+
+__all__ = [ 'unreachable_ids', 'walkto_and_action', 'target', 'state' ]
+
+
+_times = {
+ 'arrival_time': 0,
+ 'walk_request_time': 0,
+}
+
+unreachable_ids = set()
+target = None
+action = ''
+state = ''
+
+
+def reset_walkto():
+ global state
+ global target
+ global action
+
+ state = ''
+ target = None
+ action = ''
+
+
+def walkto_and_action(obj, action_, min_distance=1):
+ if obj.id in unreachable_ids:
+ return
+
+ global state
+ global target
+ global action
+
+ if state == 'waiting_confirmation':
+ return
+
+ target = obj
+ action = action_
+
+ pp = mapserv.player_pos
+ dist = distance(pp['x'], pp['y'], target.x, target.y)
+
+ if dist <= min_distance:
+ do_action(target, action)
+ else:
+ state = 'waiting_confirmation'
+ _times['walk_request_time'] = time.time()
+ mapserv.cmsg_player_change_dest(target.x, target.y)
+
+
+def do_action(target, action):
+ if action == 'attack':
+ mapserv.cmsg_player_change_act(target.id, 7)
+ elif action == 'pickup':
+ mapserv.cmsg_item_pickup(target.id)
+
+
+def walkto_logic(ts):
+ global state
+
+ if state == '':
+ return
+ elif state == 'waiting_confirmation':
+ if ts > _times['walk_request_time'] + 0.5:
+ unreachable_ids.add(target.id)
+ reset_walkto()
+ elif state == 'walking':
+ if ts >= _times['arrival_time']:
+ state = ''
+ do_action(target, action)
+
+
+@extends('smsg_being_remove')
+@extends('smsg_item_remove')
+def target_removed(data):
+ unreachable_ids.discard(data.id)
+ if target and target.id == data.id:
+ reset_walkto()
+ if data.id == charserv.server.account:
+ reset_walkto()
+
+
+@extends('smsg_player_warp')
+def player_warp(data):
+ reset_walkto()
+ unreachable_ids.clear()
+
+
+def calc_walk_time(distance, speed=0.15):
+ return 0.5 + speed * distance
+
+
+@extends('smsg_walk_response')
+def walk_response(data):
+ global state
+ if state == 'waiting_confirmation':
+ state = 'walking'
+ cp = data.coor_pair
+ dist = distance(cp.src_x, cp.src_y, cp.dst_x, cp.dst_y)
+ _times['arrival_time'] = time.time() + calc_walk_time(dist)
+
+
+logicmanager.logic_manager.add_logic(walkto_logic)