But it is almost exactly the same ( at least the necessary parts )
from pandac.PandaModules import Point3, Vec3
from direct.interval.IntervalGlobal import *
from direct.showbase.DirectObject import DirectObject
from odeWorldManager import *
from pickables import PickableObject
import random
import configurations
class Firearm(PickableObject, DirectObject):
def __init__(self, name="handgun", weight=0.630):
PickableObject.__init__(self, name, weight)
self.config = configurations.Configuration()
self.pickableType = "firearm"
self.modelPath = "models/p90.egg"
self.worldModelPath = "models/p90.egg"
self.hudModelPath = "models/p90.egg"
self.geomSize = (0.054, 0.381, 0.227)
"""
Is it automatic or semi-automatic?
"""
self.automatic = False
"""
How far do you want the bullets to go?
"""
self.effectiveRange = 300.0
"""
Rate of Fire for automatic weapons.
"""
self.autoROF = 250.0
"""
Used for ROF, more on that in the update method.
"""
self.autoAccumulator = 0.0
"""
Number of rays to search for hits with. This basically
translates to this: If it's more than one, you have a shotgun.
It it's one -- a pistol or a rifle.
"""
self.aimRaysNum = 1
"""
Holds aim rays.
"""
self.aimRays = []
"""
If you have more than one aim ray, then here you can set how
dispersed they're going to be.
"""
self.shotgunDispersion = 0.2
"""
Are we shooting ATM?
"""
self.shooting = False
"""
Contains the hits.
"""
self.aimCollisions = []
"""
The callback for aim ray collisions.
"""
def aimCollision(self, entry, object1, object2):
"""
No point hitting triggers or ccd helpers.
"""
if object2.objectType is ["ccd"]:
return
"""
So we don't shoot ourselves.
"""
if object2 is self.owner:
return
"""
Append the hit to the list.
"""
self.aimCollisions.append([entry, object2])
def destroy(self):
for ray in self.aimRays:
self.map.worldManager.removeObject(ray)
ray.destroy()
del self.aimCollisions
del self.aimRays
pickableObject.destroy(self)
self.ignoreAll()
"""
Create the requested number of aim rays.
"""
def createAimRays(self):
for i in range(self.aimRaysNum):
self.createAimRay()
"""
Create a single aim ray.
"""
def createAimRay(self):
ray = rayObject(self.map)
ray.objectType = "ray"
ray.setRayGeom(self.effectiveRange, [Vec3(0,0,0), Vec3(0,0,-1)])
ray.collisionCallback = self.aimCollision
self.map.worldManager.addObject(ray)
self.aimRays.append(ray)
def destroyAimRays(self):
for ray in self.aimRays:
self.map.worldManager.removeObject(ray)
ray.destroy()
self.aimRays = []
self.aimCollisions = []
def selectionCallback(self, character, direction):
PickableObject.selectionCallback(self, character, direction)
"""
Create the rays when we pick up the gun. No need having them around all the time.
NOTE: In my game, I actually create the rays when the Player withdraws the gun
from the inventory, but the actual usage depends on application's design.
"""
self.createAimRays()
def drop(self):
"""
Destroy the rays when we drop the gun.
"""
self.destroyAimRays()
PickableObject.drop(self)
def useHeld(self):
"""
Start shooting...
"""
self.shooting = True
return True
def useHeldStop(self):
"""
Stop shooting an automatic weapon.
Semi automatic weapons stop shooting by themselves, right after
one update pass.
"""
if self.automatic:
self.stopShooting()
return
def shoot(self, dir):
"""
Process the collected hits.
"""
for entry, object in self.aimCollisions:
p = entry.getContactPoint(0)
if object.body:
object.body.enable()
object.body.addForceAtPos(dir*(10**2), p)
def stopShooting(self):
"""
Stop shooting and clear the collisions accumulator.
"""
self.shooting = False
self.autoAccumulator = 0.0
def update(self, stepSize):
PickableObject.update(self,stepSize)
if not self.aimRays:
self.aimCollisions = []
return
"""
Only process hits if the gun is picked up.
"""
if self.owner:
"""
Get the desired position and direction of the aim ray/s.
NOTE that currently there's only support for Player (camera)
and not NPCs. Supports for NPCs will come in the next major version.
"""
pos = base.cam.getPos(render) + render.getRelativeVector(base.cam, Vec3(0, 0.8, 0))
dir = render.getRelativeVector(base.cam, Vec3(0, 1.0, 0))
"""
Handle the Rays and add some random dispersion.
"""
for ray in self.aimRays:
"""
Scatter the rays within the limits set by the shotgunDispersion variable.
"""
x = random.uniform(-self.shotgunDispersion, self.shotgunDispersion)
z = random.uniform(-self.shotgunDispersion, self.shotgunDispersion)
"""
Tweak the direction to take the random values into account.
"""
rayDir = Vec3(dir)
rayDir[0] += x
rayDir[2] += z
"""
Position the ray.
"""
ray.geom.set(pos, rayDir)
"""
Handle automatic weapons.
"""
if self.automatic and self.shooting:
"""
If this is the first frame we're self.shooting == True,
shoot once and then continue processing.
"""
if self.autoAccumulator == 0.0:
self.shoot(dir)
"""
Add the rate-of-fire to the accumulator.
"""
self.autoAccumulator += self.autoROF
"""
Get the ROF per second
"""
currentROF = 1.0/self.autoAccumulator
"""
Call shoot method as many times as shots fitting in the
simulation time step.
That's what the accumulator is for -- thanx to that,
the speed of shooting depends on values set, not on
the simulation's update rate.
"""
if currentROF < stepSize:
for i in range(int(stepSize / currentROF)):
self.shoot(dir)
self.autoAccumulator = 0.0
"""
Handle semi automatic shooting.
"""
elif self.shooting:
self.shoot(dir)
"""
If semi-automatic, make sure to shoot only once.
"""
if not self.automatic:
self.stopShooting()
"""
Clear aim collisions before the next frame.
"""
self.aimCollisions = []
def loadConfig(self, filename):
self.config.addConfig(filename)
self.configName = self.config.configs.keys()[0]
self.activateConfigs()
def activateConfigs(self):
self.name = self.config.getConfig(self.configName)["properties"]["name"]
self.rps = self.config.getConfig(self.configName)["properties"]["rps"]
self.type = self.config.getConfig(self.configName)["properties"]["type"]
self.hudModelPath = self.config.getConfig(self.configName)["properties"]["model"]
self.worldModelPath = self.config.getConfig(self.configName)["properties"]["worldmodel"]
self.modelPath = self.worldModelPath
That’s the firearm module
I’ve renamed pickableObject to PickableObject because I am used to have classes capitalized I’ve capitalized all classes =)
I hope you can find my mistake
Thank you very much
blenderkid