Пример #1
0
def kick_raytest(cont, own):
    '''
	p = own.worldPosition
	y = own.getAxisVect([0,1,0])	
	
	# just return the object
	return own.rayCastTo([p[0]+y[0],  p[1]+y[1],  p[2]+y[2]], 1.2, 'kickable')
	'''
    hit_ob = cont.sensors['kick_radar'].hitObject

    # Cant kick a dead enimy
    if hit_ob == None or hit_ob.get('life', 1) <= 0:
        return None

    if hit_ob and own.getDistanceTo(hit_ob) > 0.7:
        return

    # Pitty but radar is buggy- test angle here
    ang = AngleBetweenVecs( \
     ( Vector(own.getAxisVect((0.0, 1.0, 0.0))) ), \
     ( Vector(hit_ob.worldPosition) - Vector(own.worldPosition) ) \
    )

    if ang > 33.0:
        return None

    return hit_ob
Пример #2
0
def angle_target(own, cont, own_pos):
    # Head towards our target
    direction = target_direction(own, cont, own_pos)

    # own_mat = Matrix(*own.localOrientation).transpose()
    own_y = Vector(own.getAxisVect((0.0, 1.0, 0.0)))
    own_y.z = 0.0
    ang = AngleBetweenVecs(own_y, direction)
    if direction.cross(own_y).z < 0.0:
        ang = -ang
    return ang
Пример #3
0
def angle_target(own, cont, own_pos):
	# Head towards our target 
	direction = target_direction(own, cont, own_pos)
	
	# own_mat = Matrix(*own.localOrientation).transpose()
	own_y = Vector(own.getAxisVect((0.0, 1.0, 0.0)))
	own_y.z = 0.0
	ang = AngleBetweenVecs(own_y, direction)
	if direction.cross(own_y).z < 0.0:
		ang = -ang
	return ang
Пример #4
0
def side_of_other(own, other):
    '''
	What side of the sheep are we standing on? (2D function)
	'''
    relative_vec = Vector(own.worldPosition) - Vector(other.worldPosition)
    other_y_vec = Vector(other.getAxisVect((0.0, 1.0, 0.0)))
    relative_vec.z = other_y_vec.z = 0.0

    if other_y_vec.cross(relative_vec).z > 0.0:
        return True
    else:
        return False
Пример #5
0
def do_clamp_speed(own, cont, velocity):
    '''
	Clamp the x/y velocity, we can do speedups etc here
	but for now just clamping at around run speed is fine.
	'''
    velocity_vec = Vector(velocity[0], velocity[1])
    l = velocity_vec.length

    if own['boosted']:
        MAX_SPEED = 3.0
    else:
        MAX_SPEED = 6.0

    if l < MAX_SPEED:
        return

    velocity_vec.length = MAX_SPEED

    velocity[0] = velocity_vec[0]
    velocity[1] = velocity_vec[1]

    own.setLinearVelocity(velocity)
Пример #6
0
def do_clamp_speed(own, cont, velocity):		
	'''
	Clamp the x/y velocity, we can do speedups etc here
	but for now just clamping at around run speed is fine.
	'''
	velocity_vec = Vector(velocity[0], velocity[1])
	l = velocity_vec.length


	if own['boosted']:
		MAX_SPEED = 3.0	
	else:
		MAX_SPEED = 6.0	
	
	if l < MAX_SPEED:
		return
	
	velocity_vec.length = MAX_SPEED
	
	velocity[0] = velocity_vec[0]
	velocity[1] = velocity_vec[1]
	
	own.setLinearVelocity(velocity)
Пример #7
0
def main(cont):
    own = cont.owner

    sens_wall_ray = cont.sensors['wall_ray']
    sens_wall_time = cont.sensors['wall_run_time']
    actu_motion = cont.actuators['wall_run_motion']

    if not sens_wall_time.positive:
        # We must turn off this actuator once the time limit sensor
        # is false, otherwise it will keep benig applied

        # This will happen when first touching the wall which is not needed
        # but there is no harm in it either.
        # There is a small chance the time will run out but the ray will be hitting somthing.
        # so just to be sure, always remove motion when the wall timer is false.

        cont.deactivate(actu_motion)
        if not sens_wall_ray.positive:
            return

    # when to apply the rebound force from the wall and turn frankie
    # make sure its lower then the wall_run_time sensor maximum
    LIMIT_REBOUND_TIME = 0.25

    REBOUND_LINV = 1.0

    #if not sens_wall_ray.positive:
    #if 1:
    if not sens_wall_time.positive and sens_wall_ray.positive:
        # Either initialize a rebound, of if the angle is low, just run paralelle to the wall
        wall_nor = Vector(sens_wall_ray.hitNormal)
        wall_nor.z = 0.0

        own_neg_y = Vector(own.getAxisVect((0.0, -1.0, 0.0)))
        own_neg_y.z = 0.0

        ang = AngleBetweenVecs(own_neg_y, wall_nor)
        if ang > 22.5:
            cross = wall_nor.cross(own_neg_y)
            if cross.z > 0.0:
                paralelle_dir = wall_nor * RotationMatrix(-90.0, 3, 'z')
            else:
                paralelle_dir = wall_nor * RotationMatrix(90.0, 3, 'z')

            own.alignAxisToVect(paralelle_dir, 1, 0.1)
            return

        else:
            # Rebount! - we're running directly into it

            own['wall_run_timer'] = 0.0

            # Set the direction velocity, apply this later
            ''' # Simple direct off wall, not that fun
			wall_nor = sens_wall_ray.hitNormal
			actu_motion.linV = (wall_nor[0]*REBOUND_LINV, wall_nor[1]*REBOUND_LINV, 0.0)
			'''

            # Nicer to reflect
            wall_nor.normalize()
            ref = own_neg_y.reflect(wall_nor)
            actu_motion.linV = (ref[0] * REBOUND_LINV, ref[1] * REBOUND_LINV,
                                0.0)  # global linV

            cont.activate('run_wall')

    else:
        ## We are not facing the wall anymore, just orient to the reflection vector
        # Apply rebound and face that direction
        if own['wall_run_timer'] > LIMIT_REBOUND_TIME:
            vel = actu_motion.linV
            own.alignAxisToVect(vel, 1, 0.2)
            cont.activate(actu_motion)
Пример #8
0
def frankTestLedge(own, cont, hit_object, CORRECTION_RAY):
    '''
	hit_object is the ledge we are colliding,
		if its None then just look for all objects
		with 'ledge' property
	
	Return: ray_hit, ray_nor, z_pos
	'''

    if own['carrying'] or own['carried']:
        print("cant grab - carry!")
        return None, None, None

    own_pos = own.worldPosition
    '''
	own_pos = own.worldPosition
	own_pos_ofs = own_pos[:]
	[2] += RAY_CAST_Z_OFFSET
	'''

    # Ok we are colliding and pressing up
    y_axis = own.getAxisVect((0.0, 1.0, 0.0))

    ray_dir = own_pos[:]
    ray_dir[0] += y_axis[0]
    ray_dir[1] += y_axis[1]

    if hit_object:
        # print("HITUP!!!")
        #ob_ledge, hit_first, nor_first = own.rayCast(ray_dir, hit_object, RAY_LENGTH)
        ob_ledge, hit_first, nor_first = own.rayCast(ray_dir, own_pos,
                                                     RAY_LENGTH)
        if ob_ledge and ob_ledge != hit_object:
            print("Hit Wrong Object, was %s should be %s" %
                  (ob_ledge.name, hit_object.name))  # should never happen
            return None, None, None
    else:
        # print("NO HITOB!!!")
        ob_ledge, hit_first, nor_first = own.rayCast(ray_dir, own_pos,
                                                     RAY_LENGTH, 'ledge')

    if not hit_first:
        print("FirstLedgeRay Missed!", ray_dir, y_axis)
        return None, None, None

    # debug.setpos( hit_first )

    # Not strictly needed but makes for better results, shoot a ray allong the normal of the ray ray you just hit
    # This prevents moving too far when latching onto a ledge.

    y_axis_corrected = [-nor_first[0], -nor_first[1], 0.0]
    ray_dir_first = ray_dir[:]

    # Should we re-shoot a ray that is corrected based on the normal from the surface of what we hit?
    if CORRECTION_RAY:
        ray_dir_closer = own_pos[:]
        ray_dir_closer[0] += y_axis_corrected[0]
        ray_dir_closer[1] += y_axis_corrected[1]

        if hit_object:
            ob_closer, hit_closer, nor_closer = own.rayCast(
                ray_dir_closer, hit_object, RAY_LENGTH, 'ledge')
        else:
            ob_closer, hit_closer, nor_closer = own.rayCast(
                ray_dir_closer, None, RAY_LENGTH, 'ledge')

        if ob_closer:
            ### print("CAST !!!!!!!!2nd ray")
            AXIS = ((hit_closer, y_axis_corrected, nor_closer),
                    (hit_first, y_axis, nor_first))
        else:
            ### print("Can only castr 1 ray")
            AXIS = ((hit_first, y_axis, nor_first), )
    else:
        # Simple, dont pradict best second ray
        ob_closer = None
        AXIS = ((hit_first, y_axis, nor_first), )

    # Do Z Ray Down.
    Y_OFFSET = 0.6  # length of the Y ray forward.
    Z_OFFSET = 0.6  # length of the Z ray up.

    for hit_new, y_axis_new, nor_new in AXIS:

        # Set the 2D length of this vector to Y_OFFSET
        y_axis_new = Vector(y_axis_new[0], y_axis_new[1])
        y_axis_new.length = Y_OFFSET

        # Now cast a new ray down too see the Z posuition of the ledge above us
        new_ray_pos = [
            own_pos[0] + y_axis_new[0], own_pos[1] + y_axis_new[1],
            own_pos[2] + Z_OFFSET
        ]
        new_ray_pos_target = new_ray_pos[:]
        new_ray_pos_target[2] -= 0.5  # This dosnt matter, just lower is fine

        ### debug.setpos( new_ray_pos )
        ### debug.setpos( new_ray_pos_target )

        ob_ledge, hit_down, nor_down = own.rayCast(
            new_ray_pos_target, new_ray_pos, 0.5
        )  # Can hit objects of any property, MAYBE should choose ground.

        if ob_ledge:
            own['can_climb'] = 1
            ###print("Round nice RAY at pt", hit_down[2])
            # debug.setpos( hit_down )
            return hit_new, nor_new, hit_down[2]

    # Could not hit it vertically...
    # Ok we will try to find the bugger!
    # Cast multiple rays, this is not pretty
    ### print("BUGGER, cant climb", ob_closer)
    own['can_climb'] = 0

    new_ray_pos = own_pos[:]  # we only need to adjust its z value
    if ob_closer:
        # print("Closer")
        new_ray_pos_target = ray_dir_closer[:]
    else:
        # print("NotCloser")
        new_ray_pos_target = ray_dir_first[:]

    target_z = own_pos[2] - CLIMB_HANG_Z_OFFSET
    inc = 0.05  # Watch this, some numbers may cause jitter

    # z_ray_search_origin
    sss = z_ray_search_origin = own_pos[
        2] - 0.2  # Tested this to be a good and correct starting location for searching the ray.

    z_ray_search_limit = own_pos[2] - (CLIMB_HANG_Z_OFFSET * 1.8)

    test_ok = None  # False
    i = 0

    # Ray cast with an increasingly higher Z origin to find the top of the ledge
    while z_ray_search_origin < z_ray_search_limit:
        i += 1
        # print(i, z_ray_search_origin, (own_pos[2]-(CLIMB_HANG_Z_OFFSET*1.8))-z_ray_search_origin)
        z_ray_search_origin += inc
        new_ray_pos[2] = new_ray_pos_target[2] = z_ray_search_origin

        test = own.rayCast(
            new_ray_pos_target, new_ray_pos, RAY_LENGTH, 'ledge'
        )  # Can hit objects of any property, MAYBE should choose ground.

        if test[0]:
            test_ok = test
        elif test[0] == None and test_ok:  # If we have hit
            # no hit, return the last hit
            # print("Found", i)
            '''
			crap = test_ok[1][:]
			crap[2] = z_ray_search_limit
			debug.setpos( crap )
			'''

            return test_ok[1], test_ok[2], z_ray_search_origin

    print("Missed VRAY")
    # crap = hit_first[:]
    # crap[2] = own_pos[2]-CLIMB_HANG_Z_OFFSET
    # debug.setpos( crap )
    return hit_first, nor_first, own_pos[2] - CLIMB_HANG_Z_OFFSET
Пример #9
0
def reset_target(own, cont, own_pos, predator_ob):
    # print('RESET TARGET...')
    TARGET_DIST_MIN = 2.0
    TARGET_DIST_MAX = 8.0

    own['target_time'] = 0.0

    L = TARGET_DIST_MIN + (Rand() * (TARGET_DIST_MAX - TARGET_DIST_MIN))

    own_front = own.getAxisVect((0.0, L, 0.0))

    # Should we run toward or away?

    # we need a random angle between 90 and 270

    if predator_ob:
        if own['revive_time'] < 4.0:
            # print("recover, escape!")
            ATTACK = False
        elif own['type'] == 'ram':
            ATTACK = True

        elif own['type'] == 'shp':
            ATTACK = False
        elif own['type'] == 'rat':
            # attack only when frankie is facing away - Sneaky!
            pred_front = Vector(predator_ob.getAxisVect((0.0, 1.0, 0.0)))
            pred_front.z = 0.0

            pos = Vector(predator_ob.worldPosition)
            new_dir = own_pos - pos

            if new_dir.dot(pred_front) > 0.0:
                ATTACK = False
            else:
                ATTACK = True

        # print('ATTACK', ATTACK)
        # Attack done

        #if predator_ob and Rand() > 0.33:
        pos = Vector(predator_ob.worldPosition)
        new_dir = own_pos - pos

        if ATTACK:
            # ATTACK!
            ### print('ATTACK')
            #own['target_x'] = pos[0]
            #own['target_y'] = pos[1]
            new_dir.z = 0
            new_dir.length = 3  # set target to be 5 past the character.

            own['target_x'] = pos[0] - new_dir.x
            own['target_y'] = pos[1] - new_dir.y
        else:
            ### print('FLEE')
            new_dir.z = 0.0
            new_dir.length = L

            # new_dir = Vector(own_front) * RotationMatrix(ang, 3, 'z')
            ang = (Rand() * 45) - (45 / 2.0)
            new_dir = new_dir * RotationMatrix(ang, 3, 'z')

            own['target_x'] = new_dir.x + own_pos[0]
            own['target_y'] = new_dir.y + own_pos[1]

    else:
        ### print('RANDOM')
        # Random target
        ang = 90 + (Rand() * 180)
        new_dir = Vector(own_front) * RotationMatrix(ang, 3, 'z')

        own['target_x'] = new_dir.x + own_pos[0]
        own['target_y'] = new_dir.y + own_pos[1]
Пример #10
0
def main(cont):

    WALL_LIMIT = 0.1
    TURN_TIME = 0.5
    # we are touching somthing and will always turn the same way out.
    # If ray sensors measure this close
    TOO_CLOSE = 0.55
    DIRECTION[
        0] = 0  # just incase, multiple animals will use this module so must initialize

    own = cont.owner
    # print(own['type'])
    actu_motion = cont.actuators['motion_py']

    # print(own['target_time'])

    ### setpos([own['target_x'], own['target_y'], 0.0])

    cont_name = cont.name

    #print(cont_name, 'cont_name')
    if cont_name.startswith('walk_normal'):
        ROTATE_SPEED = 0.02
        RUN_SPEED = 0.02
        TIME_LIMIT = 6.0
        ESCAPE = False
        predator_ob = None
    else:
        ROTATE_SPEED = 0.1
        if own['type'] == 'rat':
            RUN_SPEED = 0.05
        else:
            RUN_SPEED = 0.03

        TIME_LIMIT = 4.0
        ESCAPE = True
        predator_ob = [
            ob for ob in cont.sensors['predator_sensor'].hitObjectList
            if ob.get('life', 1) != 0
        ]
        if predator_ob:
            predator_ob = predator_ob[0]
        else:
            # EXIT ESCAPE STATE
            predator_ob = None

            cont.activate('walk_state')

    own_pos = Vector(own.worldPosition)
    '''
	sens_l= cont.sensors['RayLeft']
	sens_r = cont.sensors['RayRight']
	sens_l_hitob = sens_l.hitObject
	sens_r_hitob = sens_r.hitObject
	'''

    # use python to get rays instead
    # ray should be
    ray_pos = own_pos.copy()
    ray_pos[
        2] += 0.18  # cast the ray from slightly above, be sure they dont hit objects children

    # see objects "reference_only", these are the raydirections we are casting in python
    right_ray = Vector(own.getAxisVect([0.41, 0.74, -0.53]))
    left_ray = Vector(own.getAxisVect([-0.41, 0.74, -0.53]))

    sens_l_hitob, lpos, lnor = own.rayCast(ray_pos + left_ray, ray_pos, 1.8)
    sens_r_hitob, rpos, rnor = own.rayCast(ray_pos + right_ray, ray_pos, 1.8)

    # ob_ledge, hit_down, nor_down

    # If it has a barrier, respect it

    if sens_l_hitob and ('barrier' in sens_l_hitob or 'water' in sens_l_hitob
                         or 'lava' in sens_l_hitob):
        sens_l_hitob = None

    if sens_r_hitob and ('barrier' in sens_r_hitob or 'water' in sens_r_hitob
                         or 'lava' in sens_r_hitob):
        sens_r_hitob = None

    #if sens_l_hitob:
    #	print(str(sens_l_hitob.name), 'hitob')

    # print('TETS', type(sens_l_hitob), type(sens_r_hitob))

    # Check if we are running into frankie while he is reviving, if so turn away.
    # Do this because otherwise we keep running into frankie after hitting him.
    for ob in (sens_l_hitob, sens_r_hitob):
        if ob and 'predator' in ob and ob.get('revive_time', 100.0) < 1.0:
            # would be nice to alternate but no big deal
            DIRECTION[0] = 1
            RUN_SPEED = 0.0

            # sets a too close value that is checked above
            # this means the sheep will turn for a while so it will never jitter
            own['target_time'] = -TURN_TIME
            break

    if own['target_time'] < 0.0:
        # Should this be a state rather then abusing a timer?
        # This is a bit of a hack. oh well :/
        # print('ROTATING!', own['target_time'])
        DIRECTION[0] = 1
        RUN_SPEED = 0.0
    elif sens_l_hitob and sens_r_hitob:
        # print("BOTH OK")
        # Both collide, so do somtething
        ####lpos =  sens_l.hitPosition
        ldist = own.getDistanceTo(lpos)
        ####lnor = sens_l.hitNormal

        ####rpos =  sens_r.hitPosition
        rdist = own.getDistanceTo(rpos)
        ####rnor = sens_r.hitNormal

        # print(ldist, rdist, 'DIST')

        # Not really an angle, but we can treat it a bit like one
        ang = ldist - rdist

        # Cheap trick, so flat surfaces give low angles
        # Maybe we should deal with flat surfaces differently
        # but we are really looking for walls, so flat'ish ground can be ignored.
        #
        # zl and zr both have a range of -1.0 to 1.0, so if teh surface is totally flat,
        # the 'ang' will be unchanged
        # '''
        zl = lnor[2]
        zr = rnor[2]
        if zl < 0.0: lz = 0.0
        if zr < 0.0: rz = 0.0

        ang = ang * (2.0 - (zl + zr))
        # '''
        # Done with cheap trick, remove if it causes problems

        # Do we need to agoid a wall?
        # IF we are really close to a corner we can get stuck and jitter
        # in this case just turn 1 way

        if ldist < TOO_CLOSE and rdist < TOO_CLOSE:
            # print("\tchar navigation: ray casts both too close", ldist, rdist)
            # would be nice to alternate but no big deal
            DIRECTION[0] = 1
            RUN_SPEED = 0.0

            # sets a too close value that is checked above
            # this means the sheep will turn for a while so it will never jitter
            own['target_time'] = -TURN_TIME

        elif abs(ang) > WALL_LIMIT:
            #print("GO WALL")
            if ang < 0 or (ldist < TOO_CLOSE and rdist < TOO_CLOSE):
                DIRECTION[0] = 1
            else:
                DIRECTION[0] = 2
        else:
            # print("GO TARGET")
            go_target(own, cont, own_pos, predator_ob, TIME_LIMIT)

        if not (sens_l_hitob and sens_r_hitob):
            RUN_SPEED = 0.0

    elif (not sens_l_hitob) and (not sens_r_hitob):
        # We are on a ledge
        # print("EMPTY CLOSE" #, ldist, rdist)
        # would be nice to alternate but no big deal
        DIRECTION[0] = 1
        RUN_SPEED = 0.0

        # sets a too close value that is checked above
        # this means the sheep will turn for a while so it will never jitter
        own['target_time'] = -TURN_TIME

    elif not sens_l_hitob or not sens_r_hitob:

        if abs(angle_target(own, cont,
                            own_pos)) < 90 and own['target_time'] > TIME_LIMIT:
            reset_target(own, cont, own_pos, predator_ob)
        go_target(own, cont, own_pos, predator_ob, TIME_LIMIT)

        # Dont do anything
        RUN_SPEED = 0.0

    # Apply direction
    # print('DIRECTION', DIRECTION, ldist, rdist)
    if DIRECTION[0] == 0:
        # print('NotTurning')
        actu_motion.dRot = (0.0, 0.0, 0.0)

        # cont.deactivate(actu_turn)
    else:
        if DIRECTION[0] == 1:
            # print('Turning Left')
            rot = -ROTATE_SPEED
        elif DIRECTION[0] == 2:
            # print('Turning Right')
            rot = ROTATE_SPEED
        actu_motion.dRot = (0.0, 0.0, rot)

    # This is a bit weired, use negative z dloc to stick him to the ground.
    actu_motion.dLoc = (0.0, RUN_SPEED, -0.01)

    cont.activate(actu_motion)
Пример #11
0
def main(cont):

    HANG_COUNTER_GRAVITY = 0.17
    # HANG_TIMEOFFSET = 20.0

    own = cont.owner

    # 3rd arg gets a corrected ray when its thr first ray for the state
    # This can only run the first time otherwise it makes shimmy jitter baddly.
    #	since correcting the axis can rotate frankie back and fourth.
    if cont.sensors['true_init_pulse_ledge'].positive:
        ledge_hit, ledge_nor, zpos = frankTestLedge(own, cont, None, False)
    else:

        # Drop on purpose
        sens_keyDown = cont.sensors['key_down']
        if sens_keyDown.positive and sens_keyDown.triggered:
            do_fall_state(own, cont)
            return

        ledge_hit, ledge_nor, zpos = frankTestLedge(own, cont, None, True)

        # set the timeoffset so hanging gets nice smooth movement for free.
        # cont.sensors['rig_linkonly'].owner.timeOffset = HANG_TIMEOFFSET

    if not ledge_hit:
        do_fall_state(own, cont)
        return

    sens_up = cont.sensors['key_up']
    if sens_up.positive and sens_up.triggered and own['can_climb']:
        # own.suspendDynamics()
        do_reset_timeofs(cont)
        cont.activate('climb_state')
        return

    own.setLinearVelocity((0.0, 0.0, HANG_COUNTER_GRAVITY))

    # Make sure frankie is upright. especially if he was just gliding this can happen!
    own.alignAxisToVect((0.0, 0.0, 1.0), 2)

    # We need to do somthing a bit extra tricky here, move the position of frankie around the ray intersect pivot,
    # This avoids jittering
    new_dir = Vector(-ledge_nor[0], -ledge_nor[1], 0.0)
    new_z = zpos + CLIMB_HANG_Z_OFFSET
    own_y = Vector(own.getAxisVect((0.0, 1.0, 0.0)))
    ledge_hit = Vector(ledge_hit)
    cross = own_y.cross(new_dir)
    ang = AngleBetweenVecs(own_y, new_dir)

    # Set Frankies distance from the hit position

    if ang > 0.1:
        if cross.z < 0:
            ang = -ang

        pos_orig = Vector(own.worldPosition)
        ####pos_new = ((pos_orig-ledge_hit) * rot) + ledge_hit
        # Do this instead.

        d = (pos_orig - ledge_hit)
        d.z = 0.0
        d.length = -CLIMB_HANG_Y_OFFSET

        pos_new = (d * RotationMatrix(ang, 3, 'z')) + ledge_hit

    else:
        # Simple but not good enough
        # own.localPosition = (pos_orig-ledge_hit) + ledge_hit

        # Location, use CLIMB_HANG_Y_OFFSET to offset ourselves from the ledges hit point
        d = Vector(ledge_nor)
        d.z = 0.0
        d.length = -CLIMB_HANG_Y_OFFSET
        pos_new = d + ledge_hit

    own.alignAxisToVect([-ledge_nor[0], -ledge_nor[1], 0.0], 1)
    pos_new.z = new_z
    own.localPosition = pos_new
Пример #12
0
def reset_target(own, cont, own_pos, predator_ob):
	# print('RESET TARGET...')
	TARGET_DIST_MIN = 2.0
	TARGET_DIST_MAX = 8.0
	
	own['target_time'] = 0.0
	
	L = TARGET_DIST_MIN + (Rand() * (TARGET_DIST_MAX-TARGET_DIST_MIN))

	own_front= own.getAxisVect((0.0, L, 0.0))
	
	# Should we run toward or away?

	# we need a random angle between 90 and 270
	
	if predator_ob:
		if own['revive_time'] < 4.0:
			# print("recover, escape!")
			ATTACK = False
		elif own['type'] == 'ram':
			ATTACK = True
		
		elif own['type'] == 'shp':
			ATTACK = False
		elif own['type'] == 'rat':
			# attack only when frankie is facing away - Sneaky!
			pred_front = Vector(predator_ob.getAxisVect((0.0, 1.0, 0.0)))
			pred_front.z = 0.0
			
			pos = Vector(predator_ob.worldPosition)
			new_dir = own_pos - pos
			
			if new_dir.dot(pred_front) > 0.0:
				ATTACK = False
			else:
				ATTACK = True
			
		# print('ATTACK', ATTACK)
		# Attack done
		
		
		#if predator_ob and Rand() > 0.33:
		pos = Vector(predator_ob.worldPosition)
		new_dir = own_pos - pos
		
		if ATTACK:
			# ATTACK!
			### print('ATTACK')
			#own['target_x'] = pos[0]
			#own['target_y'] = pos[1]
			new_dir.z = 0
			new_dir.length = 3 # set target to be 5 past the character.
			
			own['target_x'] = pos[0] - new_dir.x
			own['target_y'] = pos[1] - new_dir.y
		else:
			### print('FLEE')
			new_dir.z = 0.0
			new_dir.length = L
			
			# new_dir = Vector(own_front) * RotationMatrix(ang, 3, 'z')
			ang = (Rand()*45) - (45/2.0)
			new_dir = new_dir * RotationMatrix(ang, 3, 'z')
			
			own['target_x'] = new_dir.x + own_pos[0]
			own['target_y'] = new_dir.y + own_pos[1]
		
	else:
		### print('RANDOM')
		# Random target
		ang = 90 + (Rand()*180)
		new_dir = Vector(own_front) * RotationMatrix(ang, 3, 'z')
			
		own['target_x'] = new_dir.x + own_pos[0]
		own['target_y'] = new_dir.y + own_pos[1]
Пример #13
0
def main(cont):
	
	WALL_LIMIT = 0.1
	TURN_TIME = 0.5
	# we are touching somthing and will always turn the same way out.
	# If ray sensors measure this close
	TOO_CLOSE = 0.55
	DIRECTION[0] = 0 # just incase, multiple animals will use this module so must initialize
	
	own = cont.owner
	# print(own['type'])
	actu_motion = cont.actuators['motion_py']
	
	# print(own['target_time'])
	
	### setpos([own['target_x'], own['target_y'], 0.0])
	
	cont_name = cont.name
	
	#print(cont_name, 'cont_name')
	if cont_name.startswith('walk_normal'):
		ROTATE_SPEED = 0.02
		RUN_SPEED = 0.02
		TIME_LIMIT = 6.0
		ESCAPE = False
		predator_ob = None
	else:
		ROTATE_SPEED = 0.1
		if own['type'] == 'rat':
			RUN_SPEED = 0.05
		else:
			RUN_SPEED = 0.03
		
		TIME_LIMIT = 4.0
		ESCAPE = True
		predator_ob = [ob for ob in cont.sensors['predator_sensor'].hitObjectList if ob.get('life', 1) != 0]
		if predator_ob:
			predator_ob = predator_ob[0]
		else:
			# EXIT ESCAPE STATE
			predator_ob = None
			
			cont.activate('walk_state')
	
	own_pos = Vector(own.worldPosition)
	
	'''
	sens_l= cont.sensors['RayLeft']
	sens_r = cont.sensors['RayRight']
	sens_l_hitob = sens_l.hitObject
	sens_r_hitob = sens_r.hitObject
	'''
	
	# use python to get rays instead
	# ray should be 
	ray_pos = own_pos.copy()
	ray_pos[2] += 0.18 # cast the ray from slightly above, be sure they dont hit objects children
	
	
	# see objects "reference_only", these are the raydirections we are casting in python
	right_ray = Vector(own.getAxisVect([  0.41, 0.74, -0.53 ]))
	left_ray =  Vector(own.getAxisVect([ -0.41, 0.74, -0.53 ]))
	
	sens_l_hitob, lpos, lnor = own.rayCast(ray_pos + left_ray, ray_pos, 1.8)
	sens_r_hitob, rpos, rnor = own.rayCast(ray_pos + right_ray,  ray_pos, 1.8)
	
	# ob_ledge, hit_down, nor_down
	
	
	
	
	
	
	# If it has a barrier, respect it
	
	if sens_l_hitob and ('barrier' in sens_l_hitob or 'water' in sens_l_hitob or 'lava' in sens_l_hitob):
		sens_l_hitob = None
		
	if sens_r_hitob and ('barrier' in sens_r_hitob or 'water' in sens_r_hitob or 'lava' in sens_r_hitob):
		sens_r_hitob = None
	
	
	
	#if sens_l_hitob:
	#	print(str(sens_l_hitob.name), 'hitob')
	
	
	
	# print('TETS', type(sens_l_hitob), type(sens_r_hitob))
	
	
	# Check if we are running into frankie while he is reviving, if so turn away.
	# Do this because otherwise we keep running into frankie after hitting him.
	for ob in (sens_l_hitob, sens_r_hitob):
		if ob and 'predator' in ob and ob.get('revive_time', 100.0) < 1.0:
			# would be nice to alternate but no big deal
			DIRECTION[0] = 1
			RUN_SPEED = 0.0
			
			# sets a too close value that is checked above
			# this means the sheep will turn for a while so it will never jitter
			own['target_time'] = -TURN_TIME
			break
	
	
	
	if own['target_time'] < 0.0:
		# Should this be a state rather then abusing a timer?
		# This is a bit of a hack. oh well :/
		# print('ROTATING!', own['target_time'])
		DIRECTION[0] = 1
		RUN_SPEED = 0.0
	elif sens_l_hitob and sens_r_hitob:
		# print("BOTH OK")
		# Both collide, so do somtething
		####lpos =  sens_l.hitPosition
		ldist = own.getDistanceTo(lpos)
		####lnor = sens_l.hitNormal
		
		####rpos =  sens_r.hitPosition
		rdist = own.getDistanceTo(rpos)
		####rnor = sens_r.hitNormal
		
		# print(ldist, rdist, 'DIST')
		
		# Not really an angle, but we can treat it a bit like one
		ang = ldist-rdist
		
		# Cheap trick, so flat surfaces give low angles
		# Maybe we should deal with flat surfaces differently
		# but we are really looking for walls, so flat'ish ground can be ignored.
		# 
		# zl and zr both have a range of -1.0 to 1.0, so if teh surface is totally flat,
		# the 'ang' will be unchanged
		# '''
		zl = lnor[2]
		zr = rnor[2]
		if zl < 0.0: lz = 0.0 
		if zr < 0.0: rz = 0.0 
		
		ang = ang * (2.0-(zl+zr))
		# '''
		# Done with cheap trick, remove if it causes problems
		
		
		
		# Do we need to agoid a wall?
		# IF we are really close to a corner we can get stuck and jitter
		# in this case just turn 1 way
		
		if ldist<TOO_CLOSE and rdist<TOO_CLOSE:
			# print("\tchar navigation: ray casts both too close", ldist, rdist)
			# would be nice to alternate but no big deal
			DIRECTION[0] = 1
			RUN_SPEED = 0.0
			
			# sets a too close value that is checked above
			# this means the sheep will turn for a while so it will never jitter
			own['target_time'] = -TURN_TIME
			
		elif abs(ang) > WALL_LIMIT:
			#print("GO WALL")
			if ang < 0 or (ldist<TOO_CLOSE and rdist<TOO_CLOSE):
				DIRECTION[0] = 1
			else:
				DIRECTION[0] = 2
		else:
			# print("GO TARGET")
			go_target(own, cont, own_pos, predator_ob, TIME_LIMIT)
		
		if not (sens_l_hitob and sens_r_hitob):
			RUN_SPEED = 0.0

	elif (not sens_l_hitob) and (not sens_r_hitob):
		# We are on a ledge
		# print("EMPTY CLOSE" #, ldist, rdist)
		# would be nice to alternate but no big deal
		DIRECTION[0] = 1
		RUN_SPEED = 0.0
		
		# sets a too close value that is checked above
		# this means the sheep will turn for a while so it will never jitter
		own['target_time'] = -TURN_TIME
		
	elif not sens_l_hitob or not sens_r_hitob:
		
		if abs(angle_target(own, cont, own_pos)) < 90 and own['target_time'] > TIME_LIMIT:
			reset_target(own, cont, own_pos, predator_ob)
		go_target(own, cont, own_pos, predator_ob, TIME_LIMIT)
		
		# Dont do anything
		RUN_SPEED = 0.0
	
	
	# Apply direction
	# print('DIRECTION', DIRECTION, ldist, rdist)
	if DIRECTION[0] == 0:
		# print('NotTurning')
		actu_motion.dRot = (0.0, 0.0, 0.0)
		
		# cont.deactivate(actu_turn)
	else:
		if DIRECTION[0] == 1:
			# print('Turning Left')
			rot = -ROTATE_SPEED
		elif DIRECTION[0] == 2:
			# print('Turning Right')
			rot = ROTATE_SPEED	
		actu_motion.dRot = (0.0, 0.0, rot)
	
	# This is a bit weired, use negative z dloc to stick him to the ground.
	actu_motion.dLoc = (0.0, RUN_SPEED, -0.01)
	
	cont.activate(actu_motion)
Пример #14
0
def frankTestLedge(own, cont, hit_object, CORRECTION_RAY):
	
	'''
	hit_object is the ledge we are colliding,
		if its None then just look for all objects
		with 'ledge' property
	
	Return: ray_hit, ray_nor, z_pos
	'''

	if own['carrying'] or own['carried']:
		print("cant grab - carry!")
		return None, None, None

	own_pos = own.worldPosition
	'''
	own_pos = own.worldPosition
	own_pos_ofs = own_pos[:]
	[2] += RAY_CAST_Z_OFFSET
	'''	

	
	# Ok we are colliding and pressing up		
	y_axis = own.getAxisVect( (0.0, 1.0, 0.0) )
	
	ray_dir = own_pos[:]
	ray_dir[0] += y_axis[0]
	ray_dir[1] += y_axis[1]
	
	if hit_object:
		# print("HITUP!!!")
		#ob_ledge, hit_first, nor_first = own.rayCast(ray_dir, hit_object, RAY_LENGTH)
		ob_ledge, hit_first, nor_first = own.rayCast(ray_dir, own_pos, RAY_LENGTH)
		if ob_ledge and ob_ledge != hit_object:
			print("Hit Wrong Object, was %s should be %s" % (ob_ledge.name, hit_object.name)) # should never happen
			return None, None, None			
	else:
		# print("NO HITOB!!!")
		ob_ledge, hit_first, nor_first = own.rayCast(ray_dir, own_pos, RAY_LENGTH, 'ledge')
	
	if not hit_first:
		print("FirstLedgeRay Missed!", ray_dir, y_axis)
		return None, None, None
	
	# debug.setpos( hit_first )
	
	# Not strictly needed but makes for better results, shoot a ray allong the normal of the ray ray you just hit
	# This prevents moving too far when latching onto a ledge.
	
	y_axis_corrected = [-nor_first[0], -nor_first[1], 0.0]
	ray_dir_first = ray_dir[:]
	
	
	# Should we re-shoot a ray that is corrected based on the normal from the surface of what we hit?
	if CORRECTION_RAY:
		ray_dir_closer = own_pos[:]
		ray_dir_closer[0] += y_axis_corrected[0]
		ray_dir_closer[1] += y_axis_corrected[1]
		
		if hit_object:
			ob_closer, hit_closer, nor_closer = own.rayCast(ray_dir_closer, hit_object, RAY_LENGTH,  'ledge')
		else:
			ob_closer, hit_closer, nor_closer = own.rayCast(ray_dir_closer, None, RAY_LENGTH, 'ledge')
		
		if ob_closer:
			### print("CAST !!!!!!!!2nd ray")
			AXIS = ((hit_closer, y_axis_corrected, nor_closer), (hit_first, y_axis, nor_first))
		else:
			### print("Can only castr 1 ray")
			AXIS = ((hit_first, y_axis, nor_first),)
	else:
		# Simple, dont pradict best second ray
		ob_closer = None
		AXIS = ((hit_first, y_axis, nor_first),)
	
	
	# Do Z Ray Down.
	Y_OFFSET = 0.6 # length of the Y ray forward.
	Z_OFFSET = 0.6 # length of the Z ray up.
	
	for hit_new, y_axis_new, nor_new in AXIS:
		
		# Set the 2D length of this vector to Y_OFFSET
		y_axis_new = Vector(y_axis_new[0],y_axis_new[1])
		y_axis_new.length = Y_OFFSET
		
		# Now cast a new ray down too see the Z posuition of the ledge above us
		new_ray_pos= [own_pos[0]+y_axis_new[0], own_pos[1]+y_axis_new[1], own_pos[2]+Z_OFFSET]
		new_ray_pos_target = new_ray_pos[:]
		new_ray_pos_target[2] -= 0.5 # This dosnt matter, just lower is fine
		
		### debug.setpos( new_ray_pos )
		### debug.setpos( new_ray_pos_target )
		
		
		ob_ledge, hit_down, nor_down = own.rayCast(new_ray_pos_target, new_ray_pos, 0.5) # Can hit objects of any property, MAYBE should choose ground.
		
		if ob_ledge:
			own['can_climb'] = 1
			###print("Round nice RAY at pt", hit_down[2])
			# debug.setpos( hit_down )
			return hit_new, nor_new, hit_down[2]

	# Could not hit it vertically...
	# Ok we will try to find the bugger!
	# Cast multiple rays, this is not pretty
	### print("BUGGER, cant climb", ob_closer)
	own['can_climb'] = 0
	
	new_ray_pos = own_pos[:] # we only need to adjust its z value
	if ob_closer:
		# print("Closer")
		new_ray_pos_target = ray_dir_closer[:]
	else:
		# print("NotCloser")
		new_ray_pos_target = ray_dir_first[:]

	target_z = own_pos[2]-CLIMB_HANG_Z_OFFSET
	inc = 0.05 # Watch this, some numbers may cause jitter
	
	# z_ray_search_origin
	sss = z_ray_search_origin = own_pos[2]-0.2 # Tested this to be a good and correct starting location for searching the ray.
	
	z_ray_search_limit = own_pos[2]-(CLIMB_HANG_Z_OFFSET*1.8)
	
	test_ok = None # False
	i = 0
	
	# Ray cast with an increasingly higher Z origin to find the top of the ledge
	while z_ray_search_origin < z_ray_search_limit:
		i+=1
		# print(i, z_ray_search_origin, (own_pos[2]-(CLIMB_HANG_Z_OFFSET*1.8))-z_ray_search_origin)
		z_ray_search_origin += inc
		new_ray_pos[2] = new_ray_pos_target[2] = z_ray_search_origin
		
		test = own.rayCast(new_ray_pos_target, new_ray_pos, RAY_LENGTH, 'ledge') # Can hit objects of any property, MAYBE should choose ground.
		
		if test[0]:
			test_ok = test
		elif test[0]==None and test_ok: # If we have hit 
			# no hit, return the last hit
			# print("Found", i)
			'''
			crap = test_ok[1][:]
			crap[2] = z_ray_search_limit
			debug.setpos( crap )
			'''
			
			return test_ok[1], test_ok[2], z_ray_search_origin
	
	print("Missed VRAY")
	# crap = hit_first[:]
	# crap[2] = own_pos[2]-CLIMB_HANG_Z_OFFSET
	# debug.setpos( crap )
	return hit_first, nor_first, own_pos[2]-CLIMB_HANG_Z_OFFSET
Пример #15
0
def main(cont):
	
	HANG_COUNTER_GRAVITY = 0.17
	# HANG_TIMEOFFSET = 20.0
	
	own = cont.owner
		
	# 3rd arg gets a corrected ray when its thr first ray for the state
	# This can only run the first time otherwise it makes shimmy jitter baddly.
	#	since correcting the axis can rotate frankie back and fourth.
	if cont.sensors['true_init_pulse_ledge'].positive:
		ledge_hit, ledge_nor, zpos = frankTestLedge(own, cont, None, False)
	else:
		
		# Drop on purpose
		sens_keyDown = cont.sensors['key_down']
		if sens_keyDown.positive and sens_keyDown.triggered:
			do_fall_state(own, cont)
			return
		
		
		ledge_hit, ledge_nor, zpos = frankTestLedge(own, cont, None, True)
		
		# set the timeoffset so hanging gets nice smooth movement for free.
		# cont.sensors['rig_linkonly'].owner.timeOffset = HANG_TIMEOFFSET
	
	if not ledge_hit:
		do_fall_state(own, cont)
		return
	
	sens_up = cont.sensors['key_up']
	if sens_up.positive and sens_up.triggered and own['can_climb']:
		# own.suspendDynamics()
		do_reset_timeofs(cont)
		cont.activate('climb_state')
		return
	
	own.setLinearVelocity((0.0, 0.0, HANG_COUNTER_GRAVITY))
	
	# Make sure frankie is upright. especially if he was just gliding this can happen!
	own.alignAxisToVect((0.0, 0.0, 1.0), 2)
	
	# We need to do somthing a bit extra tricky here, move the position of frankie around the ray intersect pivot,
	# This avoids jittering
	new_dir = Vector(-ledge_nor[0], -ledge_nor[1], 0.0)
	new_z = zpos + CLIMB_HANG_Z_OFFSET
	own_y = Vector( own.getAxisVect((0.0, 1.0, 0.0)) )
	ledge_hit = Vector(ledge_hit)
	cross =own_y.cross(new_dir)
	ang = AngleBetweenVecs(own_y, new_dir)
	
	# Set Frankies distance from the hit position
	
	if ang > 0.1:
		if cross.z < 0:
			ang = -ang
		
		pos_orig = Vector(own.worldPosition)
		####pos_new = ((pos_orig-ledge_hit) * rot) + ledge_hit
		# Do this instead.

		d = (pos_orig-ledge_hit)
		d.z = 0.0
		d.length = -CLIMB_HANG_Y_OFFSET

		pos_new = (d*RotationMatrix(ang, 3, 'z')) + ledge_hit
		
	else:
		# Simple but not good enough
		# own.localPosition = (pos_orig-ledge_hit) + ledge_hit

		# Location, use CLIMB_HANG_Y_OFFSET to offset ourselves from the ledges hit point
		d = Vector(ledge_nor)
		d.z = 0.0
		d.length = -CLIMB_HANG_Y_OFFSET
		pos_new = d + ledge_hit
	
	own.alignAxisToVect([-ledge_nor[0], -ledge_nor[1], 0.0], 1)
	pos_new.z = new_z
	own.localPosition = pos_new
Пример #16
0
def main(cont):

    if not cont.sensors['trigger_warp_script'].positive:
        return

    own = cont.owner
    own_pos = Vector(own.worldPosition)

    sce = GameLogic.getCurrentScene()
    #for ob in sce.objects:
    #	print(ob.name)

    actu_add_object = cont.actuators['add_dyn_portal']

    # Incase we are called from the main menu
    blendFiles = GameLogic.getBlendFileList('//')
    blendFiles += GameLogic.getBlendFileList('//levels')
    blendFiles += GameLogic.getBlendFileList('//../levels')
    blendFiles += GameLogic.getBlendFileList('//../../../levels')

    # Remove doubles
    # blendFiles	= list(set(blendFiles)) # breaks py2.3
    blendFiles = dict([(b, None) for b in blendFiles]).keys()
    blendFiles = list(blendFiles)  # py3 has its own dict_keys type

    blendFiles.sort()

    if own['mini_level']:
        # Mini level selector
        for b in blendFiles[:]:
            if not ('minilevel_' in b or 'level_selector.blend' in b):
                blendFiles.remove(b)
    else:
        # normal level selector
        for b in blendFiles[:]:
            # get rid or start_menu, this blend, and any blends not containing minilevel_
            if 'minilevel_' in b or \
             'ending.blend' in b or \
             'library.blend' in b or \
             'level_selector.blend' in b or \
             '_backup.blend' in b:

                blendFiles.remove(b)

    print(blendFiles)

    totFiles = len(blendFiles)

    if not totFiles:
        print("No Levels Found!")
        return

    # Some vars for positioning the portals
    start = Vector(
        7, 0, 0)  # rotate this point around to place the portals to new levels

    totFiles = float(totFiles)
    # print('PLACING')
    for i, f in enumerate(blendFiles):
        ang = 360 * (i / totFiles)
        # print(i,f,ang)
        mat = RotationMatrix(ang, 3, 'z')
        pos_xy = list((start * mat) +
                      own_pos)  # rotate and center around the gamelogic object

        ray_down = pos_xy[:]
        ray_down[2] -= 1.0

        print(pos_xy)
        pos_xy[2] = 500  # cast down from on high
        #pos_xy[2] = 16 # cast down from on high
        ob_hit, hit_first, nor_first = own.rayCast(ray_down, pos_xy,
                                                   1000)  # 'ground')
        if ob_hit:
            pos_xy[2] = hit_first[2]
        else:
            # Rary a ray would ,iss the ground but could happen.
            pos_xy[2] = own_pos[2]

        #own.setPosition(pos_xy)

        actu_add_object.instantAddObject()
        new_portal = actu_add_object.objectLastCreated

        #new_portal.setPosition(hit_first)
        new_portal.worldPosition = pos_xy
        new_portal.worldOrientation = mat.transpose()
        if nor_first:
            new_portal.alignAxisToVect(nor_first, 2)

        new_portal['portal_blend'] = '//' + f

        # BUG THIS SHOULD WORK!!!!
        '''
		new_portal_text = new_portal.children
		new_portal_text.Text = f.replace('_', ' ').split('.')[0]
		'''

    # Since we use instantAddObject(), there is no need to activate the actuator
    # GameLogic.addActiveActuator(actu_add_object, 1)

    own.endObject()  # may as well distroy, wont use anymore
Пример #17
0
def do_kick(cont, own):
    '''
	Kick anything infront of you
	'''

    ob_kick = kick_raytest(cont, own)

    if not ob_kick:
        return
    '''
	if not ob_kick.get('grounded', 1):
		print('cant kick airbourne objects')
		return
	'''

    if ob_kick.get('carried', 0):
        print('\tkick: cant kick object being carried')
        return

    kick_dir = Vector(ob_kick.worldPosition) - Vector(own.worldPosition)

    # Tell the object we kicked it. so we cant hurt ourselves
    if 'projectile_id' in ob_kick:
        ob_kick['projectile_id'] = own['id']

    if 'type' in ob_kick:
        ob_kick_type = ob_kick['type']
    else:
        if 'predator' in ob_kick:
            ob_kick_type = 'frank'
        else:
            ob_kick_type = 'unknown'

    # print('ObKick_Type', ob_kick_type)

    if ob_kick_type == 'rat':
        # rats are like footballs
        '''
		kick_dir = own.getAxisVect([0,6,0])
		kick_dir[2] = 5
		ob_kick.setLinearVelocity(kick_dir, 0)
		'''
        # This is a bit nicer, use relative pos
        #  rather then franks direction above
        kick_dir.z = 0
        kick_dir.length = 3.0
        kick_dir.z = 4.0
        ob_kick.setLinearVelocity(kick_dir, 0)
        ob_kick.setAngularVelocity((0.0, -10.0, 0.0),
                                   1)  # We are carrying sideways

    elif ob_kick_type == 'shp':
        # We need to do some complicated crap to make sure they land on our head.
        kick_dir.z = 0.0
        kick_dir.negate()

        if own['carrying']:  # So we can kick a sheep into frankies arms
            kick_dir.length = 0.4
            kick_dir.z = 5.0  # we negate next line
        else:
            kick_dir.length = 0.8
            kick_dir.z = 4.0

        ob_kick.setLinearVelocity(kick_dir, 0)

        if side_of_other(own, ob_kick): ang = -5.0
        else: ang = 5.0
        ob_kick.setAngularVelocity((0.0, ang, 0.0),
                                   1)  # We are carrying sideways
    elif ob_kick_type == 'frank':
        # This is a bit nicer, use relative pos
        #  rather then franks direction above
        kick_dir.z = 0.0
        kick_dir.length = 2.0
        kick_dir.z = 6.0
        ob_kick.setLinearVelocity(kick_dir, False)

        # dont really need this but nice not to always turn the same way
        if side_of_other(own, ob_kick): ang_vel_z = 18
        else: ang_vel_z = -18

        ob_kick.setAngularVelocity((0.0, 0.0, 18.0),
                                   ang_vel_z)  # We are carrying sideways
        ob_kick['hit'] = 1

    else:
        kick_dir.z = 0
        kick_dir.length = 0.5
        kick_dir.negate()
        kick_dir.z = 5.0
        ob_kick.setLinearVelocity(kick_dir, 0)

        # do nothing or rams? just play animations
        print('unknown kick type...', ob_kick_type)
Пример #18
0
def target_direction(own, cont, own_pos):
    return Vector(own['target_x'] - own_pos[0], own['target_y'] - own_pos[1],
                  0.0)
Пример #19
0
def do_throw(cont, own):
    '''
	Throw objects in your inventory, object names are madeup from the property
	so you must make sure there is an object in a hidden layer that exists with this name.
	'''
    # Ok We can throw now,
    throw_item_ob = own['throw_item']
    if not throw_item_ob:
        return  # nothing to throw

    if not throw_item_ob.startswith('item_'):
        print('\twarning: throw item inavlid, must "item_" prefix -',
              throw_item_ob)
        own['throw_item'] = ''
        return

    throw_actu = cont.actuators['throw_create']

    try:
        throw_actu.object = throw_item_ob
    except:
        print('\twarning: could not find object to throw')
        print('\tmissing from scene. Add it to a background layer:',
              throw_item_ob)
        return

    # just aim ahead
    # we tried auto aim but it ended up not working well for moving objects
    own_y_throw = own.getAxisVect((0.0, 8.0, 0.0))
    own_y_throw[2] += 2.0

    throw_actu.instantAddObject()
    ob_throw = throw_actu.objectLastCreated

    # Position the object since its at friankies middle
    # you can place the 3D cursor to double check these values
    ob_throw.localPosition = Vector(own.worldPosition) + Vector(
        own.getAxisVect([0.2, 0.422, 0.455]))

    if 'projectile_id' in ob_throw:
        ob_throw['projectile_id'] = own['id']  # so we dont let it his us.
    ob_throw.setLinearVelocity(own_y_throw)

    # Decrement the number of items we have
    item_count = own[throw_item_ob] - 1

    if item_count <= 0:  # No Items? - Set to zero
        # own['throw_item'] = ''
        # Next available item
        propVal = 0
        for propName in own.getPropertyNames():
            if propName != throw_item_ob and propName.startswith('item_'):
                propVal = own[propName]
                if propVal:  # We have some items in our inventory
                    own['throw_item'] = propName
                    break

        # No Items Left
        if not propVal:
            own['throw_item'] = ''

        own[throw_item_ob] = 0
    else:  # Decrement
        own[throw_item_ob] = item_count
Пример #20
0
def main(cont):

    own = cont.owner
    own_zpos = own.worldPosition[2]

    # If we touch ANYTHING, fall out of glide mode. except for a ledge.
    collide_any = cont.sensors['collide_any']
    if collide_any.positive:
        # If any of these are a bounce object, dont detect a hit.
        if not [
                ob_hit for ob_hit in cont.sensors['collide_any'].hitObjectList
                if ('bounce' in ob_hit)
        ]:
            if own['grounded']: cont.activate('glide_stop_ground')
            else: cont.activate('glide_stop_air')
            return

    own_rig = cont.sensors[
        'rig_linkonly'].owner  # The rig owns this! - cheating way ti get the rig/

    # print(own.getLinearVelocity())
    # First check if we should quit gliding
    if cont.sensors['key_jump_off'].positive or own['grounded']:
        if own['grounded']: cont.activate('glide_stop_ground')
        else: cont.activate('glide_stop_air')

        own_rig.timeOffset = own_rig['defTimeOffset']
        return

    KEY_UP = cont.sensors['key_up'].positive
    if not KEY_UP: KEY_DOWN = cont.sensors['key_down'].positive
    else: KEY_DOWN = False

    # Initialize the height, so we can disallow ever getting higher
    if cont.sensors['true_init_pulse_rep'].positive:
        own['glide_z_init'] = own_zpos
        #### own.glide_swooped = 0
        jump_time = 0.0
        own['jump_time'] = TIME_OFFSET  # Reuse this for timing our glide since we cant jump once gliding anyway

        own_rig.timeOffset = GLIDE_SLOWPARENT_TIMEOFS
    else:
        jump_time = own['jump_time'] - TIME_OFFSET
        if KEY_UP and jump_time > 1.0:
            jump_time = ((jump_time - 1) * 0.5) + 1
            own['jump_time'] = jump_time + TIME_OFFSET

        # Scale down the timeoffset
        ### own_rig.timeOffset *= 0.9

    # pprint(jump_time, 'jump_time')

    glide = cont.actuators['glide_py']

    # Rotation and aligning are now handled in actuators

    vel = own.getLinearVelocity()
    own_y = own.getAxisVect((0.0, 1.0, 0.0))

    # -------------------------
    # own_y[2] MUST BE BETWEEN GLIDE_PITCH_LIMIT_MIN and GLIDE_PITCH_LIMIT_MAX
    # not hard to ensure, but if adjusting the rotate constraint from 45d make sure these change too.
    speed = -(own_y[2] - GLIDE_PITCH_LIMIT_MIN) / (GLIDE_PITCH_LIMIT_MIN -
                                                   GLIDE_PITCH_LIMIT_MAX)
    speed_inv = 1.0 - speed

    if KEY_UP: drot_x = -GLIDE_SPEED_PITCH
    elif KEY_DOWN: drot_x = GLIDE_SPEED_PITCH
    else: drot_x = 0.0

    # Set the rotation to tilt forward or back
    glide.dRot = (drot_x, 0.0, 0.0)  # set to local on the actuator

    # --------------------------

    # We COULD just use own_y, but better compensate for the existing
    # Calculate XY!
    orig_xy_speed = Vector(vel[0], vel[1]).length

    fac = speed_inv * GLIDE_ACCEL

    orig_xy_speed += fac * fac

    if orig_xy_speed > GLIDE_SPEED_LIMIT:
        orig_xy_speed = GLIDE_SPEED_LIMIT
    # normalize and scale to original speed, use verbose python
    own_y_length = Vector(own_y[0], own_y[1]).length
    new_x = (own_y[0] / own_y_length) * orig_xy_speed
    new_y = (own_y[1] / own_y_length) * orig_xy_speed
    #new_xy = Vector(own_y[0], own_y[1])
    #new_xy.length = orig_xy_speed

    # Calculate Z, Heres the logic,
    # tilting down makes you go faster but also fall quicker
    # tiltin up makes fall slower but slows you down X/Y motion.
    # if your not moving fast and tilting back, you fall.

    # Calculate Z Offset
    fac = GLIDE_SPEED_FALL_TIME_FAC * jump_time
    zoffset = GLIDE_SPEED_FALL + fac * fac  # jump time means start for gliding here
    # print(zoffset)
    if zoffset > 10.0:
        zoffset = 10.0

    if speed > 0.5:
        # slow down but go up
        fac = (speed - 0.5) * (1800.0 / (1 + jump_time / 20.0))
        zoffset -= (orig_xy_speed / GLIDE_SPEED_LIMIT) * fac

        fac = 1 + (0.5 - speed)  # Raising above 0.5 is bad juju
        #if own.glide_swooped==2: fac = (fac*fac)

        new_x *= fac
        new_y *= fac

    else:
        # Falling
        fac = (speed) * 30
        zoffset -= (orig_xy_speed / GLIDE_SPEED_LIMIT) * fac

        # This 0.98 dampens the forward speed, use the time stuff also
        fac = 0.98 / (1 + (GLIDE_SPEED_FALL_TIME_FAC * jump_time))
        new_x *= fac
        new_y *= fac

    new_z = vel[2] - GLIDE_SPEED_FALL_ACCEL * zoffset

    z_over = own_zpos - own['glide_z_init']
    if z_over > 0.0:
        scaler = (1 + (z_over * 0.2))
        new_x = new_x / scaler
        new_y = new_y / scaler
        if new_z > 0.0:  # only scale down if were riseing
            new_z = new_z / scaler

    # # Interpolate velocity if just started jumping!
    if jump_time < GLIDE_EASE_IN_TIME:
        fac = jump_time / GLIDE_EASE_IN_TIME
        faci = 1.0 - fac

        new_x = new_x * fac + vel[0] * faci
        new_y = new_y * fac + vel[1] * faci
        new_z = new_z * fac + vel[2] * faci
        # print("Interpolate",fac)

    glide.linV = new_x, new_y, new_z  # set to global on the actuator

    cont.activate(glide)