OIS input system (#556)

* Work

* Add ois.lib

* Add OIS headers/libs to project

* Fix small mistakes

* Update input.cpp

* Update input.cpp

* Update input.cpp

* Remove unnecessary event handlers as we are using direct polling

* Fix numpad controls not polling

* Enclose all input code under namespace, provide debug OIS lib variation

* Fix incorrect inventory call binding, add pause to control dialog

* Deselect by pushing inventory button as well, fix crossbow ammo string draw

* Demagic NUM_CONTROLS

* Verbose input init logging

* Calibrate and properly register movement analog axis input

* Fix crash when empty string is being displayed

* Initialize vibration interface, if it exists

* Register keyboard directional input as analog axis input as well

* Fix statistics exiting

* Fix weird UpdateInput call

* Copy current layout to configuration

* Fix issues with saving controls

* Register axis values for POVs too

* Register several POV directions at once

* Increase deadzone a bit

* Simplify enums

* Update input.cpp

* Move includes out of input.h

* Bump deadzone even further as it seems xbox controllers have massive axis errors

* Prevent event spamming in case OIS polling failed

* Destroy input system on exit, cosmetic changes

* Take deadzone into account when normalizing axis values

* Update TombEngine.vcxproj

* Resolve small precision loss in axis normalizing

* Clean up unused control constants and enums

* Update input.h

* Demagic InputActions enum

* Render pause menu header

* Introduce helper functions to modulate Lara turn rates and begin replacements

* Make turn directions explicit

* Conduct remaining replacements of turn rate modulations

* Update lara_helpers.cpp

* Add smoothstep function to math library

* Use scaled axis value for true analog input

* Update input.cpp

* Add Joey's camera rotation from old branch

* Fix camera not going back to previous position when stick is released

* Simplify ModulateLaraTurnRate()

* Widen look angle

* Avoid collisions with actions bound to non-directional axis

* Small tidying

* Remove unused header

* Remove copypasted code

* Mask flare animation

* Rename 5th and 6th axis to LT/RT

* Prototype force feedback support

* Add directional rumble support (probably XInput-only)

* Shake controller on startup if supports vibration

* Update OIS libs to support XInput FF

* Simplify ModulateLaraTurnRate()

* Update player modulation functions; simplify turning, leaning, and flexing in state functions; lara.h cleanup

* Update Win32ForceFeedback.h

* Fix crawl flex function

* Revert "Update Win32ForceFeedback.h"

This reverts commit aa7099ed5b.

* Update OIS libs

* Add options for thumbstick camera and vibration

* Make use of autotarget option

* Display NON-SCREAMING names in controls, add hack to cancel axis value on both right+left input events

* Remove useless control hacks for simultaneous directional input

* Delete ten_itemdata_generated.h

* Add scroll lock to bindable controls

* Update input.cpp

* Update input.cpp

* Make input device namings consistent

* Bring back IN_SELECT override

* Fix crashing on startup and some other bugs

* Add rumble to some in-game events

* Add some more vibration events, stop them when going to menus

* Some changes to rumble power

* Add rumble for rocket/grenade launchers and explosive damage

* Add rumble for screen shake effect

* Fix 2 mistakes in inventory strings

* Rumble for camera more precisely

* Fix debounce in binocular mode

* Update camera.cpp

* Add HK lasersight rumble

* Simplify ModulateLaraLean()

* Update input.cpp

* Fix crawl flex modulation(?)

* Add slight rumble to harpoon and crossbow fire

* Remove the confusing counteracting turn rate reset in favour of something simpler

* Simplify turn rate reset input checks; leanup

* Clamp turn rate axis coeff when airborne

* Remove empty line

* Simplify a function

* Cleanup

* Fix rumble being constant

* Use shorter rumble time for shooting guns

* Fix single arm shooting

* Fix leaning left with joystick; clamp crawl flex max; tweak walk lean max; cleanup

* Don't do too long splat and jump smash vibrations

* Cancel turn rate when exiting water, grabbing ledge, or doing a splat

* Rename function

* Move ModulateLaraTurnRateY() callsin crawl and crouch turn states

* Reset turn rate when performing crawl vault

* Convert all health decrease events to DoDamage calls

* Remove SpasmEffectCount and unify touching with DoDamage

* Give specific time delay before sprint jump is possible

* Don't rumble on zero damage

* Reorder input pipeline to prevent left+right collisions

* Rename shady global

* Rumble when breaking neck in swandive

* Update lara_jump.cpp

* Don't vibrate on soft splat

* Fix combine item text alignment

* Vibrate in settings only if setting was changed

* Pulse gamepad on critical health condition

* Don't get out of water into objects

* Add critical air constant

Co-authored-by: Sezz
This commit is contained in:
Lwmte 2022-06-25 16:53:58 +03:00 committed by GitHub
parent eb55180b05
commit 12663c7ce2
226 changed files with 5974 additions and 3333 deletions

59
Libs/ois/OIS.h Normal file
View file

@ -0,0 +1,59 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
/**\mainpage Object-oriented Input System
*
* Welcome to the documentation of OIS.
*
*
* This website contains the documentation of the public API exposed by OIS.
*
* As the name of the library suggest, this is 100% Object-oriented.
* Every C++ classes from the library is located inside the OIS namespace.
*
* This project is licensed under the terms of the <a href="https://opensource.org/licenses/Zlib">zlib/libpng licence</a>
*
*/
#ifndef OIS_OISALL_H
#define OIS_OISALL_H
#include "OISPrereqs.h"
#include "OISObject.h"
#include "OISMouse.h"
#include "OISKeyboard.h"
#include "OISJoyStick.h"
#include "OISMultiTouch.h"
#include "OISInputManager.h"
#include "OISFactoryCreator.h"
#include "OISException.h"
#include "OISEvents.h"
#include "OISEffect.h"
#include "OISInterface.h"
#include "OISForceFeedback.h"
#endif

BIN
Libs/ois/OIS.lib Normal file

Binary file not shown.

78
Libs/ois/OISConfig.h Normal file
View file

@ -0,0 +1,78 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_CONFIG_HEADER
#define OIS_CONFIG_HEADER
//----------------------------------------------------------------------------//
//* This file contains defines for building certain parts of this Lib
//* This file is not meant for External inclusion. However, you can edit this
//* file before a build to effect what features are used internally
//----------------------------------------------------------------------------//
/**
@remarks
These lines have no bearing on internal build of OIS. This is here for
external build settings. Meaning, changing this does not require a
rebuild of OIS. This just affects VC dll import settings, as the DLL
build already defines this during its build for setting dll exports.
The undefine here is here just incase you decide to only use
DLL, and want to set it permently and recompile OIS too.. Avoid redefinition
from DLL build of OIS.
So, if wanting to link against DLL version, just uncomment these lines.
*/
//#ifdef OIS_DYNAMIC_LIB
//# undef OIS_DYNAMIC_LIB
//#endif
//#define OIS_DYNAMIC_LIB
/**
@remarks
Build in support for LIRC / WinLIRC - remote control support.
Requires Boost::asio
@notes
Experimental - Supports connecting and enumerating. Control does not
yet return state or events
*/
//#define OIS_LIRC_SUPPORT
/**
@remarks
Build in support for PC Nintendo WiiMote Win32 HID interface.
Requires Boost::threads
@notes
Useable, but not quite finished - supports rumble, all buttons, & main orientation axis.
Still needs Nunchuck, IR, and LED/Battery support.
*/
//#define OIS_WIN32_WIIMOTE_SUPPORT
/**
@remarks
Build in support for Win32 XInput (Xbox 360 Controller)
*/
//#define OIS_WIN32_XINPUT_SUPPORT
#endif

286
Libs/ois/OISEffect.h Normal file
View file

@ -0,0 +1,286 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Effect_H
#define OIS_Effect_H
#include "OISPrereqs.h"
namespace OIS
{
//Predeclare some Effect Property structs
class ForceEffect;
class ConstantEffect;
class RampEffect;
class PeriodicEffect;
class ConditionalEffect;
/**
Force Feedback is a relatively complex set of properties to upload to a device.
The best place for information on the different properties, effects, etc is in
the DX Documentation and MSDN - there are even pretty graphs ther =)
As this class is modeled on the the DX interface you can apply that same
knowledge to creating effects via this class on any OS supported by OIS.
In anycase, this is the main class you will be using. There is *absolutely* no
need to instance any of the supporting ForceEffect classes yourself.
*/
class _OISExport Effect
{
public:
//! Type of force
enum EForce {
UnknownForce = 0,
ConstantForce,
RampForce,
PeriodicForce,
ConditionalForce,
CustomForce,
_ForcesNumber // Always keep in last position.
};
static const char* getForceTypeName(EForce eValue);
//! Type of effect
enum EType {
//Type ----- Pairs with force:
Unknown = 0, //UnknownForce
Constant, //ConstantForce
Ramp, //RampForce
Square, //PeriodicForce
Triangle, //PeriodicForce
Sine, //PeriodicForce
SawToothUp, //PeriodicForce
SawToothDown, //PeriodicForce
Friction, //ConditionalForce
Damper, //ConditionalForce
Inertia, //ConditionalForce
Spring, //ConditionalForce
Custom, //CustomForce
_TypesNumber // Always keep in last position.
};
static const char* getEffectTypeName(EType eValue);
//! Direction of the Force
enum EDirection {
NorthWest,
North,
NorthEast,
East,
SouthEast,
South,
SouthWest,
West,
_DirectionsNumber // Always keep in last position.
};
static const char* getDirectionName(EDirection eValue);
/**
This constructor allows you to set the force type and effect.
*/
Effect(EForce ef, EType et);
virtual ~Effect();
const EForce force;
const EType type;
//Infinite Time
static const unsigned int OIS_INFINITE = 0xFFFFFFFF;
//-------------------------------------------------------------------//
//--- Set these variables before uploading or modifying an effect ---//
//Direction to apply to the force - affects two axes+ effects
EDirection direction;
//Number of button triggering an effect (-1 means no trigger)
short trigger_button;
//Time to wait before an effect can be re-triggered (microseconds)
unsigned int trigger_interval;
//Duration of an effect (microseconds)
unsigned int replay_length;
//Time to wait before to start playing an effect (microseconds)
unsigned int replay_delay;
//Get the specific Force Effect. This should be cast depending on the EForce
ForceEffect* getForceEffect() const;
/**
@remarks
Set the number of Axes to use before the initial creation of the effect.
Can only be done prior to creation! Use the FF interface to determine
how many axes can be used (are availiable)
*/
void setNumAxes(short nAxes);
/**
@remarks
Returns the number of axes used in this effect
*/
short getNumAxes() const;
//------------- Library Internal -------------------------------------//
/**
set internally.. do not change or you will not be able to upload/stop
this effect any more. It will become lost. It is mutable so even
with const reference it can/will be changed by this lib
*/
mutable int _handle;
protected:
// Prevent copying.
Effect(const Effect&);
Effect& operator=(Effect);
ForceEffect* effect; //Properties depend on EForce
short axes; //Number of axes to use in effect
};
//-----------------------------------------------------------------------------//
/**
Base class of all effect property classes
*/
class _OISExport ForceEffect
{
public:
virtual ~ForceEffect() { }
};
//-----------------------------------------------------------------------------//
/**
An optional envelope to be applied to the start/end of an effect. If any of
these values are nonzero, then the envelope will be used in setting up the
effect.
*/
class _OISExport Envelope : public ForceEffect
{
public:
Envelope() :
attackLength(0), attackLevel(0), fadeLength(0), fadeLevel(0) { }
#if defined(OIS_MSVC_COMPILER)
#pragma warning(push)
#pragma warning(disable : 4800)
#endif
bool isUsed() const
{
return attackLength | attackLevel | fadeLength | fadeLevel;
}
#if defined(OIS_MSVC_COMPILER)
#pragma warning(pop)
#endif
// Duration of the attack (microseconds)
unsigned int attackLength;
// Absolute level at the beginning of the attack (0 to 10K)
// (automatically signed when necessary by FF core according to effect level sign)
unsigned short attackLevel;
// Duration of fade (microseconds)
unsigned int fadeLength;
// Absolute level at the end of fade (0 to 10K)
// (automatically signed when necessary by FF core according to effect level sign)
unsigned short fadeLevel;
};
//-----------------------------------------------------------------------------//
/**
Use this class when dealing with Force type of Constant
*/
class _OISExport ConstantEffect : public ForceEffect
{
public:
ConstantEffect() :
level(5000) { }
Envelope envelope; //Optional envolope
signed short level; //-10K to +10k
};
//-----------------------------------------------------------------------------//
/**
Use this class when dealing with Force type of Ramp
*/
class _OISExport RampEffect : public ForceEffect
{
public:
RampEffect() :
startLevel(0), endLevel(0) { }
Envelope envelope; //Optional envelope
signed short startLevel; //-10K to +10k
signed short endLevel; //-10K to +10k
};
//-----------------------------------------------------------------------------//
/**
Use this class when dealing with Force type of Periodic
*/
class _OISExport PeriodicEffect : public ForceEffect
{
public:
PeriodicEffect() :
magnitude(0), offset(0), phase(0), period(0) { }
Envelope envelope; //Optional Envelope
unsigned short magnitude; //0 to 10,0000
signed short offset;
unsigned short phase; //Position at which playback begins 0 to 35,999
unsigned int period; //Period of effect (microseconds)
};
//-----------------------------------------------------------------------------//
/**
Use this class when dealing with Force type of Condional
*/
class _OISExport ConditionalEffect : public ForceEffect
{
public:
ConditionalEffect() :
rightCoeff(0), leftCoeff(0), rightSaturation(0), leftSaturation(0),
deadband(0), center(0) { }
signed short rightCoeff; //-10k to +10k (Positive Coeff)
signed short leftCoeff; //-10k to +10k (Negative Coeff)
unsigned short rightSaturation; //0 to 10k (Pos Saturation)
unsigned short leftSaturation; //0 to 10k (Neg Saturation)
//Region around center in which the condition is not active, in the range
//from 0 through 10,000
unsigned short deadband;
//(Offset in DX) -10k and 10k
signed short center;
};
}
#endif //OIS_Effect_H

47
Libs/ois/OISEvents.h Normal file
View file

@ -0,0 +1,47 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _OIS_EVENTHEADERS_
#define _OIS_EVENTHEADERS_
#include "OISPrereqs.h"
namespace OIS
{
/**
Base class of all events
*/
class _OISExport EventArg
{
public:
explicit EventArg(Object* obj) :
device(obj) { }
virtual ~EventArg() { }
//! Pointer to the Input Device
const Object* device;
};
}
#endif //_OIS_EVENTHEADERS_

101
Libs/ois/OISException.h Normal file
View file

@ -0,0 +1,101 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _OIS_EXCEPTION_HEADER_
#define _OIS_EXCEPTION_HEADER_
#include "OISPrereqs.h"
#include <exception>
#ifdef OIS_WIN32_PLATFORM
#pragma warning(push)
#pragma warning(disable : 4275) //Silence warning from MSVC when using std::exception as the base class of a dll-interface class (OIS::Exception)
#endif
namespace OIS
{
//! Simple enum's for dealing with exceptions
enum OIS_ERROR {
E_InputDisconnected,
E_InputDeviceNonExistant,
E_InputDeviceNotSupported,
E_DeviceFull,
E_NotSupported,
E_NotImplemented,
E_Duplicate,
E_InvalidParam,
E_General
};
/**
@remarks
Class for handling OIS exceptions. Much cleaner than checking every method for reurn value.
Inherits from std::exception so you can simply log those messages if you want to be generic.
Also note that this has a source file now since OSX was not finding the OIS::Exception symbol
which would cause program abortion with now correponding exception type.
*/
class _OISExport Exception : public std::exception
{
public:
//! Creates exception object
Exception(OIS_ERROR err, const char* str, int line, const char* file) :
eType(err), eLine(line), eFile(file), eText(str) { }
Exception(const Exception& other) :
eType(other.eType), eLine(other.eLine), eFile(other.eFile), eText(other.eText) { }
~Exception() throw() { }
virtual const char* what() const throw();
//! The type of exception raised
const OIS_ERROR eType;
//! The line number it occurred on
const int eLine;
//! The source file
const char* eFile;
//! A message passed along when the exception was raised
const char* eText;
private:
// Unimplemented and unaccessible due to const members.
Exception& operator=(Exception);
};
}
//! Use this macro to handle exceptions easily
#define OIS_EXCEPT(err, str) throw(OIS::Exception(err, str, __LINE__, __FILE__))
//TODO choose what to do with this...
//#define OIS_WARN( err, str ) throw( OIS::Exception(err, str, __LINE__, __FILE__) )
#define OIS_WARN(err, str) \
do \
{ \
} while(0)
#ifdef OIS_WIN32_PLATFORM
#pragma warning(pop)
#endif
#endif //_OIS_EXCEPTION_HEADER_

View file

@ -0,0 +1,84 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_FactoryCreator_H
#define OIS_FactoryCreator_H
#include "OISPrereqs.h"
namespace OIS
{
/**
Interface for creating devices - all devices ultimately get enumerated/created via a factory.
A factory can create multiple types of objects.
*/
class _OISExport FactoryCreator
{
public:
/**
@remarks Virtual Destructor
*/
virtual ~FactoryCreator() {};
/**
@remarks Return a list of all unused devices the factory maintains
*/
virtual DeviceList freeDeviceList() = 0;
/**
@remarks Number of total devices of requested type
@param iType Type of devices to check
*/
virtual int totalDevices(Type iType) = 0;
/**
@remarks Number of free devices of requested type
@param iType Type of devices to check
*/
virtual int freeDevices(Type iType) = 0;
/**
@remarks Does a Type exist with the given vendor name
@param iType Type to check
@param vendor Vendor name to test
*/
virtual bool vendorExist(Type iType, const std::string& vendor) = 0;
/**
@remarks Creates the object
@param iType Type to create
@param bufferMode True to setup for buffered events
@param vendor Create a device with the vendor name, "" means vendor name is unimportant
*/
virtual Object* createObject(InputManager* creator, Type iType, bool bufferMode, const std::string& vendor = "") = 0;
/**
@remarks Destroys object
@param obj Object to destroy
*/
virtual void destroyObject(Object* obj) = 0;
};
}
#endif //OIS_FactoryCreator_H

123
Libs/ois/OISForceFeedback.h Normal file
View file

@ -0,0 +1,123 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_ForceFeedBack_H
#define OIS_ForceFeedBack_H
#include "OISPrereqs.h"
#include "OISInterface.h"
#include "OISEffect.h"
namespace OIS
{
/**
Interface class for dealing with Force Feedback devices
*/
class _OISExport ForceFeedback : public Interface
{
public:
ForceFeedback();
virtual ~ForceFeedback() { }
/**
@remarks
This is like setting the master volume of an audio device.
Individual effects have gain levels; however, this affects all
effects at once.
Note: If the device does not support master gain setting, nothing is done
@param level
A value between 0.0 and 1.0 represent the percentage of gain. 1.0
being the highest possible force level (means no scaling).
*/
virtual void setMasterGain(float level) = 0;
/**
@remarks
If using Force Feedback effects, this should be turned off
before uploading any effects. Auto centering is the motor moving
the joystick back to center. DirectInput only has an on/off setting,
whereas linux has levels.. Though, we go with DI's on/off mode only
Note: If the device does not support auto-centering, nothing is done
@param auto_on
true to turn auto centering on, false to turn off.
*/
virtual void setAutoCenterMode(bool auto_on) = 0;
/**
@remarks
Creates and Plays the effect immediately. If the device is full
of effects, it will fail to be uploaded. You will know this by
an invalid Effect Handle
*/
virtual void upload(const Effect* effect) = 0;
/**
@remarks
Modifies an effect that is currently playing
*/
virtual void modify(const Effect* effect) = 0;
/**
@remarks
Remove the effect from the device
*/
virtual void remove(const Effect* effect) = 0;
/**
@remarks
Get the number of supported Axes for FF usage
*/
virtual short getFFAxesNumber() = 0;
/**
@remarks
Get the current load (%, in [0, 100] of the FF device memory
*/
virtual unsigned short getFFMemoryLoad() = 0;
typedef std::multimap<Effect::EForce, Effect::EType> SupportedEffectList;
/**
@remarks
Get a list of all supported effects
*/
const SupportedEffectList& getSupportedEffects() const;
/**
@remarks
Tell if a given force / effect type pair is supported
*/
bool supportsEffect(Effect::EForce force, Effect::EType type) const;
void _addEffectTypes(Effect::EForce force, Effect::EType type);
void _setGainSupport(bool on);
void _setAutoCenterSupport(bool on);
protected:
SupportedEffectList mSupportedEffects;
bool mSetGainSupport;
bool mSetAutoCenterSupport;
};
}
#endif //OIS_ForceFeedBack_H

213
Libs/ois/OISInputManager.h Normal file
View file

@ -0,0 +1,213 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_InputManager_H
#define OIS_InputManager_H
#include "OISPrereqs.h"
namespace OIS
{
//Forward declare a couple of classes we might use later
class LIRCFactoryCreator;
class WiiMoteFactoryCreator;
/**
Base Manager class. No longer a Singleton; so feel free to create as many InputManager's as you have
windows.
*/
class _OISExport InputManager
{
public:
/**
@remarks
Returns version number (useful in DLL/SO libs)
@returns
Bits: 1-8 Patch number, 9-16 Minor version, 17-32 Major version
*/
static unsigned int getVersionNumber();
/**
@remarks
Returns version string (useful in DLL/SO libs)
@returns
Version name
*/
const std::string& getVersionName();
/**
@remarks
Creates appropriate input system dependent on platform.
@param winHandle
Contains OS specific window handle (such as HWND or X11 Window)
@returns
A pointer to the created manager, or raises Exception
*/
static InputManager* createInputSystem(std::size_t winHandle);
/**
@remarks
Creates appropriate input system dependent on platform.
@param paramList
ParamList contains OS specific info (such as HWND and HINSTANCE for window apps),
and access mode.
@returns
A pointer to the created manager, or raises Exception
*/
static InputManager* createInputSystem(ParamList& paramList);
/**
@remarks
Destroys the InputManager
@param manager
Manager to destroy
*/
static void destroyInputSystem(InputManager* manager);
/**
@remarks Gets the name of the current platform input system
*/
const std::string& inputSystemName();
/**
@remarks
Returns the number of the specified OIS::Type devices discovered by OIS
@param iType
Type that you are interested in
*/
int getNumberOfDevices(Type iType);
/**
@remarks
Lists all unused devices
@returns
DeviceList which contains Type and vendor of device
*/
DeviceList listFreeDevices();
/**
@remarks
Tries to create an object with the specified vendor. If you have no
preference of vendor, leave vender as default (""). Raises exception on failure
*/
Object* createInputObject(Type iType, bool bufferMode, const std::string& vendor = "");
/**
@remarks Destroys Input Object
*/
void destroyInputObject(Object* obj);
/**
@remarks
Add a custom object factory to allow for user controls.
@param factory
Factory instance to add
@notes
Make sure you do not delete the factory before devices created from
the factory are destroyed (either by calling RemoveFactoryCreator, or shutting down
the input system). Order should be something like the following:
* Create Input System
* Create Factory Instance
* AddFactoryCreator(factory)
* Create a device from the InputManager (device created by factory)
* One of the follwoing:
* removeFactoryCreator(factory)
* inputManager->destroyInputObject(obj)
* destroyInputSystem(inputManager)
* destroy Factory Instance
You can safely delete the factory instance once you have removed it or shut down the
input manager.
*/
void addFactoryCreator(FactoryCreator* factory);
/**
@remarks
Remove a previously added object factory
@param factory
Factory object to remove.
@notes
Removing a factory will automatically destroy any Objects created from the factory
*/
void removeFactoryCreator(FactoryCreator* factory);
//! All generic devices OIS supports internally (if they are compiled in)
enum AddOnFactories {
AddOn_All = 0, //All Devices
AddOn_LIRC = 1, //PC Linux Infrared Remote Control
AddOn_WiiMote = 2 //PC WiiMote Support
};
/**
@remarks
Enable an addon FactoryCreator extension. By default, none are activated.
If the desired support was not compiled in, this has no effect. Calling
multiple times has no effect. Once activated, there is no way to deactivate -
simply destroy and recreate input manager.
*/
void enableAddOnFactory(AddOnFactories factory);
protected:
/**
@remarks
Called from createInputSystem, gives derived input class a chance to setup after it is created
*/
virtual void _initialize(ParamList& paramList) = 0;
/**
@remarks
Derived classes must provide input system name
*/
explicit InputManager(const std::string& name);
/**
@remarks
Virtual Destructor - this base class will clean up all devices still opened in mFactoryObjects list
*/
virtual ~InputManager();
//! OIS Version name
const std::string m_VersionName;
//! FactoryCreator list
FactoryList mFactories;
//! Factory created objects - useful so we can find creator to send destruction request to
FactoryCreatedObject mFactoryObjects;
//! Name of the input system
const std::string mInputSystemName;
//! Extra factory (not enabled by default)
LIRCFactoryCreator* m_lircSupport;
WiiMoteFactoryCreator* m_wiiMoteSupport;
private:
// Prevent copying.
InputManager(const InputManager&);
InputManager& operator=(const InputManager&);
};
}
#endif

49
Libs/ois/OISInterface.h Normal file
View file

@ -0,0 +1,49 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Interface_H
#define OIS_Interface_H
#include "OISPrereqs.h"
namespace OIS
{
/**
An Object's interface is a way to gain write access to devices which support
it. For example, force feedack.
*/
class _OISExport Interface
{
public:
virtual ~Interface() {};
//! Type of Interface
enum IType {
ForceFeedback,
Reserved
};
};
}
#endif //OIS_Interface_H

254
Libs/ois/OISJoyStick.h Normal file
View file

@ -0,0 +1,254 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Joystick_H
#define OIS_Joystick_H
#include "OISObject.h"
#include "OISEvents.h"
namespace OIS
{
/** @remarks default sensitivity for vector3 component of joystick */
#define OIS_JOYSTICK_VECTOR3_DEFAULT 2.28f
//! POV / HAT Joystick component
class _OISExport Pov : public Component
{
public:
Pov() :
Component(OIS_POV), direction(0) { }
static const int Centered = 0x00000000;
static const int North = 0x00000001;
static const int South = 0x00000010;
static const int East = 0x00000100;
static const int West = 0x00001000;
static const int NorthEast = 0x00000101;
static const int SouthEast = 0x00000110;
static const int NorthWest = 0x00001001;
static const int SouthWest = 0x00001010;
int direction;
};
//! A sliding axis - only used in Win32 Right Now
class _OISExport Slider : public Component
{
public:
Slider() :
Component(OIS_Slider), abX(0), abY(0) {};
//! true if pushed, false otherwise
int abX, abY;
};
/**
Represents the state of the joystick
All members are valid for both buffered and non buffered mode
Sticks with zero values are not present on the device
*/
class _OISExport JoyStickState
{
public:
//! Constructor
JoyStickState() { clear(); }
//! Represents all the buttons (uses a bitset)
std::vector<bool> mButtons;
//! Represents all the single axes on the device
std::vector<Axis> mAxes;
//! Represents the value of a POV. Maximum of 4
Pov mPOV[4];
//! Represent the max sliders
Slider mSliders[4];
//! Represents all Vector type controls the device exports
std::vector<Vector3> mVectors;
//! internal method to reset all variables to initial values
void clear()
{
for(std::vector<bool>::iterator i = mButtons.begin(), e = mButtons.end(); i != e; ++i)
{
(*i) = false;
}
for(std::vector<Axis>::iterator i = mAxes.begin(), e = mAxes.end(); i != e; ++i)
{
i->absOnly = true; //Currently, joysticks only report Absolute values
i->clear();
}
for(std::vector<Vector3>::iterator i = mVectors.begin(), e = mVectors.end(); i != e; ++i)
{
i->clear();
}
for(int i = 0; i < 4; ++i)
{
mPOV[i].direction = Pov::Centered;
mSliders[i].abX = mSliders[i].abY = 0;
}
}
};
/** Specialised for joystick events */
class _OISExport JoyStickEvent : public EventArg
{
public:
JoyStickEvent(Object* obj, const JoyStickState& st) :
EventArg(obj), state(st) { }
virtual ~JoyStickEvent() { }
const JoyStickState& state;
private:
// Prevent copying.
JoyStickEvent(const JoyStickEvent&);
JoyStickEvent& operator=(JoyStickEvent);
};
/**
To recieve buffered joystick input, derive a class from this, and implement the
methods here. Then set the call back to your JoyStick instance with JoyStick::setEventCallback
Each JoyStick instance can use the same callback class, as a devID number will be provided
to differentiate between connected joysticks. Of course, each can have a seperate
callback instead.
*/
class _OISExport JoyStickListener
{
public:
virtual ~JoyStickListener() { }
/** @remarks Joystick button down event */
virtual bool buttonPressed(const JoyStickEvent& arg, int button) = 0;
/** @remarks Joystick button up event */
virtual bool buttonReleased(const JoyStickEvent& arg, int button) = 0;
/** @remarks Joystick axis moved event */
virtual bool axisMoved(const JoyStickEvent& arg, int axis) = 0;
//-- Not so common control events, so are not required --//
//! Joystick Event, and sliderID
virtual bool sliderMoved(const JoyStickEvent& arg, int index)
{
OIS_UNUSED(arg);
OIS_UNUSED(index);
return true;
}
//! Joystick Event, and povID
virtual bool povMoved(const JoyStickEvent& arg, int index)
{
OIS_UNUSED(arg);
OIS_UNUSED(index);
return true;
}
//! Joystick Event, and Vector3ID
virtual bool vector3Moved(const JoyStickEvent& arg, int index)
{
OIS_UNUSED(arg);
OIS_UNUSED(index);
return true;
}
};
/**
Joystick base class. To be implemented by specific system (ie. DirectX joystick)
This class is useful as you remain OS independent using this common interface.
*/
class _OISExport JoyStick : public Object
{
public:
virtual ~JoyStick() { }
/**
@remarks
Returns the number of requested components
@param cType
The ComponentType you are interested in knowing about
*/
int getNumberOfComponents(ComponentType cType) const;
/**
@remarks
Sets a cutoff limit for changes in the Vector3 component for movement to
be ignored. Helps reduce much event traffic for frequent small/sensitive
changes
@param degrees
The degree under which Vector3 events should be discarded
*/
void setVector3Sensitivity(float degrees = OIS_JOYSTICK_VECTOR3_DEFAULT);
/**
@remarks
Returns the sensitivity cutoff for Vector3 Component
*/
float getVector3Sensitivity() const;
/**
@remarks
Register/unregister a JoyStick Listener - Only one allowed for simplicity. If broadcasting
is neccessary, just broadcast from the callback you registered.
@param joyListener
Send a pointer to a class derived from JoyStickListener or 0 to clear the callback
*/
virtual void setEventCallback(JoyStickListener* joyListener);
/** @remarks Returns currently set callback.. or null */
JoyStickListener* getEventCallback() const;
/** @remarks Returns the state of the joystick - is valid for both buffered and non buffered mode */
const JoyStickState& getJoyStickState() const { return mState; }
//! The minimal axis value
static const int MIN_AXIS = -32768;
//! The maximum axis value
static const int MAX_AXIS = 32767;
protected:
JoyStick(const std::string& vendor, bool buffered, int devID, InputManager* creator);
//! Number of sliders
int mSliders;
//! Number of POVs
int mPOVs;
//! The JoyStickState structure (contains all component values)
JoyStickState mState;
//! The callback listener
JoyStickListener* mListener;
//! Adjustment factor for orientation vector accuracy
float mVector3Sensitivity;
};
}
#endif

343
Libs/ois/OISKeyboard.h Normal file
View file

@ -0,0 +1,343 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Keyboard_H
#define OIS_Keyboard_H
#include "OISObject.h"
#include "OISEvents.h"
namespace OIS
{
//! Keyboard scan codes
enum KeyCode {
KC_UNASSIGNED = 0x00,
KC_ESCAPE = 0x01,
KC_1 = 0x02,
KC_2 = 0x03,
KC_3 = 0x04,
KC_4 = 0x05,
KC_5 = 0x06,
KC_6 = 0x07,
KC_7 = 0x08,
KC_8 = 0x09,
KC_9 = 0x0A,
KC_0 = 0x0B,
KC_MINUS = 0x0C, // - on main keyboard
KC_EQUALS = 0x0D,
KC_BACK = 0x0E, // backspace
KC_TAB = 0x0F,
KC_Q = 0x10,
KC_W = 0x11,
KC_E = 0x12,
KC_R = 0x13,
KC_T = 0x14,
KC_Y = 0x15,
KC_U = 0x16,
KC_I = 0x17,
KC_O = 0x18,
KC_P = 0x19,
KC_LBRACKET = 0x1A,
KC_RBRACKET = 0x1B,
KC_RETURN = 0x1C, // Enter on main keyboard
KC_LCONTROL = 0x1D,
KC_A = 0x1E,
KC_S = 0x1F,
KC_D = 0x20,
KC_F = 0x21,
KC_G = 0x22,
KC_H = 0x23,
KC_J = 0x24,
KC_K = 0x25,
KC_L = 0x26,
KC_SEMICOLON = 0x27,
KC_APOSTROPHE = 0x28,
KC_GRAVE = 0x29, // accent
KC_LSHIFT = 0x2A,
KC_BACKSLASH = 0x2B,
KC_Z = 0x2C,
KC_X = 0x2D,
KC_C = 0x2E,
KC_V = 0x2F,
KC_B = 0x30,
KC_N = 0x31,
KC_M = 0x32,
KC_COMMA = 0x33,
KC_PERIOD = 0x34, // . on main keyboard
KC_SLASH = 0x35, // / on main keyboard
KC_RSHIFT = 0x36,
KC_MULTIPLY = 0x37, // * on numeric keypad
KC_LMENU = 0x38, // left Alt
KC_SPACE = 0x39,
KC_CAPITAL = 0x3A,
KC_F1 = 0x3B,
KC_F2 = 0x3C,
KC_F3 = 0x3D,
KC_F4 = 0x3E,
KC_F5 = 0x3F,
KC_F6 = 0x40,
KC_F7 = 0x41,
KC_F8 = 0x42,
KC_F9 = 0x43,
KC_F10 = 0x44,
KC_NUMLOCK = 0x45,
KC_SCROLL = 0x46, // Scroll Lock
KC_NUMPAD7 = 0x47,
KC_NUMPAD8 = 0x48,
KC_NUMPAD9 = 0x49,
KC_SUBTRACT = 0x4A, // - on numeric keypad
KC_NUMPAD4 = 0x4B,
KC_NUMPAD5 = 0x4C,
KC_NUMPAD6 = 0x4D,
KC_ADD = 0x4E, // + on numeric keypad
KC_NUMPAD1 = 0x4F,
KC_NUMPAD2 = 0x50,
KC_NUMPAD3 = 0x51,
KC_NUMPAD0 = 0x52,
KC_DECIMAL = 0x53, // . on numeric keypad
KC_OEM_102 = 0x56, // < > | on UK/Germany keyboards
KC_F11 = 0x57,
KC_F12 = 0x58,
KC_F13 = 0x64, // (NEC PC98)
KC_F14 = 0x65, // (NEC PC98)
KC_F15 = 0x66, // (NEC PC98)
KC_KANA = 0x70, // (Japanese keyboard)
KC_ABNT_C1 = 0x73, // / ? on Portugese (Brazilian) keyboards
KC_CONVERT = 0x79, // (Japanese keyboard)
KC_NOCONVERT = 0x7B, // (Japanese keyboard)
KC_YEN = 0x7D, // (Japanese keyboard)
KC_ABNT_C2 = 0x7E, // Numpad . on Portugese (Brazilian) keyboards
KC_NUMPADEQUALS = 0x8D, // = on numeric keypad (NEC PC98)
KC_PREVTRACK = 0x90, // Previous Track (KC_CIRCUMFLEX on Japanese keyboard)
KC_AT = 0x91, // (NEC PC98)
KC_COLON = 0x92, // (NEC PC98)
KC_UNDERLINE = 0x93, // (NEC PC98)
KC_KANJI = 0x94, // (Japanese keyboard)
KC_STOP = 0x95, // (NEC PC98)
KC_AX = 0x96, // (Japan AX)
KC_UNLABELED = 0x97, // (J3100)
KC_NEXTTRACK = 0x99, // Next Track
KC_NUMPADENTER = 0x9C, // Enter on numeric keypad
KC_RCONTROL = 0x9D,
KC_MUTE = 0xA0, // Mute
KC_CALCULATOR = 0xA1, // Calculator
KC_PLAYPAUSE = 0xA2, // Play / Pause
KC_MEDIASTOP = 0xA4, // Media Stop
KC_TWOSUPERIOR = 0xAA, // ² on French AZERTY keyboard (same place as ~ ` on QWERTY)
KC_VOLUMEDOWN = 0xAE, // Volume -
KC_VOLUMEUP = 0xB0, // Volume +
KC_WEBHOME = 0xB2, // Web home
KC_NUMPADCOMMA = 0xB3, // , on numeric keypad (NEC PC98)
KC_DIVIDE = 0xB5, // / on numeric keypad
KC_SYSRQ = 0xB7,
KC_RMENU = 0xB8, // right Alt
KC_PAUSE = 0xC5, // Pause
KC_HOME = 0xC7, // Home on arrow keypad
KC_UP = 0xC8, // UpArrow on arrow keypad
KC_PGUP = 0xC9, // PgUp on arrow keypad
KC_LEFT = 0xCB, // LeftArrow on arrow keypad
KC_RIGHT = 0xCD, // RightArrow on arrow keypad
KC_END = 0xCF, // End on arrow keypad
KC_DOWN = 0xD0, // DownArrow on arrow keypad
KC_PGDOWN = 0xD1, // PgDn on arrow keypad
KC_INSERT = 0xD2, // Insert on arrow keypad
KC_DELETE = 0xD3, // Delete on arrow keypad
KC_LWIN = 0xDB, // Left Windows key
KC_RWIN = 0xDC, // Right Windows key
KC_APPS = 0xDD, // AppMenu key
KC_POWER = 0xDE, // System Power
KC_SLEEP = 0xDF, // System Sleep
KC_WAKE = 0xE3, // System Wake
KC_WEBSEARCH = 0xE5, // Web Search
KC_WEBFAVORITES = 0xE6, // Web Favorites
KC_WEBREFRESH = 0xE7, // Web Refresh
KC_WEBSTOP = 0xE8, // Web Stop
KC_WEBFORWARD = 0xE9, // Web Forward
KC_WEBBACK = 0xEA, // Web Back
KC_MYCOMPUTER = 0xEB, // My Computer
KC_MAIL = 0xEC, // Mail
KC_MEDIASELECT = 0xED, // Media Select
};
/**
Specialised for key events
*/
class _OISExport KeyEvent : public EventArg
{
public:
KeyEvent(Object* obj, KeyCode kc, unsigned int txt) :
EventArg(obj), key(kc), text(txt) { }
virtual ~KeyEvent() { }
//! KeyCode of event
KeyCode key;
//! Text character, depends on current TextTranslationMode
unsigned int text;
};
/**
To recieve buffered keyboard input, derive a class from this, and implement the
methods here. Then set the call back to your Keyboard instance with Keyboard::setEventCallback
*/
class _OISExport KeyListener
{
public:
virtual ~KeyListener() { }
virtual bool keyPressed(const KeyEvent& arg) = 0;
virtual bool keyReleased(const KeyEvent& arg) = 0;
};
/**
Keyboard base class. To be implemented by specific system (ie. DirectX Keyboard)
This class is useful as you remain OS independent using this common interface.
*/
class _OISExport Keyboard : public Object
{
public:
virtual ~Keyboard() {};
/**
@remarks
Returns true if key is donwn
@param key
A KeyCode to check
*/
virtual bool isKeyDown(KeyCode key) const = 0;
/**
@remarks
Register/unregister a Keyboard Listener - Only one allowed for simplicity. If broadcasting
is neccessary, just broadcast from the callback you registered.
@param keyListener
Send a pointer to a class derived from KeyListener or 0 to clear the callback
*/
virtual void setEventCallback(KeyListener* keyListener) { mListener = keyListener; }
/**
@remarks
Returns currently set callback.. or 0
*/
KeyListener* getEventCallback() const { return mListener; }
//! TextTranslation Mode
enum TextTranslationMode {
Off,
Unicode,
Ascii
};
/**
@remarks
Enable extra processing to translate KC_*** to an
actual text character based off of locale. Different
managers may implement none or all. Check the
translation mode after setting to be sure
@param mode
Off, Unicode, Ascii
*/
virtual void setTextTranslation(TextTranslationMode mode);
/**
@remarks
Returns current translation mode
*/
TextTranslationMode getTextTranslation() const { return mTextMode; }
/**
@remarks
Translates KeyCode to string representation.
For example, KC_ENTER will be "Enter" - Locale
specific of course.
@param kc
KeyCode to convert
@returns
The string as determined from the current locale
*/
virtual const std::string& getAsString(KeyCode kc) = 0;
//! Enum of bit position of modifer
enum Modifier {
Shift = 0x0000001,
LShift = 0x0000002,
RShift = 0x0000004,
Ctrl = 0x0000010,
LCtrl = 0x0000020,
RCtrl = 0x0000040,
Alt = 0x0000100,
LAlt = 0x0000200,
RAlt = 0x0000400,
CapsLock = 0x0001000,
NumLock = 0x0010000,
Win = 0x0100000,
LWin = 0x0200000,
RWin = 0x0400000
};
/**
@remarks
Translates string to KeyCode representation.
For example, "Enter" will be KC_ENTER - Locale
specific of course.
@param str
string to convert
@returns
The matching KeyCode
*/
virtual OIS::KeyCode getAsKeyCode(std::string str) = 0;
/**
@remarks
Check modifier status
*/
bool isModifierDown(Modifier mod) const;
/**
@remarks
Returns the full modifiers status bit field
*/
unsigned int getModifiers() const;
/**
@remarks
Copies the state of the keys into the sent buffer
(in the form of 1 is down and 0 is up)
*/
virtual void copyKeyStates(char keys[256]) const = 0;
protected:
Keyboard(const std::string& vendor, bool buffered, int devID, InputManager* creator) :
Object(vendor, OISKeyboard, buffered, devID, creator),
mModifiers(0), mListener(0), mTextMode(Unicode) { }
//! Bit field that holds status of Alt, Ctrl, Shift, Win, CapsLock, and NumLock as well as Left and Right variants
unsigned int mModifiers;
//! Used for buffered/actionmapping callback
KeyListener* mListener;
//! The current translation mode
TextTranslationMode mTextMode;
};
}
#endif

153
Libs/ois/OISMouse.h Normal file
View file

@ -0,0 +1,153 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Mouse_H
#define OIS_Mouse_H
#include "OISObject.h"
#include "OISEvents.h"
namespace OIS
{
//! Button ID for mouse devices
enum MouseButtonID {
MB_Left = 0,
MB_Right,
MB_Middle,
MB_Button3,
MB_Button4,
MB_Button5,
MB_Button6,
MB_Button7
};
/**
Represents the state of the mouse
All members are valid for both buffered and non buffered mode
*/
class _OISExport MouseState
{
public:
MouseState() :
width(50), height(50), buttons(0) {};
/** Represents the height/width of your display area.. used if mouse clipping
or mouse grabbed in case of X11 - defaults to 50.. Make sure to set this
and change when your size changes.. */
mutable int width, height;
//! X Axis component
Axis X;
//! Y Axis Component
Axis Y;
//! Z Axis Component
Axis Z;
//! represents all buttons - bit position indicates button down
int buttons;
//! Button down test
inline bool buttonDown(MouseButtonID button) const
{
return ((buttons & (1L << button)) == 0) ? false : true;
}
//! Clear all the values
void clear()
{
X.clear();
Y.clear();
Z.clear();
buttons = 0;
}
};
/** Specialised for mouse events */
class _OISExport MouseEvent : public EventArg
{
public:
MouseEvent(Object* obj, const MouseState& ms) :
EventArg(obj), state(ms) { }
virtual ~MouseEvent() { }
//! The state of the mouse - including buttons and axes
const MouseState& state;
private:
// Prevent copying.
MouseEvent(const MouseEvent&);
MouseEvent& operator=(MouseEvent);
};
/**
To recieve buffered mouse input, derive a class from this, and implement the
methods here. Then set the call back to your Mouse instance with Mouse::setEventCallback
*/
class _OISExport MouseListener
{
public:
virtual ~MouseListener() { }
virtual bool mouseMoved(const MouseEvent& arg) = 0;
virtual bool mousePressed(const MouseEvent& arg, MouseButtonID id) = 0;
virtual bool mouseReleased(const MouseEvent& arg, MouseButtonID id) = 0;
};
/**
Mouse base class. To be implemented by specific system (ie. DirectX Mouse)
This class is useful as you remain OS independent using this common interface.
*/
class _OISExport Mouse : public Object
{
public:
virtual ~Mouse() { }
/**
@remarks
Register/unregister a Mouse Listener - Only one allowed for simplicity. If broadcasting
is neccessary, just broadcast from the callback you registered.
@param mouseListener
Send a pointer to a class derived from MouseListener or 0 to clear the callback
*/
virtual void setEventCallback(MouseListener* mouseListener) { mListener = mouseListener; }
/** @remarks Returns currently set callback.. or 0 */
MouseListener* getEventCallback() const { return mListener; }
/** @remarks Returns the state of the mouse - is valid for both buffered and non buffered mode */
const MouseState& getMouseState() const { return mState; }
protected:
Mouse(const std::string& vendor, bool buffered, int devID, InputManager* creator) :
Object(vendor, OISMouse, buffered, devID, creator), mListener(0) { }
//! The state of the mouse
MouseState mState;
//! Used for buffered/actionmapping callback
MouseListener* mListener;
};
}
#endif

183
Libs/ois/OISMultiTouch.h Normal file
View file

@ -0,0 +1,183 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_MultiTouch_H
#define OIS_MultiTouch_H
#include "OISObject.h"
#include "OISEvents.h"
#include <set>
#include <vector>
#define OIS_MAX_NUM_TOUCHES 4 // 4 finger touches are probably the highest we'll ever get
namespace OIS
{
/**
Represents the state of the multi-touch device
All members are valid for both buffered and non buffered mode
*/
//! Touch Event type
enum MultiTypeEventTypeID {
MT_None = 0,
MT_Pressed,
MT_Released,
MT_Moved,
MT_Cancelled
};
class _OISExport MultiTouchState
{
public:
MultiTouchState() :
width(50), height(50), touchType(MT_None) {};
/** Represents the height/width of your display area.. used if touch clipping
or touch grabbed in case of X11 - defaults to 50.. Make sure to set this
and change when your size changes.. */
mutable int width, height;
//! X Axis component
Axis X;
//! Y Axis Component
Axis Y;
//! Z Axis Component
Axis Z;
int touchType;
inline bool touchIsType(MultiTypeEventTypeID touch) const
{
return ((touchType & (1L << touch)) == 0) ? false : true;
}
//! Clear all the values
void clear()
{
X.clear();
Y.clear();
Z.clear();
touchType = MT_None;
}
};
/** Specialised for multi-touch events */
class _OISExport MultiTouchEvent : public EventArg
{
public:
MultiTouchEvent(Object* obj, const MultiTouchState& ms) :
EventArg(obj), state(ms) { }
virtual ~MultiTouchEvent() { }
//! The state of the touch - including axes
const MultiTouchState& state;
};
/**
To receive buffered touch input, derive a class from this, and implement the
methods here. Then set the call back to your MultiTouch instance with MultiTouch::setEventCallback
*/
class _OISExport MultiTouchListener
{
public:
virtual ~MultiTouchListener() { }
virtual bool touchMoved(const MultiTouchEvent& arg) = 0;
virtual bool touchPressed(const MultiTouchEvent& arg) = 0;
virtual bool touchReleased(const MultiTouchEvent& arg) = 0;
virtual bool touchCancelled(const MultiTouchEvent& arg) = 0;
};
/**
MultiTouch base class. To be implemented by specific system (ie. iPhone UITouch)
This class is useful as you remain OS independent using this common interface.
*/
class _OISExport MultiTouch : public Object
{
public:
virtual ~MultiTouch() { }
/**
@remarks
Register/unregister a MultiTouch Listener - Only one allowed for simplicity. If broadcasting
is necessary, just broadcast from the callback you registered.
@param touchListener
Send a pointer to a class derived from MultiTouchListener or 0 to clear the callback
*/
virtual void setEventCallback(MultiTouchListener* touchListener) { mListener = touchListener; }
/** @remarks Returns currently set callback.. or 0 */
MultiTouchListener* getEventCallback() { return mListener; }
/** @remarks Clear out the set of input states. Should be called after input has been processed by the application */
void clearStates(void) { mStates.clear(); }
/** @remarks Returns the state of the touch - is valid for both buffered and non buffered mode */
std::vector<MultiTouchState> getMultiTouchStates() const { return mStates; }
/** @remarks Returns the first n touch states. Useful if you know your app only needs to
process n touches. The return value is a vector to allow random access */
const std::vector<MultiTouchState> getFirstNTouchStates(int n)
{
std::vector<MultiTouchState> states;
for(unsigned int i = 0; i < mStates.size(); i++)
{
if(!(mStates[i].touchIsType(MT_None)))
{
states.push_back(mStates[i]);
}
}
return states;
}
/** @remarks Returns the first n touch states. Useful if you know your app only needs to
process n touches. The return value is a vector to allow random access */
const std::vector<MultiTouchState> getMultiTouchStatesOfType(MultiTypeEventTypeID type)
{
std::vector<MultiTouchState> states;
for(unsigned int i = 0; i < mStates.size(); i++)
{
if(mStates[i].touchIsType(type))
{
states.push_back(mStates[i]);
}
}
return states;
}
protected:
MultiTouch(const std::string& vendor, bool buffered, int devID, InputManager* creator) :
Object(vendor, OISMultiTouch, buffered, devID, creator), mListener(0) { }
//! The state of the touch device, implemented in a vector to store the state from each finger touch
std::vector<MultiTouchState> mStates;
//! Used for buffered/actionmapping callback
MultiTouchListener* mListener;
};
}
#endif

97
Libs/ois/OISObject.h Normal file
View file

@ -0,0 +1,97 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Object_H
#define OIS_Object_H
#include "OISPrereqs.h"
#include "OISInterface.h"
namespace OIS
{
/** The base class of all input types. */
class _OISExport Object
{
public:
virtual ~Object() { }
/** @remarks Get the type of device */
Type type() const { return mType; }
/** @remarks Get the vender string name */
const std::string& vendor() const { return mVendor; }
/** @remarks Get buffered mode - true is buffered, false otherwise */
virtual bool buffered() const { return mBuffered; }
/** @remarks Returns this input object's creator */
InputManager* getCreator() const { return mCreator; }
/** @remarks Sets buffered mode */
virtual void setBuffered(bool buffered) = 0;
/** @remarks Used for updating call once per frame before checking state or to update events */
virtual void capture() = 0;
/** @remarks This may/may not) differentiate the different controllers based on (for instance) a port number (useful for console InputManagers) */
virtual int getID() const { return mDevID; }
/**
@remarks
If available, get an interface to write to some devices.
Examples include, turning on and off LEDs, ForceFeedback, etc
@param type
The type of interface you are looking for
*/
virtual Interface* queryInterface(Interface::IType type) = 0;
/** @remarks Internal... Do not call this directly. */
virtual void _initialize() = 0;
protected:
Object(const std::string& vendor, Type iType, bool buffered, int devID, InputManager* creator) :
mVendor(vendor),
mType(iType),
mBuffered(buffered),
mDevID(devID),
mCreator(creator) { }
//! Vendor name if applicable/known
std::string mVendor;
//! Type of controller object
Type mType;
//! Buffered flag
bool mBuffered;
//! Not fully implemented yet
int mDevID;
//! The creator who created this object
InputManager* mCreator;
};
}
#endif

250
Libs/ois/OISPrereqs.h Normal file
View file

@ -0,0 +1,250 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Prereqs_H
#define OIS_Prereqs_H
//----------------------------------------------------------------------------//
// This Header File contains: forward declared classes
// * Forward Declarations of all public API classes
// * Several typedef's used around the library
// * Base class component types
// * Preprocessor definitons
//----------------------------------------------------------------------------//
//-------------- Common STL Containers ---------------------------------------//
#include <vector>
#include <string>
#include <map>
#include "OISConfig.h"
// Default is blank for most OS's
#define _OISExport
//-------------- Determine Compiler ---------------------------------
#if defined( _MSC_VER )
# define OIS_MSVC_COMPILER
#elif defined( __GNUC__ )
# if defined( __WIN32__ ) || defined( _WIN32 )
# define OIS_MINGW_COMPILER
# else
# define OIS_GCC_COMPILER
# endif
#elif defined( __BORLANDC__ )
# define OIS_BORLAND_COMPILER
#else
# error No Recognized Compiler!
#endif
// --------------- Determine Operating System Platform ---------------
#if defined( __WIN32__ ) || defined( _WIN32 ) // Windows 2000, XP, ETC
# if defined ( _XBOX )
# define OIS_XBOX_PLATFORM
# else
# define OIS_WIN32_PLATFORM
# if defined( OIS_DYNAMIC_LIB )
# undef _OISExport
//Ignorable Dll interface warning...
# if !defined(OIS_MINGW_COMPILER)
# pragma warning (disable : 4251)
# endif
# if defined( OIS_NONCLIENT_BUILD )
# define _OISExport __declspec( dllexport )
# else
# if defined(OIS_MINGW_COMPILER)
# define _OISExport
# else
# define _OISExport __declspec( dllimport )
# endif
# endif
# endif
# endif
#elif defined( __APPLE_CC__ ) // Apple OS X
// Device Simulator
# if __IPHONE_OS_VERSION_MIN_REQUIRED >= 20201 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 20000
//# if __IPHONE_OS_VERSION_MIN_REQUIRED >= 30000 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 30000
# define OIS_IPHONE_PLATFORM
# else
# define OIS_APPLE_PLATFORM
# endif
# undef _OISExport
# define _OISExport __attribute__((visibility("default")))
#else //Probably Linux
# define OIS_LINUX_PLATFORM
# include <unistd.h>
#endif
//Is Processor 32 or 64 bits...
#if defined(__x86_64__)
# define OIS_ARCH_64
#else
# define OIS_ARCH_32
#endif
//-------------- Various helper preprocessor definitions ---------------------//
#ifdef OIS_MSVC_COMPILER
# define OIS_INLINE_PRAGMA(x) __pragma(x) // x is intentionally not wrapped; __pragma rejects expressions beginning with '('.
#else
# define OIS_INLINE_PRAGMA(x)
#endif
#define OIS_MACRO_BEGIN do {
#define OIS_MACRO_END \
} OIS_INLINE_PRAGMA(warning(push)) OIS_INLINE_PRAGMA(warning(disable:4127)) while (0) OIS_INLINE_PRAGMA(warning(pop))
// This creative trickery taken from this StackOverflow answer:
// http://stackoverflow.com/questions/4030959/will-a-variablename-c-statement-be-a-no-op-at-all-times/4030983#4030983
#define OIS_UNUSED(x)\
OIS_MACRO_BEGIN\
((void)(true ? 0 : ((x), void(), 0)));\
OIS_MACRO_END
//-------------- Common Classes, Enums, and Typdef's -------------------------//
#define OIS_VERSION_MAJOR 1
#define OIS_VERSION_MINOR 5
#define OIS_VERSION_PATCH 1
#define OIS_VERSION_NAME "1.5.0"
#define OIS_VERSION ((OIS_VERSION_MAJOR << 16) | (OIS_VERSION_MINOR << 8) | OIS_VERSION_PATCH)
namespace OIS
{
//Forward Declarations
class InputManager;
class FactoryCreator;
class Object;
class Keyboard;
class Mouse;
class JoyStick;
class MultiTouch;
class KeyListener;
class MouseListener;
class MultiTouchListener;
class JoyStickListener;
class Interface;
class ForceFeedback;
class Effect;
class Exception;
//! Way to send OS nuetral parameters.. ie OS Window handles, modes, flags
typedef std::multimap<std::string, std::string> ParamList;
//! List of FactoryCreator's
typedef std::vector<FactoryCreator*> FactoryList;
//! Map of FactoryCreator created Objects
typedef std::map<Object*, FactoryCreator*> FactoryCreatedObject;
//! Each Input class has a General Type variable, a form of RTTI
enum Type
{
OISUnknown = 0,
OISKeyboard = 1,
OISMouse = 2,
OISJoyStick = 3,
OISTablet = 4,
OISMultiTouch = 5
};
//! Map of device objects connected and their respective vendors
typedef std::multimap<Type, std::string> DeviceList;
//-------- Shared common components ------------------------//
//! Base type for all device components (button, axis, etc)
enum ComponentType
{
OIS_Unknown = 0,
OIS_Button = 1, //ie. Key, mouse button, joy button, etc
OIS_Axis = 2, //ie. A joystick or mouse axis
OIS_Slider = 3, //
OIS_POV = 4, //ie. Arrow direction keys
OIS_Vector3 = 5 //ie. WiiMote orientation
};
//! Base of all device components (button, axis, etc)
class _OISExport Component
{
public:
Component() : cType(OIS_Unknown) {};
explicit Component(ComponentType type) : cType(type) {};
//! Indicates what type of coponent this is
ComponentType cType;
};
//! Button can be a keyboard key, mouse button, etc
class _OISExport Button : public Component
{
public:
Button() : Component(OIS_Button), pushed(false) {}
explicit Button(bool bPushed) : Component(OIS_Button), pushed(bPushed) {}
//! true if pushed, false otherwise
bool pushed;
};
//! Axis component
class _OISExport Axis : public Component
{
public:
Axis() : Component(OIS_Axis), abs(0), rel(0), absOnly(false) {};
//! Absoulte and Relative value components
int abs, rel;
//! Indicates if this Axis only supports Absoulte (ie JoyStick)
bool absOnly;
//! Used internally by OIS
void clear()
{
abs = rel = 0;
}
};
//! A 3D Vector component (perhaps an orientation, as in the WiiMote)
class _OISExport Vector3 : public Component
{
public:
Vector3() {}
Vector3(float _x, float _y, float _z) : Component(OIS_Vector3), x(_x), y(_y), z(_z) {};
//! X component of vector
float x;
//! Y component of vector
float y;
//! Z component of vector
float z;
void clear()
{
x = y = z = 0.0f;
}
};
}
#endif //end if prereq header defined

250
Libs/ois/OISPrereqs.h.in Normal file
View file

@ -0,0 +1,250 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Prereqs_H
#define OIS_Prereqs_H
//----------------------------------------------------------------------------//
// This Header File contains: forward declared classes
// * Forward Declarations of all public API classes
// * Several typedef's used around the library
// * Base class component types
// * Preprocessor definitons
//----------------------------------------------------------------------------//
//-------------- Common STL Containers ---------------------------------------//
#include <vector>
#include <string>
#include <map>
#include "OISConfig.h"
// Default is blank for most OS's
#define _OISExport
//-------------- Determine Compiler ---------------------------------
#if defined( _MSC_VER )
# define OIS_MSVC_COMPILER
#elif defined( __GNUC__ )
# if defined( __WIN32__ ) || defined( _WIN32 )
# define OIS_MINGW_COMPILER
# else
# define OIS_GCC_COMPILER
# endif
#elif defined( __BORLANDC__ )
# define OIS_BORLAND_COMPILER
#else
# error No Recognized Compiler!
#endif
// --------------- Determine Operating System Platform ---------------
#if defined( __WIN32__ ) || defined( _WIN32 ) // Windows 2000, XP, ETC
# if defined ( _XBOX )
# define OIS_XBOX_PLATFORM
# else
# define OIS_WIN32_PLATFORM
# if defined( OIS_DYNAMIC_LIB )
# undef _OISExport
//Ignorable Dll interface warning...
# if !defined(OIS_MINGW_COMPILER)
# pragma warning (disable : 4251)
# endif
# if defined( OIS_NONCLIENT_BUILD )
# define _OISExport __declspec( dllexport )
# else
# if defined(OIS_MINGW_COMPILER)
# define _OISExport
# else
# define _OISExport __declspec( dllimport )
# endif
# endif
# endif
# endif
#elif defined( __APPLE_CC__ ) // Apple OS X
// Device Simulator
# if __IPHONE_OS_VERSION_MIN_REQUIRED >= 20201 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 20000
//# if __IPHONE_OS_VERSION_MIN_REQUIRED >= 30000 || __IPHONE_OS_VERSION_MIN_REQUIRED >= 30000
# define OIS_IPHONE_PLATFORM
# else
# define OIS_APPLE_PLATFORM
# endif
# undef _OISExport
# define _OISExport __attribute__((visibility("default")))
#else //Probably Linux
# define OIS_LINUX_PLATFORM
# include <unistd.h>
#endif
//Is Processor 32 or 64 bits...
#if defined(__x86_64__)
# define OIS_ARCH_64
#else
# define OIS_ARCH_32
#endif
//-------------- Various helper preprocessor definitions ---------------------//
#ifdef OIS_MSVC_COMPILER
# define OIS_INLINE_PRAGMA(x) __pragma(x) // x is intentionally not wrapped; __pragma rejects expressions beginning with '('.
#else
# define OIS_INLINE_PRAGMA(x)
#endif
#define OIS_MACRO_BEGIN do {
#define OIS_MACRO_END \
} OIS_INLINE_PRAGMA(warning(push)) OIS_INLINE_PRAGMA(warning(disable:4127)) while (0) OIS_INLINE_PRAGMA(warning(pop))
// This creative trickery taken from this StackOverflow answer:
// http://stackoverflow.com/questions/4030959/will-a-variablename-c-statement-be-a-no-op-at-all-times/4030983#4030983
#define OIS_UNUSED(x)\
OIS_MACRO_BEGIN\
((void)(true ? 0 : ((x), void(), 0)));\
OIS_MACRO_END
//-------------- Common Classes, Enums, and Typdef's -------------------------//
#define OIS_VERSION_MAJOR @OIS_MAJOR_VERSION@
#define OIS_VERSION_MINOR @OIS_MINOR_VERSION@
#define OIS_VERSION_PATCH @OIS_PATCH_VERSION@
#define OIS_VERSION_NAME "@OIS_SOVERSION@"
#define OIS_VERSION ((OIS_VERSION_MAJOR << 16) | (OIS_VERSION_MINOR << 8) | OIS_VERSION_PATCH)
namespace OIS
{
//Forward Declarations
class InputManager;
class FactoryCreator;
class Object;
class Keyboard;
class Mouse;
class JoyStick;
class MultiTouch;
class KeyListener;
class MouseListener;
class MultiTouchListener;
class JoyStickListener;
class Interface;
class ForceFeedback;
class Effect;
class Exception;
//! Way to send OS nuetral parameters.. ie OS Window handles, modes, flags
typedef std::multimap<std::string, std::string> ParamList;
//! List of FactoryCreator's
typedef std::vector<FactoryCreator*> FactoryList;
//! Map of FactoryCreator created Objects
typedef std::map<Object*, FactoryCreator*> FactoryCreatedObject;
//! Each Input class has a General Type variable, a form of RTTI
enum Type
{
OISUnknown = 0,
OISKeyboard = 1,
OISMouse = 2,
OISJoyStick = 3,
OISTablet = 4,
OISMultiTouch = 5
};
//! Map of device objects connected and their respective vendors
typedef std::multimap<Type, std::string> DeviceList;
//-------- Shared common components ------------------------//
//! Base type for all device components (button, axis, etc)
enum ComponentType
{
OIS_Unknown = 0,
OIS_Button = 1, //ie. Key, mouse button, joy button, etc
OIS_Axis = 2, //ie. A joystick or mouse axis
OIS_Slider = 3, //
OIS_POV = 4, //ie. Arrow direction keys
OIS_Vector3 = 5 //ie. WiiMote orientation
};
//! Base of all device components (button, axis, etc)
class _OISExport Component
{
public:
Component() : cType(OIS_Unknown) {};
explicit Component(ComponentType type) : cType(type) {};
//! Indicates what type of coponent this is
ComponentType cType;
};
//! Button can be a keyboard key, mouse button, etc
class _OISExport Button : public Component
{
public:
Button() : Component(OIS_Button), pushed(false) {}
explicit Button(bool bPushed) : Component(OIS_Button), pushed(bPushed) {}
//! true if pushed, false otherwise
bool pushed;
};
//! Axis component
class _OISExport Axis : public Component
{
public:
Axis() : Component(OIS_Axis), abs(0), rel(0), absOnly(false) {};
//! Absoulte and Relative value components
int abs, rel;
//! Indicates if this Axis only supports Absoulte (ie JoyStick)
bool absOnly;
//! Used internally by OIS
void clear()
{
abs = rel = 0;
}
};
//! A 3D Vector component (perhaps an orientation, as in the WiiMote)
class _OISExport Vector3 : public Component
{
public:
Vector3() {}
Vector3(float _x, float _y, float _z) : Component(OIS_Vector3), x(_x), y(_y), z(_z) {};
//! X component of vector
float x;
//! Y component of vector
float y;
//! Z component of vector
float z;
void clear()
{
x = y = z = 0.0f;
}
};
}
#endif //end if prereq header defined

BIN
Libs/ois/OIS_d.lib Normal file

Binary file not shown.

View file

@ -0,0 +1,119 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Win32ForceFeedBack_H
#define OIS_Win32ForceFeedBack_H
#include "OISPrereqs.h"
#include "OISForceFeedback.h"
#include "win32/Win32Prereqs.h"
namespace OIS
{
class Win32ForceFeedback : public ForceFeedback
{
Win32ForceFeedback() { }
public:
Win32ForceFeedback(IDirectInputDevice8* pDIJoy, const DIDEVCAPS* pDIJoyCaps);
Win32ForceFeedback(unsigned int xInputIndex);
~Win32ForceFeedback();
/** @copydoc ForceFeedback::upload */
void upload(const Effect* effect);
/** @copydoc ForceFeedback::modify */
void modify(const Effect* effect);
/** @copydoc ForceFeedback::remove */
void remove(const Effect* effect);
/** @copydoc ForceFeedback::setMasterGain */
void setMasterGain(float level);
/** @copydoc ForceFeedback::setAutoCenterMode */
void setAutoCenterMode(bool auto_on);
/** @copydoc ForceFeedback::getFFAxesNumber */
short getFFAxesNumber();
/** @copydoc ForceFeedback::getFFMemoryLoad */
unsigned short getFFMemoryLoad();
/**
@remarks
Internal use.. Used during enumeration to build a list of a devices
support effects.
*/
void _addEffectSupport(LPCDIEFFECTINFO pdei);
/**
@remarks
Internal use.. Used during axis enumeration to get number of FF axes
support effects.
*/
void _addFFAxis();
protected:
//Specific Effect Settings
void _updateConstantEffect(const Effect* effect);
void _updateRampEffect(const Effect* effect);
void _updatePeriodicEffect(const Effect* effect);
void _updateConditionalEffect(const Effect* effect);
void _updateCustomEffect(const Effect* effect);
//XInput-specific methods
bool _isXInput();
void _setXInputVibration(unsigned short leftPower, unsigned short rightPower);
void _updateXInputConstantEffect(const Effect* effect);
//Sets the common properties to all effects
void _setCommonProperties(DIEFFECT* diEffect, DWORD* rgdwAxes, LONG* rglDirection, DIENVELOPE* diEnvelope, DWORD struct_size, LPVOID struct_type, const Effect* effect, const Envelope* envelope);
//Actually do the upload
void _upload(GUID, DIEFFECT*, const Effect*);
// Map of currently uploaded effects (handle => effect)
typedef std::map<int, LPDIRECTINPUTEFFECT> EffectList;
EffectList mEffectList;
//Simple unique handle creation - allows for upto 2+ billion effects
//during the lifetime of application. Hopefully, that is enough.
int mHandles;
// Joystick device descriptor.
IDirectInputDevice8* mJoyStick;
// Joystick capabilities.
const DIDEVCAPS* mpDIJoyCaps;
// An index specifying XInput device index.
// It will be -1 if device is DInput device.
int mXInputIndex;
// Number of axis supporting FF.
short mFFAxes;
};
}
#endif //OIS_Win32ForceFeedBack_H

View file

@ -0,0 +1,116 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef OIS_Win32InputManager_H
#define OIS_Win32InputManager_H
#include "OISInputManager.h"
#include "OISFactoryCreator.h"
#include "win32/Win32Prereqs.h"
namespace OIS
{
/** Win32InputManager specialization - Using DirectInput8 */
class Win32InputManager : public InputManager, public FactoryCreator
{
public:
Win32InputManager();
virtual ~Win32InputManager();
//InputManager Overrides
/** @copydoc InputManager::_initialize */
void _initialize(ParamList& paramList);
//FactoryCreator Overrides
/** @copydoc FactoryCreator::deviceList */
DeviceList freeDeviceList();
/** @copydoc FactoryCreator::totalDevices */
int totalDevices(Type iType);
/** @copydoc FactoryCreator::freeDevices */
int freeDevices(Type iType);
/** @copydoc FactoryCreator::vendorExist */
bool vendorExist(Type iType, const std::string& vendor);
/** @copydoc FactoryCreator::createObject */
Object* createObject(InputManager* creator, Type iType, bool bufferMode, const std::string& vendor = "");
/** @copydoc FactoryCreator::destroyObject */
void destroyObject(Object* obj);
//Internal Items
//! Internal method, used for flaggin keyboard as available/unavailable for creation
void _setKeyboardUsed(bool used) { keyboardUsed = used; }
//! Internal method, used for flaggin mouse as available/unavailable for creation
void _setMouseUsed(bool used) { mouseUsed = used; }
//! Internal method, return unused joystick to queue
void _returnJoyStick(const JoyStickInfo& joystick);
//! Returns HWND needed by DirectInput Device Object
HWND getWindowHandle() { return hWnd; }
protected:
//! internal class method for dealing with param list
void _parseConfigSettings(ParamList& paramList);
//! internal class method for finding attached devices
void _enumerateDevices();
//! Used during device enumeration
static BOOL CALLBACK _DIEnumDevCallback(LPCDIDEVICEINSTANCE lpddi, LPVOID pvRef);
//! Keep a list of all joysticks enumerated, but not in use
JoyStickInfoList unusedJoyStickList;
//! The window handle we are using
HWND hWnd;
//! Direct Input Interface
IDirectInput8* mDirectInput;
//! Used for keyboard device settings
DWORD kbSettings;
//! Used for mouse device settings
DWORD mouseSettings;
//! Used for joystick device settings
DWORD joySettings;
//! Number of total joysticks (inuse or not)
char joySticks;
//! Used to know if we used up keyboard
bool keyboardUsed;
//! Used to know if we used up mouse
bool mouseUsed;
};
}
#endif

View file

@ -0,0 +1,91 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _WIN32_JOYSTICK_H_EADER_
#define _WIN32_JOYSTICK_H_EADER_
#include "OISJoyStick.h"
#include "win32/Win32Prereqs.h"
namespace OIS
{
class Win32JoyStick : public JoyStick
{
public:
Win32JoyStick(InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings, const JoyStickInfo& info);
virtual ~Win32JoyStick();
/** @copydoc Object::setBuffered */
virtual void setBuffered(bool buffered);
/** @copydoc Object::capture */
virtual void capture();
//! hanlde xinput
void captureXInput();
/** @copydoc Object::queryInterface */
virtual Interface* queryInterface(Interface::IType type);
/** @copydoc Object::_initialize */
virtual void _initialize();
#ifdef OIS_WIN32_XINPUT_SUPPORT
/**
@remarks
Enum each PNP device using WMI and check each device ID to see if it contains
"IG_" (ex. "VID_045E&PID_028E&IG_00"). If it does, then it's an XInput device
Unfortunately this information can not be found by just using DirectInput
*/
static void CheckXInputDevices(JoyStickInfoList& joys);
#endif
protected:
//! Enumerates all things
void _enumerate();
//! Enumerate axis callback
static BOOL CALLBACK DIEnumDeviceObjectsCallback(LPCDIDEVICEOBJECTINSTANCE lpddoi, LPVOID pvRef);
//! Enumerate Force Feedback callback
static BOOL CALLBACK DIEnumEffectsCallback(LPCDIEFFECTINFO pdei, LPVOID pvRef);
bool _doButtonClick(int button, DIDEVICEOBJECTDATA& di);
bool _changePOV(int pov, DIDEVICEOBJECTDATA& di);
IDirectInput8* mDirectInput;
IDirectInputDevice8* mJoyStick;
DIDEVCAPS mDIJoyCaps;
DWORD coopSetting;
JoyStickInfo mJoyInfo;
//! A force feedback device
Win32ForceFeedback* mFfDevice;
//! Mapping
int _AxisNumber;
};
}
#endif //_WIN32_JOYSTICK_H_EADER_

View file

@ -0,0 +1,101 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _WIN32_KEYBOARD_H_EADER_
#define _WIN32_KEYBOARD_H_EADER_
#include "OISKeyboard.h"
#include "win32/Win32Prereqs.h"
namespace OIS
{
class Win32Keyboard : public Keyboard
{
public:
/**
@remarks
Constructor
@param pDI
Valid DirectInput8 Interface
@param buffered
True for buffered input mode
@param coopSettings
A combination of DI Flags (see DX Help for info on input device settings)
*/
Win32Keyboard(InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings);
virtual ~Win32Keyboard();
/** @copydoc Keyboard::isKeyDown */
virtual bool isKeyDown(KeyCode key) const;
/** @copydoc Keyboard::getAsString */
virtual const std::string& getAsString(KeyCode kc);
/** @copydoc Keyboard::getAsKeyCode */
virtual KeyCode getAsKeyCode(std::string str)
{ /*TODO: Implement OS version*/
return KC_UNASSIGNED;
}
/** @copydoc Keyboard::copyKeyStates */
virtual void copyKeyStates(char keys[256]) const;
/** @copydoc Object::setBuffered */
virtual void setBuffered(bool buffered);
/** @copydoc Object::capture */
virtual void capture();
/** @copydoc Object::queryInterface */
virtual Interface* queryInterface(Interface::IType type)
{
OIS_UNUSED(type);
return 0;
}
/** @copydoc Object::_initialize */
virtual void _initialize();
protected:
void _readBuffered();
void _read();
IDirectInput8* mDirectInput;
IDirectInputDevice8* mKeyboard;
DWORD coopSetting;
unsigned char KeyBuffer[256];
//! Internal method for translating KeyCodes to Text
int _translateText(KeyCode kc);
//! Stored dead key from last translation
WCHAR deadKey;
//! used for getAsString
std::string mGetString;
};
}
#endif //_WIN32_KEYBOARD_H_EADER_

View file

@ -0,0 +1,66 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _WIN32_MOUSE_H_EADER_
#define _WIN32_MOUSE_H_EADER_
#include "OISMouse.h"
#include "win32/Win32Prereqs.h"
namespace OIS
{
class Win32Mouse : public Mouse
{
public:
Win32Mouse(InputManager* creator, IDirectInput8* pDI, bool buffered, DWORD coopSettings);
virtual ~Win32Mouse();
/** @copydoc Object::setBuffered */
virtual void setBuffered(bool buffered);
/** @copydoc Object::capture */
virtual void capture();
/** @copydoc Object::queryInterface */
virtual Interface* queryInterface(Interface::IType type)
{
OIS_UNUSED(type);
return 0;
}
/** @copydoc Object::_initialize */
virtual void _initialize();
protected:
bool _doMouseClick(int mouseButton, unsigned char di);
IDirectInput8* mDirectInput;
IDirectInputDevice8* mMouse;
DWORD coopSetting;
HWND mHwnd;
};
}
#endif //_WIN32_MOUSE_H_EADER_

View file

@ -0,0 +1,74 @@
/*
The zlib/libpng License
Copyright (c) 2018 Arthur Brainville
Copyright (c) 2015 Andrew Fenn
Copyright (c) 2005-2010 Phillip Castaneda (pjcast -- www.wreckedgames.com)
This software is provided 'as-is', without any express or implied warranty. In no
event will the authors be held liable for any damages arising from the use of this
software.
Permission is granted to anyone to use this software for any purpose, including
commercial applications, and to alter it and redistribute it freely, subject to the
following restrictions:
1. The origin of this software must not be misrepresented; you must not claim that
you wrote the original software. If you use this software in a product,
an acknowledgment in the product documentation would be appreciated
but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef _WIN32_INPUTSYSTEM_PREREQS_H
#define _WIN32_INPUTSYSTEM_PREREQS_H
#include <cstddef>
#define WIN32_LEAN_AND_MEAN
#define DIRECTINPUT_VERSION 0x0800
#include <windows.h>
#include <dinput.h>
#ifdef OIS_WIN32_XINPUT_SUPPORT
#include <xinput.h>
#endif
//Max number of elements to collect from buffered DirectInput
#define KEYBOARD_DX_BUFFERSIZE 17
#define MOUSE_DX_BUFFERSIZE 128
#define JOYSTICK_DX_BUFFERSIZE 129
//MinGW defines
#if defined(OIS_MINGW_COMPILER)
#undef FIELD_OFFSET
#define FIELD_OFFSET offsetof
#endif
namespace OIS
{
//Local Forward declarations
class Win32InputManager;
class Win32Keyboard;
class Win32JoyStick;
class Win32Mouse;
class Win32ForceFeedback;
//Information needed to create DirectInput joysticks
class JoyStickInfo
{
public:
int devId;
GUID deviceID;
GUID productGuid;
std::string vendor;
bool isXInput;
int xInputDev;
};
typedef std::vector<JoyStickInfo> JoyStickInfoList;
}
#endif //_WIN32_INPUTSYSTEM_PREREQS_H

View file

@ -1,128 +0,0 @@
-- Place in this LUA script all the strings of your game
-- Please follow the rules for IDs in the comments before each section
local strings = {
new_game = {"New Game", "Nouvelle partie", "Nuova partita", "Neues Spiel", "Nueva partida"},
load_game = {"Load Game", "Chargement", "Carica partita", "Spiel laden", "Cargar partida"}
}
GameFlow:SetStrings(strings)
local languages = {"English", "Français", "Italiano", "Deutsch", "Español"}
GameFlow:SetLanguageNames(languages)
-- Global engine string, please don't change the IDs because internally TEN machine code refers to strings by fixed ID
GameFlow.strings[1] = "Game";
GameFlow.strings[2] = "Lara's home";
GameFlow.strings[3] = "Controls";
GameFlow.strings[4] = "Display";
GameFlow.strings[5] = "Sound";
GameFlow.strings[6] = "New game";
GameFlow.strings[7] = "Load game";
GameFlow.strings[8] = "Save game";
GameFlow.strings[9] = "Exit game";
GameFlow.strings[10] = "Exit to title";
GameFlow.strings[11] = "Uzi";
GameFlow.strings[12] = "Pistols";
GameFlow.strings[13] = "Shotgun";
GameFlow.strings[14] = "Revolver";
GameFlow.strings[15] = "Revolver + LaserSight";
GameFlow.strings[16] = "Desert Eagle";
GameFlow.strings[17] = "Desert Eagle + LaserSight";
GameFlow.strings[18] = "Desert Eagle Ammo";
GameFlow.strings[19] = "HK Gun";
GameFlow.strings[20] = "HK Gun (Silenced)";
GameFlow.strings[21] = "Shotgun Normal Ammo";
GameFlow.strings[22] = "Shotgun Wideshot Ammo";
GameFlow.strings[23] = "HK Sniper Mode";
GameFlow.strings[24] = "HK Burst Mode";
GameFlow.strings[25] = "HK Rapid Mode";
GameFlow.strings[26] = "HK Ammo";
GameFlow.strings[27] = "Revolver Ammo";
GameFlow.strings[28] = "Uzi Ammo";
GameFlow.strings[29] = "Pistol Ammo";
GameFlow.strings[30] = "LaserSight";
GameFlow.strings[31] = "Silencer";
GameFlow.strings[32] = "Large Medipack";
GameFlow.strings[33] = "Small Medipack";
GameFlow.strings[34] = "Binoculars";
GameFlow.strings[35] = "Headset";
GameFlow.strings[36] = "Flares";
GameFlow.strings[37] = "Timex-TMX";
GameFlow.strings[38] = "Crowbar";
GameFlow.strings[39] = "Use";
GameFlow.strings[40] = "Combine";
GameFlow.strings[41] = "Separe";
GameFlow.strings[42] = "Choose ammo";
GameFlow.strings[43] = "Select level";
GameFlow.strings[44] = "%02d days %02d:%02d:%02d";
GameFlow.strings[45] = "Not saved";
GameFlow.strings[46] = "Grenade launcher";
GameFlow.strings[47] = "Grenade Normal Ammo";
GameFlow.strings[48] = "Grenade Poisoned Ammo";
GameFlow.strings[49] = "Grenade Explosive Ammo";
GameFlow.strings[50] = "Harpoon gun";
GameFlow.strings[51] = "Harpoon ammo";
GameFlow.strings[52] = "Rocket launcher";
GameFlow.strings[53] = "Rocket ammo";
GameFlow.strings[54] = "Crossbow";
GameFlow.strings[55] = "Crossbow + LaserSight";
GameFlow.strings[56] = "Crossbow Normal Ammo";
GameFlow.strings[57] = "Crossbow Poisoned Ammo";
GameFlow.strings[58] = "Crossbow Explosive Ammo";
GameFlow.strings[59] = "Diary";
GameFlow.strings[60] = "Enabled";
GameFlow.strings[61] = "Disabled";
GameFlow.strings[62] = "Music volume";
GameFlow.strings[63] = "SFX volume";
GameFlow.strings[64] = "Screen resolution";
GameFlow.strings[65] = "Dynamic shadows";
GameFlow.strings[66] = "Underwater caustics";
GameFlow.strings[67] = "Volumetric fog";
GameFlow.strings[68] = "Apply";
GameFlow.strings[69] = "Cancel";
GameFlow.strings[70] = "Enable sound";
GameFlow.strings[71] = "Special effects";
GameFlow.strings[75] = "Small Waterskin (Empty)"
GameFlow.strings[76] = "Large Waterskin (Empty)"
GameFlow.strings[78] = "Move forward"
GameFlow.strings[79] = "Move backward"
GameFlow.strings[80] = "Move left"
GameFlow.strings[81] = "Move right"
GameFlow.strings[82] = "Duck"
GameFlow.strings[83] = "Dash"
GameFlow.strings[84] = "Walk"
GameFlow.strings[85] = "Jump"
GameFlow.strings[86] = "Action"
GameFlow.strings[87] = "Draw weapon"
GameFlow.strings[88] = "Use flare"
GameFlow.strings[89] = "Look"
GameFlow.strings[90] = "Roll"
GameFlow.strings[91] = "Inventory"
GameFlow.strings[92] = "Step left"
GameFlow.strings[93] = "Step right"
GameFlow.strings[94] = "Items"
GameFlow.strings[95] = "Puzzles"
-- Level names (from 100 to 199)
GameFlow.strings[100] = "Title level";
GameFlow.strings[101] = "Strets of Rome";
GameFlow.strings[102] = "Trajan Markets";
GameFlow.strings[103] = "The Colosseum";
GameFlow.strings[104] = "The base";
GameFlow.strings[105] = "The submarine";
GameFlow.strings[106] = "Deepsea Dive";
GameFlow.strings[107] = "Sinking Submarine";
GameFlow.strings[108] = "Gallows Tree";
GameFlow.strings[109] = "Labyrinth";
GameFlow.strings[110] = "Old Mill";
GameFlow.strings[111] = "The 13th Floor";
GameFlow.strings[112] = "Escape with the Iris";
GameFlow.strings[113] = "Security breach";
GameFlow.strings[114] = "Red alert!";
GameFlow.strings[115] = "Test level";
-- Puzzle names (from 200 to 499)
GameFlow.strings[200] = "Bronze key";
GameFlow.strings[201] = "Golden key";
-- Examines strings (from 500 to 799, use \n sequence for new line)
GameFlow.strings[500] = "Examine test \n This is a new line of text \n This is another new line of text";

View file

@ -19,6 +19,16 @@ local strings = {
"",
""
},
auto_target = {
"Automatic targeting",
"",
"",
"",
"",
"",
"",
""
},
back = {
"Back",
"",
@ -259,6 +269,16 @@ local strings = {
"",
""
},
controls_pause = {
"Pause",
"",
"",
"",
"",
"",
"",
""
},
controls_use_flare = {
"Use Flare",
"",
@ -399,16 +419,6 @@ local strings = {
"",
""
},
sounds = {
"Audio settings",
"",
"",
"",
"",
"",
"",
""
},
enable_sound = {
"Enable Sounds",
"",
@ -669,6 +679,26 @@ local strings = {
"",
""
},
options = {
"Options",
"",
"",
"",
"",
"",
"",
""
},
other_settings = {
"Sound and Gameplay",
"",
"",
"",
"",
"",
"",
""
},
output_settings = {
"Output Settings",
"",
@ -719,6 +749,16 @@ local strings = {
"",
""
},
reverb = {
"Reverb",
"",
"",
"",
"",
"",
"",
""
},
revolver = {
"Revolver",
"",
@ -769,6 +809,16 @@ local strings = {
"",
""
},
rumble = {
"Vibration",
"",
"",
"",
"",
"",
"",
""
},
save_game = {
"Save game",
"",
@ -889,18 +939,8 @@ local strings = {
"",
""
},
options = {
"Options",
"",
"",
"",
"",
"",
"",
""
},
sound = {
"Sound settings",
"Sound",
"",
"",
"",
@ -909,17 +949,7 @@ local strings = {
"",
""
},
special_sound_fx = {
"Special Sound FX",
"",
"",
"",
"",
"",
"",
""
},
SILENCER_ITEM = {
silencer = {
"Silencer",
"",
"",
@ -939,6 +969,16 @@ SILENCER_ITEM = {
"",
""
},
thumbstick_camera = {
"Thumbstick camera",
"",
"",
"",
"",
"",
"",
""
},
time_taken = {
"Time Taken",
"",

View file

@ -1,116 +0,0 @@
local tracks = {
AudioTrack.new("001", false),
AudioTrack.new("002", false),
AudioTrack.new("003", false),
AudioTrack.new("004", false),
AudioTrack.new("005", false),
AudioTrack.new("006", false),
AudioTrack.new("007", false),
AudioTrack.new("008", false),
AudioTrack.new("009", false),
AudioTrack.new("010", false),
AudioTrack.new("011", false),
AudioTrack.new("012", false),
AudioTrack.new("013", false),
AudioTrack.new("014", false),
AudioTrack.new("015", false),
AudioTrack.new("016", false),
AudioTrack.new("017", false),
AudioTrack.new("018", false),
AudioTrack.new("019", false),
AudioTrack.new("020", false),
AudioTrack.new("021", false),
AudioTrack.new("022", false),
AudioTrack.new("023", false),
AudioTrack.new("024", false),
AudioTrack.new("025", false),
AudioTrack.new("026", false),
AudioTrack.new("027", false),
AudioTrack.new("028", false),
AudioTrack.new("029", false),
AudioTrack.new("030", false),
AudioTrack.new("031", false),
AudioTrack.new("032", false),
AudioTrack.new("033", false),
AudioTrack.new("034", false),
AudioTrack.new("035", false),
AudioTrack.new("036", false),
AudioTrack.new("037", false),
AudioTrack.new("038", false),
AudioTrack.new("039", false),
AudioTrack.new("040", false),
AudioTrack.new("041", false),
AudioTrack.new("042", false),
AudioTrack.new("043", false),
AudioTrack.new("044", false),
AudioTrack.new("045", false),
AudioTrack.new("046", false),
AudioTrack.new("047", false),
AudioTrack.new("048", false),
AudioTrack.new("049", false),
AudioTrack.new("050", false),
AudioTrack.new("051", false),
AudioTrack.new("052", false),
AudioTrack.new("053", false),
AudioTrack.new("054", false),
AudioTrack.new("055", false),
AudioTrack.new("056", false),
AudioTrack.new("057", false),
AudioTrack.new("058", false),
AudioTrack.new("059", false),
AudioTrack.new("060", false),
AudioTrack.new("061", false),
AudioTrack.new("062", false),
AudioTrack.new("063", false),
AudioTrack.new("064", false),
AudioTrack.new("065", false),
AudioTrack.new("066", false),
AudioTrack.new("067", false),
AudioTrack.new("068", false),
AudioTrack.new("069", false),
AudioTrack.new("070", false),
AudioTrack.new("071", false),
AudioTrack.new("072", false),
AudioTrack.new("074", false),
AudioTrack.new("075", false),
AudioTrack.new("076", false),
AudioTrack.new("077", false),
AudioTrack.new("078", false),
AudioTrack.new("079", false),
AudioTrack.new("080", false),
AudioTrack.new("081", false),
AudioTrack.new("082", false),
AudioTrack.new("083", false),
AudioTrack.new("084", false),
AudioTrack.new("085", false),
AudioTrack.new("086", false),
AudioTrack.new("087", false),
AudioTrack.new("088", false),
AudioTrack.new("089", false),
AudioTrack.new("090", false),
AudioTrack.new("091", false),
AudioTrack.new("092", false),
AudioTrack.new("093", false),
AudioTrack.new("094", false),
AudioTrack.new("095", false),
AudioTrack.new("096", false),
AudioTrack.new("097", false),
AudioTrack.new("098", false),
AudioTrack.new("099", false),
AudioTrack.new("100", false),
AudioTrack.new("101", true),
AudioTrack.new("102", true),
AudioTrack.new("103", true),
AudioTrack.new("104", true),
AudioTrack.new("105", true),
AudioTrack.new("106", true),
AudioTrack.new("107", true),
AudioTrack.new("108", true),
AudioTrack.new("109", false),
AudioTrack.new("110", false),
AudioTrack.new("111", false),
AudioTrack.new("112", false),
AudioTrack.new("073", false) -- secret must always be last one in the list
};
SetAudioTracks(tracks);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 337 KiB

View file

@ -39,6 +39,8 @@
using namespace TEN::Effects::Lara;
using namespace TEN::Control::Volumes;
using namespace TEN::Input;
using std::function;
using TEN::Renderer::g_Renderer;
@ -454,6 +456,8 @@ void LaraControl(ItemInfo* item, CollisionInfo* coll)
if (lara->SprintEnergy < LARA_SPRINT_ENERGY_MAX && item->Animation.ActiveState != LS_SPRINT)
lara->SprintEnergy++;
RumbleLaraHealthCondition(item);
lara->Control.IsLow = false;
bool isWater = TestEnvironment(ENV_FLAG_WATER, item);
@ -844,28 +848,11 @@ void LaraWaterSurface(ItemInfo* item, CollisionInfo* coll)
auto level = g_GameFlow->GetLevel(CurrentLevel);
if (level->GetLaraType() == LaraType::Divesuit)
{
if (lara->Control.TurnRate < -ANGLE(0.5f))
lara->Control.TurnRate += ANGLE(0.5f);
else if (lara->Control.TurnRate > ANGLE(0.5f))
lara->Control.TurnRate -= ANGLE(0.5f);
else
lara->Control.TurnRate = 0;
}
else
{
// Reset turn rate.
int sign = copysign(1, lara->Control.TurnRate);
if (abs(lara->Control.TurnRate) > ANGLE(2.0f))
lara->Control.TurnRate -= ANGLE(2.0f) * sign;
else if (abs(lara->Control.TurnRate) > ANGLE(0.5f))
lara->Control.TurnRate -= ANGLE(0.5f) * sign;
else
lara->Control.TurnRate = 0;
}
// TODO: Subsuit gradually slows down at rate of 0.5 degrees. @Sezz 2022.06.23
// Apply and reset turn rate.
item->Pose.Orientation.y += lara->Control.TurnRate;
if (!(TrInput & (IN_LEFT | IN_RIGHT)))
lara->Control.TurnRate = 0;
if (level->GetLaraType() == LaraType::Divesuit)
UpdateLaraSubsuitAngles(item);
@ -931,22 +918,11 @@ void LaraUnderwater(ItemInfo* item, CollisionInfo* coll)
auto* level = g_GameFlow->GetLevel(CurrentLevel);
if (level->GetLaraType() == LaraType::Divesuit)
{
if (lara->Control.TurnRate < -ANGLE(0.5f))
lara->Control.TurnRate += ANGLE(0.5f);
else if (lara->Control.TurnRate > ANGLE(0.5f))
lara->Control.TurnRate -= ANGLE(0.5f);
else
lara->Control.TurnRate = 0;
}
else if (lara->Control.TurnRate < -ANGLE(2.0f))
lara->Control.TurnRate += ANGLE(2.0f);
else if (lara->Control.TurnRate > ANGLE(2.0f))
lara->Control.TurnRate -= ANGLE(2.0f);
else
lara->Control.TurnRate = 0;
// TODO: Subsuit gradually slowed down at rate of 0.5 degrees. @Sezz 2022.06.23
// Apply and reset turn rate.
item->Pose.Orientation.y += lara->Control.TurnRate;
if (!(TrInput & (IN_LEFT | IN_RIGHT)))
lara->Control.TurnRate = 0;
if (level->GetLaraType() == LaraType::Divesuit)
UpdateLaraSubsuitAngles(item);

View file

@ -5,74 +5,77 @@
struct ItemInfo;
struct CollisionInfo;
#define LARA_GRAB_THRESHOLD ANGLE(40.0f)
#define FRONT_ARC ANGLE(90.0f) // TODO: Check use.
#define LARA_GRAB_THRESHOLD ANGLE(40.0f)
#define FRONT_ARC ANGLE(90.0f) // TODO: Check use.
// Lean rates
#define LARA_LEAN_RATE ANGLE(1.5f)
#define LARA_LEAN_MAX ANGLE(11.0f)
#define LARA_LEAN_MAX ANGLE(11.0f)
// Turn rates
#define LARA_TURN_RATE ANGLE(2.25f)
#define LARA_CRAWL_MOVE_TURN_RATE ANGLE(2.15f)
#define LARA_POLE_TURN_RATE ANGLE(2.25f)
#define LARA_SUBSUIT_TURN_RATE ANGLE(0.75f)
// Turn rate acceleration rates
#define LARA_TURN_RATE_ACCEL ANGLE(0.25f)
#define LARA_CRAWL_MOVE_TURN_RATE_ACCEL ANGLE(0.15f)
#define LARA_POLE_TURN_RATE_ACCEL ANGLE(0.25f)
#define LARA_SUBSUIT_TURN_RATE_ACCEL ANGLE(0.25f)
// Turn rate maxes
#define LARA_SLOW_TURN_MAX ANGLE(4.0f)
#define LARA_SLOW_MED_TURN_MAX ANGLE(5.0f)
#define LARA_MED_TURN_MAX ANGLE(6.0f)
#define LARA_MED_FAST_TURN_MAX ANGLE(7.0f)
#define LARA_FAST_TURN_MAX ANGLE(8.0f)
#define LARA_WADE_TURN_MAX ANGLE(5.5f)
#define LARA_SWAMP_TURN_MAX ANGLE(2.0f)
#define LARA_JUMP_TURN_MAX ANGLE(3.0f)
#define LARA_REACH_TURN_MAX ANGLE(1.3f)
#define LARA_SLIDE_TURN_MAX ANGLE(5.70f)
#define LARA_CRAWL_TURN_MAX ANGLE(2.0f)
#define LARA_CRAWL_MOVE_TURN_MAX ANGLE(3.75f)
#define LARA_CROUCH_ROLL_TURN_MAX ANGLE(2.75f)
#define LARA_POLE_TURN_MAX ANGLE(4.5f)
#define LARA_SLOW_TURN_RATE_MAX ANGLE(2.0f)
#define LARA_SLOW_MED_TURN_RATE_MAX ANGLE(3.0f)
#define LARA_MED_TURN_RATE_MAX ANGLE(4.0f)
#define LARA_MED_FAST_TURN_RATE_MAX ANGLE(5.0f)
#define LARA_FAST_TURN_RATE_MAX ANGLE(6.0f)
#define LARA_WADE_TURN_RATE_MAX ANGLE(3.5f)
#define LARA_SWAMP_TURN_RATE_MAX ANGLE(1.5f)
#define LARA_JUMP_TURN_RATE_MAX ANGLE(1.0f)
#define LARA_REACH_TURN_RATE_MAX ANGLE(0.8f)
#define LARA_SLIDE_TURN_RATE_MAX ANGLE(3.70f)
#define LARA_CRAWL_TURN_RATE_MAX ANGLE(1.5f)
#define LARA_CRAWL_MOVE_TURN_RATE_MAX ANGLE(1.75f)
#define LARA_CROUCH_ROLL_TURN_RATE_MAX ANGLE(0.75f)
#define LARA_POLE_TURN_RATE_MAX ANGLE(2.5f)
// Flex rates
#define LARA_CRAWL_FLEX_RATE ANGLE(2.25f)
#define LARA_CRAWL_FLEX_MAX ANGLE(45.0f) / 2 // 2 = hardcoded number of bones to flex (head and torso).
#define LARA_CRAWL_FLEX_MAX ANGLE(50.0f) / 2 // 2 = hardcoded number of bones to flex (head and torso).
constexpr auto LARA_HEIGHT = CLICK(3) - 1; // Lara height in basic states.
constexpr auto LARA_HEIGHT_CRAWL = 350; // Lara height in crawl states.
constexpr auto LARA_HEIGHT_MONKEY = 850; // Lara height in monkey swing states.
constexpr auto LARA_HEIGHT_TREAD = 700; // Lara height in water treading states.
constexpr auto LARA_HEIGHT_STRETCH = 870; // Lara height in jump-up and ledge hanging states.
constexpr auto LARA_HEIGHT_REACH = 820; // Lara height in reach state.
constexpr auto LARA_HEIGHT_SURFACE = 800; // Lara height when surfacing water.
constexpr auto LARA_HEADROOM = 160; // Amount of reasonable space above Lara's head.
constexpr auto LARA_RADIUS = 100;
constexpr auto LARA_RADIUS_CRAWL = 200;
constexpr auto LARA_RADIUS_UNDERWATER = 300;
constexpr auto LARA_RADIUS_DEATH = 400;
constexpr auto LARA_VELOCITY = 12;
constexpr int LARA_HEIGHT = CLICK(3) - 1; // Lara height in basic states.
constexpr int LARA_HEIGHT_CRAWL = 350; // Lara height in crawl states.
constexpr int LARA_HEIGHT_MONKEY = 850; // Lara height in monkey swing states.
constexpr int LARA_HEIGHT_TREAD = 700; // Lara height in water treading states.
constexpr int LARA_HEIGHT_STRETCH = 870; // Lara height in jump up and ledge hanging states.
constexpr int LARA_HEIGHT_REACH = 820; // Lara height in reach state.
constexpr int LARA_HEIGHT_SURFACE = 800; // Lara height when resurfacing from water.
constexpr int LARA_HEADROOM = 160; // Reasonable space above Lara's head.
constexpr int LARA_RADIUS = 100;
constexpr int LARA_RADIUS_CRAWL = 200;
constexpr int LARA_RADIUS_UNDERWATER = 300;
constexpr int LARA_RADIUS_DEATH = 400;
constexpr int LARA_VELOCITY = 12;
// TODO: Convert velocities to floats and eliminate the division that goes on with these values. @Sezz
constexpr auto LARA_SWIM_ACCELERATION = 8;
constexpr auto LARA_SWIM_DECELERATION = 6;
constexpr auto LARA_TREAD_VELOCITY_MAX = 70;
constexpr auto LARA_SWIM_VELOCITY_MAX = 200;
constexpr auto LARA_SWIM_INTERTIA_VELOCITY_MIN = 134;
// TODO: Convert velocities to floats and eliminate the format conversion that goes on with these values. @Sezz
constexpr int LARA_SWIM_VELOCITY_ACCEL = 2 * 4;
constexpr int LARA_SWIM_VELOCITY_DECEL = 1.5f * 4;
constexpr int LARA_TREAD_VELOCITY_MAX = 17.5f * 4;
constexpr int LARA_SWIM_VELOCITY_MAX = 50 * 4;
constexpr int LARA_SWIM_INTERTIA_VELOCITY_MIN = 33.5f * 4;
constexpr auto LARA_FREEFALL_VELOCITY = 131;
constexpr auto LARA_DAMAGE_VELOCITY = 141;
constexpr auto LARA_DEATH_VELOCITY = 155;
constexpr auto LARA_DIVE_DEATH_VELOCITY = 134;
constexpr auto LARA_TERMINAL_VELOCITY = CLICK(10);
constexpr int LARA_FREEFALL_VELOCITY = 131;
constexpr int LARA_DAMAGE_VELOCITY = 141;
constexpr int LARA_DEATH_VELOCITY = 155;
constexpr int LARA_DIVE_DEATH_VELOCITY = 134;
constexpr int LARA_TERMINAL_VELOCITY = CLICK(10);
constexpr auto LARA_POSITION_ADJUST_MAX_TIME = FPS * 3; // 30 frames * 3 = 3 seconds allowed for position adjustment.
constexpr auto LARA_POSE_TIME = FPS * 30; // 30 frames * 30 = 30 seconds to AFK pose.
constexpr auto LARA_RUN_JUMP_TIME = 22; // Frames to count before a running jump is possible.
constexpr auto LARA_POSITION_ADJUST_MAX_TIME = FPS * 3; // 30 frames * 3 = 3 seconds allowed for position adjustment.
constexpr auto LARA_POSE_TIME = FPS * 30; // 30 frames * 30 = 30 seconds to AFK pose.
constexpr auto LARA_RUN_JUMP_TIME = 22; // Frames to count before a running jump is possible.
constexpr auto LARA_SPRINT_JUMP_TIME = 50; // Frames to count before a sprint jump is possible.
constexpr auto LARA_HEALTH_MAX = 1000.0f;
constexpr auto LARA_AIR_MAX = 1800.0f;
constexpr auto LARA_SPRINT_ENERGY_MAX = 120.0f;
constexpr auto LARA_POISON_POTENCY_MAX = 64.0f;
constexpr float LARA_HEALTH_MAX = 1000.0f;
constexpr float LARA_HEALTH_CRITICAL = LARA_HEALTH_MAX / 4.0f;
constexpr float LARA_AIR_MAX = 1800.0f;
constexpr float LARA_AIR_CRITICAL = LARA_AIR_MAX / 4.0f;
constexpr float LARA_SPRINT_ENERGY_MAX = 120.0f;
constexpr float LARA_POISON_POTENCY_MAX = 64.0f;
extern LaraInfo Lara;
extern ItemInfo* LaraItem;

View file

@ -19,6 +19,8 @@
#include "Specific/setup.h"
#include "Flow/ScriptInterfaceFlowHandler.h"
using namespace TEN::Input;
// ------------------------------
// BASIC MOVEMENT & MISCELLANEOUS
// Control & Collision Functions
@ -127,9 +129,9 @@ void lara_as_walk_forward(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
lara->Control.Count.RunJump++;
if (lara->Control.Count.RunJump > (LARA_RUN_JUMP_TIME / 2 + 4))
lara->Control.Count.RunJump = LARA_RUN_JUMP_TIME / 2 + 4;
lara->Control.Count.Run++;
if (lara->Control.Count.Run > (LARA_RUN_JUMP_TIME / 2 + 4))
lara->Control.Count.Run = LARA_RUN_JUMP_TIME / 2 + 4;
if (item->HitPoints <= 0)
{
@ -141,21 +143,10 @@ void lara_as_walk_forward(ItemInfo* item, CollisionInfo* coll)
if (lara->Control.IsMoving)
return;
if (TrInput & IN_LEFT)
if (TrInput & (IN_LEFT | IN_RIGHT))
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLOW_MED_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_MED_TURN_MAX;
DoLaraLean(item, coll, -LARA_LEAN_MAX / 3, LARA_LEAN_RATE / 6);
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLOW_MED_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_MED_TURN_MAX;
DoLaraLean(item, coll, LARA_LEAN_MAX / 3, LARA_LEAN_RATE / 6);
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_MED_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 6, LARA_LEAN_MAX / 2);
}
if (TrInput & IN_FORWARD)
@ -245,9 +236,9 @@ void lara_as_run_forward(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
lara->Control.Count.RunJump++;
if (lara->Control.Count.RunJump > LARA_RUN_JUMP_TIME)
lara->Control.Count.RunJump = LARA_RUN_JUMP_TIME;
lara->Control.Count.Run++;
if (lara->Control.Count.Run > LARA_RUN_JUMP_TIME)
lara->Control.Count.Run = LARA_RUN_JUMP_TIME;
if (item->HitPoints <= 0)
{
@ -255,26 +246,15 @@ void lara_as_run_forward(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & IN_LEFT)
if (TrInput & (IN_LEFT | IN_RIGHT))
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_FAST_TURN_MAX)
lara->Control.TurnRate = -LARA_FAST_TURN_MAX;
DoLaraLean(item, coll, -LARA_LEAN_MAX, LARA_LEAN_RATE);
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_FAST_TURN_MAX)
lara->Control.TurnRate = LARA_FAST_TURN_MAX;
DoLaraLean(item, coll, LARA_LEAN_MAX, LARA_LEAN_RATE);
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_FAST_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX);
}
if (TrInput & IN_JUMP || lara->Control.RunJumpQueued)
{
if (lara->Control.Count.RunJump >= LARA_RUN_JUMP_TIME &&
if (!(TrInput & IN_SPRINT) && lara->Control.Count.Run >= LARA_RUN_JUMP_TIME &&
TestLaraRunJumpForward(item, coll))
{
item->Animation.TargetState = LS_JUMP_FORWARD;
@ -285,7 +265,7 @@ void lara_as_run_forward(ItemInfo* item, CollisionInfo* coll)
}
if ((TrInput & IN_ROLL || (TrInput & IN_FORWARD && TrInput & IN_BACK)) &&
!lara->Control.RunJumpQueued && // Jump queue blocks roll.
!lara->Control.RunJumpQueued && // Jump queue blocks roll.
lara->Control.WaterStatus != WaterStatus::Wade)
{
item->Animation.TargetState = LS_ROLL_FORWARD;
@ -371,6 +351,7 @@ void lara_col_run_forward(ItemInfo* item, CollisionInfo* coll)
item->Animation.TargetState = LS_SPLAT;
if (GetChange(item, &g_Level.Anims[item->Animation.AnimNumber]))
{
Rumble(0.4f, 0.15f);
item->Animation.ActiveState = LS_SPLAT;
return;
}
@ -421,21 +402,14 @@ void lara_as_idle(ItemInfo* item, CollisionInfo* coll)
if (BinocularOn)
return;
if (!(TrInput & IN_JUMP) || isSwamp) // JUMP locks orientation outside swamps.
if (!(TrInput & IN_JUMP) || isSwamp) // JUMP locks orientation outside swamps.
{
if (TrInput & IN_LEFT &&
!(TrInput & IN_LSTEP || (TrInput & IN_WALK && TrInput & IN_LEFT))) // Sidestep locks orientation.
if ((TrInput & IN_LEFT &&
!(TrInput & IN_LSTEP || (TrInput & IN_WALK && TrInput & IN_LEFT))) || // Sidestep locks orientation.
(TrInput & IN_RIGHT &&
!(TrInput & IN_RSTEP || (TrInput & IN_WALK && TrInput & IN_RIGHT))))
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_TURN_MAX;
}
else if (TrInput & IN_RIGHT &&
!(TrInput & IN_RSTEP || (TrInput & IN_WALK && TrInput & IN_RIGHT)))
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_TURN_MAX;
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
}
}
@ -538,7 +512,7 @@ void lara_as_idle(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_LEFT)
{
if (TrInput & IN_SPRINT ||
lara->Control.TurnRate <= -LARA_SLOW_TURN_MAX || TestLaraFastTurn(item))
lara->Control.TurnRate <= -LARA_SLOW_TURN_RATE_MAX || TestLaraFastTurn(item))
{
item->Animation.TargetState = LS_TURN_LEFT_FAST;
}
@ -550,7 +524,7 @@ void lara_as_idle(ItemInfo* item, CollisionInfo* coll)
else if (TrInput & IN_RIGHT)
{
if (TrInput & IN_SPRINT ||
lara->Control.TurnRate >= LARA_SLOW_TURN_MAX || TestLaraFastTurn(item))
lara->Control.TurnRate >= LARA_SLOW_TURN_RATE_MAX || TestLaraFastTurn(item))
{
item->Animation.TargetState = LS_TURN_RIGHT_FAST;
}
@ -794,21 +768,10 @@ void lara_as_run_back(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
if (TrInput & IN_LEFT)
if (TrInput & (IN_LEFT | IN_RIGHT))
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_MED_TURN_MAX)
lara->Control.TurnRate = -LARA_MED_TURN_MAX;
DoLaraLean(item, coll, -LARA_LEAN_MAX / 3, LARA_LEAN_RATE / 4);
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_MED_TURN_MAX)
lara->Control.TurnRate = LARA_MED_TURN_MAX;
DoLaraLean(item, coll, LARA_LEAN_MAX / 3, LARA_LEAN_RATE / 4);
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 4, LARA_LEAN_MAX / 3);
}
if (TrInput & IN_ROLL)
@ -880,12 +843,6 @@ void lara_as_turn_right_slow(ItemInfo* item, CollisionInfo* coll)
return;
}
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate < 0)
lara->Control.TurnRate = 0;
else if (lara->Control.TurnRate > LARA_MED_FAST_TURN_MAX)
lara->Control.TurnRate = LARA_MED_FAST_TURN_MAX;
if (lara->Control.WaterStatus == WaterStatus::Wade)
{
if (isSwamp)
@ -896,6 +853,8 @@ void lara_as_turn_right_slow(ItemInfo* item, CollisionInfo* coll)
return;
}
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_FAST_TURN_RATE_MAX);
if (TrInput & IN_JUMP)
{
SetLaraJumpDirection(item, coll);
@ -990,10 +949,10 @@ void lara_as_turn_right_slow(ItemInfo* item, CollisionInfo* coll)
{
item->Animation.TargetState = LS_TURN_RIGHT_SLOW;
if (lara->Control.TurnRate > LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_TURN_MAX;
if (lara->Control.TurnRate > LARA_SLOW_TURN_RATE_MAX)
lara->Control.TurnRate = LARA_SLOW_TURN_RATE_MAX;
}
else */if (lara->Control.TurnRate > LARA_SLOW_MED_TURN_MAX)
else */if (lara->Control.TurnRate > LARA_SLOW_MED_TURN_RATE_MAX)
item->Animation.TargetState = LS_TURN_RIGHT_FAST;
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_TURN_RIGHT_SLOW;
@ -1009,8 +968,7 @@ void PsuedoLaraAsWadeTurnRightSlow(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
if (lara->Control.TurnRate > LARA_WADE_TURN_MAX)
lara->Control.TurnRate = LARA_WADE_TURN_MAX;
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_WADE_TURN_RATE_MAX);
if (TrInput & IN_JUMP && TestLaraJumpUp(item, coll))
{
@ -1074,8 +1032,7 @@ void PsuedoLaraAsSwampTurnRightSlow(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
if (lara->Control.TurnRate > LARA_SWAMP_TURN_MAX)
lara->Control.TurnRate = LARA_SWAMP_TURN_MAX;
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SWAMP_TURN_RATE_MAX);
if (TrInput & IN_FORWARD)
{
@ -1150,12 +1107,6 @@ void lara_as_turn_left_slow(ItemInfo* item, CollisionInfo* coll)
return;
}
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate > 0)
lara->Control.TurnRate = 0;
else if (lara->Control.TurnRate < -LARA_MED_FAST_TURN_MAX)
lara->Control.TurnRate = -LARA_MED_FAST_TURN_MAX;
if (lara->Control.WaterStatus == WaterStatus::Wade)
{
if (isSwamp)
@ -1166,6 +1117,8 @@ void lara_as_turn_left_slow(ItemInfo* item, CollisionInfo* coll)
return;
}
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_FAST_TURN_RATE_MAX);
if (TrInput & IN_JUMP)
{
SetLaraJumpDirection(item, coll);
@ -1260,10 +1213,10 @@ void lara_as_turn_left_slow(ItemInfo* item, CollisionInfo* coll)
{
item->Animation.TargetState = LS_TURN_LEFT_SLOW;
if (lara->Control.TurnRate < -LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_TURN_MAX;
if (lara->Control.TurnRate < -LARA_SLOW_TURN_RATE_MAX)
lara->Control.TurnRate = -LARA_SLOW_TURN_RATE_MAX;
}
else */if (lara->Control.TurnRate < -LARA_SLOW_MED_TURN_MAX)
else */if (lara->Control.TurnRate < -LARA_SLOW_MED_TURN_RATE_MAX)
item->Animation.TargetState = LS_TURN_LEFT_FAST;
else USE_FEATURE_IF_CPP20([[likely]])
item->Animation.TargetState = LS_TURN_LEFT_SLOW;
@ -1279,8 +1232,7 @@ void PsuedoLaraAsWadeTurnLeftSlow(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
if (lara->Control.TurnRate < -LARA_WADE_TURN_MAX)
lara->Control.TurnRate = -LARA_WADE_TURN_MAX;
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_WADE_TURN_RATE_MAX);
if (TrInput & IN_JUMP && TestLaraJumpUp(item, coll))
{
@ -1344,8 +1296,7 @@ void PsuedoLaraAsSwampTurnLeftSlow(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
if (lara->Control.TurnRate < -LARA_SWAMP_TURN_MAX)
lara->Control.TurnRate = -LARA_SWAMP_TURN_MAX;
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SWAMP_TURN_RATE_MAX);
if (TrInput & IN_FORWARD)
{
@ -1504,29 +1455,16 @@ void lara_as_walk_back(ItemInfo* item, CollisionInfo* coll)
if (lara->Control.IsMoving)
return;
if (isSwamp &&
lara->Control.WaterStatus == WaterStatus::Wade)
if (isSwamp && lara->Control.WaterStatus == WaterStatus::Wade)
{
PseudoLaraAsSwampWalkBack(item, coll);
return;
}
if (TrInput & IN_LEFT)
if (TrInput & (IN_LEFT | IN_RIGHT))
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_TURN_MAX;
DoLaraLean(item, coll, -LARA_LEAN_MAX / 3, LARA_LEAN_RATE / 4);
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_TURN_MAX;
DoLaraLean(item, coll, LARA_LEAN_MAX / 3, LARA_LEAN_RATE / 4);
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 4, LARA_LEAN_MAX / 3);
}
if (TrInput & IN_BACK &&
@ -1544,22 +1482,10 @@ void PseudoLaraAsSwampWalkBack(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
if (TrInput & IN_LEFT)
if (TrInput & (IN_LEFT | IN_RIGHT))
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLOW_TURN_MAX / 3)
lara->Control.TurnRate = -LARA_SLOW_TURN_MAX / 3;
DoLaraLean(item, coll, -LARA_LEAN_MAX / 3, LARA_LEAN_RATE / 3);
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLOW_TURN_MAX / 3)
lara->Control.TurnRate = LARA_SLOW_TURN_MAX / 3;
DoLaraLean(item, coll, LARA_LEAN_MAX / 3, LARA_LEAN_RATE / 3);
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX / 3);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 3, LARA_LEAN_MAX / 3);
}
if (TrInput & IN_BACK)
@ -1631,11 +1557,7 @@ void lara_as_turn_right_fast(ItemInfo* item, CollisionInfo* coll)
return;
}
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate < LARA_MED_TURN_MAX)
lara->Control.TurnRate = LARA_MED_TURN_MAX;
else if (lara->Control.TurnRate > LARA_FAST_TURN_MAX)
lara->Control.TurnRate = LARA_FAST_TURN_MAX;
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, LARA_MED_TURN_RATE_MAX, LARA_FAST_TURN_RATE_MAX);
if (TrInput & IN_JUMP)
{
@ -1762,11 +1684,7 @@ void lara_as_turn_left_fast(ItemInfo* item, CollisionInfo* coll)
return;
}
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate > -LARA_MED_TURN_MAX)
lara->Control.TurnRate = -LARA_MED_TURN_MAX;
else if (lara->Control.TurnRate < -LARA_FAST_TURN_MAX)
lara->Control.TurnRate = -LARA_FAST_TURN_MAX;
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, LARA_MED_TURN_RATE_MAX, LARA_FAST_TURN_RATE_MAX);
if (TrInput & IN_JUMP)
{
@ -1899,18 +1817,8 @@ void lara_as_step_right(ItemInfo* item, CollisionInfo* coll)
if (!(TrInput & IN_WALK)) // WALK locks orientation.
{
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
}
// TODO: Funky?
@ -1999,18 +1907,8 @@ void lara_as_step_left(ItemInfo* item, CollisionInfo* coll)
if (!(TrInput & IN_WALK)) // WALK locks orientation.
{
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
}
if (TrInput & IN_LSTEP || (TrInput & IN_WALK && TrInput & IN_LEFT))
@ -2231,21 +2129,10 @@ void lara_as_wade_forward(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & IN_LEFT)
if (TrInput & (IN_LEFT | IN_RIGHT))
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_FAST_TURN_MAX)
lara->Control.TurnRate = -LARA_FAST_TURN_MAX;
DoLaraLean(item, coll, -LARA_LEAN_MAX, LARA_LEAN_RATE / 2);
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_FAST_TURN_MAX)
lara->Control.TurnRate = LARA_FAST_TURN_MAX;
DoLaraLean(item, coll, LARA_LEAN_MAX, LARA_LEAN_RATE / 2);
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 2, LARA_LEAN_MAX);
}
if (TrInput & IN_FORWARD)
@ -2274,21 +2161,10 @@ void PseudoLaraAsSwampWadeForward(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
if (TrInput & IN_LEFT)
if (TrInput & (IN_LEFT | IN_RIGHT))
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SWAMP_TURN_MAX)
lara->Control.TurnRate = -LARA_SWAMP_TURN_MAX;
DoLaraLean(item, coll, -LARA_LEAN_MAX / 5 * 3, LARA_LEAN_RATE / 3);
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SWAMP_TURN_MAX)
lara->Control.TurnRate = LARA_SWAMP_TURN_MAX;
DoLaraLean(item, coll, LARA_LEAN_MAX / 5 * 3, LARA_LEAN_RATE / 3);
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SWAMP_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 3, LARA_LEAN_MAX * 0.6f);
}
if (TrInput & IN_FORWARD)
@ -2364,9 +2240,9 @@ void lara_as_sprint(ItemInfo* item, CollisionInfo* coll)
lara->SprintEnergy--;
lara->Control.Count.RunJump++;
if (lara->Control.Count.RunJump > LARA_RUN_JUMP_TIME)
lara->Control.Count.RunJump = LARA_RUN_JUMP_TIME;
lara->Control.Count.Run++;
if (lara->Control.Count.Run > LARA_SPRINT_JUMP_TIME)
lara->Control.Count.Run = LARA_SPRINT_JUMP_TIME;
if (item->HitPoints <= 0)
{
@ -2374,21 +2250,10 @@ void lara_as_sprint(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & IN_LEFT)
if (TrInput & (IN_LEFT | IN_RIGHT))
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_TURN_MAX;
DoLaraLean(item, coll, -LARA_LEAN_MAX, LARA_LEAN_RATE);
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_TURN_MAX;
DoLaraLean(item, coll, LARA_LEAN_MAX, LARA_LEAN_RATE);
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX);
}
if (TrInput & IN_JUMP || lara->Control.RunJumpQueued)
@ -2398,7 +2263,7 @@ void lara_as_sprint(ItemInfo* item, CollisionInfo* coll)
item->Animation.TargetState = LS_SPRINT_DIVE;
return;
}
else if (lara->Control.Count.RunJump >= LARA_RUN_JUMP_TIME &&
else if (TrInput & IN_SPRINT && lara->Control.Count.Run >= LARA_SPRINT_JUMP_TIME &&
TestLaraRunJumpForward(item, coll) && HasStateDispatch(item, LS_JUMP_FORWARD))
{
item->Animation.TargetState = LS_JUMP_FORWARD;
@ -2481,6 +2346,8 @@ void lara_col_sprint(ItemInfo* item, CollisionInfo* coll)
if (TestLaraWall(item, OFFSET_RADIUS(coll->Setup.Radius), -CLICK(2.5f)) ||
coll->HitTallObject)
{
Rumble(0.5f, 0.15f);
item->Animation.TargetState = LS_SPLAT;
if (GetChange(item, &g_Level.Anims[item->Animation.AnimNumber]))
{
@ -2515,25 +2382,14 @@ void lara_as_sprint_dive(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
lara->Control.Count.RunJump++;
if (lara->Control.Count.RunJump > LARA_RUN_JUMP_TIME)
lara->Control.Count.RunJump = LARA_RUN_JUMP_TIME;
lara->Control.Count.Run++;
if (lara->Control.Count.Run > LARA_RUN_JUMP_TIME)
lara->Control.Count.Run = LARA_RUN_JUMP_TIME;
if (TrInput & IN_LEFT)
if (TrInput & (IN_LEFT | IN_RIGHT))
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_TURN_MAX;
DoLaraLean(item, coll, -(LARA_LEAN_MAX * 3) / 5, LARA_LEAN_RATE);
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_TURN_MAX;
DoLaraLean(item, coll, (LARA_LEAN_MAX * 3) / 5, LARA_LEAN_RATE);
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX * 0.6f);
}
item->Animation.TargetState = LS_RUN_FORWARD;

View file

@ -1,17 +1,20 @@
#include "framework.h"
#include "Game/Lara/lara_cheat.h"
#include <OISKeyboard.h>
#include "Game/collision/collide_room.h"
#include "Game/effects/effects.h"
#include "Game/items.h"
#include "Game/Lara/lara.h"
#include "Flow/ScriptInterfaceFlowHandler.h"
#include "Game/Lara/lara_helpers.h"
#include "Flow/ScriptInterfaceFlowHandler.h"
#include "Sound/sound.h"
#include "Specific/input.h"
#include "Specific/level.h"
#include "Specific/setup.h"
using namespace TEN::Input;
void lara_as_swimcheat(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
@ -22,17 +25,9 @@ void lara_as_swimcheat(ItemInfo* item, CollisionInfo* coll)
item->Pose.Orientation.x += ANGLE(3.0f);
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= ANGLE(3.4f);
if (lara->Control.TurnRate < -ANGLE(6.0f))
lara->Control.TurnRate = -ANGLE(6.0f);
}
ModulateLaraTurnRateY(item, ANGLE(3.4f), 0, ANGLE(6.0f));
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += ANGLE(3.4f);
if (lara->Control.TurnRate > ANGLE(6.0f))
lara->Control.TurnRate = ANGLE(6.0f);
}
ModulateLaraTurnRateY(item, ANGLE(3.4f), 0, ANGLE(6.0f));
if (TrInput & IN_ACTION)
TriggerDynamicLight(item->Pose.Position.x, item->Pose.Position.y, item->Pose.Position.z, 31, 150, 150, 150);
@ -42,13 +37,13 @@ void lara_as_swimcheat(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_JUMP)
{
item->Animation.VerticalVelocity += LARA_SWIM_ACCELERATION * 2;
item->Animation.VerticalVelocity += LARA_SWIM_VELOCITY_ACCEL * 2;
if (item->Animation.VerticalVelocity > LARA_SWIM_VELOCITY_MAX * 2)
item->Animation.VerticalVelocity = LARA_SWIM_VELOCITY_MAX * 2;
}
else
{
if (item->Animation.VerticalVelocity >= LARA_SWIM_ACCELERATION)
if (item->Animation.VerticalVelocity >= LARA_SWIM_VELOCITY_ACCEL)
item->Animation.VerticalVelocity -= item->Animation.VerticalVelocity / 8;
else
item->Animation.VerticalVelocity = 0;
@ -61,7 +56,7 @@ void LaraCheatyBits(ItemInfo* item)
if (g_GameFlow->IsFlyCheatEnabled())
{
if (KeyMap[DIK_O])
if (KeyMap[OIS::KeyCode::KC_O])
{
if (lara->Vehicle == NO_ITEM)
{

View file

@ -13,6 +13,8 @@
#include "Specific/input.h"
#include "Flow/ScriptInterfaceFlowHandler.h"
using namespace TEN::Input;
// -----------------------------
// LADDER CLIMB
// Control & Collision Functions

View file

@ -17,6 +17,8 @@
#include "Flow/ScriptInterfaceFlowHandler.h"
#include "ScriptInterfaceLevel.h"
using namespace TEN::Input;
// -----------------------------
// COLLISION TEST FUNCTIONS
// For State Control & Collision
@ -24,6 +26,8 @@
bool LaraDeflectEdge(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
if (coll->CollisionType == CT_FRONT || coll->CollisionType == CT_TOP_FRONT)
{
ShiftItem(item, coll);
@ -31,6 +35,7 @@ bool LaraDeflectEdge(ItemInfo* item, CollisionInfo* coll)
item->Animation.TargetState = LS_IDLE;
item->Animation.Velocity = 0;
item->Animation.Airborne = false;
lara->Control.TurnRate = 0;
return true;
}
@ -64,8 +69,12 @@ bool LaraDeflectEdgeJump(ItemInfo* item, CollisionInfo* coll)
SetAnimation(item, LA_LAND);
LaraSnapToHeight(item, coll);
}
else if (abs(item->Animation.Velocity) > 47) // TODO: Demagic. This is Lara's running velocity. Jumps have a minimum of 50.
else if (abs(item->Animation.Velocity) > 47)
{
// TODO: Demagic. This is Lara's running velocity. Jumps have a minimum of 50.
SetAnimation(item, LA_JUMP_WALL_SMASH_START, 1);
Rumble(0.5f, 0.15f);
}
item->Animation.Velocity /= 4;
lara->Control.MoveAngle += ANGLE(180.0f);

View file

@ -16,6 +16,8 @@
#include "Specific/level.h"
#include "Flow/ScriptInterfaceFlowHandler.h"
using namespace TEN::Input;
// -----------------------------
// CROUCH & CRAWL
// Control & Collision Functions
@ -57,10 +59,8 @@ void lara_as_crouch_idle(ItemInfo* item, CollisionInfo* coll)
if (BinocularOn)
return;
if (TrInput & IN_LEFT)
lara->Control.TurnRate = -LARA_CRAWL_TURN_MAX;
else if (TrInput & IN_RIGHT)
lara->Control.TurnRate = LARA_CRAWL_TURN_MAX;
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_CRAWL_TURN_RATE_MAX);
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade)
@ -156,21 +156,10 @@ void lara_as_crouch_roll(ItemInfo* item, CollisionInfo* coll)
coll->Setup.EnableSpasm = false;
Camera.targetDistance = SECTOR(1);
if (TrInput & IN_LEFT)
if (TrInput & (IN_LEFT | IN_RIGHT))
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_CROUCH_ROLL_TURN_MAX)
lara->Control.TurnRate = -LARA_CROUCH_ROLL_TURN_MAX;
DoLaraLean(item, coll, -LARA_LEAN_MAX, LARA_LEAN_RATE);
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_CROUCH_ROLL_TURN_MAX)
lara->Control.TurnRate = LARA_CROUCH_ROLL_TURN_MAX;
DoLaraLean(item, coll, LARA_LEAN_MAX, LARA_LEAN_RATE);
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_CROUCH_ROLL_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE, LARA_LEAN_MAX);
}
item->Animation.TargetState = LS_CROUCH_IDLE;
@ -247,8 +236,6 @@ void lara_as_crouch_turn_left(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_LOOK)
LookUpDown(item);
lara->Control.TurnRate = -LARA_CRAWL_TURN_MAX;
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
@ -268,6 +255,7 @@ void lara_as_crouch_turn_left(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_LEFT)
{
item->Animation.TargetState = LS_CROUCH_TURN_LEFT;
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_CRAWL_TURN_RATE_MAX);
return;
}
@ -303,8 +291,6 @@ void lara_as_crouch_turn_right(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_LOOK)
LookUpDown(item);
lara->Control.TurnRate = LARA_CRAWL_TURN_MAX;
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
@ -324,6 +310,7 @@ void lara_as_crouch_turn_right(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_RIGHT)
{
item->Animation.TargetState = LS_CROUCH_TURN_RIGHT;
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_CRAWL_TURN_RATE_MAX);
return;
}
@ -405,10 +392,8 @@ void lara_as_crawl_idle(ItemInfo* item, CollisionInfo* coll)
if (BinocularOn)
return;
if (TrInput & IN_LEFT)
lara->Control.TurnRate = -LARA_CRAWL_TURN_MAX;
else if (TrInput & IN_RIGHT)
lara->Control.TurnRate = LARA_CRAWL_TURN_MAX;
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_CRAWL_TURN_RATE_MAX);
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade)
@ -436,6 +421,7 @@ void lara_as_crawl_idle(ItemInfo* item, CollisionInfo* coll)
g_GameFlow->HasCrawlExtended())
{
item->Animation.TargetState = crawlVaultResult.TargetState;
lara->Control.TurnRate = 0;
ResetLaraFlex(item);
return;
}
@ -540,21 +526,10 @@ void lara_as_crawl_forward(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & IN_LEFT)
if (TrInput & (IN_LEFT | IN_RIGHT))
{
lara->Control.TurnRate -= LARA_CRAWL_MOVE_TURN_RATE;
if (lara->Control.TurnRate < -LARA_CRAWL_MOVE_TURN_MAX)
lara->Control.TurnRate = -LARA_CRAWL_MOVE_TURN_MAX;
DoLaraCrawlFlex(item, coll, -LARA_CRAWL_FLEX_MAX, LARA_CRAWL_FLEX_RATE);
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_CRAWL_MOVE_TURN_RATE;
if (lara->Control.TurnRate > LARA_CRAWL_MOVE_TURN_MAX)
lara->Control.TurnRate = LARA_CRAWL_MOVE_TURN_MAX;
DoLaraCrawlFlex(item, coll, LARA_CRAWL_FLEX_MAX, LARA_CRAWL_FLEX_RATE);
ModulateLaraTurnRateY(item, LARA_CRAWL_MOVE_TURN_RATE_ACCEL, 0, LARA_CRAWL_MOVE_TURN_RATE_MAX);
ModulateLaraCrawlFlex(item, LARA_CRAWL_FLEX_RATE, LARA_CRAWL_FLEX_MAX);
}
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
@ -645,21 +620,10 @@ void lara_as_crawl_back(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & IN_LEFT)
if (TrInput & (IN_LEFT | IN_RIGHT))
{
lara->Control.TurnRate -= LARA_CRAWL_MOVE_TURN_RATE;
if (lara->Control.TurnRate < -LARA_CRAWL_MOVE_TURN_MAX)
lara->Control.TurnRate = -LARA_CRAWL_MOVE_TURN_MAX;
DoLaraCrawlFlex(item, coll, LARA_CRAWL_FLEX_MAX, LARA_CRAWL_FLEX_RATE);
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_CRAWL_MOVE_TURN_RATE;
if (lara->Control.TurnRate > LARA_CRAWL_MOVE_TURN_MAX)
lara->Control.TurnRate = LARA_CRAWL_MOVE_TURN_MAX;
DoLaraCrawlFlex(item, coll, -LARA_CRAWL_FLEX_MAX, LARA_CRAWL_FLEX_RATE);
ModulateLaraTurnRateY(item, LARA_CRAWL_MOVE_TURN_RATE_ACCEL, 0, LARA_CRAWL_MOVE_TURN_RATE_MAX);
ModulateLaraCrawlFlex(item, LARA_CRAWL_FLEX_RATE, LARA_CRAWL_FLEX_MAX);
}
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
@ -741,8 +705,6 @@ void lara_as_crawl_turn_left(ItemInfo* item, CollisionInfo* coll)
return;
}
lara->Control.TurnRate = -LARA_CRAWL_TURN_MAX;
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
@ -767,6 +729,7 @@ void lara_as_crawl_turn_left(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_LEFT)
{
item->Animation.TargetState = LS_CRAWL_TURN_LEFT;
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_CRAWL_MOVE_TURN_RATE_MAX);
return;
}
@ -801,8 +764,6 @@ void lara_as_crawl_turn_right(ItemInfo* item, CollisionInfo* coll)
return;
}
lara->Control.TurnRate = LARA_CRAWL_TURN_MAX;
if ((TrInput & IN_CROUCH || lara->Control.KeepLow) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
@ -827,6 +788,7 @@ void lara_as_crawl_turn_right(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_RIGHT)
{
item->Animation.TargetState = LS_CRAWL_TURN_RIGHT;
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_CRAWL_MOVE_TURN_RATE_MAX);
return;
}

View file

@ -21,6 +21,7 @@
#include "Flow/ScriptInterfaceFlowHandler.h"
#include "ScriptInterfaceLevel.h"
#include "Sound/sound.h"
#include "Specific/configuration.h"
#include "Specific/setup.h"
#include "Specific/input.h"
#include "Specific/level.h"
@ -29,6 +30,7 @@
#include "Objects/ScriptInterfaceObjectsHandler.h"
using namespace TEN::Entities::Generic;
using namespace TEN::Input;
bool MonksAttackLara;
ItemInfo* LastTargets[MAX_TARGETS];
@ -1036,6 +1038,9 @@ void LaraTargetInfo(ItemInfo* laraItem, WeaponInfo* weaponInfo)
void LaraGetNewTarget(ItemInfo* laraItem, WeaponInfo* weaponInfo)
{
if (!g_Configuration.AutoTarget)
return;
auto* lara = GetLaraInfo(laraItem);
if (BinocularRange)

View file

@ -12,6 +12,8 @@
#include "Specific/input.h"
#include "Specific/level.h"
using namespace TEN::Input;
// -----------------------------
// LEDGE HANG
// Control & Collision Functions

View file

@ -25,6 +25,7 @@
#include "Objects/TR4/Vehicles/motorbike.h"
using namespace TEN::Renderer;
using namespace TEN::Input;
// -----------------------------
// HELPER FUNCTIONS
@ -47,7 +48,7 @@ void HandleLaraMovementParameters(ItemInfo* item, CollisionInfo* coll)
// Reset running jump timer.
if (!IsRunJumpCountableState((LaraState)item->Animation.ActiveState))
lara->Control.Count.RunJump = 0;
lara->Control.Count.Run = 0;
// Reset running jump action queue.
if (!IsRunJumpQueueableState((LaraState)item->Animation.ActiveState))
@ -64,16 +65,10 @@ void HandleLaraMovementParameters(ItemInfo* item, CollisionInfo* coll)
ResetLaraFlex(item, 12.0f);
}
// Reset turn rate.
// TODO: Make it less stupid in the future. Do it according to a curve?
int sign = copysign(1, lara->Control.TurnRate);
if (abs(lara->Control.TurnRate) > ANGLE(2.0f))
lara->Control.TurnRate -= ANGLE(2.0f) * sign;
else if (abs(lara->Control.TurnRate) > ANGLE(0.5f))
lara->Control.TurnRate -= ANGLE(0.5f) * sign;
else
lara->Control.TurnRate = 0;
// Apply and reset turn rate.
item->Pose.Orientation.y += lara->Control.TurnRate;
if (!(TrInput & (IN_LEFT | IN_RIGHT)))
lara->Control.TurnRate = 0;
}
bool HandleLaraVehicle(ItemInfo* item, CollisionInfo* coll)
@ -166,7 +161,7 @@ void EaseOutLaraHeight(ItemInfo* item, int height)
static constexpr int rate = 50;
int threshold = std::max(abs(item->Animation.Velocity) * 1.5f, CLICK(0.25f) / 4);
int sign = std::copysign(1, height);
if (TestEnvironment(ENV_FLAG_SWAMP, item) && height > 0)
item->Pose.Position.y += SWAMP_GRAVITY;
else if (abs(height) > (STEPUP_HEIGHT / 2)) // Outer range.
@ -180,21 +175,6 @@ void EaseOutLaraHeight(ItemInfo* item, int height)
item->Pose.Position.y += height;
}
// TODO: Make lean rate proportional to the turn rate, allowing for nicer aesthetics with future analog stick input.
void DoLaraLean(ItemInfo* item, CollisionInfo* coll, short maxAngle, short rate)
{
if (!item->Animation.Velocity)
return;
rate = abs(rate);
int sign = copysign(1, maxAngle);
if (coll->CollisionType == CT_LEFT || coll->CollisionType == CT_RIGHT)
item->Pose.Orientation.z += std::min<short>(rate, abs((maxAngle * 3) / 5 - item->Pose.Orientation.z) / 3) * sign;
else
item->Pose.Orientation.z += std::min<short>(rate, abs(maxAngle - item->Pose.Orientation.z) / 3) * sign;
}
// TODO: Some states can't make the most of this function due to missing step up/down animations.
// Try implementing leg IK as a substitute to make step animations obsolete. @Sezz 2021.10.09
void DoLaraStep(ItemInfo* item, CollisionInfo* coll)
@ -245,26 +225,6 @@ void DoLaraCrawlToHangSnap(ItemInfo* item, CollisionInfo* coll)
}
}
void DoLaraCrawlFlex(ItemInfo* item, CollisionInfo* coll, short maxAngle, short rate)
{
auto* lara = GetLaraInfo(item);
if (!item->Animation.Velocity)
return;
int sign = copysign(1, maxAngle);
rate = copysign(rate, maxAngle);
lara->ExtraTorsoRot.z += std::min(abs(rate), abs(maxAngle - lara->ExtraTorsoRot.z) / 6) * sign;
if (!(TrInput & IN_LOOK) &&
item->Animation.ActiveState != LS_CRAWL_BACK)
{
lara->ExtraHeadRot.z = lara->ExtraTorsoRot.z / 2;
lara->ExtraHeadRot.y = lara->ExtraHeadRot.z;
}
}
void DoLaraTightropeBalance(ItemInfo* item)
{
auto* lara = GetLaraInfo(item);
@ -326,7 +286,7 @@ void DoLaraTightropeBalanceRegen(ItemInfo* item)
}
}
void DealLaraFallDamage(ItemInfo* item)
void DoLaraFallDamage(ItemInfo* item)
{
if (item->Animation.VerticalVelocity >= LARA_DAMAGE_VELOCITY)
{
@ -334,9 +294,12 @@ void DealLaraFallDamage(ItemInfo* item)
item->HitPoints = 0;
else USE_FEATURE_IF_CPP20([[likely]])
{
int base = item->Animation.VerticalVelocity - (LARA_DAMAGE_VELOCITY - 1);
float base = item->Animation.VerticalVelocity - (LARA_DAMAGE_VELOCITY - 1);
item->HitPoints -= LARA_HEALTH_MAX * (pow(base, 2) / 196);
}
float rumblePower = ((float)item->Animation.VerticalVelocity / (float)LARA_DEATH_VELOCITY) * 0.7f;
Rumble(rumblePower, 0.3f);
}
}
@ -344,58 +307,113 @@ LaraInfo*& GetLaraInfo(ItemInfo* item)
{
if (item->ObjectNumber == ID_LARA)
return (LaraInfo*&)item->Data;
else
{
TENLog(std::string("Attempted to fetch LaraInfo data from entity with object ID ") + std::to_string(item->ObjectNumber), LogLevel::Warning);
TENLog(std::string("Attempted to fetch LaraInfo data from entity with object ID ") + std::to_string(item->ObjectNumber), LogLevel::Warning);
auto* firstLaraItem = FindItem(ID_LARA);
return (LaraInfo*&)firstLaraItem->Data;
auto* firstLaraItem = FindItem(ID_LARA);
return (LaraInfo*&)firstLaraItem->Data;
}
}
short GetLaraSlideDirection(ItemInfo* item, CollisionInfo* coll)
{
short direction = coll->Setup.ForwardAngle;
short headingAngle = coll->Setup.ForwardAngle;
auto probe = GetCollision(item);
// Ground is flat.
if (!probe.FloorTilt.x && !probe.FloorTilt.y)
return direction;
if (probe.FloorTilt == Vector2::Zero)
return headingAngle;
direction = GetSurfaceAspectAngle(probe.FloorTilt.x, probe.FloorTilt.y);
// Determine nearest cardinal direction of surface aspect.
if (!g_GameFlow->HasSlideExtended())
direction = GetQuadrant(direction) * ANGLE(90.0f);
return direction;
// Get either:
// a) the surface aspect angle (extended slides), or
// b) the derived nearest cardinal direction from it (original slides).
headingAngle = GetSurfaceAspectAngle(probe.FloorTilt.x, probe.FloorTilt.y);
if (g_GameFlow->HasSlideExtended())
return headingAngle;
else
return (GetQuadrant(headingAngle) * ANGLE(90.0f));
}
void ModulateLaraSlideVelocity(ItemInfo* item, CollisionInfo* coll)
short ModulateLaraTurnRate(short turnRate, short accelRate, short minTurnRate, short maxTurnRate, float axisCoeff)
{
int sign = std::copysign(1, axisCoeff);
short minTurnRateNormalized = minTurnRate * abs(axisCoeff);
short maxTurnRateNormalized = maxTurnRate * abs(axisCoeff);
short newTurnRate = (turnRate + (accelRate * sign)) * sign;
newTurnRate = std::clamp(newTurnRate, minTurnRateNormalized, maxTurnRateNormalized);
return newTurnRate * sign;
}
void ModulateLaraTurnRateX(ItemInfo* item, short accelRate, short minTurnRate, short maxTurnRate)
{
auto* lara = GetLaraInfo(item);
constexpr int minVelocity = 50;
constexpr int maxVelocity = LARA_TERMINAL_VELOCITY;
if (g_GameFlow->HasSlideExtended())
{
auto probe = GetCollision(item);
short minSlideAngle = ANGLE(33.75f);
short steepness = GetSurfaceSteepnessAngle(probe.FloorTilt.x, probe.FloorTilt.y);
short direction = GetSurfaceAspectAngle(probe.FloorTilt.x, probe.FloorTilt.y);
float velocityMultiplier = 1 / (float)ANGLE(33.75f);
int slideVelocity = std::min<int>(minVelocity + 10 * (steepness * velocityMultiplier), LARA_TERMINAL_VELOCITY);
//short deltaAngle = abs((short)(direction - item->Pose.Orientation.y));
g_Renderer.PrintDebugMessage("%d", slideVelocity);
lara->ExtraVelocity.x += slideVelocity;
lara->ExtraVelocity.y += slideVelocity * phd_sin(steepness);
}
else
lara->ExtraVelocity.x += minVelocity;
//lara->Control.TurnRate.x = ModulateLaraTurnRate(lara->Control.TurnRate.x, accelRate, minTurnRate, maxTurnRate, AxisMap[InputAxis::MoveVertical]);
}
void ModulateLaraTurnRateY(ItemInfo* item, short accelRate, short minTurnRate, short maxTurnRate)
{
auto* lara = GetLaraInfo(item);
float axisCoeff = AxisMap[InputAxis::MoveHorizontal];
if (item->Animation.Airborne)
{
int sign = std::copysign(1, axisCoeff);
axisCoeff = std::min(1.2f, abs(axisCoeff)) * sign;
}
lara->Control.TurnRate/*.y*/ = ModulateLaraTurnRate(lara->Control.TurnRate/*.y*/, accelRate, minTurnRate, maxTurnRate, axisCoeff);
}
void ModulateLaraSwimTurnRates(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
/*if (TrInput & (IN_FORWARD | IN_BACK))
ModulateLaraTurnRateX(item, 0, 0, 0);*/
if (TrInput & IN_FORWARD)
item->Pose.Orientation.x -= ANGLE(3.0f);
else if (TrInput & IN_BACK)
item->Pose.Orientation.x += ANGLE(3.0f);
if (TrInput & (IN_LEFT | IN_RIGHT))
{
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_MED_TURN_RATE_MAX);
// TODO: ModulateLaraLean() doesn't really work here. @Sezz 2022.06.22
if (TrInput & IN_LEFT)
item->Pose.Orientation.z -= LARA_LEAN_RATE;
else if (TrInput & IN_RIGHT)
item->Pose.Orientation.z += LARA_LEAN_RATE;
}
}
void ModulateLaraSubsuitSwimTurnRates(ItemInfo* item)
{
auto* lara = GetLaraInfo(item);
if (TrInput & IN_FORWARD && item->Pose.Orientation.x > -ANGLE(85.0f))
lara->Control.Subsuit.DXRot = -ANGLE(45.0f);
else if (TrInput & IN_BACK && item->Pose.Orientation.x < ANGLE(85.0f))
lara->Control.Subsuit.DXRot = ANGLE(45.0f);
else
lara->Control.Subsuit.DXRot = 0;
if (TrInput & (IN_LEFT | IN_RIGHT))
{
ModulateLaraTurnRateY(item, LARA_SUBSUIT_TURN_RATE_ACCEL, 0, LARA_MED_TURN_RATE_MAX);
if (TrInput & IN_LEFT)
item->Pose.Orientation.z -= LARA_LEAN_RATE;
else if (TrInput & IN_RIGHT)
item->Pose.Orientation.z += LARA_LEAN_RATE;
}
}
// TODO: Simplify this function. Some members of SubsuitControlData may be unnecessary. @Sezz 2022.06.22
void UpdateLaraSubsuitAngles(ItemInfo* item)
{
auto* lara = GetLaraInfo(item);
@ -465,60 +483,69 @@ void UpdateLaraSubsuitAngles(ItemInfo* item)
}
}
void ModulateLaraSubsuitSwimTurn(ItemInfo* item)
void ModulateLaraLean(ItemInfo* item, CollisionInfo* coll, short baseRate, short maxAngle)
{
if (!item->Animation.Velocity)
return;
float axisCoeff = AxisMap[InputAxis::MoveHorizontal];
int sign = copysign(1, axisCoeff);
short maxAngleNormalized = maxAngle * axisCoeff;
if (coll->CollisionType == CT_LEFT || coll->CollisionType == CT_RIGHT)
maxAngleNormalized *= 0.6f;
item->Pose.Orientation.z += std::min<short>(baseRate, abs(maxAngleNormalized - item->Pose.Orientation.z) / 3) * sign;
}
void ModulateLaraCrawlFlex(ItemInfo* item, short baseRate, short maxAngle)
{
auto* lara = GetLaraInfo(item);
if (TrInput & IN_FORWARD && item->Pose.Orientation.x > -ANGLE(85.0f))
lara->Control.Subsuit.DXRot = -ANGLE(45.0f);
else if (TrInput & IN_BACK && item->Pose.Orientation.x < ANGLE(85.0f))
lara->Control.Subsuit.DXRot = ANGLE(45.0f);
else
lara->Control.Subsuit.DXRot = 0;
if (!item->Animation.Velocity)
return;
if (TrInput & IN_LEFT)
float axisCoeff = AxisMap[InputAxis::MoveHorizontal];
int sign = copysign(1, axisCoeff);
short maxAngleNormalized = maxAngle * axisCoeff;
if (abs(lara->ExtraTorsoRot.z) < LARA_CRAWL_FLEX_MAX)
lara->ExtraTorsoRot.z += std::min<short>(baseRate, abs(maxAngleNormalized - lara->ExtraTorsoRot.z) / 6) * sign;
if (!(TrInput & IN_LOOK) &&
item->Animation.ActiveState != LS_CRAWL_BACK)
{
lara->Control.TurnRate -= LARA_SUBSUIT_TURN_RATE;
if (lara->Control.TurnRate < -LARA_MED_TURN_MAX)
lara->Control.TurnRate = -LARA_MED_TURN_MAX;
item->Pose.Orientation.z -= LARA_LEAN_RATE;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_SUBSUIT_TURN_RATE;
if (lara->Control.TurnRate > LARA_MED_TURN_MAX)
lara->Control.TurnRate = LARA_MED_TURN_MAX;
item->Pose.Orientation.z += LARA_LEAN_RATE;
lara->ExtraHeadRot.z = lara->ExtraTorsoRot.z / 2;
lara->ExtraHeadRot.y = lara->ExtraHeadRot.z;
}
}
void ModulateLaraSwimTurn(ItemInfo* item, CollisionInfo* coll)
// TODO: Unused; I will pick this back up later. @Sezz 2022.06.22
void ModulateLaraSlideVelocity(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
if (TrInput & IN_FORWARD)
item->Pose.Orientation.x -= ANGLE(2.0f);
else if (TrInput & IN_BACK)
item->Pose.Orientation.x += ANGLE(2.0f);
constexpr int minVelocity = 50;
constexpr int maxVelocity = LARA_TERMINAL_VELOCITY;
if (TrInput & IN_LEFT)
if (g_GameFlow->HasSlideExtended())
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_MED_TURN_MAX)
lara->Control.TurnRate = -LARA_MED_TURN_MAX;
auto probe = GetCollision(item);
short minSlideAngle = ANGLE(33.75f);
short steepness = GetSurfaceSteepnessAngle(probe.FloorTilt.x, probe.FloorTilt.y);
short direction = GetSurfaceAspectAngle(probe.FloorTilt.x, probe.FloorTilt.y);
item->Pose.Orientation.z -= LARA_LEAN_RATE;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_MED_TURN_MAX)
lara->Control.TurnRate = LARA_MED_TURN_MAX;
float velocityMultiplier = 1 / (float)ANGLE(33.75f);
int slideVelocity = std::min<int>(minVelocity + 10 * (steepness * velocityMultiplier), LARA_TERMINAL_VELOCITY);
//short deltaAngle = abs((short)(direction - item->Pose.Orientation.y));
item->Pose.Orientation.z += LARA_LEAN_RATE;
g_Renderer.PrintDebugMessage("%d", slideVelocity);
lara->ExtraVelocity.x += slideVelocity;
lara->ExtraVelocity.y += slideVelocity * phd_sin(steepness);
}
else
lara->ExtraVelocity.x += minVelocity;
}
void SetLaraJumpDirection(ItemInfo* item, CollisionInfo* coll)
@ -562,8 +589,8 @@ void SetLaraRunJumpQueue(ItemInfo* item, CollisionInfo* coll)
auto probe = GetCollision(item, item->Pose.Orientation.y, distance, -coll->Setup.Height);
if ((TestLaraRunJumpForward(item, coll) || // Area close ahead is permissive...
(probe.Position.Ceiling - y) < -(coll->Setup.Height + (LARA_HEADROOM * 0.8f)) || // OR ceiling height far ahead is permissive
(probe.Position.Floor - y) >= CLICK(0.5f)) && // OR there is a drop below far ahead.
(probe.Position.Ceiling - y) < -(coll->Setup.Height + (LARA_HEADROOM * 0.8f)) || // OR ceiling height far ahead is permissive
(probe.Position.Floor - y) >= CLICK(0.5f)) && // OR there is a drop below far ahead.
probe.Position.Floor != NO_HEIGHT)
{
lara->Control.RunJumpQueued = IsRunJumpQueueableState((LaraState)item->Animation.TargetState);
@ -695,11 +722,11 @@ void SetLaraSlideAnimation(ItemInfo* item, CollisionInfo* coll)
// TODO: Do it later.
void newSetLaraSlideAnimation(ItemInfo* item, CollisionInfo* coll)
{
short direction = GetLaraSlideDirection(item, coll);
short deltaAngle = direction - item->Pose.Orientation.y;
short headinAngle = GetLaraSlideDirection(item, coll);
short deltaAngle = headinAngle - item->Pose.Orientation.y;
if (!g_GameFlow->HasSlideExtended())
item->Pose.Orientation.y = direction;
item->Pose.Orientation.y = headinAngle;
// Snap to height upon slide entrance.
if (item->Animation.ActiveState != LS_SLIDE_FORWARD &&
@ -837,3 +864,15 @@ void ResetLaraFlex(ItemInfo* item, float rate)
else
lara->ExtraTorsoRot.z = 0;
}
void RumbleLaraHealthCondition(ItemInfo* lara)
{
auto* info = GetLaraInfo(lara);
if (lara->HitPoints > LARA_HEALTH_CRITICAL && !info->PoisonPotency)
return;
bool pulse = (GlobalCounter & 0x0F) / 0x0F == 1;
if (pulse)
Rumble(0.2f, 0.1f);
}

View file

@ -15,23 +15,26 @@ void HandleLaraMovementParameters(ItemInfo* item, CollisionInfo* coll);
bool HandleLaraVehicle(ItemInfo* item, CollisionInfo* coll);
void ApproachLaraTargetOrientation(ItemInfo* item, Vector3Shrt targetOrient, float rate = 1.0f);
void EaseOutLaraHeight(ItemInfo* item, int height);
void DoLaraLean(ItemInfo* item, CollisionInfo* coll, short maxAngle, short rate);
void DoLaraStep(ItemInfo* item, CollisionInfo* coll);
void DoLaraMonkeyStep(ItemInfo* item, CollisionInfo* coll);
void DoLaraCrawlToHangSnap(ItemInfo* item, CollisionInfo* coll);
void DoLaraCrawlFlex(ItemInfo* item, CollisionInfo* coll, short maxAngle, short rate);
void DoLaraTightropeBalance(ItemInfo* item);
void DoLaraTightropeLean(ItemInfo* item);
void DoLaraTightropeBalanceRegen(ItemInfo* item);
void DealLaraFallDamage(ItemInfo* item);
void DoLaraFallDamage(ItemInfo* item);
LaraInfo*& GetLaraInfo(ItemInfo* item);
short GetLaraSlideDirection(ItemInfo* item, CollisionInfo* coll);
void ModulateLaraSlideVelocity(ItemInfo* item, CollisionInfo* coll);
short ModulateLaraTurnRate(short turnRate, short accelRate, short minTurnRate, short maxTurnRate, float axisCoeff);
void ModulateLaraTurnRateX(ItemInfo* item, short accelRate, short minTurnRate, short maxTurnRate);
void ModulateLaraTurnRateY(ItemInfo* item, short accelRate, short minTurnRate, short maxTurnRate);
void ModulateLaraSwimTurnRates(ItemInfo* item, CollisionInfo* coll);
void ModulateLaraSubsuitSwimTurnRates(ItemInfo* item);
void UpdateLaraSubsuitAngles(ItemInfo* item);
void ModulateLaraSubsuitSwimTurn(ItemInfo* item);
void ModulateLaraSwimTurn(ItemInfo* item, CollisionInfo* coll);
void ModulateLaraLean(ItemInfo* item, CollisionInfo* coll, short baseRate, short maxAngle);
void ModulateLaraCrawlFlex(ItemInfo* item, short baseRate, short maxAngle);
void ModulateLaraSlideVelocity(ItemInfo* item, CollisionInfo* coll);
void SetLaraJumpDirection(ItemInfo* item, CollisionInfo* coll);
void SetLaraRunJumpQueue(ItemInfo* item, CollisionInfo* coll);
@ -47,3 +50,5 @@ void SetLaraSwimDiveAnimation(ItemInfo* item);
void ResetLaraLean(ItemInfo* item, float rate = 1.0f, bool resetRoll = true, bool resetPitch = true);
void ResetLaraFlex(ItemInfo* item, float rate = 1.0f);
void RumbleLaraHealthCondition(ItemInfo* lara);

View file

@ -16,6 +16,8 @@
#include "Specific/level.h"
#include "Specific/setup.h"
using namespace TEN::Input;
// -----------------------------
// JUMP
// Control & Collision Functions
@ -36,9 +38,9 @@ void lara_as_jump_forward(ItemInfo* item, CollisionInfo* coll)
auto* lara = GetLaraInfo(item);
// Update running jump counter in preparation for possible jump action soon after landing.
lara->Control.Count.RunJump++;
if (lara->Control.Count.RunJump > LARA_RUN_JUMP_TIME / 2)
lara->Control.Count.RunJump = LARA_RUN_JUMP_TIME / 2;
lara->Control.Count.Run++;
if (lara->Control.Count.Run > LARA_RUN_JUMP_TIME / 2)
lara->Control.Count.Run = LARA_RUN_JUMP_TIME / 2;
if (item->HitPoints <= 0)
{
@ -51,22 +53,12 @@ void lara_as_jump_forward(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_JUMP_TURN_MAX)
lara->Control.TurnRate = -LARA_JUMP_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_JUMP_TURN_MAX)
lara->Control.TurnRate = LARA_JUMP_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_JUMP_TURN_RATE_MAX);
if (TestLaraLand(item, coll))
{
DealLaraFallDamage(item);
DoLaraFallDamage(item);
if (item->HitPoints <= 0) USE_FEATURE_IF_CPP20([[unlikely]])
item->Animation.TargetState = LS_DEATH;
@ -146,7 +138,7 @@ void lara_as_freefall(ItemInfo* item, CollisionInfo* coll)
if (TestLaraLand(item, coll))
{
DealLaraFallDamage(item);
DoLaraFallDamage(item);
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
@ -198,22 +190,12 @@ void lara_as_reach(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_JUMP_TURN_MAX / 2)
lara->Control.TurnRate = -LARA_JUMP_TURN_MAX / 2;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_JUMP_TURN_MAX / 2)
lara->Control.TurnRate = LARA_JUMP_TURN_MAX / 2;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_JUMP_TURN_RATE_MAX / 2);
if (TestLaraLand(item, coll))
{
DealLaraFallDamage(item);
DoLaraFallDamage(item);
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
@ -286,18 +268,8 @@ void lara_as_jump_prepare(ItemInfo* item, CollisionInfo* coll)
if (TrInput & (IN_FORWARD | IN_BACK) &&
lara->Control.WaterStatus != WaterStatus::Wade)
{
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
}
// JUMP key repressed without directional key; cancel directional jump lock.
@ -434,22 +406,12 @@ void lara_as_jump_back(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_JUMP_TURN_MAX)
lara->Control.TurnRate = -LARA_JUMP_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_JUMP_TURN_MAX)
lara->Control.TurnRate = LARA_JUMP_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_JUMP_TURN_RATE_MAX);
if (TestLaraLand(item, coll))
{
DealLaraFallDamage(item);
DoLaraFallDamage(item);
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
@ -505,7 +467,7 @@ void lara_as_jump_right(ItemInfo* item, CollisionInfo* coll)
if (TestLaraLand(item, coll))
{
DealLaraFallDamage(item);
DoLaraFallDamage(item);
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
@ -562,7 +524,7 @@ void lara_as_jump_left(ItemInfo* item, CollisionInfo* coll)
if (TestLaraLand(item, coll))
{
DealLaraFallDamage(item);
DoLaraFallDamage(item);
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
@ -707,22 +669,12 @@ void lara_as_fall_back(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_JUMP_TURN_MAX / 2)
lara->Control.TurnRate = -LARA_JUMP_TURN_MAX / 2;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_JUMP_TURN_MAX / 2)
lara->Control.TurnRate = LARA_JUMP_TURN_MAX / 2;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_JUMP_TURN_RATE_MAX / 2);
if (TestLaraLand(item, coll))
{
DealLaraFallDamage(item);
DoLaraFallDamage(item);
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
@ -786,26 +738,15 @@ void lara_as_swan_dive(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & IN_LEFT)
if (TrInput & (IN_LEFT | IN_RIGHT))
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_JUMP_TURN_MAX)
lara->Control.TurnRate = -LARA_JUMP_TURN_MAX;
DoLaraLean(item, coll, -LARA_LEAN_MAX, LARA_LEAN_RATE / 2);
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_JUMP_TURN_MAX)
lara->Control.TurnRate = LARA_JUMP_TURN_MAX;
DoLaraLean(item, coll, LARA_LEAN_MAX, LARA_LEAN_RATE / 2);
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_JUMP_TURN_RATE_MAX);
ModulateLaraLean(item, coll, LARA_LEAN_RATE / 2, LARA_LEAN_MAX);
}
if (TestLaraLand(item, coll))
{
DealLaraFallDamage(item);
DoLaraFallDamage(item);
if (item->HitPoints <= 0)
item->Animation.TargetState = LS_DEATH;
@ -886,6 +827,7 @@ void lara_as_freefall_dive(ItemInfo* item, CollisionInfo* coll)
item->HitPoints <= 0)
{
item->Animation.TargetState = LS_DEATH;
Rumble(0.5f, 0.2f);
}
else if (TestLaraSlide(item, coll))
SetLaraSlideAnimation(item, coll);

View file

@ -16,6 +16,8 @@
#include "Specific/level.h"
#include "Flow/ScriptInterfaceFlowHandler.h"
using namespace TEN::Input;
// -----------------------------
// MONKEY SWING
// Control & Collision Functions
@ -45,19 +47,12 @@ void lara_as_monkey_idle(ItemInfo* item, CollisionInfo* coll)
// Overhang hook.
SlopeMonkeyExtra(item, coll);
if (TrInput & IN_LEFT &&
!(TrInput & IN_LSTEP || (TrInput & IN_WALK && TrInput & IN_LEFT))) // Shimmy locks orientation.
if ((TrInput & IN_LEFT &&
!(TrInput & IN_LSTEP || (TrInput & IN_WALK && TrInput & IN_LEFT))) || // Shimmy locks orientation.
(TrInput & IN_RIGHT &&
!(TrInput & IN_RSTEP || (TrInput & IN_WALK && TrInput & IN_RIGHT))))
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLOW_TURN_MAX / 2)
lara->Control.TurnRate = -LARA_SLOW_TURN_MAX / 2;
}
else if (TrInput & IN_RIGHT &&
!(TrInput & IN_RSTEP || (TrInput & IN_WALK && TrInput & IN_RIGHT)))
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLOW_TURN_MAX / 2)
lara->Control.TurnRate = LARA_SLOW_TURN_MAX / 2;
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX / 2);
}
if (TrInput & IN_ACTION && lara->Control.CanMonkeySwing)
@ -179,18 +174,8 @@ void lara_as_monkey_forward(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
if (TrInput & IN_ACTION && lara->Control.CanMonkeySwing)
{
@ -266,18 +251,8 @@ void lara_as_monkey_back(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
if (TrInput & IN_ACTION && lara->Control.CanMonkeySwing)
{
@ -349,18 +324,8 @@ void lara_as_monkey_shimmy_left(ItemInfo* item, CollisionInfo* coll)
if (!(TrInput & IN_WALK)) // WALK locks orientation.
{
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
}
if (TrInput & IN_ACTION && lara->Control.CanMonkeySwing)
@ -433,18 +398,8 @@ void lara_as_monkey_shimmy_right(ItemInfo* item, CollisionInfo* coll)
if (!(TrInput & IN_WALK)) // WALK locks orientation.
{
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
}
if (TrInput & IN_ACTION && lara->Control.CanMonkeySwing)
@ -575,11 +530,7 @@ void lara_as_monkey_turn_left(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_LEFT)
{
item->Animation.TargetState = LS_MONKEY_TURN_LEFT;
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_TURN_MAX;
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
return;
}
@ -658,11 +609,7 @@ void lara_as_monkey_turn_right(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_RIGHT)
{
item->Animation.TargetState = LS_MONKEY_TURN_RIGHT;
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLOW_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_TURN_MAX;
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL, 0, LARA_SLOW_TURN_RATE_MAX);
return;
}

View file

@ -14,6 +14,7 @@
#include "Specific/input.h"
#include "Specific/level.h"
using namespace TEN::Input;
using namespace TEN::Entities::Generic;
// -----------------------------------
@ -737,20 +738,10 @@ void lara_as_pole_idle(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_ACTION)
{
if (item->Animation.ActiveState == LA_POLE_IDLE) // Hack.
if (item->Animation.ActiveState == LA_POLE_IDLE) // HACK.
{
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate += LARA_POLE_TURN_RATE;
if (lara->Control.TurnRate > LARA_POLE_TURN_MAX)
lara->Control.TurnRate = LARA_POLE_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate -= LARA_POLE_TURN_RATE;
if (lara->Control.TurnRate < -LARA_POLE_TURN_MAX)
lara->Control.TurnRate = -LARA_POLE_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX);
}
// TODO: Add forward jump.
@ -840,18 +831,8 @@ void lara_as_pole_up(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_ACTION)
{
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate += LARA_POLE_TURN_RATE;
if (lara->Control.TurnRate > LARA_POLE_TURN_MAX)
lara->Control.TurnRate = LARA_POLE_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate -= LARA_POLE_TURN_RATE;
if (lara->Control.TurnRate < -LARA_POLE_TURN_MAX)
lara->Control.TurnRate = -LARA_POLE_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX);
if (TrInput & IN_JUMP)
{
@ -899,18 +880,8 @@ void lara_as_pole_down(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_ACTION)
{
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate += LARA_POLE_TURN_RATE;
if (lara->Control.TurnRate > LARA_POLE_TURN_MAX)
lara->Control.TurnRate = LARA_POLE_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate -= LARA_POLE_TURN_RATE;
if (lara->Control.TurnRate < -LARA_POLE_TURN_MAX)
lara->Control.TurnRate = -LARA_POLE_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX);
if (TrInput & IN_JUMP)
{
@ -999,11 +970,8 @@ void lara_as_pole_turn_clockwise(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate += LARA_POLE_TURN_RATE;
if (lara->Control.TurnRate > LARA_POLE_TURN_MAX)
lara->Control.TurnRate = LARA_POLE_TURN_MAX;
item->Animation.TargetState = LS_POLE_TURN_CLOCKWISE;
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX);
return;
}
@ -1054,11 +1022,8 @@ void lara_as_pole_turn_counter_clockwise(ItemInfo* item, CollisionInfo* coll)
if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate -= LARA_POLE_TURN_RATE;
if (lara->Control.TurnRate < -LARA_POLE_TURN_MAX)
lara->Control.TurnRate = -LARA_POLE_TURN_MAX;
item->Animation.TargetState = LS_POLE_TURN_COUNTER_CLOCKWISE;
ModulateLaraTurnRateY(item, LARA_POLE_TURN_RATE_ACCEL, 0, LARA_POLE_TURN_RATE_MAX);
return;
}

View file

@ -26,6 +26,7 @@
#include "Specific/input.h"
#include "Sound/sound.h"
using namespace TEN::Input;
using namespace TEN::Effects::Lara;
using namespace TEN::Entities::Switches;
using namespace TEN::Effects::Environment;
@ -341,6 +342,8 @@ void FireShotgun(ItemInfo* laraItem)
SoundEffect(SFX_TR4_EXPLOSION1, &laraItem->Pose, TestEnvironment(ENV_FLAG_WATER, laraItem) ? SoundEnvironment::Water : SoundEnvironment::Land);
SoundEffect(Weapons[(int)LaraWeaponType::Shotgun].SampleNum, &laraItem->Pose);
Rumble(0.5f, 0.2f);
Statistics.Game.AmmoUsed++;
}
}
@ -451,7 +454,7 @@ void FireHarpoon(ItemInfo* laraItem)
{
auto* lara = GetLaraInfo(laraItem);
Ammo& ammos = GetAmmo(laraItem, LaraWeaponType::HarpoonGun);
auto& ammos = GetAmmo(laraItem, LaraWeaponType::HarpoonGun);
if (!ammos)
return;
@ -499,6 +502,7 @@ void FireHarpoon(ItemInfo* laraItem)
item->Animation.VerticalVelocity = -HARPOON_VELOCITY * phd_sin(item->Pose.Orientation.x);
item->HitPoints = HARPOON_TIME;
Rumble(0.2f, 0.1f);
AddActiveItem(itemNumber);
Statistics.Level.AmmoUsed++;
@ -721,6 +725,8 @@ void FireGrenade(ItemInfo* laraItem)
item->HitPoints = GRENADE_TIME;
item->ItemFlags[0] = (int)WeaponAmmoType::Ammo2;
Rumble(0.4f, 0.25f);
AddActiveItem(itemNumber);
if (!ammo.hasInfinite())
@ -1169,6 +1175,7 @@ void FireRocket(ItemInfo* laraItem)
AddActiveItem(itemNumber);
Rumble(0.4f, 0.3f);
SoundEffect(SFX_TR4_EXPLOSION1, &laraItem->Pose);
Statistics.Level.AmmoUsed++;
@ -1456,6 +1463,7 @@ void FireCrossbow(ItemInfo* laraItem, PHD_3DPOS* pos)
item->ItemFlags[0] = (int)lara->Weapons[(int)LaraWeaponType::Crossbow].SelectedAmmo;
Rumble(0.2f, 0.1f);
SoundEffect(SFX_TR4_CROSSBOW_FIRE, &laraItem->Pose);
Statistics.Level.AmmoUsed++;
@ -1723,6 +1731,8 @@ void FireHK(ItemInfo* laraItem, int mode)
SmokeWeapon = LaraWeaponType::HK;
TriggerGunShell(1, ID_GUNSHELL, LaraWeaponType::HK);
lara->RightArm.FlashGun = Weapons[(int)LaraWeaponType::HK].FlashTime;
Rumble(0.2f, 0.1f);
}
}
@ -1811,6 +1821,7 @@ void DoExplosiveDamageOnBaddy(ItemInfo* laraItem, ItemInfo* dest, ItemInfo* src,
}
else
{
Rumble(0.5f, 0.3f);
laraItem->HitPoints -= (Weapons[(int)weaponType].Damage * 5);
if (!TestEnvironment(ENV_FLAG_WATER, dest->RoomNumber) && laraItem->HitPoints <= Weapons[(int)weaponType].Damage)
LaraBurn(laraItem);

View file

@ -15,6 +15,8 @@
#include "Flow/ScriptInterfaceFlowHandler.h"
#include "Specific/level.h"
using namespace TEN::Input;
constexpr auto HORIZONTAL_ALIGN_NORTHEAST = 155;
constexpr auto HORIZONTAL_ALIGN_SOUTHWEST = 101;
constexpr auto FORWARD_ALIGNMENT = 868;

View file

@ -12,6 +12,8 @@
#include "Specific/input.h"
#include "Specific/level.h"
using namespace TEN::Input;
// -----------------------------
// SLIDE
// Control & Collision Functions
@ -46,17 +48,17 @@ void lara_as_slide_forward(ItemInfo* item, CollisionInfo* coll)
// TODO: Prepped for another time.
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLIDE_TURN_MAX)
lara->Control.TurnRate = -LARA_SLIDE_TURN_MAX;
lara->Control.TurnRate -= LARA_TURN_RATE_ACCEL;
if (lara->Control.TurnRate < -LARA_SLIDE_TURN_RATE_MAX)
lara->Control.TurnRate = -LARA_SLIDE_TURN_RATE_MAX;
DoLaraLean(item, coll, -LARA_LEAN_MAX, LARA_LEAN_RATE / 3 * 2);
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLIDE_TURN_MAX)
lara->Control.TurnRate = LARA_SLIDE_TURN_MAX;
lara->Control.TurnRate += LARA_TURN_RATE_ACCEL;
if (lara->Control.TurnRate > LARA_SLIDE_TURN_RATE_MAX)
lara->Control.TurnRate = LARA_SLIDE_TURN_RATE_MAX;
DoLaraLean(item, coll, LARA_LEAN_MAX, LARA_LEAN_RATE / 3 * 2);
}
@ -155,17 +157,17 @@ void lara_as_slide_back(ItemInfo* item, CollisionInfo* coll)
// TODO: Prepped for another time.
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE;
if (lara->Control.TurnRate < -LARA_SLIDE_TURN_MAX)
lara->Control.TurnRate = -LARA_SLIDE_TURN_MAX;
lara->Control.TurnRate -= LARA_TURN_RATE_ACCEL;
if (lara->Control.TurnRate < -LARA_SLIDE_TURN_RATE_MAX)
lara->Control.TurnRate = -LARA_SLIDE_TURN_RATE_MAX;
DoLaraLean(item, coll, LARA_LEAN_MAX, LARA_LEAN_RATE / 3 * 2);
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE;
if (lara->Control.TurnRate > LARA_SLIDE_TURN_MAX)
lara->Control.TurnRate = LARA_SLIDE_TURN_MAX;
lara->Control.TurnRate += LARA_TURN_RATE_ACCEL;
if (lara->Control.TurnRate > LARA_SLIDE_TURN_RATE_MAX)
lara->Control.TurnRate = LARA_SLIDE_TURN_RATE_MAX;
DoLaraLean(item, coll, -LARA_LEAN_MAX, LARA_LEAN_RATE / 3 * 2);
}

View file

@ -1154,7 +1154,7 @@ struct LaraCountData
{
unsigned int Pose;
unsigned int PositionAdjust;
unsigned int RunJump;
unsigned int Run;
unsigned int Death;
unsigned int NoCheat;
};
@ -1276,7 +1276,6 @@ struct LaraInfo
int HitFrame;
int HitDirection;
FX_INFO* SpasmEffect; // Not saved.
unsigned int SpasmEffectCount;
short InteractedItem;
int ProjectedFloorHeight;

View file

@ -13,6 +13,8 @@
#include "Specific/level.h"
#include "Specific/input.h"
using namespace TEN::Input;
// -----------------------------
// WATER SURFACE TREAD
// Control & Collision Functions
@ -39,7 +41,7 @@ void lara_as_surface_idle(ItemInfo* item, CollisionInfo* coll)
{
auto* lara = GetLaraInfo(item);
item->Animation.VerticalVelocity -= LARA_SWIM_DECELERATION;
item->Animation.VerticalVelocity -= LARA_SWIM_VELOCITY_DECEL;
if (item->Animation.VerticalVelocity < 0)
item->Animation.VerticalVelocity = 0;
@ -55,18 +57,8 @@ void lara_as_surface_idle(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE * 1.25f;
if (lara->Control.TurnRate < -LARA_MED_TURN_MAX)
lara->Control.TurnRate = -LARA_MED_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE * 1.25f;
if (lara->Control.TurnRate > LARA_MED_TURN_MAX)
lara->Control.TurnRate = LARA_MED_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL * 1.25f, 0, LARA_MED_TURN_RATE_MAX);
if (DbInput & IN_JUMP)
{
@ -126,19 +118,9 @@ void lara_as_surface_swim_forward(ItemInfo* item, CollisionInfo* coll)
item->Animation.TargetState = LS_WATER_DEATH;
return;
}
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE * 1.25f;
if (lara->Control.TurnRate < -LARA_MED_TURN_MAX)
lara->Control.TurnRate = -LARA_MED_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE * 1.25f;
if (lara->Control.TurnRate > LARA_MED_TURN_MAX)
lara->Control.TurnRate = LARA_MED_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL * 1.25f, 0, LARA_MED_TURN_RATE_MAX);
if (!(TrInput & IN_FORWARD))
item->Animation.TargetState = LS_ONWATER_IDLE;
@ -146,7 +128,7 @@ void lara_as_surface_swim_forward(ItemInfo* item, CollisionInfo* coll)
if (DbInput & IN_JUMP)
SetLaraSwimDiveAnimation(item);
item->Animation.VerticalVelocity += LARA_SWIM_ACCELERATION;
item->Animation.VerticalVelocity += LARA_SWIM_VELOCITY_ACCEL;
if (item->Animation.VerticalVelocity > LARA_TREAD_VELOCITY_MAX)
item->Animation.VerticalVelocity = LARA_TREAD_VELOCITY_MAX;
}
@ -178,18 +160,8 @@ void lara_as_surface_swim_left(ItemInfo* item, CollisionInfo* coll)
if (!(TrInput & IN_WALK)) // WALK locks orientation.
{
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE * 1.25f;
if (lara->Control.TurnRate < -LARA_SLOW_MED_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_MED_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE * 1.25f;
if (lara->Control.TurnRate > LARA_SLOW_MED_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_MED_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL * 1.25f, 0, LARA_SLOW_MED_TURN_RATE_MAX);
}
if (!(TrInput & IN_LSTEP || (TrInput & IN_WALK && TrInput & IN_LEFT)))
@ -198,7 +170,7 @@ void lara_as_surface_swim_left(ItemInfo* item, CollisionInfo* coll)
if (DbInput & IN_JUMP)
SetLaraSwimDiveAnimation(item);
item->Animation.VerticalVelocity += LARA_SWIM_ACCELERATION;
item->Animation.VerticalVelocity += LARA_SWIM_VELOCITY_ACCEL;
if (item->Animation.VerticalVelocity > LARA_TREAD_VELOCITY_MAX)
item->Animation.VerticalVelocity = LARA_TREAD_VELOCITY_MAX;
}
@ -227,18 +199,8 @@ void lara_as_surface_swim_right(ItemInfo* item, CollisionInfo* coll)
if (!(TrInput & IN_WALK)) // WALK locks orientation.
{
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE * 1.25f;
if (lara->Control.TurnRate < -LARA_SLOW_MED_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_MED_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE * 1.25f;
if (lara->Control.TurnRate > LARA_SLOW_MED_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_MED_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL * 1.25f, 0, LARA_SLOW_MED_TURN_RATE_MAX);
}
if (!(TrInput & IN_RSTEP || (TrInput & IN_WALK && TrInput & IN_RIGHT)))
@ -247,7 +209,7 @@ void lara_as_surface_swim_right(ItemInfo* item, CollisionInfo* coll)
if (DbInput & IN_JUMP)
SetLaraSwimDiveAnimation(item);
item->Animation.VerticalVelocity += LARA_SWIM_ACCELERATION;
item->Animation.VerticalVelocity += LARA_SWIM_VELOCITY_ACCEL;
if (item->Animation.VerticalVelocity > LARA_TREAD_VELOCITY_MAX)
item->Animation.VerticalVelocity = LARA_TREAD_VELOCITY_MAX;
}
@ -274,18 +236,8 @@ void lara_as_surface_swim_back(ItemInfo* item, CollisionInfo* coll)
return;
}
if (TrInput & IN_LEFT)
{
lara->Control.TurnRate -= LARA_TURN_RATE * 1.25f;
if (lara->Control.TurnRate < -LARA_SLOW_MED_TURN_MAX)
lara->Control.TurnRate = -LARA_SLOW_MED_TURN_MAX;
}
else if (TrInput & IN_RIGHT)
{
lara->Control.TurnRate += LARA_TURN_RATE * 1.25f;
if (lara->Control.TurnRate > LARA_SLOW_MED_TURN_MAX)
lara->Control.TurnRate = LARA_SLOW_MED_TURN_MAX;
}
if (TrInput & (IN_LEFT | IN_RIGHT))
ModulateLaraTurnRateY(item, LARA_TURN_RATE_ACCEL * 1.25f, 0, LARA_SLOW_MED_TURN_RATE_MAX);
if (DbInput & IN_JUMP)
SetLaraSwimDiveAnimation(item);
@ -293,7 +245,7 @@ void lara_as_surface_swim_back(ItemInfo* item, CollisionInfo* coll)
if (!(TrInput & IN_BACK))
item->Animation.TargetState = LS_ONWATER_IDLE;
item->Animation.VerticalVelocity += LARA_SWIM_ACCELERATION;
item->Animation.VerticalVelocity += LARA_SWIM_VELOCITY_ACCEL;
if (item->Animation.VerticalVelocity > LARA_TREAD_VELOCITY_MAX)
item->Animation.VerticalVelocity = LARA_TREAD_VELOCITY_MAX;
}

View file

@ -14,6 +14,8 @@
#include "Specific/level.h"
#include "Specific/input.h"
using namespace TEN::Input;
// -----------------------------
// UNDERWATER SWIM
// Control & Collision Functions
@ -45,14 +47,14 @@ void lara_as_underwater_idle(ItemInfo* item, CollisionInfo* coll)
LookUpDown(item);
if (laraType == LaraType::Divesuit)
ModulateLaraSubsuitSwimTurn(item);
ModulateLaraSubsuitSwimTurnRates(item);
else
ModulateLaraSwimTurn(item, coll);
ModulateLaraSwimTurnRates(item, coll);
if (TrInput & IN_JUMP)
item->Animation.TargetState = LS_UNDERWATER_SWIM_FORWARD;
item->Animation.VerticalVelocity -= LARA_SWIM_DECELERATION;
item->Animation.VerticalVelocity -= LARA_SWIM_VELOCITY_DECEL;
if (item->Animation.VerticalVelocity < 0)
item->Animation.VerticalVelocity = 0;
@ -86,11 +88,11 @@ void lara_as_underwater_swim_forward(ItemInfo* item, CollisionInfo* coll)
}
if (laraType != LaraType::Divesuit)
ModulateLaraSwimTurn(item, coll);
ModulateLaraSwimTurnRates(item, coll);
else
ModulateLaraSubsuitSwimTurn(item);
ModulateLaraSubsuitSwimTurnRates(item);
item->Animation.VerticalVelocity += LARA_SWIM_ACCELERATION;
item->Animation.VerticalVelocity += LARA_SWIM_VELOCITY_ACCEL;
if (item->Animation.VerticalVelocity > LARA_SWIM_VELOCITY_MAX)
item->Animation.VerticalVelocity = LARA_SWIM_VELOCITY_MAX;
@ -124,14 +126,14 @@ void lara_as_underwater_inertia(ItemInfo* item, CollisionInfo* coll)
}
if (laraType != LaraType::Divesuit)
ModulateLaraSwimTurn(item, coll);
ModulateLaraSwimTurnRates(item, coll);
else
ModulateLaraSubsuitSwimTurn(item);
ModulateLaraSubsuitSwimTurnRates(item);
if (TrInput & IN_JUMP)
item->Animation.TargetState = LS_UNDERWATER_SWIM_FORWARD;
item->Animation.VerticalVelocity -= LARA_SWIM_DECELERATION;
item->Animation.VerticalVelocity -= LARA_SWIM_VELOCITY_DECEL;
if (item->Animation.VerticalVelocity < 0)
item->Animation.VerticalVelocity = 0;
@ -154,7 +156,7 @@ void lara_as_underwater_death(ItemInfo* item, CollisionInfo* coll)
lara->Control.CanLook = false;
item->Animation.VerticalVelocity -= LARA_SWIM_DECELERATION;
item->Animation.VerticalVelocity -= LARA_SWIM_VELOCITY_DECEL;
if (item->Animation.VerticalVelocity < 0)
item->Animation.VerticalVelocity = 0;

View file

@ -18,6 +18,7 @@
#include "Specific/input.h"
#include "Specific/level.h"
using namespace TEN::Input;
using namespace TEN::Renderer;
using namespace TEN::Floordata;
@ -320,6 +321,7 @@ bool TestLaraHangJump(ItemInfo* item, CollisionInfo* coll)
item->Animation.Velocity = 2;
item->Animation.VerticalVelocity = 1;
item->Animation.Airborne = true;
lara->Control.TurnRate = 0;
lara->Control.HandStatus = HandStatus::Busy;
return true;
}
@ -938,6 +940,10 @@ bool TestLaraWaterClimbOut(ItemInfo* item, CollisionInfo* coll)
if (!TestValidLedge(item, coll))
return false;
TestForObjectOnLedge(item, coll);
if (coll->HitStatic)
return false;
auto probe = GetCollision(item, coll->Setup.ForwardAngle, CLICK(2), -CLICK(1));
int headroom = probe.Position.Floor - probe.Position.Ceiling;
@ -987,6 +993,7 @@ bool TestLaraWaterClimbOut(ItemInfo* item, CollisionInfo* coll)
item->Animation.Airborne = false;
item->Animation.Velocity = 0;
item->Animation.VerticalVelocity = 0;
lara->Control.TurnRate = 0;
lara->Control.HandStatus = HandStatus::Busy;
lara->Control.WaterStatus = WaterStatus::Dry;
return true;
@ -1173,11 +1180,11 @@ bool IsRunJumpQueueableState(LaraState state)
bool IsRunJumpCountableState(LaraState state)
{
if (state == LS_RUN_FORWARD ||
state == LS_WALK_FORWARD ||
state == LS_JUMP_FORWARD ||
if (state == LS_WALK_FORWARD ||
state == LS_RUN_FORWARD ||
state == LS_SPRINT ||
state == LS_SPRINT_DIVE)
state == LS_SPRINT_DIVE ||
state == LS_JUMP_FORWARD)
{
return true;
}

View file

@ -16,6 +16,7 @@
#include "Specific/setup.h"
#include "Specific/input.h"
using namespace TEN::Input;
using namespace TEN::Math::Random;
struct PistolDef
@ -41,7 +42,7 @@ void AnimatePistols(ItemInfo* laraItem, LaraWeaponType weaponType)
auto* weapon = &Weapons[(int)weaponType];
auto* p = &PistolsTable[(int)lara->Control.Weapon.GunType];
int soundPlayed = false;
int fired = false;
if (laraItem->MeshBits)
{
@ -126,7 +127,7 @@ void AnimatePistols(ItemInfo* laraItem, LaraWeaponType weaponType)
SoundEffect(SFX_TR4_EXPLOSION1, &laraItem->Pose, SoundEnvironment::Land, 0.9f, 0.3f);
SoundEffect(weapon->SampleNum, &laraItem->Pose);
soundPlayed = true;
fired = true;
if (weaponType == LaraWeaponType::Uzi)
lara->Control.Weapon.UziRight = true;
@ -215,10 +216,11 @@ void AnimatePistols(ItemInfo* laraItem, LaraWeaponType weaponType)
lara->LeftArm.FlashGun = weapon->FlashTime;
}
if (!soundPlayed)
if (!fired)
{
SoundEffect(SFX_TR4_EXPLOSION1, &laraItem->Pose, SoundEnvironment::Land, 0.9f, 0.3f);
SoundEffect(weapon->SampleNum, &laraItem->Pose);
fired = true;
}
if (weaponType == LaraWeaponType::Uzi)
@ -265,6 +267,12 @@ void AnimatePistols(ItemInfo* laraItem, LaraWeaponType weaponType)
}
}
if (fired) // Rumble gamepad only once if any of the hands fired.
{
float power = weaponType == LaraWeaponType::Uzi ? GenerateFloat(0.1f, 0.3f) : 1.0f;
Rumble(power, 0.1f);
}
SetArmInfo(laraItem, &lara->LeftArm, frameLeft);
}

View file

@ -13,6 +13,7 @@
#include "Game/Lara/lara_helpers.h"
#include "Game/room.h"
#include "Game/savegame.h"
#include "Game/spotcam.h"
#include "Objects/Generic/Object/burning_torch.h"
#include "Sound/sound.h"
#include "Specific/input.h"
@ -20,6 +21,8 @@
#include "Specific/setup.h"
using TEN::Renderer::g_Renderer;
using namespace TEN::Input;
using namespace TEN::Entities::Generic;
using namespace TEN::Effects::Environment;
@ -28,6 +31,9 @@ constexpr auto COLL_CANCEL_THRESHOLD = SECTOR(2);
constexpr auto COLL_DISCARD_THRESHOLD = CLICK(0.5f);
constexpr auto CAMERA_RADIUS = CLICK(1);
constexpr auto THUMBCAM_VERTICAL_CONSTRAINT_ANGLE = 120.0f;
constexpr auto THUMBCAM_HORIZONTAL_CONSTRAINT_ANGLE = 80.0f;
struct OLD_CAMERA
{
short ActiveState;
@ -102,6 +108,11 @@ void AlterFOV(int value)
PhdPerspective = g_Renderer.ScreenWidth / 2 * phd_cos(CurrentFOV / 2) / phd_sin(CurrentFOV / 2);
}
inline void RumbleFromBounce()
{
Rumble(std::clamp((float)abs(Camera.bounce) / 70.0f, 0.0f, 0.8f), 0.2f);
}
void InitialiseCamera()
{
@ -206,6 +217,7 @@ void MoveCamera(GameVector* ideal, int speed)
Camera.target.y += GetRandomControl() % bounce - bounce2;
Camera.target.z += GetRandomControl() % bounce - bounce2;
Camera.bounce += 5;
RumbleFromBounce();
}
else
{
@ -425,18 +437,34 @@ void ChaseCamera(ItemInfo* item)
MoveCamera(&ideal, Camera.speed);
}
void DoThumbstickCamera()
{
if (!g_Configuration.EnableThumbstickCameraControl)
return;
if (Camera.laraNode == -1 && (Camera.target.x == OldCam.target.x &&
Camera.target.y == OldCam.target.y &&
Camera.target.z == OldCam.target.z))
{
Camera.targetAngle = ANGLE(THUMBCAM_VERTICAL_CONSTRAINT_ANGLE * AxisMap[InputAxis::CameraHorizontal]);
Camera.targetElevation = ANGLE(-10.0f + (THUMBCAM_HORIZONTAL_CONSTRAINT_ANGLE * AxisMap[InputAxis::CameraVertical]));
}
}
void UpdateCameraElevation()
{
DoThumbstickCamera();
if (Camera.laraNode != -1)
{
Vector3Int pos = { 0, 0, 0 };
auto pos = Vector3Int();
GetLaraJointPosition(&pos, Camera.laraNode);
Vector3Int pos1 = { 0, -CLICK(1), SECTOR(2) };
auto pos1 = Vector3Int(0, -CLICK(1), SECTOR(2));
GetLaraJointPosition(&pos1, Camera.laraNode);
pos.z = pos1.z - pos.z;
pos.x = pos1.x - pos.x;
pos.z = pos1.z - pos.z;
Camera.actualAngle = Camera.targetAngle + phd_atan(pos.z, pos.x);
}
else
@ -956,6 +984,7 @@ void LookCamera(ItemInfo* item)
Camera.target.y += GetRandomControl() % (-Camera.bounce) - (-Camera.bounce >> 1);
Camera.target.z += GetRandomControl() % (-Camera.bounce) - (-Camera.bounce >> 1);
Camera.bounce += 5;
RumbleFromBounce();
}
else
{
@ -1075,7 +1104,7 @@ void BinocularCamera(ItemInfo* item)
if (!LaserSight)
{
// TODO: Some of these inputs should ideally be blocked. @Sezz 2022.05.19
if (InputBusy & (IN_DESELECT | IN_LOOK | IN_DRAW | IN_FLARE | IN_WALK | IN_JUMP))
if (RawInput & (IN_DESELECT | IN_OPTION | IN_LOOK | IN_DRAW | IN_FLARE | IN_WALK | IN_JUMP))
{
item->MeshBits = ALL_JOINT_BITS;
lara->Inventory.IsBusy = false;
@ -1150,6 +1179,7 @@ void BinocularCamera(ItemInfo* item)
Camera.target.y += (CLICK(0.25f) / 4) * (GetRandomControl() % (-Camera.bounce) - (-Camera.bounce >> 1));
Camera.target.z += (CLICK(0.25f) / 4) * (GetRandomControl() % (-Camera.bounce) - (-Camera.bounce >> 1));
Camera.bounce += 5;
RumbleFromBounce();
}
else
{
@ -1179,7 +1209,7 @@ void BinocularCamera(ItemInfo* item)
int range = 0;
int flags = 0;
if (!(InputBusy & IN_WALK))
if (!(RawInput & IN_WALK))
{
range = 64;
flags = 0x10000;
@ -1190,7 +1220,7 @@ void BinocularCamera(ItemInfo* item)
flags = 0x8000;
}
if (InputBusy & IN_SPRINT)
if (RawInput & IN_SPRINT)
{
BinocularRange -= range;
if (BinocularRange < ANGLE(0.7f))
@ -1198,7 +1228,7 @@ void BinocularCamera(ItemInfo* item)
else
SoundEffect(SFX_TR4_BINOCULARS_ZOOM, nullptr, SoundEnvironment::Land, 0.9f);
}
else if (InputBusy & IN_CROUCH)
else if (RawInput & IN_CROUCH)
{
BinocularRange += range;
if (BinocularRange > ANGLE(8.5f))
@ -1215,10 +1245,10 @@ void BinocularCamera(ItemInfo* item)
bool firing = false;
auto& ammo = GetAmmo(item, lara->Control.Weapon.GunType);
if (!(InputBusy & IN_ACTION) ||
if (!(RawInput & IN_ACTION) ||
WeaponDelay || !ammo)
{
if (!(InputBusy & IN_ACTION))
if (!(RawInput & IN_ACTION))
{
LSHKShotsFired = 0;
Camera.bounce = 0;
@ -1256,6 +1286,8 @@ void BinocularCamera(ItemInfo* item)
SoundEffect(SFX_TR4_EXPLOSION1, nullptr, SoundEnvironment::Land, 1.0f, 0.4f);
SoundEffect(SFX_TR4_HK_FIRE, nullptr);
}
Camera.bounce = -16 - (GetRandomControl() & 0x1F);
}
else if (lara->Weapons[(int)LaraWeaponType::HK].SelectedAmmo == WeaponAmmoType::Ammo2)
{
@ -1277,6 +1309,8 @@ void BinocularCamera(ItemInfo* item)
SoundEffect(SFX_TR4_EXPLOSION1, nullptr, SoundEnvironment::Land, 1.0f, 0.4f);
SoundEffect(SFX_TR4_HK_FIRE, nullptr);
}
Camera.bounce = -16 - (GetRandomControl() & 0x1F);
}
else
{
@ -1289,6 +1323,8 @@ void BinocularCamera(ItemInfo* item)
SoundEffect(SFX_TR4_EXPLOSION1, nullptr, SoundEnvironment::Land, 1.0f, 0.4f);
SoundEffect(SFX_TR4_HK_FIRE, nullptr);
}
Camera.bounce = -16 - (GetRandomControl() & 0x1F);
}
}
else
@ -1316,8 +1352,6 @@ void BinocularCamera(ItemInfo* item)
SoundEffect(SFX_TR4_HK_FIRE, nullptr);
}
}
Camera.bounce = -16 - (GetRandomControl() & 0x1F);
}
if (!ammo.hasInfinite())
@ -1331,7 +1365,7 @@ void BinocularCamera(ItemInfo* item)
{
GetTargetOnLOS(&Camera.pos, &Camera.target, false, false);
if (!(InputBusy & IN_ACTION))
if (!(RawInput & IN_ACTION))
{
// Reimplement this mode?
}
@ -2032,3 +2066,58 @@ void UpdateFadeScreenAndCinematicBars()
}
}
}
void HandleOptics()
{
if (!(TrInput & IN_LOOK) || UseSpotCam || TrackCameraInit ||
((LaraItem->Animation.ActiveState != LS_IDLE || LaraItem->Animation.AnimNumber != LA_STAND_IDLE) &&
(!Lara.Control.IsLow || TrInput & IN_CROUCH || LaraItem->Animation.TargetState != LS_CROUCH_IDLE || LaraItem->Animation.AnimNumber != LA_CROUCH_IDLE)))
{
if (BinocularRange == 0)
{
if (UseSpotCam || TrackCameraInit)
TrInput &= ~IN_LOOK;
}
else
{
// If any input but optic controls (directions + action), immediately exit binoculars mode.
if (TrInput != IN_NONE && ((TrInput & ~IN_OPTIC_CONTROLS) != IN_NONE))
BinocularRange = 0;
if (LaserSight)
{
BinocularRange = 0;
BinocularOn = false;
LaserSight = false;
Camera.type = BinocularOldCamera;
Camera.bounce = 0;
AlterFOV(ANGLE(80.0f));
LaraItem->MeshBits = ALL_JOINT_BITS;
Lara.Inventory.IsBusy = false;
ResetLaraFlex(LaraItem);
TrInput &= ~IN_LOOK;
}
else
{
TrInput |= IN_LOOK;
DbInput = 0;
}
}
}
else if (BinocularRange == 0)
{
if (Lara.Control.HandStatus == HandStatus::WeaponReady &&
((Lara.Control.Weapon.GunType == LaraWeaponType::Revolver && Lara.Weapons[(int)LaraWeaponType::Revolver].HasLasersight) ||
Lara.Control.Weapon.GunType == LaraWeaponType::HK ||
(Lara.Control.Weapon.GunType == LaraWeaponType::Crossbow && Lara.Weapons[(int)LaraWeaponType::Crossbow].HasLasersight)))
{
BinocularRange = 128;
BinocularOldCamera = Camera.oldType;
BinocularOn = true;
LaserSight = true;
Lara.Inventory.IsBusy = true;
}
}
}

View file

@ -48,9 +48,6 @@ enum CAMERA_FLAGS
CF_CHASE_OBJECT = 3,
};
constexpr auto MAX_CAMERA = 18;
constexpr auto NO_MINY = 0xFFFFFF;
constexpr auto FADE_SCREEN_SPEED = 16.0f / 255.0f;
extern Vector3Int CurrentCameraPosition;
@ -101,3 +98,4 @@ void SetScreenFadeOut(float speed);
void SetScreenFadeIn(float speed);
void SetCinematicBars(float height, float speed);
void UpdateFadeScreenAndCinematicBars();
void HandleOptics();

View file

@ -727,15 +727,7 @@ bool ItemPushItem(ItemInfo* item, ItemInfo* item2, CollisionInfo* coll, bool spa
dz -= cosY * rz - sinY * rx;
lara->HitDirection = (item2->Pose.Orientation.y - phd_atan(dz, dz) - ANGLE(135.0f)) / ANGLE(90.0f);
if (!lara->HitFrame && !lara->SpasmEffectCount)
{
SoundEffect(SFX_TR4_LARA_INJURY, &item2->Pose);
lara->SpasmEffectCount = GenerateInt(15, 35);
}
if (lara->SpasmEffectCount)
lara->SpasmEffectCount--;
DoDamage(item2, 0); // Dummy hurt call. Only for ooh sound!
lara->HitFrame++;
if (lara->HitFrame > 34)

View file

@ -67,6 +67,7 @@ using namespace TEN::Entities::TR4;
using namespace TEN::Renderer;
using namespace TEN::Math::Random;
using namespace TEN::Floordata;
using namespace TEN::Input;
int GameTimer = 0;
int GlobalCounter = 0;
@ -113,8 +114,6 @@ GameStatus ControlPhase(int numFrames, int demoMode)
if (TrackCameraInit)
UseSpotCam = false;
SetDebounce = true;
g_GameStringsHandler->ProcessDisplayStrings(DELTA_TIME);
static int framesCount = 0;
@ -129,10 +128,7 @@ GameStatus ControlPhase(int numFrames, int demoMode)
// Poll the keyboard and update input variables
if (CurrentLevel != 0)
{
if (S_UpdateInput() == -1)
return GameStatus::None;
}
UpdateInput();
// Has Lara control been disabled?
if (Lara.Control.Locked || CurrentLevel == 0)
@ -142,14 +138,13 @@ GameStatus ControlPhase(int numFrames, int demoMode)
TrInput &= IN_LOOK;
}
// Does the player want to enter inventory?
SetDebounce = false;
if (CurrentLevel != 0)
{
// Does the player want to enter inventory?
if (TrInput & IN_SAVE && LaraItem->HitPoints > 0 && g_Gui.GetInventoryMode() != InventoryMode::Save)
{
StopAllSounds();
StopRumble();
g_Gui.SetInventoryMode(InventoryMode::Save);
@ -159,6 +154,7 @@ GameStatus ControlPhase(int numFrames, int demoMode)
else if (TrInput & IN_LOAD && g_Gui.GetInventoryMode() != InventoryMode::Load)
{
StopAllSounds();
StopRumble();
g_Gui.SetInventoryMode(InventoryMode::Load);
@ -168,16 +164,18 @@ GameStatus ControlPhase(int numFrames, int demoMode)
else if (TrInput & IN_PAUSE && g_Gui.GetInventoryMode() != InventoryMode::Pause && LaraItem->HitPoints > 0)
{
StopAllSounds();
StopRumble();
g_Renderer.DumpGameScene();
g_Gui.SetInventoryMode(InventoryMode::Pause);
g_Gui.SetMenuToDisplay(Menu::Pause);
g_Gui.SetSelectedOption(0);
}
else if ((DbInput & IN_DESELECT || g_Gui.GetEnterInventory() != NO_ITEM) &&
else if ((DbInput & IN_OPTION || g_Gui.GetEnterInventory() != NO_ITEM) &&
LaraItem->HitPoints > 0 && !BinocularOn)
{
// Stop all sounds
StopAllSounds();
StopRumble();
if (g_Gui.CallInventory(true))
return GameStatus::LoadGame;
@ -216,59 +214,7 @@ GameStatus ControlPhase(int numFrames, int demoMode)
// Handle lasersight and binocular
if (CurrentLevel != 0)
{
if (!(TrInput & IN_LOOK) || UseSpotCam || TrackCameraInit ||
((LaraItem->Animation.ActiveState != LS_IDLE || LaraItem->Animation.AnimNumber != LA_STAND_IDLE) &&
(!Lara.Control.IsLow || TrInput & IN_CROUCH || LaraItem->Animation.TargetState != LS_CROUCH_IDLE || LaraItem->Animation.AnimNumber != LA_CROUCH_IDLE)))
{
if (BinocularRange == 0)
{
if (UseSpotCam || TrackCameraInit)
TrInput &= ~IN_LOOK;
}
else
{
// If any input but optic controls (directions + action), immediately exit binoculars mode.
if (TrInput != IN_NONE && ((TrInput & ~IN_OPTIC_CONTROLS) != IN_NONE))
BinocularRange = 0;
if (LaserSight)
{
BinocularRange = 0;
BinocularOn = false;
LaserSight = false;
Camera.type = BinocularOldCamera;
Camera.bounce = 0;
AlterFOV(ANGLE(80.0f));
LaraItem->MeshBits = ALL_JOINT_BITS;
Lara.Inventory.IsBusy = false;
ResetLaraFlex(LaraItem);
TrInput &= ~IN_LOOK;
}
else
{
TrInput |= IN_LOOK;
DbInput = 0;
}
}
}
else if (BinocularRange == 0)
{
if (Lara.Control.HandStatus == HandStatus::WeaponReady &&
((Lara.Control.Weapon.GunType == LaraWeaponType::Revolver && Lara.Weapons[(int)LaraWeaponType::Revolver].HasLasersight) ||
Lara.Control.Weapon.GunType == LaraWeaponType::HK ||
(Lara.Control.Weapon.GunType == LaraWeaponType::Crossbow && Lara.Weapons[(int)LaraWeaponType::Crossbow].HasLasersight)))
{
BinocularRange = 128;
BinocularOldCamera = Camera.oldType;
BinocularOn = true;
LaserSight = true;
Lara.Inventory.IsBusy = true;
}
}
}
HandleOptics();
// Update all items
InItemControlLoop = true;
@ -463,9 +409,6 @@ GameStatus DoTitle(int index, std::string const& ambient)
{
TENLog("DoTitle", LogLevel::Info);
// Reset all the globals for the game which needs this
CleanUp();
// Load the level
LoadLevelFile(index);
@ -477,7 +420,6 @@ GameStatus DoTitle(int index, std::string const& ambient)
InitialiseFXArray(true);
InitialisePickupDisplay();
InitialiseCamera();
StopAllSounds();
g_GameScript->ResetScripts(true);
@ -512,7 +454,7 @@ GameStatus DoTitle(int index, std::string const& ambient)
// Play background music
// MERGE: PlaySoundTrack(index);
// Initialize menu
// Initialise menu
g_Gui.SetMenuToDisplay(Menu::Title);
g_Gui.SetSelectedOption(0);
@ -534,9 +476,7 @@ GameStatus DoTitle(int index, std::string const& ambient)
{
g_Renderer.RenderTitle();
SetDebounce = true;
S_UpdateInput();
SetDebounce = false;
UpdateInput();
status = g_Gui.TitleOptions();
@ -576,9 +516,6 @@ GameStatus DoTitle(int index, std::string const& ambient)
GameStatus DoLevel(int index, std::string const& ambient, bool loadFromSavegame)
{
// Reset all the globals for the game which needs this
CleanUp();
// Load the level
LoadLevelFile(index);
@ -586,7 +523,6 @@ GameStatus DoLevel(int index, std::string const& ambient, bool loadFromSavegame)
InitialiseFXArray(true);
InitialisePickupDisplay();
InitialiseCamera();
StopAllSounds();
g_GameScript->ResetScripts(loadFromSavegame);
@ -681,6 +617,7 @@ GameStatus DoLevel(int index, std::string const& ambient, bool loadFromSavegame)
// Here is the only way for exiting from the loop
StopAllSounds();
StopSoundTracks();
StopRumble();
return result;
}

View file

@ -398,8 +398,6 @@ bool DoRayBox(GameVector* start, GameVector* end, BOUNDING_BOX* box, PHD_3DPOS*
int sp = -2;
float minDistance = std::numeric_limits<float>::max();
int action = TrInput & IN_ACTION;
if (closesItemNumber < 0)
{
// Static meshes don't require further tests

View file

@ -25,7 +25,6 @@ struct BUBBLE_STRUCT
int age;
bool active;
};
extern std::vector<BUBBLE_STRUCT> Bubbles;
void DisableBubbles();

View file

@ -89,9 +89,7 @@ void TriggerChaffEffects(ItemInfo* item, Vector3Int* pos, Vector3Int* vel, int s
TriggerChaffSparkles(pos, vel, &color, age, item);
if (isUnderwater)
{
TriggerChaffBubbles(pos, item->RoomNumber);
}
else
{
Vector3 position = Vector3(pos->x,pos->y,pos->z);
@ -105,7 +103,6 @@ void TriggerChaffEffects(ItemInfo* item, Vector3Int* pos, Vector3Int* vel, int s
SoundEffect(cond ? SFX_TR4_FLARE_BURN_UNDERWATER : SFX_TR4_FLARE_BURN_DRY, & item->Pose, cond ? SoundEnvironment::Water : SoundEnvironment::Always, 1.0f, 0.5f);
}
void TriggerChaffSparkles(Vector3Int* pos, Vector3Int* vel, CVECTOR* color, int age, ItemInfo* item)
{
/*
@ -145,7 +142,6 @@ void TriggerChaffSparkles(Vector3Int* pos, Vector3Int* vel, CVECTOR* color, int
TEN::Effects::Spark::TriggerFlareSparkParticles(pos, vel,color,item->RoomNumber);
}
void TriggerChaffSmoke(Vector3Int* pos, Vector3Int* vel, int speed, bool moving, bool wind)
{
SMOKE_SPARKS* smoke;
@ -201,9 +197,7 @@ void TriggerChaffSmoke(Vector3Int* pos, Vector3Int* vel, int speed, bool moving,
smoke->rotAdd = (GetRandomControl() & 7) + 24;
}
else
{
smoke->flags = SP_EXPDEF | SP_DEF | SP_SCALE;
}
if (wind)
smoke->flags |= SP_WIND;
@ -216,11 +210,10 @@ void TriggerChaffSmoke(Vector3Int* pos, Vector3Int* vel, int speed, bool moving,
smoke->size = smoke->dSize = size;
}
void TriggerChaffBubbles(Vector3Int* pos, int FlareRoomNumber)
{
auto& bubble = Bubbles[GetFreeBubble()];
BUBBLE_STRUCT& bubble = Bubbles[GetFreeBubble()];
bubble = {};
bubble.active = true;
bubble.size = 0;
@ -240,4 +233,4 @@ void TriggerChaffBubbles(Vector3Int* pos, int FlareRoomNumber)
bubble.wavePeriod = Vector3(GenerateFloat(-3.14, 3.14), GenerateFloat(-3.14, 3.14), GenerateFloat(-3.14, 3.14));
bubble.waveSpeed = Vector3(1 / GenerateFloat(8, 16), 1 / GenerateFloat(8, 16), 1 / GenerateFloat(8, 16));
bubble.roomNumber = FlareRoomNumber;
}
}

View file

@ -17,4 +17,4 @@ void TriggerChaffBubbles(Vector3Int* pos, int FlareRoomNumber);
/* void TriggerChaffEffects(ItemInfo* item, PHD_3DPOS pos, short angle, int speed, bool underwater);
void TriggerChaffSparkles(PHD_3DPOS pos, short angle, int speed);
void TriggerChaffSmoke(PHD_3DPOS pos, short angle, int speed, bool moving);
void TriggerChaffBubbles(PHD_3DPOS pos, int FlareRoomNumber); */
void TriggerChaffBubbles(PHD_3DPOS pos, int FlareRoomNumber); */

View file

@ -15,11 +15,7 @@
using namespace TEN::Effects::Environment;
using namespace TEN::Math::Random;
namespace TEN
{
namespace Effects
{
namespace Drip
namespace TEN::Effects::Drip
{
using namespace DirectX::SimpleMath;
@ -36,11 +32,12 @@ namespace Drip
{
for (int i = 0; i < dripParticles.size(); i++)
{
DripParticle& d = dripParticles[i];
if (!d.active) continue;
auto& d = dripParticles[i];
if (!d.active)
continue;
d.age++;
if (d.age > d.life)
d.active = false;
@ -85,7 +82,7 @@ namespace Drip
void SpawnWetnessDrip(Vector3 const & pos, int room)
{
DripParticle& d = getFreeDrip();
auto& d = getFreeDrip();
d = {};
d.active = true;
d.pos = pos;
@ -131,4 +128,4 @@ namespace Drip
drip.active = true;
}
}
}}}
}

View file

@ -3,31 +3,31 @@
#include <d3d11.h>
#include <SimpleMath.h>
namespace TEN {
namespace Effects {
namespace Drip {
constexpr float DRIP_LIFE = 25.0f;
constexpr float DRIP_LIFE_LONG = 120.0f;
constexpr float DRIP_WIDTH = 4;
constexpr int NUM_DRIPS = 512;
struct DripParticle {
DirectX::SimpleMath::Vector3 pos;
DirectX::SimpleMath::Vector3 velocity;
DirectX::SimpleMath::Vector4 color;
int room;
float gravity;
float life;
float age;
float height;
bool active;
};
extern std::array<DripParticle, NUM_DRIPS> dripParticles;
void UpdateDripParticles();
void DisableDripParticles();
DripParticle& getFreeDrip();
void SpawnWetnessDrip(DirectX::SimpleMath::Vector3 pos, int room);
void SpawnSplashDrips(Vector3 const & pos, int num, int room);
void SpawnGunshellDrips(Vector3 const & pos, int room);
}
}
}
namespace TEN::Effects::Drip
{
constexpr float DRIP_LIFE = 25.0f;
constexpr float DRIP_LIFE_LONG = 120.0f;
constexpr float DRIP_WIDTH = 4;
constexpr int NUM_DRIPS = 512;
struct DripParticle
{
Vector3 pos;
Vector3 velocity;
Vector4 color;
int room;
float gravity;
float life;
float age;
float height;
bool active;
};
extern std::array<DripParticle, NUM_DRIPS> dripParticles;
void UpdateDripParticles();
void DisableDripParticles();
DripParticle& getFreeDrip();
void SpawnWetnessDrip(Vector3 pos, int room);
void SpawnSplashDrips(Vector3 const& pos, int num, int room);
void SpawnGunshellDrips(Vector3 const& pos, int room);
}

View file

@ -9,80 +9,94 @@
#include "Specific/trmath.h"
using namespace TEN::Math::Random;
namespace TEN {
namespace Effects {
namespace Explosion {
using namespace DirectX::SimpleMath;
using namespace TEN::Effects::Spark;
std::array<ExplosionParticle, 64> explosionParticles;
constexpr float PARTICLE_DISTANCE = 512;
void TriggerExplosion(Vector3 const& pos, float size, bool triggerSparks, bool triggerSmoke, bool triggerShockwave, int room)
{
SpawnExplosionParticle(pos);
for (int i = 0; i < 3; i++) {
Vector3 particlePos = pos + Vector3(GenerateFloat(-size / 2, size / 2), GenerateFloat(-size / 2, size / 2), GenerateFloat(-size / 2, size / 2));
SpawnExplosionParticle(particlePos);
}
if (triggerSparks) {
Vector3Int sparkPos;
sparkPos.x = pos.x;
sparkPos.y = pos.y;
sparkPos.z = pos.z;
//TriggerExplosionSparks(&sparkPos, room); @TODO
}
if (triggerShockwave) {
PHD_3DPOS shockPos;
shockPos.Position.x = pos.x;
shockPos.Position.y = pos.y;
shockPos.Position.z = pos.z;
TriggerShockwave(&shockPos, 0, size, 64, 32, 32, 32, 30, rand() & 0xFFFF, 0);
}
}
void UpdateExplosionParticles()
{
for (int i = 0; i < explosionParticles.size(); i++) {
ExplosionParticle& e = explosionParticles[i];
if (!e.active) continue;
e.age++;
if (e.age > e.life) {
e.active = false;
continue;
};
e.vel *= 0.98f;
e.pos += e.vel;
e.angularVel *= 0.98f;
e.rotation += e.angularVel;
int numSprites = -Objects[ID_EXPLOSION_SPRITES].nmeshes - 1;
float normalizedAge = e.age / e.life;
e.sprite = lerp(0, numSprites, normalizedAge);
e.tint = Vector4::Lerp(Vector4(2, 2, 2, 1), Vector4(0, 0, 0, 0), normalizedAge);
}
}
ExplosionParticle& getFreeExplosionParticle()
{
for (int i = 0; i < explosionParticles.size(); i++)
{
if (!explosionParticles[i].active) {
return explosionParticles[i];
}
}
return explosionParticles[0];
}
void SpawnExplosionParticle(Vector3 const & pos)
{
ExplosionParticle& e = getFreeExplosionParticle();
e = {};
e.pos = pos;
const float maxVel = 10;
e.vel = Vector3(GenerateFloat(-maxVel / 2, maxVel / 2), GenerateFloat(-maxVel / 2, maxVel / 2), GenerateFloat(-maxVel / 2, maxVel / 2));
e.active = true;
e.tint = Vector4(1, 1, 1, 1);
e.life = GenerateFloat(60, 90);
e.size = GenerateFloat(512, 768);
e.angularVel = GenerateFloat(-RADIAN, RADIAN);
e.rotation = GenerateFloat(-0.05, 0.05);
}
namespace TEN::Effects::Explosion
{
using namespace DirectX::SimpleMath;
using namespace TEN::Effects::Spark;
std::array<ExplosionParticle, 64> explosionParticles;
constexpr float PARTICLE_DISTANCE = 512;
void TriggerExplosion(Vector3 const& pos, float size, bool triggerSparks, bool triggerSmoke, bool triggerShockwave, int room)
{
SpawnExplosionParticle(pos);
for (int i = 0; i < 3; i++)
{
Vector3 particlePos = pos + Vector3(GenerateFloat(-size / 2, size / 2), GenerateFloat(-size / 2, size / 2), GenerateFloat(-size / 2, size / 2));
SpawnExplosionParticle(particlePos);
}
if (triggerSparks)
{
Vector3Int sparkPos;
sparkPos.x = pos.x;
sparkPos.y = pos.y;
sparkPos.z = pos.z;
//TriggerExplosionSparks(&sparkPos, room); @TODO
}
if (triggerShockwave)
{
PHD_3DPOS shockPos;
shockPos.Position.x = pos.x;
shockPos.Position.y = pos.y;
shockPos.Position.z = pos.z;
TriggerShockwave(&shockPos, 0, size, 64, 32, 32, 32, 30, rand() & 0xFFFF, 0);
}
}
}
void UpdateExplosionParticles()
{
for (int i = 0; i < explosionParticles.size(); i++)
{
auto& e = explosionParticles[i];
if (!e.active)
continue;
e.age++;
if (e.age > e.life)
{
e.active = false;
continue;
};
e.vel *= 0.98f;
e.pos += e.vel;
e.angularVel *= 0.98f;
e.rotation += e.angularVel;
int numSprites = -Objects[ID_EXPLOSION_SPRITES].nmeshes - 1;
float normalizedAge = e.age / e.life;
e.sprite = lerp(0, numSprites, normalizedAge);
e.tint = Vector4::Lerp(Vector4(2, 2, 2, 1), Vector4(0, 0, 0, 0), normalizedAge);
}
}
ExplosionParticle& getFreeExplosionParticle()
{
for (int i = 0; i < explosionParticles.size(); i++)
{
if (!explosionParticles[i].active)
return explosionParticles[i];
}
return explosionParticles[0];
}
void SpawnExplosionParticle(Vector3 const & pos)
{
auto& e = getFreeExplosionParticle();
e = {};
e.pos = pos;
const float maxVel = 10;
e.vel = Vector3(GenerateFloat(-maxVel / 2, maxVel / 2), GenerateFloat(-maxVel / 2, maxVel / 2), GenerateFloat(-maxVel / 2, maxVel / 2));
e.active = true;
e.tint = Vector4(1, 1, 1, 1);
e.life = GenerateFloat(60, 90);
e.size = GenerateFloat(512, 768);
e.angularVel = GenerateFloat(-RADIAN, RADIAN);
e.rotation = GenerateFloat(-0.05, 0.05);
}
}

View file

@ -3,27 +3,26 @@
#include <d3d11.h>
#include <SimpleMath.h>
namespace TEN {
namespace Effects {
namespace Explosion {
struct ExplosionParticle {
DirectX::SimpleMath::Vector3 pos;
DirectX::SimpleMath::Vector3 vel;
DirectX::SimpleMath::Vector4 tint;
float size;
float rotation;
float angularVel;
float age;
float life;
int room;
int sprite;
bool active;
};
extern std::array<ExplosionParticle, 64> explosionParticles;
void TriggerExplosion(DirectX::SimpleMath::Vector3 const & pos, float size, bool triggerSparks, bool triggerSmoke, bool triggerShockwave, int room);
void UpdateExplosionParticles();
ExplosionParticle& getFreeExplosionParticle();
void SpawnExplosionParticle(DirectX::SimpleMath::Vector3 const & pos);
}
}
}
namespace TEN::Effects::Explosion
{
struct ExplosionParticle
{
Vector3 pos;
Vector3 vel;
Vector4 tint;
float size;
float rotation;
float angularVel;
float age;
float life;
int room;
int sprite;
bool active;
};
extern std::array<ExplosionParticle, 64> explosionParticles;
void TriggerExplosion(Vector3 const& pos, float size, bool triggerSparks, bool triggerSmoke, bool triggerShockwave, int room);
void UpdateExplosionParticles();
ExplosionParticle& getFreeExplosionParticle();
void SpawnExplosionParticle(Vector3 const& pos);
}

View file

@ -9,10 +9,8 @@
#include "Sound/sound.h"
#include "Specific/level.h"
namespace TEN {
namespace Effects {
namespace Footprints {
namespace TEN::Effects::Footprints
{
std::deque<FOOTPRINT_STRUCT> footprints = std::deque<FOOTPRINT_STRUCT>();
bool CheckFootOnFloor(ItemInfo const & item, int mesh, Vector3& outFootprintPosition)
@ -260,5 +258,3 @@ namespace Footprints {
}
}
}
}
}

View file

@ -4,12 +4,11 @@
struct ItemInfo;
namespace TEN{
namespace Effects {
namespace Footprints {
namespace TEN::Effects::Footprints
{
constexpr size_t MAX_FOOTPRINTS = 20;
constexpr auto FOOTPRINT_SIZE = 64.0f;
constexpr int FOOT_HEIGHT_OFFSET = 64;
struct FOOTPRINT_STRUCT
{
@ -21,12 +20,9 @@ namespace Footprints {
float Opacity;
bool Active;
};
extern std::deque<FOOTPRINT_STRUCT> footprints;
constexpr int FOOT_HEIGHT_OFFSET = 64;
bool CheckFootOnFloor(ItemInfo const & item, int mesh, Vector3& outFootprintPosition);
void AddFootprint(ItemInfo* item, bool rightFoot);
void UpdateFootprints();
}}}
}

View file

@ -24,13 +24,13 @@ void InitialiseHair()
{
int* bone = &g_Level.Bones[Objects[ID_LARA_HAIR].boneIndex];
Hairs[h][0].initialized = true;
Hairs[h][0].initialised = true;
Hairs[h][0].pos.Orientation.y = 0;
Hairs[h][0].pos.Orientation.x = -0x4000;
for (int i = 1; i < HAIR_SEGMENTS + 1; i++, bone += 4)
{
Hairs[h][i].initialized = true;
Hairs[h][i].initialised = true;
Hairs[h][i].pos.Position.x = *(bone + 1);
Hairs[h][i].pos.Position.y = *(bone + 2);
Hairs[h][i].pos.Position.z = *(bone + 3);
@ -182,9 +182,9 @@ void HairControl(ItemInfo* item, int ponytail, ANIM_FRAME* framePtr)
int* bone = &g_Level.Bones[Objects[ID_LARA_HAIR].boneIndex];
if (Hairs[ponytail][0].initialized)
if (Hairs[ponytail][0].initialised)
{
Hairs[ponytail][0].initialized = false;
Hairs[ponytail][0].initialised = false;
Hairs[ponytail][0].pos.Position.x = pos.x;
Hairs[ponytail][0].pos.Position.y = pos.y;
Hairs[ponytail][0].pos.Position.z = pos.z;
@ -195,7 +195,7 @@ void HairControl(ItemInfo* item, int ponytail, ANIM_FRAME* framePtr)
world = Matrix::CreateFromYawPitchRoll(TO_RAD(Hairs[ponytail][i].pos.Orientation.y), TO_RAD(Hairs[ponytail][i].pos.Orientation.x), 0) * world;
world = Matrix::CreateTranslation(*(bone + 1), *(bone + 2), *(bone + 3)) * world;
Hairs[ponytail][i + 1].initialized = false;
Hairs[ponytail][i + 1].initialised = false;
Hairs[ponytail][i + 1].pos.Position.x = world.Translation().x;
Hairs[ponytail][i + 1].pos.Position.y = world.Translation().y;
Hairs[ponytail][i + 1].pos.Position.z = world.Translation().z;

View file

@ -14,7 +14,7 @@ struct HAIR_STRUCT
Vector3Int hvel;
Vector3Int unknown;
bool initialized = false;
bool initialised = false;
};
extern HAIR_STRUCT Hairs[HAIR_MAX][HAIR_SEGMENTS + 1];

View file

@ -7,4 +7,4 @@ namespace TEN::Effects::Lara
void LaraBurn(ItemInfo* item);
void LavaBurn(ItemInfo* item);
void LaraBreath(ItemInfo* item);
}
}

View file

@ -43,14 +43,13 @@ namespace TEN::Effects::Lightning
int type;
int sLife;
};
extern std::vector<LIGHTNING_INFO> Lightning;
extern int LightningRandomSeed;
extern float FloatSinCosTable[8192];
extern Vector3Int LightningPos[6];
extern short LightningBuffer[1024];
extern std::vector<LIGHTNING_INFO> Lightning;
void InitialiseFloatSinCosTable();
void UpdateLightning();
void TriggerLightning(Vector3Int* src, Vector3Int* dest, char amplitude, byte r, byte g, byte b, byte life, char flags, char width, char segments);

View file

@ -6,8 +6,11 @@
#include "Objects\objectslist.h"
struct ItemInfo;
namespace TEN::Effects{
struct SimpleParticle {
namespace TEN::Effects
{
struct SimpleParticle
{
DirectX::SimpleMath::Vector3 worldPosition;
float size;
float age;
@ -24,4 +27,4 @@ namespace TEN::Effects{
void TriggerSnowmobileSnow(ItemInfo* snowMobile);
void TriggerSpeedboatFoam(ItemInfo* boat, Vector3 offset);
void updateSimpleParticles();
}
}

View file

@ -16,252 +16,246 @@
using namespace TEN::Effects::Environment;
using namespace TEN::Math::Random;
namespace TEN
namespace TEN::Effects::Smoke
{
namespace Effects
std::array<SmokeParticle, 128> SmokeParticles;
auto& GetFreeSmokeParticle()
{
namespace Smoke
for (int i = 0; i < SmokeParticles.size(); i++)
{
std::array<SmokeParticle, 128> SmokeParticles;
if (!SmokeParticles[i].active)
return SmokeParticles[i];
}
auto& GetFreeSmokeParticle()
return SmokeParticles[0];
}
void DisableSmokeParticles()
{
for (int i = 0; i < SmokeParticles.size(); i++)
SmokeParticles[i].active = false;
}
void UpdateSmokeParticles()
{
for (int i = 0; i < SmokeParticles.size(); i++)
{
auto& s = SmokeParticles[i];
if (!s.active)
continue;
s.age += 1;
if (s.age > s.life)
{
for (int i = 0; i < SmokeParticles.size(); i++)
{
if (!SmokeParticles[i].active)
return SmokeParticles[i];
}
return SmokeParticles[0];
s.active = false;
continue;
}
void DisableSmokeParticles()
s.velocity.y += s.gravity;
if (s.terminalVelocity != 0)
{
for (int i = 0; i < SmokeParticles.size(); i++)
SmokeParticles[i].active = false;
float velocityLength = s.velocity.Length();
if (velocityLength > s.terminalVelocity)
s.velocity *= (s.terminalVelocity / velocityLength);
}
void UpdateSmokeParticles()
s.position += s.velocity;
if (s.affectedByWind)
{
for (int i = 0; i < SmokeParticles.size(); i++)
if (TestEnvironment(ENV_FLAG_WIND, s.room))
{
auto& s = SmokeParticles[i];
if (!s.active)
continue;
s.age += 1;
if (s.age > s.life)
{
s.active = false;
continue;
}
s.velocity.y += s.gravity;
if (s.terminalVelocity != 0)
{
float velocityLength = s.velocity.Length();
if (velocityLength > s.terminalVelocity)
s.velocity *= (s.terminalVelocity / velocityLength);
}
s.position += s.velocity;
if (s.affectedByWind)
{
if (TestEnvironment(ENV_FLAG_WIND, s.room))
{
s.position.x += Weather.Wind().x;
s.position.z += Weather.Wind().z;
}
}
float normalizedLife = std::clamp(s.age / s.life,0.0f,1.0f);
s.size = lerp(s.sourceSize, s.destinationSize, normalizedLife);
s.angularVelocity *= s.angularDrag;
s.rotation += s.angularVelocity;
s.color = DirectX::SimpleMath::Vector4::Lerp(s.sourceColor, s.destinationColor, normalizedLife);
int numSprites = -Objects[ID_SMOKE_SPRITES].nmeshes;
s.sprite = lerp(0, numSprites - 1, normalizedLife);
s.position.x += Weather.Wind().x;
s.position.z += Weather.Wind().z;
}
}
void TriggerFlareSmoke(const DirectX::SimpleMath::Vector3& pos, DirectX::SimpleMath::Vector3& direction, int life, int room)
float normalizedLife = std::clamp(s.age / s.life,0.0f,1.0f);
s.size = lerp(s.sourceSize, s.destinationSize, normalizedLife);
s.angularVelocity *= s.angularDrag;
s.rotation += s.angularVelocity;
s.color = DirectX::SimpleMath::Vector4::Lerp(s.sourceColor, s.destinationColor, normalizedLife);
int numSprites = -Objects[ID_SMOKE_SPRITES].nmeshes;
s.sprite = lerp(0, numSprites - 1, normalizedLife);
}
}
void TriggerFlareSmoke(const DirectX::SimpleMath::Vector3& pos, DirectX::SimpleMath::Vector3& direction, int life, int room)
{
using namespace DirectX::SimpleMath;
auto& s = GetFreeSmokeParticle();
s = {};
s.position = pos;
s.age = 0;
constexpr float d = 0.2f;
Vector3 randomDir = Vector3(GenerateFloat(-d, d), GenerateFloat(-d, d), GenerateFloat(-d, d));
Vector3 direction2;
(direction + randomDir).Normalize(direction2);
s.velocity = direction2 * GenerateFloat(7, 9);
s.gravity = -0.2f;
s.friction = GenerateFloat(0.7f, 0.85f);
s.sourceColor = Vector4(1, 131 / 255.0f, 100 / 255.0f, 1);
s.destinationColor = Vector4(1, 1, 1, 0);
s.life = GenerateFloat(25, 35);
s.angularVelocity = GenerateFloat(-0.3f, 0.3f);
s.angularDrag = 0.97f;
s.sourceSize = life > 4 ? GenerateFloat(16, 24) : GenerateFloat(100, 128);
s.destinationSize = life > 4 ? GenerateFloat(160, 200) : GenerateFloat(256, 300);
s.affectedByWind = true;
s.active = true;
s.room = room;
}
//TODO: add additional "Weapon Special" param or something. Currently initial == 2 means Rocket Launcher backwards smoke.
//TODO: Refactor different weapon types out of it
void TriggerGunSmokeParticles(int x, int y, int z, int xv, int yv, int zv, byte initial, LaraWeaponType weaponType, byte count)
{
auto& s = GetFreeSmokeParticle();
s = {};
s.active = true;
s.position = Vector3(x, y, z);
Vector3 direction = Vector3(xv, yv, zv);
direction.Normalize();
s.velocity = direction;
s.gravity = -.1f;
s.affectedByWind = TestEnvironment(ENV_FLAG_WIND, LaraItem);
s.sourceColor = Vector4(.4, .4, .4, 1);
s.destinationColor = Vector4(0, 0, 0, 0);
if (initial)
{
if (weaponType == LaraWeaponType::RocketLauncher)
{
using namespace DirectX::SimpleMath;
float size = GenerateFloat(48, 80);
s.sourceSize = size * 2;
s.destinationSize = size * 8;
s.sourceColor = {0.75,0.75,1,1};
s.terminalVelocity = 0;
s.friction = 0.82f;
s.life = GenerateFloat(60, 90);
auto& s = GetFreeSmokeParticle();
s = {};
s.position = pos;
s.age = 0;
constexpr float d = 0.2f;
Vector3 randomDir = Vector3(GenerateFloat(-d, d), GenerateFloat(-d, d), GenerateFloat(-d, d));
Vector3 direction2;
(direction + randomDir).Normalize(direction2);
s.velocity = direction2 * GenerateFloat(7, 9);
s.gravity = -0.2f;
s.friction = GenerateFloat(0.7f, 0.85f);
s.sourceColor = Vector4(1, 131 / 255.0f, 100 / 255.0f, 1);
s.destinationColor = Vector4(1, 1, 1, 0);
s.life = GenerateFloat(25, 35);
s.angularVelocity = GenerateFloat(-0.3f, 0.3f);
s.angularDrag = 0.97f;
s.sourceSize = life > 4 ? GenerateFloat(16, 24) : GenerateFloat(100, 128);
s.destinationSize = life > 4 ? GenerateFloat(160, 200) : GenerateFloat(256, 300);
s.affectedByWind = true;
s.active = true;
s.room = room;
}
//TODO: add additional "Weapon Special" param or something. Currently initial == 2 means Rocket Launcher backwards smoke.
//TODO: Refactor different weapon types out of it
void TriggerGunSmokeParticles(int x, int y, int z, int xv, int yv, int zv, byte initial, LaraWeaponType weaponType, byte count)
{
auto& s = GetFreeSmokeParticle();
s = {};
s.active = true;
s.position = Vector3(x, y, z);
Vector3 direction = Vector3(xv, yv, zv);
direction.Normalize();
s.velocity = direction;
s.gravity = -.1f;
s.affectedByWind = TestEnvironment(ENV_FLAG_WIND, LaraItem);
s.sourceColor = Vector4(.4, .4, .4, 1);
s.destinationColor = Vector4(0, 0, 0, 0);
if (initial)
if (initial == 1)
{
if (weaponType == LaraWeaponType::RocketLauncher)
{
float size = GenerateFloat(48, 80);
s.sourceSize = size * 2;
s.destinationSize = size * 8;
s.sourceColor = {0.75,0.75,1,1};
s.terminalVelocity = 0;
s.friction = 0.82f;
s.life = GenerateFloat(60, 90);
if (initial == 1)
{
float size = GenerateFloat(48, 80);
s.sourceSize = size * 2;
s.destinationSize = size * 16;
s.velocity = getRandomVectorInCone(direction,25);
s.velocity *= GenerateFloat(0, 32);
}
else
{
float size = GenerateFloat(48, 80);
s.sourceSize = size;
s.destinationSize = size * 8;
s.velocity = getRandomVectorInCone(direction,3);
s.velocity *= GenerateFloat(0, 16);
}
}
else
{
float size = GenerateFloat(48, 73);
s.sourceSize = size * 2;
s.destinationSize = size * 8;
s.terminalVelocity = 0;
s.friction = 0.88f;
s.life = GenerateFloat(60, 90);
s.velocity = getRandomVectorInCone(direction, 10);
s.velocity *= GenerateFloat(16, 30);
}
float size = GenerateFloat(48, 80);
s.sourceSize = size * 2;
s.destinationSize = size * 16;
s.velocity = getRandomVectorInCone(direction,25);
s.velocity *= GenerateFloat(0, 32);
}
else
{
float size = (float)((GetRandomControl() & 0x0F) + 48); // -TriggerGunSmoke_SubFunction(weaponType);
if (weaponType == LaraWeaponType::RocketLauncher)
s.sourceColor = {0.75,0.75,1,1};
s.sourceSize = size / 2;
s.destinationSize = size * 4;
s.terminalVelocity = 0;
s.friction = 0.97f;
s.life = GenerateFloat(42, 62);
s.velocity *= GenerateFloat(16, 40);
float size = GenerateFloat(48, 80);
s.sourceSize = size;
s.destinationSize = size * 8;
s.velocity = getRandomVectorInCone(direction,3);
s.velocity *= GenerateFloat(0, 16);
}
s.position = Vector3(x, y, z);
s.position += Vector3(GenerateFloat(-8, 8), GenerateFloat(-8, 8), GenerateFloat(-8, 8));
s.angularVelocity = GenerateFloat(-PI / 4, PI / 4);
s.angularDrag = 0.95f;
s.room = LaraItem->RoomNumber;
}
void TriggerQuadExhaustSmoke(int x, int y, int z, short angle, int velocity, int moving)
else
{
auto& s = GetFreeSmokeParticle();
s = {};
s.position = Vector3(x, y, z) + Vector3(GenerateFloat(8, 16), GenerateFloat(8, 16), GenerateFloat(8, 16));
float xVel = std::sin(TO_RAD(angle)) * velocity;
float zVel = std::cos(TO_RAD(angle)) * velocity;
s.velocity = Vector3(xVel, GenerateFloat(-1, 4), zVel);
s.sourceColor = Vector4(1, 1, 1, 1);
s.destinationColor = Vector4(0, 0, 0, 0);
s.sourceSize = GenerateFloat(8,24);
s.active = true;
s.affectedByWind = true;
s.friction = 0.999f;
s.gravity = -0.1f;
s.life = GenerateFloat(16, 24);
s.destinationSize = GenerateFloat(128, 160);
s.angularVelocity = GenerateFloat(-1, 1);
s.angularDrag = GenerateFloat(0.97, 0.999);
}
void TriggerRocketSmoke(int x, int y, int z, int bodyPart)
{
auto& s = GetFreeSmokeParticle();
s = {};
s.position = Vector3(x, y, z) + Vector3(GenerateFloat(8, 16), GenerateFloat(8, 16), GenerateFloat(8, 16));
s.sourceColor = Vector4(0.8, 0.8, 1, 1);
s.destinationColor = Vector4(0, 0, 0, 0);
s.sourceSize = GenerateFloat(32, 64);
s.active = true;
s.velocity = getRandomVector() * GenerateFloat(1, 3);
s.affectedByWind = true;
s.friction = 0.979f;
s.gravity = -0.1f;
s.life = GenerateFloat(80, 120);
s.destinationSize = GenerateFloat(1024, 1152);
s.angularVelocity = GenerateFloat(-0.6, 0.6);
s.angularDrag = GenerateFloat(0.87, 0.99);
}
void TriggerBreathSmoke(long x, long y, long z, short angle)
{
auto& s = GetFreeSmokeParticle();
s = {};
s.position = Vector3(x, y, z) + Vector3(GenerateFloat(8, 16), GenerateFloat(8, 16), GenerateFloat(8, 16));
float xVel = std::sin(TO_RAD(angle)) * GenerateFloat(8, 12);
float zVel = std::cos(TO_RAD(angle)) * GenerateFloat(8, 12);
s.velocity = Vector3(xVel, 0, zVel);
s.sourceColor = Vector4(1, 1, 1, 0.7f);
s.destinationColor = Vector4(1, 1, 1, 0);
s.sourceSize = GenerateFloat(8, 24);
s.active = true;
s.affectedByWind = true;
s.friction = 0.999f;
s.gravity = -0.1f;
s.life = GenerateFloat(12, 20);
s.destinationSize = GenerateFloat(128, 160);
s.angularVelocity = GenerateFloat(-0.5f, 0.5f);
s.angularDrag = GenerateFloat(0.95f, 0.95f);
float size = GenerateFloat(48, 73);
s.sourceSize = size * 2;
s.destinationSize = size * 8;
s.terminalVelocity = 0;
s.friction = 0.88f;
s.life = GenerateFloat(60, 90);
s.velocity = getRandomVectorInCone(direction, 10);
s.velocity *= GenerateFloat(16, 30);
}
}
else
{
float size = (float)((GetRandomControl() & 0x0F) + 48); // -TriggerGunSmoke_SubFunction(weaponType);
if (weaponType == LaraWeaponType::RocketLauncher)
s.sourceColor = {0.75,0.75,1,1};
s.sourceSize = size / 2;
s.destinationSize = size * 4;
s.terminalVelocity = 0;
s.friction = 0.97f;
s.life = GenerateFloat(42, 62);
s.velocity *= GenerateFloat(16, 40);
}
s.position = Vector3(x, y, z);
s.position += Vector3(GenerateFloat(-8, 8), GenerateFloat(-8, 8), GenerateFloat(-8, 8));
s.angularVelocity = GenerateFloat(-PI / 4, PI / 4);
s.angularDrag = 0.95f;
s.room = LaraItem->RoomNumber;
}
void TriggerQuadExhaustSmoke(int x, int y, int z, short angle, int velocity, int moving)
{
auto& s = GetFreeSmokeParticle();
s = {};
s.position = Vector3(x, y, z) + Vector3(GenerateFloat(8, 16), GenerateFloat(8, 16), GenerateFloat(8, 16));
float xVel = std::sin(TO_RAD(angle)) * velocity;
float zVel = std::cos(TO_RAD(angle)) * velocity;
s.velocity = Vector3(xVel, GenerateFloat(-1, 4), zVel);
s.sourceColor = Vector4(1, 1, 1, 1);
s.destinationColor = Vector4(0, 0, 0, 0);
s.sourceSize = GenerateFloat(8,24);
s.active = true;
s.affectedByWind = true;
s.friction = 0.999f;
s.gravity = -0.1f;
s.life = GenerateFloat(16, 24);
s.destinationSize = GenerateFloat(128, 160);
s.angularVelocity = GenerateFloat(-1, 1);
s.angularDrag = GenerateFloat(0.97, 0.999);
}
void TriggerRocketSmoke(int x, int y, int z, int bodyPart)
{
auto& s = GetFreeSmokeParticle();
s = {};
s.position = Vector3(x, y, z) + Vector3(GenerateFloat(8, 16), GenerateFloat(8, 16), GenerateFloat(8, 16));
s.sourceColor = Vector4(0.8, 0.8, 1, 1);
s.destinationColor = Vector4(0, 0, 0, 0);
s.sourceSize = GenerateFloat(32, 64);
s.active = true;
s.velocity = getRandomVector() * GenerateFloat(1, 3);
s.affectedByWind = true;
s.friction = 0.979f;
s.gravity = -0.1f;
s.life = GenerateFloat(80, 120);
s.destinationSize = GenerateFloat(1024, 1152);
s.angularVelocity = GenerateFloat(-0.6, 0.6);
s.angularDrag = GenerateFloat(0.87, 0.99);
}
void TriggerBreathSmoke(long x, long y, long z, short angle)
{
auto& s = GetFreeSmokeParticle();
s = {};
s.position = Vector3(x, y, z) + Vector3(GenerateFloat(8, 16), GenerateFloat(8, 16), GenerateFloat(8, 16));
float xVel = std::sin(TO_RAD(angle)) * GenerateFloat(8, 12);
float zVel = std::cos(TO_RAD(angle)) * GenerateFloat(8, 12);
s.velocity = Vector3(xVel, 0, zVel);
s.sourceColor = Vector4(1, 1, 1, 0.7f);
s.destinationColor = Vector4(1, 1, 1, 0);
s.sourceSize = GenerateFloat(8, 24);
s.active = true;
s.affectedByWind = true;
s.friction = 0.999f;
s.gravity = -0.1f;
s.life = GenerateFloat(12, 20);
s.destinationSize = GenerateFloat(128, 160);
s.angularVelocity = GenerateFloat(-0.5f, 0.5f);
s.angularDrag = GenerateFloat(0.95f, 0.95f);
}
}

View file

@ -6,45 +6,38 @@
struct ItemInfo;
enum class LaraWeaponType;
namespace TEN
namespace TEN::Effects::Smoke
{
namespace Effects
struct SmokeParticle
{
namespace Smoke
{
struct SmokeParticle
{
DirectX::SimpleMath::Vector4 sourceColor;
DirectX::SimpleMath::Vector4 destinationColor;
DirectX::SimpleMath::Vector4 color;
DirectX::SimpleMath::Vector3 position;
DirectX::SimpleMath::Vector3 velocity;
int room;
int sprite;
float gravity;
float friction;
float sourceSize;
float destinationSize;
float size;
float age;
float life;
float angularVelocity;
float angularDrag;
float rotation;
float terminalVelocity;
bool affectedByWind;
bool active;
};
Vector4 sourceColor;
Vector4 destinationColor;
Vector4 color;
Vector3 position;
Vector3 velocity;
int room;
int sprite;
float gravity;
float friction;
float sourceSize;
float destinationSize;
float size;
float age;
float life;
float angularVelocity;
float angularDrag;
float rotation;
float terminalVelocity;
bool affectedByWind;
bool active;
};
extern std::array<SmokeParticle, 128> SmokeParticles;
extern std::array<SmokeParticle, 128> SmokeParticles;
void UpdateSmokeParticles();
void DisableSmokeParticles();
void TriggerFlareSmoke(const DirectX::SimpleMath::Vector3& pos, DirectX::SimpleMath::Vector3& direction, int life, int room);
void TriggerGunSmokeParticles(int x, int y, int z, int xv, int yv, int zv, byte initial, LaraWeaponType weaponType, byte count);
void TriggerQuadExhaustSmoke(int x, int y, int z, short angle, int velocity, int moving);
void TriggerRocketSmoke(int x, int y, int z, int bodyPart);
void TriggerBreathSmoke(long x, long y, long z, short angle);
}
}
void UpdateSmokeParticles();
void DisableSmokeParticles();
void TriggerFlareSmoke(const Vector3& pos, Vector3& direction, int life, int room);
void TriggerGunSmokeParticles(int x, int y, int z, int xv, int yv, int zv, byte initial, LaraWeaponType weaponType, byte count);
void TriggerQuadExhaustSmoke(int x, int y, int z, short angle, int velocity, int moving);
void TriggerRocketSmoke(int x, int y, int z, int bodyPart);
void TriggerBreathSmoke(long x, long y, long z, short angle);
}

View file

@ -9,108 +9,110 @@
using namespace DirectX::SimpleMath;
using namespace TEN::Math::Random;
namespace TEN {
namespace Effects {
namespace Spark {
std::array<SparkParticle, 128> SparkParticles;
void UpdateSparkParticles()
namespace TEN::Effects::Spark
{
std::array<SparkParticle, 128> SparkParticles;
void UpdateSparkParticles()
{
for (int i = 0; i < SparkParticles.size(); i++)
{
auto& s = SparkParticles[i];
if (!s.active)
continue;
s.age += 1;
if (s.age > s.life)
{
for (int i = 0; i < SparkParticles.size(); i++) {
SparkParticle& s = SparkParticles[i];
if (!s.active)continue;
s.age += 1;
if (s.age > s.life) {
s.active = false;
continue;
}
s.velocity.y += s.gravity;
s.velocity *= s.friction;
s.pos += s.velocity;
}
s.active = false;
continue;
}
SparkParticle& GetFreeSparkParticle()
{
for (int i = 0; i < SparkParticles.size(); i++)
{
if (!SparkParticles[i].active) {
return SparkParticles[i];
}
}
return SparkParticles[0];
}
s.velocity.y += s.gravity;
s.velocity *= s.friction;
s.pos += s.velocity;
}
}
void TriggerFlareSparkParticles(Vector3Int* pos, Vector3Int* vel, CVECTOR* color, int room)
{
SparkParticle& s = GetFreeSparkParticle();
s = {};
s.age = 0;
s.life = GenerateFloat(10, 20);
s.friction = 0.98f;
s.gravity = 1.2f;
s.width = 8.0f;
s.height = 48.0f;
s.room = room;
s.pos = Vector3(pos->x, pos->y, pos->z);
Vector3 v = Vector3(vel->x, vel->y, vel->z);
v += Vector3(GenerateFloat(-64, 64), GenerateFloat(-64, 64), GenerateFloat(-64, 64));
v.Normalize(v);
s.velocity = v *GenerateFloat(17,24);
s.sourceColor = Vector4(1, 1, 1, 1);
s.destinationColor = Vector4(color->r/255.0f,color->g/255.0f,color->b/255.0f,1);
s.active = true;
}
SparkParticle& GetFreeSparkParticle()
{
for (int i = 0; i < SparkParticles.size(); i++)
{
if (!SparkParticles[i].active)
return SparkParticles[i];
}
void TriggerRicochetSpark(GameVector* pos, short angle, int num)
{
for (int i = 0; i < num; i++)
{
SparkParticle& s = GetFreeSparkParticle();
s = {};
s.age = 0;
s.life = GenerateFloat(10, 20);
s.friction = 0.98f;
s.gravity = 1.2f;
s.width = 8.0f;
s.height = 64.0f;
s.room = pos->roomNumber;
s.pos = Vector3(pos->x, pos->y, pos->z);
float ang = TO_RAD(angle);
Vector3 v = Vector3(sin(ang + GenerateFloat(-PI / 2, PI / 2)), GenerateFloat(-1, 1), cos(ang + GenerateFloat(-PI / 2, PI / 2)));
v += Vector3(GenerateFloat(-64, 64), GenerateFloat(-64, 64), GenerateFloat(-64, 64));
v.Normalize(v);
s.velocity = v * GenerateFloat(17, 24);
s.sourceColor = Vector4(1, 0.8, 0.2f, 1) * 3;
s.destinationColor = Vector4(0, 0, 0, 0);
s.active = true;
}
}
return SparkParticles[0];
}
void TriggerFrictionSpark(GameVector* pos, Vector3Shrt angle, float length, int num)
{
for (int i = 0; i < num; i++)
{
SparkParticle& s = GetFreeSparkParticle();
s = {};
s.age = 0;
s.life = GenerateFloat(8, 15);
s.friction = 0.1f;
s.gravity = 0.0f;
s.height = length;
s.width = GenerateFloat(16.0f, 32.0f);
s.room = pos->roomNumber;
s.pos = Vector3(pos->x + GenerateFloat(-16, 16), pos->y + GenerateFloat(-16, 16), pos->z + GenerateFloat(-16, 16));
float ang = TO_RAD(angle.y);
float vAng = -TO_RAD(angle.x);
Vector3 v = Vector3(sin(ang), vAng + GenerateFloat(-PI / 16, PI / 16), cos(ang));
v.Normalize(v);
s.velocity = v * GenerateFloat(32, 64);
s.sourceColor = Vector4(1, 0.7, 0.4f, 1) * 3;
s.destinationColor = Vector4(0.4f, 0.1f, 0, 0.5f);
s.active = true;
}
}
void TriggerFlareSparkParticles(Vector3Int* pos, Vector3Int* vel, CVECTOR* color, int room)
{
auto& s = GetFreeSparkParticle();
s = {};
s.age = 0;
s.life = GenerateFloat(10, 20);
s.friction = 0.98f;
s.gravity = 1.2f;
s.width = 8.0f;
s.height = 48.0f;
s.room = room;
s.pos = Vector3(pos->x, pos->y, pos->z);
Vector3 v = Vector3(vel->x, vel->y, vel->z);
v += Vector3(GenerateFloat(-64, 64), GenerateFloat(-64, 64), GenerateFloat(-64, 64));
v.Normalize(v);
s.velocity = v *GenerateFloat(17,24);
s.sourceColor = Vector4(1, 1, 1, 1);
s.destinationColor = Vector4(color->r/255.0f,color->g/255.0f,color->b/255.0f,1);
s.active = true;
}
void TriggerRicochetSpark(GameVector* pos, short angle, int num)
{
for (int i = 0; i < num; i++)
{
auto& s = GetFreeSparkParticle();
s = {};
s.age = 0;
s.life = GenerateFloat(10, 20);
s.friction = 0.98f;
s.gravity = 1.2f;
s.width = 8.0f;
s.height = 64.0f;
s.room = pos->roomNumber;
s.pos = Vector3(pos->x, pos->y, pos->z);
float ang = TO_RAD(angle);
Vector3 v = Vector3(sin(ang + GenerateFloat(-PI / 2, PI / 2)), GenerateFloat(-1, 1), cos(ang + GenerateFloat(-PI / 2, PI / 2)));
v += Vector3(GenerateFloat(-64, 64), GenerateFloat(-64, 64), GenerateFloat(-64, 64));
v.Normalize(v);
s.velocity = v * GenerateFloat(17, 24);
s.sourceColor = Vector4(1, 0.8, 0.2f, 1) * 3;
s.destinationColor = Vector4(0, 0, 0, 0);
s.active = true;
}
}
void TriggerFrictionSpark(GameVector* pos, Vector3Shrt angle, float length, int num)
{
for (int i = 0; i < num; i++)
{
auto& s = GetFreeSparkParticle();
s = {};
s.age = 0;
s.life = GenerateFloat(8, 15);
s.friction = 0.1f;
s.gravity = 0.0f;
s.height = length;
s.width = GenerateFloat(16.0f, 32.0f);
s.room = pos->roomNumber;
s.pos = Vector3(pos->x + GenerateFloat(-16, 16), pos->y + GenerateFloat(-16, 16), pos->z + GenerateFloat(-16, 16));
float ang = TO_RAD(angle.y);
float vAng = -TO_RAD(angle.x);
Vector3 v = Vector3(sin(ang), vAng + GenerateFloat(-PI / 16, PI / 16), cos(ang));
v.Normalize(v);
s.velocity = v * GenerateFloat(32, 64);
s.sourceColor = Vector4(1, 0.7, 0.4f, 1) * 3;
s.destinationColor = Vector4(0.4f, 0.1f, 0, 0.5f);
s.active = true;
}
}
}

View file

@ -3,32 +3,29 @@
#include <SimpleMath.h>
#include "Specific/phd_global.h"
namespace TEN {
namespace Effects {
namespace Spark {
struct SparkParticle {
DirectX::SimpleMath::Vector3 pos;
DirectX::SimpleMath::Vector3 velocity;
DirectX::SimpleMath::Vector4 sourceColor;
DirectX::SimpleMath::Vector4 destinationColor;
DirectX::SimpleMath::Vector4 color;
int room;
float gravity;
float friction;
float age;
float life;
float width;
float height;
bool active;
};
extern std::array<SparkParticle, 128> SparkParticles;
namespace TEN::Effects::Spark
{
struct SparkParticle
{
Vector3 pos;
Vector3 velocity;
Vector4 sourceColor;
Vector4 destinationColor;
Vector4 color;
int room;
float gravity;
float friction;
float age;
float life;
float width;
float height;
bool active;
};
extern std::array<SparkParticle, 128> SparkParticles;
void UpdateSparkParticles();
SparkParticle& GetFreeSparkParticle();
void TriggerFlareSparkParticles(Vector3Int* pos, Vector3Int* vel, CVECTOR* color,int room);
void TriggerRicochetSpark(GameVector* pos, short angle, int num);
void TriggerFrictionSpark(GameVector* pos, Vector3Shrt angle, float length, int num);
}
}
}
void UpdateSparkParticles();
SparkParticle& GetFreeSparkParticle();
void TriggerFlareSparkParticles(Vector3Int* pos, Vector3Int* vel, CVECTOR* color, int room);
void TriggerRicochetSpark(GameVector* pos, short angle, int num);
void TriggerFrictionSpark(GameVector* pos, Vector3Shrt angle, float length, int num);
}

View file

@ -1,6 +1,7 @@
#include "framework.h"
#include "Game/gui.h"
#include <OISKeyboard.h>
#include "Game/animation.h"
#include "Game/camera.h"
#include "Game/control/control.h"
@ -23,6 +24,8 @@
#include "Scripting/Include/ScriptInterfaceGame.h"
using namespace TEN::Renderer;
using namespace TEN::Input;
GuiController g_Gui;
const char* optmessages[] =
@ -58,6 +61,7 @@ const char* controlmsgs[] =
STRING_CONTROLS_LOOK,
STRING_CONTROLS_ROLL,
STRING_CONTROLS_INVENTORY,
STRING_CONTROLS_PAUSE,
STRING_CONTROLS_STEP_LEFT,
STRING_CONTROLS_STEP_RIGHT
};
@ -160,8 +164,8 @@ InventoryObject inventry_objects_list[INVENTORY_TABLE_SIZE] =
{ID_CROSSBOW_ITEM, 0, 0.5f, ANGLE(-90), ANGLE(33), 0, OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_CROSSBOW, STRING_CROSSBOW, 1, INV_ROT_Y},
{ID_CROSSBOW_ITEM, 0, 0.5f, ANGLE(-90), ANGLE(33), 0, OPT_EQUIP | OPT_SEPERATABLE | OPT_CHOOSEAMMO_CROSSBOW, STRING_CROSSBOW_LASER, 3, INV_ROT_Y},
{ID_CROSSBOW_AMMO1_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_CROSSBOW_AMMO1, NO_JOINT_BITS, INV_ROT_Y},
{ID_CROSSBOW_AMMO2_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_CROSSBOW_AMMO1, NO_JOINT_BITS, INV_ROT_Y},
{ID_CROSSBOW_AMMO3_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_CROSSBOW_AMMO1, NO_JOINT_BITS, INV_ROT_Y},
{ID_CROSSBOW_AMMO2_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_CROSSBOW_AMMO2, NO_JOINT_BITS, INV_ROT_Y},
{ID_CROSSBOW_AMMO3_ITEM, 0, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_CROSSBOW_AMMO3, NO_JOINT_BITS, INV_ROT_Y},
{ID_HK_ITEM, 0, 0.5f, ANGLE(0), ANGLE(280), 0, OPT_EQUIP | OPT_COMBINABLE | OPT_CHOOSEAMMO_HK, STRING_HK, 1, INV_ROT_Y},
{ID_HK_ITEM, 0, 0.5f, ANGLE(-45), ANGLE(280), 0, OPT_EQUIP | OPT_SEPERATABLE | OPT_CHOOSEAMMO_HK, STRING_HK_SILENCED, NO_JOINT_BITS, INV_ROT_Y},
{ID_HK_AMMO_ITEM, 3, 0.5f, ANGLE(90), 0, 0, OPT_USE, STRING_HK_AMMO, 2},
@ -568,7 +572,7 @@ void GuiController::DoDebouncedInput()
else
dbSelect = 0;
if ((TrInput & IN_DESELECT))
if (TrInput & IN_OPTION || TrInput & IN_DESELECT)
{
if (!dbDeselect)
goDeselect = 1;
@ -608,18 +612,15 @@ InventoryResult GuiController::TitleOptions()
break;
case Menu::Display:
option_count = 6;
HandleDisplaySettingsInput(false);
break;
case Menu::Controls:
option_count = 17;
HandleControlSettingsInput(false);
break;
case Menu::Sound:
option_count = 4;
HandleSoundSettingsInput(false);
case Menu::OtherSettings:
HandleOtherSettingsInput(false);
break;
}
@ -717,24 +718,7 @@ InventoryResult GuiController::TitleOptions()
}
else if (menu_to_display == Menu::Options)
{
switch (selected_option)
{
case 0:
FillDisplayOptions();
menu_to_display = Menu::Display;
break;
case 1:
menu_to_display = Menu::Controls;
selected_option = 0;
break;
case 2:
FillSound();
menu_to_display = Menu::Sound;
selected_option = 0;
break;
}
HandleOptionsInput();
}
}
}
@ -745,7 +729,7 @@ InventoryResult GuiController::TitleOptions()
void GuiController::FillDisplayOptions()
{
// Copy configuration to a temporary object
memcpy(&CurrentSettings.conf, &g_Configuration, sizeof(GameConfiguration));
BackupOptions();
// Get current display mode
CurrentSettings.selectedScreenResolution = 0;
@ -763,10 +747,9 @@ void GuiController::FillDisplayOptions()
void GuiController::HandleDisplaySettingsInput(bool pause)
{
SetDebounce = true;
S_UpdateInput();
SetDebounce = false;
option_count = 6;
UpdateInput();
DoDebouncedInput();
if (goDeselect)
@ -892,8 +875,9 @@ void GuiController::HandleDisplaySettingsInput(bool pause)
void GuiController::HandleControlSettingsInput(bool pause)
{
option_count = KEY_COUNT + 1;
CurrentSettings.waitingForkey = false;
memcpy(&CurrentSettings.conf.KeyboardLayout, &KeyboardLayout[1], NUM_CONTROLS);
if (CurrentSettings.ignoreInput)
{
@ -902,12 +886,10 @@ void GuiController::HandleControlSettingsInput(bool pause)
return;
}
SetDebounce = true;
S_UpdateInput();
SetDebounce = false;
UpdateInput();
DoDebouncedInput();
if (goSelect && selected_option != 16 && selected_option != 17)
if (goSelect && (selected_option <= 16))
{
SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
CurrentSettings.waitingForkey = true;
@ -918,13 +900,10 @@ void GuiController::HandleControlSettingsInput(bool pause)
{
TrInput = 0;
DbInput = 0;
ZeroMemory(KeyMap, 256);
while (true)
{
SetDebounce = true;
S_UpdateInput();
SetDebounce = false;
UpdateInput();
if (CurrentSettings.ignoreInput)
{
@ -934,22 +913,19 @@ void GuiController::HandleControlSettingsInput(bool pause)
else
{
int selectedKey = 0;
for (selectedKey = 0; selectedKey < 256; selectedKey++)
for (selectedKey = 0; selectedKey < MAX_INPUT_SLOTS; selectedKey++)
{
if (KeyMap[selectedKey] & 0x80)
if (KeyMap[selectedKey])
break;
}
if (selectedKey == 256)
if (selectedKey == MAX_INPUT_SLOTS)
selectedKey = 0;
if (selectedKey && g_KeyNames[selectedKey])
{
if (selectedKey != DIK_ESCAPE)
{
KeyboardLayout[1][selected_option] = selectedKey;
DefaultConflict();
}
KeyboardLayout[1][selected_option] = selectedKey;
DefaultConflict();
CurrentSettings.waitingForkey = false;
CurrentSettings.ignoreInput = true;
@ -995,21 +971,23 @@ void GuiController::HandleControlSettingsInput(bool pause)
if (goSelect)
{
if (selected_option == 16) // Apply
if (selected_option == option_count - 1) // Apply
{
SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
memcpy(KeyboardLayout[1], CurrentSettings.conf.KeyboardLayout, NUM_CONTROLS);
memcpy(CurrentSettings.conf.KeyboardLayout, KeyboardLayout[1], KEY_COUNT * sizeof(short));
memcpy(g_Configuration.KeyboardLayout, KeyboardLayout[1], KEY_COUNT * sizeof(short));
SaveConfiguration();
menu_to_display = pause ? Menu::Pause : Menu::Options;
selected_option = 1;
selected_option = 2;
return;
}
if (selected_option == 17) // Cancel
if (selected_option == option_count) // Cancel
{
SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
memcpy(KeyboardLayout[1], CurrentSettings.conf.KeyboardLayout, KEY_COUNT * sizeof(short));
menu_to_display = pause ? Menu::Pause : Menu::Options;
selected_option = 1;
selected_option = 2;
return;
}
}
@ -1019,21 +997,45 @@ void GuiController::HandleControlSettingsInput(bool pause)
SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
menu_to_display = Menu::Options;
selected_option = 1;
selected_option = 2;
}
}
}
void GuiController::FillSound()
void GuiController::BackupOptions()
{
memcpy(&CurrentSettings.conf, &g_Configuration, sizeof(GameConfiguration));
}
void GuiController::HandleSoundSettingsInput(bool pause)
void GuiController::HandleOptionsInput()
{
SetDebounce = true;
S_UpdateInput();
SetDebounce = false;
switch (selected_option)
{
case 0:
FillDisplayOptions();
menu_to_display = Menu::Display;
selected_option = 0;
break;
case 1:
BackupOptions();
menu_to_display = Menu::OtherSettings;
selected_option = 0;
break;
case 2:
BackupOptions();
menu_to_display = Menu::Controls;
selected_option = 0;
break;
}
}
void GuiController::HandleOtherSettingsInput(bool pause)
{
option_count = 7;
UpdateInput();
DoDebouncedInput();
if (goDeselect)
@ -1041,22 +1043,44 @@ void GuiController::HandleSoundSettingsInput(bool pause)
SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
menu_to_display = Menu::Options;
selected_option = 2;
selected_option = 1;
SetVolumeMusic(g_Configuration.MusicVolume);
SetVolumeFX(g_Configuration.SfxVolume);
return;
}
if (goLeft || goRight)
{
switch (selected_option)
{
case 0:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.conf.EnableReverb = !CurrentSettings.conf.EnableReverb;
break;
case 3:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.conf.AutoTarget = !CurrentSettings.conf.AutoTarget;
break;
case 4:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.conf.EnableRumble = !CurrentSettings.conf.EnableRumble;
break;
case 5:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.conf.EnableThumbstickCameraControl = !CurrentSettings.conf.EnableThumbstickCameraControl;
break;
}
}
if (goLeft)
{
switch (selected_option)
{
case 0:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.conf.EnableAudioSpecialEffects = !CurrentSettings.conf.EnableAudioSpecialEffects;
break;
case 1:
if (CurrentSettings.conf.MusicVolume > 0)
{
@ -1071,7 +1095,6 @@ void GuiController::HandleSoundSettingsInput(bool pause)
else
db -= 2;
}
break;
case 2:
@ -1088,7 +1111,6 @@ void GuiController::HandleSoundSettingsInput(bool pause)
else
db -= 2;
}
break;
}
}
@ -1097,11 +1119,6 @@ void GuiController::HandleSoundSettingsInput(bool pause)
{
switch (selected_option)
{
case 0:
SoundEffect(SFX_TR4_MENU_CHOOSE, nullptr, SoundEnvironment::Always);
CurrentSettings.conf.EnableAudioSpecialEffects = !CurrentSettings.conf.EnableAudioSpecialEffects;
break;
case 1:
if (CurrentSettings.conf.MusicVolume < 100)
{
@ -1116,7 +1133,6 @@ void GuiController::HandleSoundSettingsInput(bool pause)
else
db -= 2;
}
break;
case 2:
@ -1133,7 +1149,6 @@ void GuiController::HandleSoundSettingsInput(bool pause)
else
db -= 2;
}
break;
}
}
@ -1162,22 +1177,29 @@ void GuiController::HandleSoundSettingsInput(bool pause)
{
SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
if (selected_option == 3)
if (selected_option == option_count - 1)
{
// Was rumble setting changed?
bool indicateRumble = CurrentSettings.conf.EnableRumble && !g_Configuration.EnableRumble;
// Save the configuration
memcpy(&g_Configuration, &CurrentSettings.conf, sizeof(GameConfiguration));
SaveConfiguration();
// Rumble if setting was changed
if (indicateRumble)
Rumble(0.5f);
menu_to_display = pause ? Menu::Pause : Menu::Options;
selected_option = pause ? 1 : 2;
selected_option = 1;
}
else if (selected_option == 4)
else if (selected_option == option_count)
{
SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
SetVolumeMusic(g_Configuration.MusicVolume);
SetVolumeFX(g_Configuration.SfxVolume);
menu_to_display = pause ? Menu::Pause : Menu::Options;
selected_option = pause ? 1 : 2;
selected_option = 1;
}
}
}
@ -1201,25 +1223,20 @@ InventoryResult GuiController::DoPauseMenu()
break;
case Menu::Display:
option_count = 6;
HandleDisplaySettingsInput(true);
break;
case Menu::Controls:
option_count = 17;
HandleControlSettingsInput(true);
break;
case Menu::Sound:
option_count = 4;
HandleSoundSettingsInput(true);
case Menu::OtherSettings:
HandleOtherSettingsInput(true);
break;
}
ClearInputVariables(1);
SetDebounce = true;
S_UpdateInput();
SetDebounce = false;
UpdateInput();
DoDebouncedInput();
if (menu_to_display == Menu::Pause || menu_to_display == Menu::Options)
@ -1287,25 +1304,7 @@ InventoryResult GuiController::DoPauseMenu()
break;
case Menu::Options:
switch (selected_option)
{
case 0:
FillDisplayOptions();
menu_to_display = Menu::Display;
break;
case 1:
selected_option = 0;
menu_to_display = Menu::Controls;
break;
case 2:
FillSound();
selected_option = 0;
menu_to_display = Menu::Sound;
break;
}
HandleOptionsInput();
break;
case Menu::Statistics:
@ -1866,7 +1865,7 @@ void GuiController::ConstructCombineObjectList()
rings[(int)RingTypes::Ammo]->ringactive = 0;
}
void GuiController::InitializeInventory()
void GuiController::InitialiseInventory()
{
compassNeedleAngle = 4096;
AlterFOV(ANGLE(80.0f));
@ -3049,9 +3048,9 @@ void GuiController::DrawCurrentObjectList(int ringnum)
if (ringnum == (int)RingTypes::Inventory)
objmeup = (int)(phd_centery - (phd_winymax + 1) * 0.0625 * 3.0);
else
objmeup = (int)((phd_winymax + 1) * 0.0625 * 3.0 + phd_centery);
objmeup = (int)(phd_centery + (phd_winymax + 1) * 0.0625 * 2.0);
g_Renderer.DrawString(phd_centerx, ringnum == (int)RingTypes::Inventory ? 230 : 300, textbufme, PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
g_Renderer.DrawString(phd_centerx, objmeup, textbufme, PRINTSTRING_COLOR_YELLOW, PRINTSTRING_CENTER | PRINTSTRING_OUTLINE);
}
if (!i && !rings[ringnum]->objlistmovement)
@ -3195,7 +3194,7 @@ bool GuiController::CallInventory(bool reset_mode)
if (reset_mode)
invMode = InventoryMode::InGame;
InitializeInventory();
InitialiseInventory();
Camera.numberFrames = 2;
bool exitLoop = false;
@ -3206,9 +3205,8 @@ bool GuiController::CallInventory(bool reset_mode)
if (compassNeedleAngle != 1024)
compassNeedleAngle -= 32;
SetDebounce = true;
S_UpdateInput();
TrInput = InputBusy;
UpdateInput();
TrInput = RawInput;
GameTimer++;
if (DbInput & IN_OPTION)
@ -3298,7 +3296,7 @@ void GuiController::DoStatisticsMode()
{
SoundEffect(SFX_TR4_MENU_SELECT, nullptr, SoundEnvironment::Always);
goDeselect = 0;
invMode = InventoryMode::None;
invMode = InventoryMode::InGame;
}
}

View file

@ -97,7 +97,7 @@ enum class Menu
Options,
Display,
Controls,
Sound
OtherSettings
};
enum InventoryObjectTypes
@ -442,10 +442,11 @@ private:
void ClearInputVariables(bool flag);
void HandleDisplaySettingsInput(bool pause);
void HandleControlSettingsInput(bool pause);
void HandleSoundSettingsInput(bool pause);
void FillSound();
void HandleOtherSettingsInput(bool pause);
void HandleOptionsInput();
void BackupOptions();
bool DoObjectsCombine(int obj1, int obj2);
void InitializeInventory();
void InitialiseInventory();
void FillDisplayOptions();
bool IsItemCurrentlyCombinable(short obj);
bool IsItemInInventory(short obj);

View file

@ -72,20 +72,20 @@ void UpdateHealthBar(ItemInfo* item, int flash)
{
auto* lara = GetLaraInfo(item);
auto HitPoints = item->HitPoints;
auto hitPoints = item->HitPoints;
if (HitPoints < 0)
HitPoints = 0;
else if (HitPoints > LARA_HEALTH_MAX)
HitPoints = LARA_HEALTH_MAX;
if (hitPoints < 0)
hitPoints = 0;
else if (hitPoints > LARA_HEALTH_MAX)
hitPoints = LARA_HEALTH_MAX;
// OPT: smoothly transition health bar display.
// Smoothly transition health bar display.
if (EnableSmoothHealthBar)
{
if (OldHitPoints != HitPoints)
if (OldHitPoints != hitPoints)
{
MutateAmount += OldHitPoints - HitPoints;
OldHitPoints = HitPoints;
MutateAmount += OldHitPoints - hitPoints;
OldHitPoints = hitPoints;
HealthBarTimer = 40;
}
@ -100,17 +100,16 @@ void UpdateHealthBar(ItemInfo* item, int flash)
if (MutateAmount > -0.5f && MutateAmount < 0.5f)
{
MutateAmount = 0;
HealthBar = HitPoints;
HealthBar = hitPoints;
}
}
// OG: discretely transition health bar display.
// Discretely transition health bar display.
else
{
if (OldHitPoints != HitPoints)
if (OldHitPoints != hitPoints)
{
OldHitPoints = HitPoints;
HealthBar = HitPoints;
OldHitPoints = hitPoints;
HealthBar = hitPoints;
HealthBarTimer = 40;
}
}
@ -118,8 +117,8 @@ void UpdateHealthBar(ItemInfo* item, int flash)
if (HealthBarTimer < 0)
HealthBarTimer = 0;
// Flash when at 1/4 capacity AND HP bar is not transitioning.
if (HealthBar <= LARA_HEALTH_MAX / 4)
// Flash when at critical capacity and bar is not transitioning.
if (HealthBar <= LARA_HEALTH_CRITICAL)
{
if (!BinocularRange)
{
@ -179,7 +178,7 @@ void UpdateAirBar(ItemInfo* item, int flash)
else if (air > LARA_AIR_MAX)
air = LARA_AIR_MAX;
if (air <= (LARA_AIR_MAX / 4))
if (air <= LARA_AIR_CRITICAL)
{
if (flash)
DrawAirBar(air / LARA_AIR_MAX);

View file

@ -8,9 +8,14 @@
#include "ScriptInterfaceGame.h"
#include "Specific/setup.h"
#include "Specific/level.h"
#include "Specific/input.h"
#include "Objects/ScriptInterfaceObjectsHandler.h"
#include "Sound/sound.h"
#include "Specific/prng.h"
using namespace TEN::Floordata;
using namespace TEN::Input;
using namespace TEN::Math::Random;
void ItemInfo::SetBits(JointBitType type, std::vector<int> jointIndices)
{
@ -646,3 +651,32 @@ int FindItem(ItemInfo* item)
return -1;
}
void DoDamage(ItemInfo* item, int damage)
{
static int lastHurtTime = 0;
if (item->HitPoints <= 0)
return;
item->HitStatus = true;
item->HitPoints -= damage;
if (item->HitPoints < 0)
item->HitPoints = 0;
if (item->IsLara())
{
if (damage > 0)
{
float power = item->HitPoints ? GenerateFloat(0.1f, 0.4f) : 0.5f;
Rumble(power, 0.15f);
}
if ((GlobalCounter - lastHurtTime) > (FPS * 2 + GenerateInt(0, FPS)))
{
SoundEffect(SFX_TR4_LARA_INJURY, &LaraItem->Pose);
lastHurtTime = GlobalCounter;
}
}
}

View file

@ -149,3 +149,4 @@ void UpdateItemRoom(ItemInfo* item, int height, int xOffset = 0, int zOffset = 0
std::vector<int> FindAllItems(short objectNumber);
ItemInfo* FindItem(int objectNumber);
int FindItem(ItemInfo* item);
void DoDamage(ItemInfo* item, int damage);

View file

@ -85,8 +85,7 @@ void ControlMissile(short fxNumber)
{
if (ItemNearLara(&fx->pos, 350))
{
LaraItem->HitPoints -= 3;
LaraItem->hitStatus = 1;
DoDamage(LaraItem, 3);
LaraBurn(LaraItem);
return;
}
@ -95,14 +94,12 @@ void ControlMissile(short fxNumber)
{
/*if (fx->objectNumber == KNIFE)
{
LaraItem->HitPoints -= KNIFE_DAMAGE;
SoundEffect(317, &fx->pos);
DoDamage(LaraItem, KNIFE_DAMAGE);
KillEffect(fx_number);
}
else*/ if (fx->objectNumber == ID_SCUBA_HARPOON)
{
LaraItem->HitPoints -= DIVER_HARPOON_DAMAGE;
SoundEffect(317, &fx->pos);
DoDamage(LaraItem, DIVER_HARPOON_DAMAGE);
KillEffect(fxNumber);
}

View file

@ -47,8 +47,7 @@ bool ShotLara(ItemInfo* item, AI_INFO* AI, BITE_INFO* gun, short extraRotation,
if (hit)
{
CreatureEffect(item, gun, &GunHit);
LaraItem->HitPoints -= damage;
LaraItem->HitStatus = true;
DoDamage(LaraItem, damage);
}
else if (targetable)
CreatureEffect(item, gun, &GunMiss);
@ -94,10 +93,7 @@ short GunHit(int x, int y, int z, short velocity, short yRot, short roomNumber)
{
Vector3Int pos = { 0, 0, 0 };
GetLaraJointPosition(&pos, (25 * GetRandomControl()) >> 15);
DoBloodSplat(pos.x, pos.y, pos.z, (GetRandomControl() & 3) + 3, LaraItem->Pose.Orientation.y, LaraItem->RoomNumber);
SoundEffect(SFX_TR4_LARA_INJURY, &LaraItem->Pose);
return GunShot(x, y, z, velocity, yRot, roomNumber);
}

View file

@ -28,6 +28,7 @@
#include "Specific/phd_global.h"
#include "Specific/setup.h"
using namespace TEN::Input;
using namespace TEN::Entities::Generic;
// TODO: Adjust these bounds when crawl surface alignment is implemented. @Sezz 2021.11.04

View file

@ -260,7 +260,7 @@ bool SaveGame::Save(int slot)
count.add_no_cheat(Lara.Control.Count.NoCheat);
count.add_pose(Lara.Control.Count.Pose);
count.add_position_adjust(Lara.Control.Count.PositionAdjust);
count.add_run_jump(Lara.Control.Count.RunJump);
count.add_run_jump(Lara.Control.Count.Run);
auto countOffset = count.Finish();
Save::WeaponControlDataBuilder weaponControl{ fbb };
@ -390,7 +390,6 @@ bool SaveGame::Save(int slot)
lara.add_poison_potency(Lara.PoisonPotency);
lara.add_projected_floor_height(Lara.ProjectedFloorHeight);
lara.add_right_arm(rightArmOffset);
lara.add_spasm_effect_count(Lara.SpasmEffectCount);
lara.add_sprint_energy(Lara.SprintEnergy);
lara.add_target_facing_angle(Lara.TargetOrientation.y);
lara.add_target_arm_angles(laraTargetAnglesOffset);
@ -1620,7 +1619,7 @@ bool SaveGame::Load(int slot)
Lara.Control.Count.NoCheat = s->lara()->control()->count()->no_cheat();
Lara.Control.Count.Pose = s->lara()->control()->count()->pose();
Lara.Control.Count.PositionAdjust = s->lara()->control()->count()->position_adjust();
Lara.Control.Count.RunJump = s->lara()->control()->count()->run_jump();
Lara.Control.Count.Run = s->lara()->control()->count()->run_jump();
Lara.Control.Count.Death = s->lara()->control()->count()->death();
Lara.Control.IsClimbingLadder = s->lara()->control()->is_climbing_ladder();
Lara.Control.IsLow = s->lara()->control()->is_low();
@ -1738,7 +1737,6 @@ bool SaveGame::Load(int slot)
Lara.Control.Tightrope.TightropeItem = s->lara()->control()->tightrope()->tightrope_item();
Lara.Control.Tightrope.TimeOnTightrope = s->lara()->control()->tightrope()->time_on_tightrope();
Lara.Control.WaterStatus = (WaterStatus)s->lara()->control()->water_status();
Lara.SpasmEffectCount = s->lara()->spasm_effect_count();
Lara.SprintEnergy = s->lara()->sprint_energy();
Lara.TargetEntity = (s->lara()->target_entity_number() >= 0 ? &g_Level.Items[s->lara()->target_entity_number()] : nullptr);
Lara.TargetArmOrient.y = s->lara()->target_arm_angles()->Get(0);

View file

@ -11,9 +11,12 @@
#include "Game/Lara/lara_helpers.h"
#include "Specific/input.h"
using namespace TEN::Input;
using namespace TEN::Renderer;
using namespace TEN::Control::Volumes;
constexpr auto MAX_CAMERA = 18;
int TrackCameraInit;
int SpotcamTimer;
int SpotcamPaused;

View file

@ -18,6 +18,7 @@
#include "Specific/trmath.h"
#include "input.h"
using namespace TEN::Input;
using namespace TEN::Effects::Lara;
using namespace TEN::Effects::Lightning;
using namespace TEN::Effects::Environment;

View file

@ -19,6 +19,8 @@
#include "Objects/Generic/Doors/double_doors.h"
#include "Game/collision/collide_item.h"
using namespace TEN::Input;
namespace TEN::Entities::Doors
{
Vector3Int DoubleDoorPos(0, 0, 220);

View file

@ -23,6 +23,8 @@
#include "Game/collision/collide_item.h"
#include "Game/itemdata/itemdata.h"
using namespace TEN::Input;
namespace TEN::Entities::Doors
{
Vector3Int CrowbarDoorPos(-412, 0, 256);

View file

@ -20,6 +20,8 @@
#include "Game/collision/collide_item.h"
#include "Game/itemdata/door_data.h"
using namespace TEN::Input;
namespace TEN::Entities::Doors
{
enum STATES_PUSHPULL_KICK_DOOR

View file

@ -19,6 +19,8 @@
#include "Objects/Generic/Doors/underwater_door.h"
#include "Game/collision/collide_item.h"
using namespace TEN::Input;
namespace TEN::Entities::Doors
{
Vector3Int UnderwaterDoorPos(-251, -540, -46);

View file

@ -16,6 +16,7 @@
#include "Game/control/los.h"
#include "Renderer/Renderer11Enums.h"
using namespace TEN::Input;
using namespace TEN::Entities::Effects;
namespace TEN::Entities::Generic

View file

@ -12,8 +12,8 @@
#include "Renderer/Renderer11.h"
#include "Game/collision/collide_item.h"
using namespace TEN::Input;
using namespace TEN::Renderer;
using namespace TEN::Floordata;
OBJECT_COLLISION_BOUNDS CeilingTrapDoorBounds =

View file

@ -14,6 +14,8 @@
#include "Game/collision/collide_item.h"
#include "Renderer/Renderer11Enums.h"
using namespace TEN::Input;
OBJECT_TEXTURE* WaterfallTextures[6];
float WaterfallY[6];
int lastWaterfallY = 0;

View file

@ -13,6 +13,8 @@
#include "Game/collision/collide_item.h"
#include "Game/collision/sphere.h"
using namespace TEN::Input;
namespace TEN::Entities::Generic
{
Vector3Int PolePos = { 0, 0, -208 };

View file

@ -15,6 +15,8 @@
#include "Sound/sound.h"
#include "Game/camera.h"
using namespace TEN::Input;
namespace TEN::Entities::Generic
{
PENDULUM CurrentPendulum;

View file

@ -12,6 +12,7 @@
#include "Game/animation.h"
#include "Game/items.h"
using namespace TEN::Input;
using namespace TEN::Entities::Doors;
namespace TEN::Entities::Switches

View file

@ -12,6 +12,8 @@
#include "Game/animation.h"
#include "Game/items.h"
using namespace TEN::Input;
namespace TEN::Entities::Switches
{
Vector3Int CrowbarPos = { -89, 0, -328 };

View file

@ -10,6 +10,8 @@
#include "Game/animation.h"
#include "Game/items.h"
using namespace TEN::Input;
namespace TEN::Entities::Switches
{
OBJECT_COLLISION_BOUNDS FullBlockSwitchBounds =

View file

@ -9,6 +9,8 @@
#include "Game/collision/collide_item.h"
#include "Game/items.h"
using namespace TEN::Input;
namespace TEN::Entities::Switches
{
OBJECT_COLLISION_BOUNDS SwitchBounds =

View file

@ -9,6 +9,8 @@
#include "Game/collision/collide_item.h"
#include "Game/items.h"
using namespace TEN::Input;
namespace TEN::Entities::Switches
{
OBJECT_COLLISION_BOUNDS JumpSwitchBounds =

View file

@ -11,6 +11,8 @@
#include "Game/collision/collide_item.h"
#include "Game/items.h"
using namespace TEN::Input;
namespace TEN::Entities::Switches
{
OBJECT_COLLISION_BOUNDS PulleyBounds =

View file

@ -9,6 +9,8 @@
#include "Game/animation.h"
#include "Game/items.h"
using namespace TEN::Input;
namespace TEN::Entities::Switches
{
Vector3Int RailSwitchPos = { 0, 0, -550 };

Some files were not shown because too many files have changed in this diff Show more