Last active
December 30, 2021 13:00
-
-
Save kergalym/ed34d5b9874d0b3dec28109e80f0ca4e to your computer and use it in GitHub Desktop.
Panda3D Archery Logic
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def bow_shoot(self, actor_name, arrow_name, bow_name): | |
""" Function : bow_shoot | |
Description : Performs bow shooting. | |
Input : Strings, Nodepath | |
Output : None | |
Return : None | |
""" | |
if actor_name and arrow_name and bow_name and self.world: | |
# Find actor which should do bow shoot | |
if render.find("**/{0}".format(actor_name)): | |
actor = render.find("**/{0}".format(actor_name)) | |
# Find arrow from that actor | |
if actor.find("**/{0}".format(arrow_name)): | |
arrow = actor.find("**/{0}".format(arrow_name)) | |
if arrow and self.aimed_target_pos and self.aimed_target_np: | |
bow = actor.find("**/{0}".format(bow_name)) | |
# Start arrow trajectory | |
if bow: | |
self.trajectory = ProjectileInterval(arrow, duration=1, startPos=bow.get_pos(), | |
endPos=self.aimed_target_pos, gravityMult=1.0) | |
self.trajectory.start() | |
arrow.reparent_to(render) | |
if self.trajectory.isPlaying(): | |
if isinstance(self.aimed_target_np, NodePath): | |
arrow.setCollideMask(BitMask32.allOff()) | |
arrow.reparent_to(self.aimed_target_np) | |
arrow.set_h(0) | |
# print(arrow, arrow.get_pos()) | |
def bow_shoot_enhanced(self, actor_name, arrow_name, bow_name): | |
""" Function : bow_shoot_enhanced | |
Description : Performs enhanced bow shooting. | |
Input : Strings, Nodepath | |
Output : None | |
Return : None | |
""" | |
if actor_name and arrow_name and bow_name and self.world: | |
# Find actor which should do bow shoot | |
if render.find("**/{0}".format(actor_name)): | |
actor = render.find("**/{0}".format(actor_name)) | |
# Find arrow from that actor | |
if actor.find("**/{0}".format(arrow_name)): | |
arrow = actor.find("**/{0}".format(arrow_name)) | |
# Construct arrow and start its trajectory | |
if arrow and self.aimed_target_pos and self.aimed_target_np: | |
# Calculate initial velocity | |
velocity = self.aimed_target_pos - actor.get_pos() + Vec3(0, 0.4, 0) | |
# velocity = self.aimed_target_pos - self.bow.get_pos() | |
velocity.normalize() | |
velocity *= 100.0 | |
# Create Bullet collider for an arrow | |
shape = BulletBoxShape(Vec3(0.5, 0.5, 0.5)) | |
body = BulletRigidBodyNode('Bullet') | |
body_np = render.attachNewNode(body) | |
body_np.node().addShape(shape) | |
body_np.node().setMass(2.0) | |
body_np.node().setLinearVelocity(velocity) | |
body_np.setPos(actor.get_pos() + (0, 0.5, 0)) | |
body_np.setCollideMask(BitMask32.allOff()) | |
arrow.reparent_to(body_np) | |
arrow.set_pos(0, 0, 0) | |
arrow.set_hpr(velocity) | |
# Enable Bullet Continuous Collision Detection | |
body_np.node().setCcdMotionThreshold(1e-7) | |
body_np.node().setCcdSweptSphereRadius(0.50) | |
self.world.attachRigidBody(body_np.node()) | |
Wait(1) | |
arrow.setCollideMask(BitMask32.allOff()) | |
self.world.removeRigidBody(body.node()) | |
def calculate_arrow_trajectory_task(self, actor, task): | |
""" Function : calculate_arrow_trajectory_task | |
Description : Task calculating arrow trajectory. | |
Input : Strings, Nodepath | |
Output : None | |
Return : Task status | |
""" | |
if not actor: | |
return task.done | |
elif actor: | |
bow_name = "bow" | |
if "Player" in actor.get_name(): | |
bow_name = "bow_kazakh" | |
arrow = actor.find("**/{0}".format(bow_name)) | |
if arrow: | |
mouse_watch = base.mouseWatcherNode | |
if mouse_watch.has_mouse(): | |
pos_mouse = base.mouseWatcherNode.get_mouse() | |
pos_from = Point3() | |
pos_to = Point3() | |
base.camLens.extrude(pos_mouse, pos_from, pos_to) | |
pos_from = self.render.get_relative_point(actor, pos_from) | |
pos_to = self.render.get_relative_point(base.camera, pos_to) | |
raytest_result = self.world.rayTestClosest(pos_from, pos_to) | |
# print(raytest_result.hasHit()) | |
if (raytest_result.get_node() | |
and "Korlan" not in str(raytest_result.get_node())): | |
self.aimed_target_np = raytest_result.get_node() | |
self.aimed_target_pos = raytest_result.get_hit_pos() | |
# Leave this here for testing purposes | |
if self.aimed_target_pos: | |
self.target_test_ui.setText("") | |
name = self.aimed_target_np.get_name() | |
self.target_test_ui.setText("Target hit: {0}".format(name)) | |
elif not self.aimed_target_np: | |
self.target_test_ui.setText("") | |
else: | |
self.target_test_ui.setText("") | |
return task.cont |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment