diff options
Diffstat (limited to 'src/object/motion')
-rw-r--r-- | src/object/motion/motion.cpp | 478 | ||||
-rw-r--r-- | src/object/motion/motion.h | 186 | ||||
-rw-r--r-- | src/object/motion/motionant.cpp | 1742 | ||||
-rw-r--r-- | src/object/motion/motionant.h | 146 | ||||
-rw-r--r-- | src/object/motion/motionbee.cpp | 1288 | ||||
-rw-r--r-- | src/object/motion/motionbee.h | 132 | ||||
-rw-r--r-- | src/object/motion/motionhuman.cpp | 3540 | ||||
-rw-r--r-- | src/object/motion/motionhuman.h | 188 | ||||
-rw-r--r-- | src/object/motion/motionmother.cpp | 1048 | ||||
-rw-r--r-- | src/object/motion/motionmother.h | 108 | ||||
-rw-r--r-- | src/object/motion/motionspider.cpp | 1518 | ||||
-rw-r--r-- | src/object/motion/motionspider.h | 142 | ||||
-rw-r--r-- | src/object/motion/motiontoto.cpp | 1738 | ||||
-rw-r--r-- | src/object/motion/motiontoto.h | 140 | ||||
-rw-r--r-- | src/object/motion/motionvehicle.cpp | 4146 | ||||
-rw-r--r-- | src/object/motion/motionvehicle.h | 138 | ||||
-rw-r--r-- | src/object/motion/motionworm.cpp | 730 | ||||
-rw-r--r-- | src/object/motion/motionworm.h | 124 |
18 files changed, 8766 insertions, 8766 deletions
diff --git a/src/object/motion/motion.cpp b/src/object/motion/motion.cpp index 3231f7a..5ffa63c 100644 --- a/src/object/motion/motion.cpp +++ b/src/object/motion/motion.cpp @@ -1,239 +1,239 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motion.cpp
-
-
-#include <stdio.h>
-
-#include "object/motion/motion.h"
-
-#include "common/iman.h"
-#include "script/cmdtoken.h"
-
-
-
-
-// Object's constructor.
-
-CMotion::CMotion(CInstanceManager* iMan, CObject* object)
-{
- m_iMan = iMan;
- m_iMan->AddInstance(CLASS_MOTION, this, 100);
-
- m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE);
- m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT);
- m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE);
- m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN);
- m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER);
- m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA);
- m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN);
- m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND);
-
- m_object = object;
- m_physics = 0;
- m_brain = 0;
-
- m_actionType = -1;
- m_actionTime = 0.0f;
- m_progress = 0.0f;
-
- m_linVibration = Math::Vector(0.0f, 0.0f, 0.0f);
- m_cirVibration = Math::Vector(0.0f, 0.0f, 0.0f);
- m_inclinaison = Math::Vector(0.0f, 0.0f, 0.0f);
-}
-
-// Object's destructor.
-
-CMotion::~CMotion()
-{
- m_iMan->DeleteInstance(CLASS_MOTION, this);
-}
-
-// Deletes the object.
-
-void CMotion::DeleteObject(bool bAll)
-{
-}
-
-
-void CMotion::SetPhysics(CPhysics* physics)
-{
- m_physics = physics;
-}
-
-void CMotion::SetBrain(CBrain* brain)
-{
- m_brain = brain;
-}
-
-
-// Creates.
-
-bool CMotion::Create(Math::Vector pos, float angle, ObjectType type, float power)
-{
- return true;
-}
-
-// Management of an event.
-
-bool CMotion::EventProcess(const Event &event)
-{
- Math::Vector pos, dir;
- float time;
-
- if ( m_object->RetType() != OBJECT_TOTO &&
- m_engine->RetPause() ) return true;
-
- if ( event.event != EVENT_FRAME ) return true;
-
- m_progress += event.rTime*m_actionTime;
- if ( m_progress > 1.0f ) m_progress = 1.0f; // (*)
-
- pos = m_object->RetPosition(0);
- if ( pos.y < m_water->RetLevel(m_object) ) // underwater?
- {
- time = event.rTime*3.0f; // everything is slower
- }
- else
- {
- time = event.rTime*10.0f;
- }
-
- dir = m_object->RetLinVibration();
- dir.x = Math::Smooth(dir.x, m_linVibration.x, time);
- dir.y = Math::Smooth(dir.y, m_linVibration.y, time);
- dir.z = Math::Smooth(dir.z, m_linVibration.z, time);
- m_object->SetLinVibration(dir);
-
- dir = m_object->RetCirVibration();
- dir.x = Math::Smooth(dir.x, m_cirVibration.x, time);
- dir.y = Math::Smooth(dir.y, m_cirVibration.y, time);
- dir.z = Math::Smooth(dir.z, m_cirVibration.z, time);
- m_object->SetCirVibration(dir);
-
- dir = m_object->RetInclinaison();
- dir.x = Math::Smooth(dir.x, m_inclinaison.x, time);
- dir.y = Math::Smooth(dir.y, m_inclinaison.y, time);
- dir.z = Math::Smooth(dir.z, m_inclinaison.z, time);
- m_object->SetInclinaison(dir);
-
- return true;
-}
-
-// (*) Avoids the bug of ants returned by the thumper and
-// whose abdomen grown to infinity!
-
-
-// Start an action.
-
-Error CMotion::SetAction(int action, float time)
-{
- m_actionType = action;
- m_actionTime = 1.0f/time;
- m_progress = 0.0f;
- return ERR_OK;
-}
-
-// Returns the current action.
-
-int CMotion::RetAction()
-{
- return m_actionType;
-}
-
-
-// Specifies a special parameter.
-
-bool CMotion::SetParam(int rank, float value)
-{
- return false;
-}
-
-float CMotion::RetParam(int rank)
-{
- return 0.0f;
-}
-
-
-// Saves all parameters of the object.
-
-bool CMotion::Write(char *line)
-{
- char name[100];
-
- if ( m_actionType == -1 ) return false;
-
- sprintf(name, " mType=%d", m_actionType);
- strcat(line, name);
-
- sprintf(name, " mTime=%.2f", m_actionTime);
- strcat(line, name);
-
- sprintf(name, " mProgress=%.2f", m_progress);
- strcat(line, name);
-
- return false;
-}
-
-// Restores all parameters of the object.
-
-bool CMotion::Read(char *line)
-{
- m_actionType = OpInt(line, "mType", -1);
- m_actionTime = OpFloat(line, "mTime", 0.0f);
- m_progress = OpFloat(line, "mProgress", 0.0f);
-
- return false;
-}
-
-
-// Gives the linear vibration.
-
-void CMotion::SetLinVibration(Math::Vector dir)
-{
- m_linVibration = dir;
-}
-
-Math::Vector CMotion::RetLinVibration()
-{
- return m_linVibration;
-}
-
-// Gives the circular vibration.
-
-void CMotion::SetCirVibration(Math::Vector dir)
-{
- m_cirVibration = dir;
-}
-
-Math::Vector CMotion::RetCirVibration()
-{
- return m_cirVibration;
-}
-
-// Gives the tilt.
-
-void CMotion::SetInclinaison(Math::Vector dir)
-{
- m_inclinaison = dir;
-}
-
-Math::Vector CMotion::RetInclinaison()
-{
- return m_inclinaison;
-}
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motion.cpp + + +#include <stdio.h> + +#include "object/motion/motion.h" + +#include "common/iman.h" +#include "script/cmdtoken.h" + + + + +// Object's constructor. + +CMotion::CMotion(CInstanceManager* iMan, CObject* object) +{ + m_iMan = iMan; + m_iMan->AddInstance(CLASS_MOTION, this, 100); + + m_engine = (CD3DEngine*)m_iMan->SearchInstance(CLASS_ENGINE); + m_light = (CLight*)m_iMan->SearchInstance(CLASS_LIGHT); + m_particule = (CParticule*)m_iMan->SearchInstance(CLASS_PARTICULE); + m_terrain = (CTerrain*)m_iMan->SearchInstance(CLASS_TERRAIN); + m_water = (CWater*)m_iMan->SearchInstance(CLASS_WATER); + m_camera = (CCamera*)m_iMan->SearchInstance(CLASS_CAMERA); + m_main = (CRobotMain*)m_iMan->SearchInstance(CLASS_MAIN); + m_sound = (CSound*)m_iMan->SearchInstance(CLASS_SOUND); + + m_object = object; + m_physics = 0; + m_brain = 0; + + m_actionType = -1; + m_actionTime = 0.0f; + m_progress = 0.0f; + + m_linVibration = Math::Vector(0.0f, 0.0f, 0.0f); + m_cirVibration = Math::Vector(0.0f, 0.0f, 0.0f); + m_inclinaison = Math::Vector(0.0f, 0.0f, 0.0f); +} + +// Object's destructor. + +CMotion::~CMotion() +{ + m_iMan->DeleteInstance(CLASS_MOTION, this); +} + +// Deletes the object. + +void CMotion::DeleteObject(bool bAll) +{ +} + + +void CMotion::SetPhysics(CPhysics* physics) +{ + m_physics = physics; +} + +void CMotion::SetBrain(CBrain* brain) +{ + m_brain = brain; +} + + +// Creates. + +bool CMotion::Create(Math::Vector pos, float angle, ObjectType type, float power) +{ + return true; +} + +// Management of an event. + +bool CMotion::EventProcess(const Event &event) +{ + Math::Vector pos, dir; + float time; + + if ( m_object->RetType() != OBJECT_TOTO && + m_engine->RetPause() ) return true; + + if ( event.event != EVENT_FRAME ) return true; + + m_progress += event.rTime*m_actionTime; + if ( m_progress > 1.0f ) m_progress = 1.0f; // (*) + + pos = m_object->RetPosition(0); + if ( pos.y < m_water->RetLevel(m_object) ) // underwater? + { + time = event.rTime*3.0f; // everything is slower + } + else + { + time = event.rTime*10.0f; + } + + dir = m_object->RetLinVibration(); + dir.x = Math::Smooth(dir.x, m_linVibration.x, time); + dir.y = Math::Smooth(dir.y, m_linVibration.y, time); + dir.z = Math::Smooth(dir.z, m_linVibration.z, time); + m_object->SetLinVibration(dir); + + dir = m_object->RetCirVibration(); + dir.x = Math::Smooth(dir.x, m_cirVibration.x, time); + dir.y = Math::Smooth(dir.y, m_cirVibration.y, time); + dir.z = Math::Smooth(dir.z, m_cirVibration.z, time); + m_object->SetCirVibration(dir); + + dir = m_object->RetInclinaison(); + dir.x = Math::Smooth(dir.x, m_inclinaison.x, time); + dir.y = Math::Smooth(dir.y, m_inclinaison.y, time); + dir.z = Math::Smooth(dir.z, m_inclinaison.z, time); + m_object->SetInclinaison(dir); + + return true; +} + +// (*) Avoids the bug of ants returned by the thumper and +// whose abdomen grown to infinity! + + +// Start an action. + +Error CMotion::SetAction(int action, float time) +{ + m_actionType = action; + m_actionTime = 1.0f/time; + m_progress = 0.0f; + return ERR_OK; +} + +// Returns the current action. + +int CMotion::RetAction() +{ + return m_actionType; +} + + +// Specifies a special parameter. + +bool CMotion::SetParam(int rank, float value) +{ + return false; +} + +float CMotion::RetParam(int rank) +{ + return 0.0f; +} + + +// Saves all parameters of the object. + +bool CMotion::Write(char *line) +{ + char name[100]; + + if ( m_actionType == -1 ) return false; + + sprintf(name, " mType=%d", m_actionType); + strcat(line, name); + + sprintf(name, " mTime=%.2f", m_actionTime); + strcat(line, name); + + sprintf(name, " mProgress=%.2f", m_progress); + strcat(line, name); + + return false; +} + +// Restores all parameters of the object. + +bool CMotion::Read(char *line) +{ + m_actionType = OpInt(line, "mType", -1); + m_actionTime = OpFloat(line, "mTime", 0.0f); + m_progress = OpFloat(line, "mProgress", 0.0f); + + return false; +} + + +// Gives the linear vibration. + +void CMotion::SetLinVibration(Math::Vector dir) +{ + m_linVibration = dir; +} + +Math::Vector CMotion::RetLinVibration() +{ + return m_linVibration; +} + +// Gives the circular vibration. + +void CMotion::SetCirVibration(Math::Vector dir) +{ + m_cirVibration = dir; +} + +Math::Vector CMotion::RetCirVibration() +{ + return m_cirVibration; +} + +// Gives the tilt. + +void CMotion::SetInclinaison(Math::Vector dir) +{ + m_inclinaison = dir; +} + +Math::Vector CMotion::RetInclinaison() +{ + return m_inclinaison; +} + diff --git a/src/object/motion/motion.h b/src/object/motion/motion.h index bdb9ce0..9828283 100644 --- a/src/object/motion/motion.h +++ b/src/object/motion/motion.h @@ -1,93 +1,93 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motion.h
-
-#pragma once
-
-
-#include "common/event.h"
-#include "common/misc.h"
-#include "object/object.h"
-
-
-class CInstanceManager;
-class CD3DEngine;
-class CLight;
-class CParticule;
-class CTerrain;
-class CWater;
-class CCamera;
-class CBrain;
-class CPhysics;
-class CObject;
-class CRobotMain;
-class CSound;
-
-
-class CMotion
-{
-public:
- CMotion(CInstanceManager* iMan, CObject* object);
- virtual ~CMotion();
-
- void SetPhysics(CPhysics* physics);
- void SetBrain(CBrain* brain);
-
- virtual void DeleteObject(bool bAll=false);
- virtual bool Create(Math::Vector pos, float angle, ObjectType type, float power);
- virtual bool EventProcess(const Event &event);
- virtual Error SetAction(int action, float time=0.2f);
- virtual int RetAction();
-
- virtual bool SetParam(int rank, float value);
- virtual float RetParam(int rank);
-
- virtual bool Write(char *line);
- virtual bool Read(char *line);
-
- virtual void SetLinVibration(Math::Vector dir);
- virtual Math::Vector RetLinVibration();
- virtual void SetCirVibration(Math::Vector dir);
- virtual Math::Vector RetCirVibration();
- virtual void SetInclinaison(Math::Vector dir);
- virtual Math::Vector RetInclinaison();
-
-protected:
-
-protected:
- CInstanceManager* m_iMan;
- CD3DEngine* m_engine;
- CLight* m_light;
- CParticule* m_particule;
- CTerrain* m_terrain;
- CWater* m_water;
- CCamera* m_camera;
- CObject* m_object;
- CBrain* m_brain;
- CPhysics* m_physics;
- CRobotMain* m_main;
- CSound* m_sound;
-
- int m_actionType;
- float m_actionTime;
- float m_progress;
-
- Math::Vector m_linVibration; // linear vibration
- Math::Vector m_cirVibration; // circular vibration
- Math::Vector m_inclinaison; // tilt
-};
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motion.h + +#pragma once + + +#include "common/event.h" +#include "common/misc.h" +#include "object/object.h" + + +class CInstanceManager; +class CD3DEngine; +class CLight; +class CParticule; +class CTerrain; +class CWater; +class CCamera; +class CBrain; +class CPhysics; +class CObject; +class CRobotMain; +class CSound; + + +class CMotion +{ +public: + CMotion(CInstanceManager* iMan, CObject* object); + virtual ~CMotion(); + + void SetPhysics(CPhysics* physics); + void SetBrain(CBrain* brain); + + virtual void DeleteObject(bool bAll=false); + virtual bool Create(Math::Vector pos, float angle, ObjectType type, float power); + virtual bool EventProcess(const Event &event); + virtual Error SetAction(int action, float time=0.2f); + virtual int RetAction(); + + virtual bool SetParam(int rank, float value); + virtual float RetParam(int rank); + + virtual bool Write(char *line); + virtual bool Read(char *line); + + virtual void SetLinVibration(Math::Vector dir); + virtual Math::Vector RetLinVibration(); + virtual void SetCirVibration(Math::Vector dir); + virtual Math::Vector RetCirVibration(); + virtual void SetInclinaison(Math::Vector dir); + virtual Math::Vector RetInclinaison(); + +protected: + +protected: + CInstanceManager* m_iMan; + CD3DEngine* m_engine; + CLight* m_light; + CParticule* m_particule; + CTerrain* m_terrain; + CWater* m_water; + CCamera* m_camera; + CObject* m_object; + CBrain* m_brain; + CPhysics* m_physics; + CRobotMain* m_main; + CSound* m_sound; + + int m_actionType; + float m_actionTime; + float m_progress; + + Math::Vector m_linVibration; // linear vibration + Math::Vector m_cirVibration; // circular vibration + Math::Vector m_inclinaison; // tilt +}; + diff --git a/src/object/motion/motionant.cpp b/src/object/motion/motionant.cpp index c85a631..c6a9357 100644 --- a/src/object/motion/motionant.cpp +++ b/src/object/motion/motionant.cpp @@ -1,871 +1,871 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motionant.cpp
-
-
-#include <stdio.h>
-
-#include "object/motion/motionant.h"
-
-#include "old/modfile.h"
-#include "old/particule.h"
-#include "physics/physics.h"
-
-
-
-#define ADJUST_ANGLE false // true -> adjusts the angles of the members
-const float START_TIME = 1000.0f; // beginning of the relative time
-
-
-
-// Object's constructor.
-
-CMotionAnt::CMotionAnt(CInstanceManager* iMan, CObject* object)
- : CMotion(iMan, object)
-{
- m_armMember = START_TIME;
- m_armTimeAbs = START_TIME;
- m_armTimeMarch = START_TIME;
- m_armTimeAction = START_TIME;
- m_armTimeIndex = 0;
- m_armPartIndex = 0;
- m_armMemberIndex = 0;
- m_armLastAction = -1;
- m_bArmStop = false;
- m_lastParticule = 0.0f;
-}
-
-// Object's destructor.
-
-CMotionAnt::~CMotionAnt()
-{
-}
-
-
-// Removes an object.
-
-void CMotionAnt::DeleteObject(bool bAll)
-{
-}
-
-
-// Creates a vehicle poses some rolling on the floor.
-
-bool CMotionAnt::Create(Math::Vector pos, float angle, ObjectType type,
- float power)
-{
- CModFile* pModFile;
- int rank;
-
- if ( m_engine->RetRestCreate() < 3+18 ) return false;
-
- pModFile = new CModFile(m_iMan);
-
- m_object->SetType(type);
-
- // Creates the main base.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object
- m_object->SetObjectRank(0, rank);
-
- pModFile->ReadModel("objects\\ant1.mod");
- pModFile->CreateEngineObject(rank);
-
- m_object->SetPosition(0, pos);
- m_object->SetAngleY(0, angle);
-
- // A vehicle must have necessarily a collision
- //with a sphere of center (0, y, 0) (see GetCrashSphere).
- m_object->CreateCrashSphere(Math::Vector(0.0f, -2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f);
- m_object->SetGlobalSphere(Math::Vector(-0.5f, 1.0f, 0.0f), 4.0f);
-
- // Creates the head.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\ant2.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(2.0f, 0.0f, 0.0f));
-
- // Creates the tail.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 0);
- pModFile->ReadModel("objects\\ant3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2, Math::Vector(-1.0f, 0.0f, 0.0f));
-
- // Creates a right-back thigh.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(3, rank);
- m_object->SetObjectParent(3, 0);
- pModFile->ReadModel("objects\\ant4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(3, Math::Vector(-0.4f, -0.1f, -0.3f));
-
- // Creates a right-back leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(4, rank);
- m_object->SetObjectParent(4, 3);
- pModFile->ReadModel("objects\\ant5.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(4, Math::Vector(0.0f, 0.0f, -1.0f));
-
- // Creates a right-back foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(5, rank);
- m_object->SetObjectParent(5, 4);
- pModFile->ReadModel("objects\\ant6.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(5, Math::Vector(0.0f, 0.0f, -2.0f));
-
- // Creates two middle-right thighs.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(6, rank);
- m_object->SetObjectParent(6, 0);
- pModFile->ReadModel("objects\\ant4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(6, Math::Vector(0.1f, -0.1f, -0.4f));
-
- // Creates two middle-right legs.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(7, rank);
- m_object->SetObjectParent(7, 6);
- pModFile->ReadModel("objects\\ant5.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(7, Math::Vector(0.0f, 0.0f, -1.0f));
-
- // Creates two middle-right foots.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(8, rank);
- m_object->SetObjectParent(8, 7);
- pModFile->ReadModel("objects\\ant6.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(8, Math::Vector(0.0f, 0.0f, -2.0f));
-
- // Creates the right front thigh.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(9, rank);
- m_object->SetObjectParent(9, 0);
- pModFile->ReadModel("objects\\ant4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(9, Math::Vector(1.4f, -0.1f, -0.6f));
-
- // Creates the right front leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(10, rank);
- m_object->SetObjectParent(10, 9);
- pModFile->ReadModel("objects\\ant5.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(10, Math::Vector(0.0f, 0.0f, -1.0f));
-
- // Creates the right front foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(11, rank);
- m_object->SetObjectParent(11, 10);
- pModFile->ReadModel("objects\\ant6.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(11, Math::Vector(0.0f, 0.0f, -2.0f));
-
- // Creates a left-back thigh.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(12, rank);
- m_object->SetObjectParent(12, 0);
- pModFile->ReadModel("objects\\ant4.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(12, Math::Vector(-0.4f, -0.1f, 0.3f));
-
- // Creates a left-back leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(13, rank);
- m_object->SetObjectParent(13, 12);
- pModFile->ReadModel("objects\\ant5.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(13, Math::Vector(0.0f, 0.0f, 1.0f));
-
- // Creates a left-back foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(14, rank);
- m_object->SetObjectParent(14, 13);
- pModFile->ReadModel("objects\\ant6.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(14, Math::Vector(0.0f, 0.0f, 2.0f));
-
- // Creates two middle-left thighs.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(15, rank);
- m_object->SetObjectParent(15, 0);
- pModFile->ReadModel("objects\\ant4.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(15, Math::Vector(0.1f, -0.1f, 0.4f));
-
- // Creates two middle-left legs.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(16, rank);
- m_object->SetObjectParent(16, 15);
- pModFile->ReadModel("objects\\ant5.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(16, Math::Vector(0.0f, 0.0f, 1.0f));
-
- // Creates two middle-left foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(17, rank);
- m_object->SetObjectParent(17, 16);
- pModFile->ReadModel("objects\\ant6.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(17, Math::Vector(0.0f, 0.0f, 2.0f));
-
- // Creates the left front thigh.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(18, rank);
- m_object->SetObjectParent(18, 0);
- pModFile->ReadModel("objects\\ant4.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(18, Math::Vector(1.4f, -0.1f, 0.6f));
-
- // Creates the left front leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(19, rank);
- m_object->SetObjectParent(19, 18);
- pModFile->ReadModel("objects\\ant5.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(19, Math::Vector(0.0f, 0.0f, 1.0f));
-
- // Creates the left front foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(20, rank);
- m_object->SetObjectParent(20, 19);
- pModFile->ReadModel("objects\\ant6.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(20, Math::Vector(0.0f, 0.0f, 2.0f));
-
- m_object->CreateShadowCircle(4.0f, 0.5f);
-
- CreatePhysics();
- m_object->SetFloorHeight(0.0f);
-
- pos = m_object->RetPosition(0);
- m_object->SetPosition(0, pos); // to display the shadows immediately
-
- m_engine->LoadAllTexture();
-
- delete pModFile;
- return true;
-}
-
-// Creates the physics of the object.
-
-void CMotionAnt::CreatePhysics()
-{
- Character* character;
- int i;
-
- int member_march[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air:
- 0,45,0, 0,45,0, 0,50,0, // t0: thighs 1..3
- 30,-70,0, 20,-105,20, 25,-100,0, // t0: legs 1..3
- -70,75,0, -30,80,0, -80,80,0, // t0: feet 1..3
- // on the ground:
- 0,30,0, 0,20,0, 0,15,0, // t1: thighs 1..3
- -15,-50,0, -20,-60,0, -10,-75,0, // t1: legs 1..3
- -40,50,0, -25,15,0, -50,35,0, // t1: feet 1..3
- // on the ground back:
- 0,35,0, 0,30,0, 0,20,0, // t2: thighs 1..3
- -20,-15,0, -30,-55,0, -25,-70,15, // t2: legs 1..3
- -25,25,0, -20,60,0, -30,95,0, // t2: feet 1..3
- };
-
- int member_stop[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air:
- 0,30,0, 0,20,0, 0,15,0, // t0: thighs 1..3
- -15,-35,0, -20,-60,0, -15,-75,0, // t0: legs 1..3
- -35,35,0, -25,40,0, -40,65,0, // t0: feet 1..3
- // on the ground:
- 0,30,0, 0,20,0, 0,15,0, // t1: thighs 1..3
- -15,-35,0, -20,-60,0, -15,-75,0, // t1: legs 1..3
- -35,35,0, -25,40,0, -40,65,0, // t1: feet 1..3
- // on the ground back:
- 0,30,0, 0,20,0, 0,15,0, // t2: thighs 1..3
- -15,-35,0, -20,-60,0, -15,-75,0, // t2: legs 1..3
- -35,35,0, -25,40,0, -40,65,0, // t2: feet 1..3
- };
-
- int member_spec[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3, // prepares the fire:
- 0,20,0, 0,10,0, 0,50,0, // s0: thighs 1..3
- -50,-30,0, -20,-15,0, 35,-65,0, // s0: legs 1..3
- -5,-40,0, 20,-70,0, -10,-40,0, // s0: feet 1..3
- // shot:
- 0,20,0, 0,10,0, 0,50,0, // s1: thighs 1..3
- -50,-30,0, -20,-15,0, 35,-65,0, // s1: legs 1..3
- -5,-40,0, 20,-70,0, -10,-40,0, // s1: feet 1..3
- // ends the fire:
- 0,30,0, 0,20,0, 0,15,0, // s2: thighs 1..3
- -15,-50,0, -20,-60,0, -10,-75,0, // s2: legs 1..3
- -40,50,0, -25,15,0, -50,35,0, // s2: feet 1..3
- // burning:
- 0,30,0, 0,20,0, 0,15,0, // s3: thighs 1..3
- -15,-35,0, -20,-60,0, -15,-75,0, // s3: legs 1..3
- -35,35,0, -25,40,0, -40,65,0, // s3: feet 1..3
- // destroyed:
- 0,30,0, 0,20,0, 0,15,0, // s4: thighs 1..3
- -15,-35,0, -20,-60,0, -15,-75,0, // s4: legs 1..3
- -35,35,0, -25,40,0, -40,65,0, // s4: feet 1..3
- // back1 :
- 0,30,0, 0,20,0, 0,15,0, // s5: thighs 1..3
- -15,-35,0, -20,-60,0, -15,-75,0, // s5: legs 1..3
- -35,35,0, -25,40,0, -40,65,0, // s5: feet 1..3
- // back2 :
- 0,45,0, 0,45,0, 0,50,0, // s6: thighs 1..3
- -35,-70,0, -20,-85,-25, -25,-100,0, // s6: legs 1..3
- -110,75,-15, -130,80,-25, -125,40,0, // s6: feet 1..3
- // back3 :
- 0,30,0, 0,20,0, 0,15,0, // s7: thighs 1..3
- -15,-35,0, -20,-60,0, -15,-75,0, // s7: legs 1..3
- -35,35,0, -25,40,0, -40,65,0, // s7: feet 1..3
- };
-
- m_physics->SetType(TYPE_ROLLING);
-
- character = m_object->RetCharacter();
- character->wheelFront = 3.0f;
- character->wheelBack = 3.0f;
- character->wheelLeft = 5.0f;
- character->wheelRight = 5.0f;
- character->height = 1.2f;
-
- m_physics->SetLinMotionX(MO_ADVSPEED, 12.0f);
- m_physics->SetLinMotionX(MO_RECSPEED, 12.0f);
- m_physics->SetLinMotionX(MO_ADVACCEL, 15.0f);
- m_physics->SetLinMotionX(MO_RECACCEL, 15.0f);
- m_physics->SetLinMotionX(MO_STOACCEL, 40.0f);
- m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionX(MO_TERFORCE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERFORCE, 5.0f);
- m_physics->SetLinMotionZ(MO_MOTACCEL, 10.0f);
-
- m_physics->SetCirMotionY(MO_ADVSPEED, 1.0f*Math::PI);
- m_physics->SetCirMotionY(MO_RECSPEED, 1.0f*Math::PI);
- m_physics->SetCirMotionY(MO_ADVACCEL, 20.0f);
- m_physics->SetCirMotionY(MO_RECACCEL, 20.0f);
- m_physics->SetCirMotionY(MO_STOACCEL, 40.0f);
-
- for ( i=0 ; i<3*3*3*3 ; i++ )
- {
- m_armAngles[3*3*3*3*MA_MARCH+i] = member_march[i];
- }
- for ( i=0 ; i<3*3*3*3 ; i++ )
- {
- m_armAngles[3*3*3*3*MA_STOP+i] = member_stop[i];
- }
- for ( i=0 ; i<3*3*3*8 ; i++ )
- {
- m_armAngles[3*3*3*3*MA_SPEC+i] = member_spec[i];
- }
-}
-
-
-// Management of an event.
-
-bool CMotionAnt::EventProcess(const Event &event)
-{
- CMotion::EventProcess(event);
-
- if ( event.event == EVENT_FRAME )
- {
- return EventFrame(event);
- }
-
- if ( event.event == EVENT_KEYDOWN )
- {
-#if ADJUST_ANGLE
- int i;
-
- if ( event.param == 'A' ) m_armTimeIndex++;
- if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0;
-
- if ( event.param == 'Q' ) m_armPartIndex++;
- if ( m_armPartIndex >= 3 ) m_armPartIndex = 0;
-
- if ( event.param == 'W' ) m_armMemberIndex++;
- if ( m_armMemberIndex >= 3 ) m_armMemberIndex = 0;
-
- i = m_armMemberIndex*3;
- i += m_armPartIndex*3*3;
- i += m_armTimeIndex*3*3*3;
-//? i += 3*3*3*3;
-
- if ( event.param == 'E' ) m_armAngles[i+0] += 5;
- if ( event.param == 'D' ) m_armAngles[i+0] -= 5;
- if ( event.param == 'R' ) m_armAngles[i+1] += 5;
- if ( event.param == 'F' ) m_armAngles[i+1] -= 5;
- if ( event.param == 'T' ) m_armAngles[i+2] += 5;
- if ( event.param == 'G' ) m_armAngles[i+2] -= 5;
-
- if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop;
-#endif
- }
-
- return true;
-}
-
-// Management of an event.
-
-bool CMotionAnt::EventFrame(const Event &event)
-{
- Math::Vector dir, pos, speed;
- Math::Point dim;
- float s, a, prog, time;
- float tSt[9], tNd[9];
- int i, ii, st, nd, action;
- bool bStop;
-
- if ( m_engine->RetPause() ) return true;
- if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return true;
-
- s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.5f;
- a = fabs(m_physics->RetCirMotionY(MO_MOTSPEED)*2.0f);
-
- if ( s == 0.0f && a != 0.0f ) a *= 1.5f;
-
- m_armTimeAbs += event.rTime;
- m_armTimeMarch += (s)*event.rTime*0.15f;
- m_armMember += (s+a)*event.rTime*0.15f;
-
- bStop = ( a == 0.0f && s == 0.0f ); // stopped?
-
- action = MA_MARCH; // walking
- if ( s == 0.0f && a == 0.0f )
- {
- action = MA_STOP; // stop
- }
-
- if ( bStop )
- {
- prog = Math::Mod(m_armTimeAbs, 2.0f)/10.0f;
- a = Math::Mod(m_armMember, 1.0f);
- a = (prog-a)*event.rTime*2.0f; // stop position is pleasantly
- m_armMember += a;
- }
-
- if ( m_object->RetRuin() ) // destroyed?
- {
- m_actionType = MAS_RUIN;
- }
- if ( m_object->RetBurn() ) // burning?
- {
- if ( m_object->RetFixed() )
- {
- m_actionType = MAS_BURN;
- }
- else
- {
- m_actionType = -1;
- }
- }
-
- for ( i=0 ; i<6 ; i++ ) // the six legs
- {
- if ( m_actionType != -1 ) // special action in progress?
- {
- st = 3*3*3*3*MA_SPEC + 3*3*3*m_actionType + (i%3)*3;
- nd = st;
- time = event.rTime*m_actionTime;
- m_armTimeAction = 0.0f;
- }
- else
- {
- if ( i < 3 ) prog = Math::Mod(m_armMember+(2.0f-(i%3))*0.33f+0.0f, 1.0f);
- else prog = Math::Mod(m_armMember+(2.0f-(i%3))*0.33f+0.3f, 1.0f);
- if ( m_bArmStop )
- {
- prog = (float)m_armTimeIndex/3.0f;
- }
- if ( prog < 0.33f ) // t0..t1 ?
- {
- prog = prog/0.33f; // 0..1
- st = 0; // index start
- nd = 1; // index end
- }
- else if ( prog < 0.67f ) // t1..t2 ?
- {
- prog = (prog-0.33f)/0.33f; // 0..1
- st = 1; // index start
- nd = 2; // index end
- }
- else // t2..t0 ?
- {
- prog = (prog-0.67f)/0.33f; // 0..1
- st = 2; // index start
- nd = 0; // index end
- }
- st = 3*3*3*3*action + st*3*3*3 + (i%3)*3;
- nd = 3*3*3*3*action + nd*3*3*3 + (i%3)*3;
-
- // More and more soft ...
- time = event.rTime*(10.0f+Math::Min(m_armTimeAction*100.0f, 200.0f));
- }
-
- tSt[0] = m_armAngles[st+ 0]; // x
- tSt[1] = m_armAngles[st+ 1]; // y
- tSt[2] = m_armAngles[st+ 2]; // z
- tSt[3] = m_armAngles[st+ 9]; // x
- tSt[4] = m_armAngles[st+10]; // y
- tSt[5] = m_armAngles[st+11]; // z
- tSt[6] = m_armAngles[st+18]; // x
- tSt[7] = m_armAngles[st+19]; // y
- tSt[8] = m_armAngles[st+20]; // z
-
- tNd[0] = m_armAngles[nd+ 0]; // x
- tNd[1] = m_armAngles[nd+ 1]; // y
- tNd[2] = m_armAngles[nd+ 2]; // z
- tNd[3] = m_armAngles[nd+ 9]; // x
- tNd[4] = m_armAngles[nd+10]; // y
- tNd[5] = m_armAngles[nd+11]; // z
- tNd[6] = m_armAngles[nd+18]; // x
- tNd[7] = m_armAngles[nd+19]; // y
- tNd[8] = m_armAngles[nd+20]; // z
-
- if ( m_actionType == MAS_BACK2 ) // on the back?
- {
- for ( ii=0 ; ii<9 ; ii++ )
- {
- tSt[ii] += Math::Rand()*50.0f;
- tNd[ii] = tSt[ii];
- }
-//? time = 100.0f;
- time = event.rTime*10.0f;
- }
-
- if ( i < 3 ) // right leg (1..3) ?
- {
- m_object->SetAngleX(3+3*i+0, Math::Smooth(m_object->RetAngleX(3+3*i+0), Math::PropAngle(tSt[0], tNd[0], prog), time));
- m_object->SetAngleY(3+3*i+0, Math::Smooth(m_object->RetAngleY(3+3*i+0), Math::PropAngle(tSt[1], tNd[1], prog), time));
- m_object->SetAngleZ(3+3*i+0, Math::Smooth(m_object->RetAngleZ(3+3*i+0), Math::PropAngle(tSt[2], tNd[2], prog), time));
- m_object->SetAngleX(3+3*i+1, Math::Smooth(m_object->RetAngleX(3+3*i+1), Math::PropAngle(tSt[3], tNd[3], prog), time));
- m_object->SetAngleY(3+3*i+1, Math::Smooth(m_object->RetAngleY(3+3*i+1), Math::PropAngle(tSt[4], tNd[4], prog), time));
- m_object->SetAngleZ(3+3*i+1, Math::Smooth(m_object->RetAngleZ(3+3*i+1), Math::PropAngle(tSt[5], tNd[5], prog), time));
- m_object->SetAngleX(3+3*i+2, Math::Smooth(m_object->RetAngleX(3+3*i+2), Math::PropAngle(tSt[6], tNd[6], prog), time));
- m_object->SetAngleY(3+3*i+2, Math::Smooth(m_object->RetAngleY(3+3*i+2), Math::PropAngle(tSt[7], tNd[7], prog), time));
- m_object->SetAngleZ(3+3*i+2, Math::Smooth(m_object->RetAngleZ(3+3*i+2), Math::PropAngle(tSt[8], tNd[8], prog), time));
- }
- else // left leg (4..6) ?
- {
- m_object->SetAngleX(3+3*i+0, Math::Smooth(m_object->RetAngleX(3+3*i+0), Math::PropAngle(-tSt[0], -tNd[0], prog), time));
- m_object->SetAngleY(3+3*i+0, Math::Smooth(m_object->RetAngleY(3+3*i+0), Math::PropAngle(-tSt[1], -tNd[1], prog), time));
- m_object->SetAngleZ(3+3*i+0, Math::Smooth(m_object->RetAngleZ(3+3*i+0), Math::PropAngle( tSt[2], tNd[2], prog), time));
- m_object->SetAngleX(3+3*i+1, Math::Smooth(m_object->RetAngleX(3+3*i+1), Math::PropAngle(-tSt[3], -tNd[3], prog), time));
- m_object->SetAngleY(3+3*i+1, Math::Smooth(m_object->RetAngleY(3+3*i+1), Math::PropAngle(-tSt[4], -tNd[4], prog), time));
- m_object->SetAngleZ(3+3*i+1, Math::Smooth(m_object->RetAngleZ(3+3*i+1), Math::PropAngle( tSt[5], tNd[5], prog), time));
- m_object->SetAngleX(3+3*i+2, Math::Smooth(m_object->RetAngleX(3+3*i+2), Math::PropAngle(-tSt[6], -tNd[6], prog), time));
- m_object->SetAngleY(3+3*i+2, Math::Smooth(m_object->RetAngleY(3+3*i+2), Math::PropAngle(-tSt[7], -tNd[7], prog), time));
- m_object->SetAngleZ(3+3*i+2, Math::Smooth(m_object->RetAngleZ(3+3*i+2), Math::PropAngle( tSt[8], tNd[8], prog), time));
- }
- }
-
-#if ADJUST_ANGLE
- if ( m_object->RetSelect() )
- {
- char s[100];
- sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex);
- m_engine->SetInfoText(4, s);
- }
-#endif
-
- if ( m_actionType == MAS_PREPARE ) // prepares the shooting?
- {
- prog = m_progress;
-
- dir.x = 0.0f;
- dir.y = 0.0f;
- dir.z = Math::PropAngle(0, -50, prog);
- SetInclinaison(dir);
- m_object->SetAngleZ(1, Math::PropAngle(0, 65, prog)); // head
- m_object->SetAngleZ(2, Math::PropAngle(0, -95, prog)); // tail
- }
- else if ( m_actionType == MAS_FIRE ) // shooting?
- {
- if ( m_progress < 0.75f ) a = m_progress/0.75f;
- else a = (1.0f-m_progress)/0.25f;
- m_object->SetZoom(2, (a*0.5f)+1.0f); // tail
- m_object->SetAngleX(2, (Math::Rand()-0.5f)*0.3f*a);
- m_object->SetAngleY(2, (Math::Rand()-0.5f)*0.3f*a);
-
- dir.x = (Math::Rand()-0.5f)*0.02f*a;
- dir.y = (Math::Rand()-0.5f)*0.05f*a;
- dir.z = (Math::Rand()-0.5f)*0.03f*a;
- SetCirVibration(dir);
- }
- else if ( m_actionType == MAS_TERMINATE ) // ends the shooting?
- {
- prog = 1.0f-m_progress;
-
- dir.x = 0.0f;
- dir.y = 0.0f;
- dir.z = Math::PropAngle(0, -50, prog);
- SetInclinaison(dir);
- m_object->SetAngleZ(1, Math::PropAngle(0, 65, prog)); // head
- m_object->SetAngleZ(2, Math::PropAngle(0, -95, prog)); // tail
- }
- else if ( m_actionType == MAS_BURN ) // burning?
- {
- dir = Math::Vector(Math::PI, 0.0f, 0.0f);
- SetCirVibration(dir);
- dir = Math::Vector(0.0f, -1.5f, 0.0f);
- SetLinVibration(dir);
- dir = Math::Vector(0.0f, 0.0f, 0.0f);
- SetInclinaison(dir);
-
- time = event.rTime*1.0f;
- m_object->SetAngleZ(1, Math::Smooth(m_object->RetAngleZ(1), 0.0f, time)); // head
- m_object->SetAngleZ(2, Math::Smooth(m_object->RetAngleZ(2), 0.0f, time)); // tail
- }
- else if ( m_actionType == MAS_RUIN ) // destroyed?
- {
- dir = Math::Vector(0.0f, 0.0f, 0.0f);
- SetLinVibration(dir);
- SetCirVibration(dir);
- SetInclinaison(dir);
- }
- else if ( m_actionType == MAS_BACK1 ) // starts on the back?
- {
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs )
- {
- m_lastParticule = m_armTimeAbs;
-
- pos = m_object->RetPosition(0);
- speed.x = (Math::Rand()-0.5f)*10.0f;
- speed.z = (Math::Rand()-0.5f)*10.0f;
- speed.y = Math::Rand()*5.0f;
- dim.x = Math::Rand()*3.0f+2.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f);
- }
-
- if ( m_progress < 0.5f )
- {
- dir.x = 0.0f;
- dir.y = powf(m_progress/0.5f, 2.0f)*12.0f;
- dir.z = 0.0f;
- SetLinVibration(dir);
- }
- else
- {
- dir.x = 0.0f;
- dir.y = powf(2.0f-m_progress/0.5f, 2.0f)*12.0f;
- dir.z = 0.0f;
- SetLinVibration(dir);
- }
- dir.x = m_progress*Math::PI;
- dir.y = 0.0f;
- dir.z = 0.0f;
- SetCirVibration(dir);
-
- dir = Math::Vector(0.0f, 0.0f, 0.0f);
- SetInclinaison(dir);
-
- if ( m_progress >= 1.0f )
- {
- SetAction(MAS_BACK2, 55.0f+Math::Rand()*10.0f);
- }
- }
- else if ( m_actionType == MAS_BACK2 ) // moves on the back?
- {
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs )
- {
- m_lastParticule = m_armTimeAbs;
-
- if ( rand()%10 == 0 )
- {
- pos = m_object->RetPosition(0);
- pos.x += (Math::Rand()-0.5f)*5.0f;
- pos.z += (Math::Rand()-0.5f)*5.0f;
- pos.y -= 1.0f;
- speed.x = (Math::Rand()-0.5f)*2.0f;
- speed.z = (Math::Rand()-0.5f)*2.0f;
- speed.y = Math::Rand()*2.0f;
- dim.x = Math::Rand()*1.0f+1.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f);
- }
- }
-
- dir = Math::Vector(0.0f, -1.0f, 0.0f);
- SetLinVibration(dir);
- dir.x = sinf(m_armTimeAbs* 4.0f)*0.10f+
- sinf(m_armTimeAbs* 7.0f)*0.20f+
- sinf(m_armTimeAbs*10.0f)*0.40f+
- sinf(m_armTimeAbs*21.0f)*0.50f+Math::PI;
- dir.y = sinf(m_armTimeAbs* 3.0f)*0.01f+
- sinf(m_armTimeAbs* 6.0f)*0.02f+
- sinf(m_armTimeAbs*11.0f)*0.04f+
- sinf(m_armTimeAbs*20.0f)*0.02f;
- dir.z = sinf(m_armTimeAbs* 5.0f)*0.01f+
- sinf(m_armTimeAbs* 8.0f)*0.02f+
- sinf(m_armTimeAbs* 9.0f)*0.04f+
- sinf(m_armTimeAbs*23.0f)*0.03f;
- SetCirVibration(dir);
- dir = Math::Vector(0.0f, 0.0f, 0.0f);
- SetInclinaison(dir);
-
- m_object->SetAngleY(1, sinf(m_armTimeAbs*8.0f)*0.7f); // head
- m_object->SetAngleY(2, cosf(m_armTimeAbs*8.0f)*0.7f); // tail
- m_object->SetAngleZ(1, 0.0f); // head
- m_object->SetAngleZ(2, 0.0f); // tail
-
- if ( m_progress >= 1.0f )
- {
- SetAction(MAS_BACK3, 0.4f);
- }
- }
- else if ( m_actionType == MAS_BACK3 ) // goes back on the legs?
- {
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs )
- {
- m_lastParticule = m_armTimeAbs;
-
- pos = m_object->RetPosition(0);
- speed.x = (Math::Rand()-0.5f)*10.0f;
- speed.z = (Math::Rand()-0.5f)*10.0f;
- speed.y = Math::Rand()*5.0f;
- dim.x = Math::Rand()*3.0f+2.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f);
- }
-
- if ( m_progress < 0.5f )
- {
- dir.x = 0.0f;
- dir.y = powf(m_progress/0.5f, 2.0f)*5.0f;
- dir.z = 0.0f;
- SetLinVibration(dir);
- }
- else
- {
- dir.x = 0.0f;
- dir.y = powf(2.0f-m_progress/0.5f, 2.0f)*5.0f;
- dir.z = 0.0f;
- SetLinVibration(dir);
- }
- dir.x = (1.0f-m_progress)*Math::PI;
- dir.y = 0.0f;
- dir.z = 0.0f;
- SetCirVibration(dir);
-
- dir = Math::Vector(0.0f, 0.0f, 0.0f);
- SetInclinaison(dir);
-
- if ( m_progress >= 1.0f )
- {
- SetAction(-1);
- m_object->SetFixed(false); // moving again
- }
- }
- else
- {
- m_object->SetZoom(2, 1.0f); // tail
- m_object->SetAngleX(2, 0.0f);
- m_object->SetAngleY(2, 0.0f);
-
- if ( bStop )
- {
- m_object->SetAngleZ(2, sinf(m_armTimeAbs*1.7f)*0.15f); // tail
-
- dir = Math::Vector(0.0f, 0.0f, 0.0f);
- SetLinVibration(dir);
- SetInclinaison(dir);
- }
- else
- {
- a = Math::Mod(m_armTimeMarch, 1.0f);
- if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1
- else a = 3.0f-4.0f*a; // 1..-1
- dir.x = sinf(a)*0.05f;
-
- s = Math::Mod(m_armTimeMarch/2.0f, 1.0f);
- if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1
- else s = 3.0f-4.0f*s; // 1..-1
- dir.z = sinf(s)*0.1f;
-
- dir.y = 0.0f;
- SetInclinaison(dir);
-
- m_object->SetAngleZ(2, -sinf(a)*0.3f); // tail
-
- a = Math::Mod(m_armMember-0.1f, 1.0f);
- if ( a < 0.33f )
- {
- dir.y = -(1.0f-(a/0.33f))*0.3f;
- }
- else if ( a < 0.67f )
- {
- dir.y = 0.0f;
- }
- else
- {
- dir.y = -(a-0.67f)/0.33f*0.3f;
- }
- dir.x = 0.0f;
- dir.z = 0.0f;
- SetLinVibration(dir);
- }
-
- dir = Math::Vector(0.0f, 0.0f, 0.0f);
- SetCirVibration(dir);
-
- m_object->SetAngleZ(1, sinf(m_armTimeAbs*1.4f)*0.20f); // head
- m_object->SetAngleX(1, sinf(m_armTimeAbs*1.9f)*0.10f); // head
- m_object->SetAngleY(1, sinf(m_armTimeAbs*2.1f)*0.50f); // head
- }
-
- return true;
-}
-
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionant.cpp + + +#include <stdio.h> + +#include "object/motion/motionant.h" + +#include "old/modfile.h" +#include "old/particule.h" +#include "physics/physics.h" + + + +#define ADJUST_ANGLE false // true -> adjusts the angles of the members +const float START_TIME = 1000.0f; // beginning of the relative time + + + +// Object's constructor. + +CMotionAnt::CMotionAnt(CInstanceManager* iMan, CObject* object) + : CMotion(iMan, object) +{ + m_armMember = START_TIME; + m_armTimeAbs = START_TIME; + m_armTimeMarch = START_TIME; + m_armTimeAction = START_TIME; + m_armTimeIndex = 0; + m_armPartIndex = 0; + m_armMemberIndex = 0; + m_armLastAction = -1; + m_bArmStop = false; + m_lastParticule = 0.0f; +} + +// Object's destructor. + +CMotionAnt::~CMotionAnt() +{ +} + + +// Removes an object. + +void CMotionAnt::DeleteObject(bool bAll) +{ +} + + +// Creates a vehicle poses some rolling on the floor. + +bool CMotionAnt::Create(Math::Vector pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + int rank; + + if ( m_engine->RetRestCreate() < 3+18 ) return false; + + pModFile = new CModFile(m_iMan); + + m_object->SetType(type); + + // Creates the main base. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + + pModFile->ReadModel("objects\\ant1.mod"); + pModFile->CreateEngineObject(rank); + + m_object->SetPosition(0, pos); + m_object->SetAngleY(0, angle); + + // A vehicle must have necessarily a collision + //with a sphere of center (0, y, 0) (see GetCrashSphere). + m_object->CreateCrashSphere(Math::Vector(0.0f, -2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f); + m_object->SetGlobalSphere(Math::Vector(-0.5f, 1.0f, 0.0f), 4.0f); + + // Creates the head. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\ant2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(2.0f, 0.0f, 0.0f)); + + // Creates the tail. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\ant3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, Math::Vector(-1.0f, 0.0f, 0.0f)); + + // Creates a right-back thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, Math::Vector(-0.4f, -0.1f, -0.3f)); + + // Creates a right-back leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(4, rank); + m_object->SetObjectParent(4, 3); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(4, Math::Vector(0.0f, 0.0f, -1.0f)); + + // Creates a right-back foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(5, rank); + m_object->SetObjectParent(5, 4); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(5, Math::Vector(0.0f, 0.0f, -2.0f)); + + // Creates two middle-right thighs. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, Math::Vector(0.1f, -0.1f, -0.4f)); + + // Creates two middle-right legs. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 6); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, Math::Vector(0.0f, 0.0f, -1.0f)); + + // Creates two middle-right foots. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 7); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, Math::Vector(0.0f, 0.0f, -2.0f)); + + // Creates the right front thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(9, rank); + m_object->SetObjectParent(9, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(9, Math::Vector(1.4f, -0.1f, -0.6f)); + + // Creates the right front leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(10, rank); + m_object->SetObjectParent(10, 9); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(10, Math::Vector(0.0f, 0.0f, -1.0f)); + + // Creates the right front foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(11, rank); + m_object->SetObjectParent(11, 10); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(11, Math::Vector(0.0f, 0.0f, -2.0f)); + + // Creates a left-back thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(12, rank); + m_object->SetObjectParent(12, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(12, Math::Vector(-0.4f, -0.1f, 0.3f)); + + // Creates a left-back leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(13, rank); + m_object->SetObjectParent(13, 12); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(13, Math::Vector(0.0f, 0.0f, 1.0f)); + + // Creates a left-back foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(14, rank); + m_object->SetObjectParent(14, 13); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(14, Math::Vector(0.0f, 0.0f, 2.0f)); + + // Creates two middle-left thighs. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(15, rank); + m_object->SetObjectParent(15, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(15, Math::Vector(0.1f, -0.1f, 0.4f)); + + // Creates two middle-left legs. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(16, rank); + m_object->SetObjectParent(16, 15); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(16, Math::Vector(0.0f, 0.0f, 1.0f)); + + // Creates two middle-left foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(17, rank); + m_object->SetObjectParent(17, 16); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(17, Math::Vector(0.0f, 0.0f, 2.0f)); + + // Creates the left front thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(18, rank); + m_object->SetObjectParent(18, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(18, Math::Vector(1.4f, -0.1f, 0.6f)); + + // Creates the left front leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(19, rank); + m_object->SetObjectParent(19, 18); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(19, Math::Vector(0.0f, 0.0f, 1.0f)); + + // Creates the left front foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(20, rank); + m_object->SetObjectParent(20, 19); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(20, Math::Vector(0.0f, 0.0f, 2.0f)); + + m_object->CreateShadowCircle(4.0f, 0.5f); + + CreatePhysics(); + m_object->SetFloorHeight(0.0f); + + pos = m_object->RetPosition(0); + m_object->SetPosition(0, pos); // to display the shadows immediately + + m_engine->LoadAllTexture(); + + delete pModFile; + return true; +} + +// Creates the physics of the object. + +void CMotionAnt::CreatePhysics() +{ + Character* character; + int i; + + int member_march[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: + 0,45,0, 0,45,0, 0,50,0, // t0: thighs 1..3 + 30,-70,0, 20,-105,20, 25,-100,0, // t0: legs 1..3 + -70,75,0, -30,80,0, -80,80,0, // t0: feet 1..3 + // on the ground: + 0,30,0, 0,20,0, 0,15,0, // t1: thighs 1..3 + -15,-50,0, -20,-60,0, -10,-75,0, // t1: legs 1..3 + -40,50,0, -25,15,0, -50,35,0, // t1: feet 1..3 + // on the ground back: + 0,35,0, 0,30,0, 0,20,0, // t2: thighs 1..3 + -20,-15,0, -30,-55,0, -25,-70,15, // t2: legs 1..3 + -25,25,0, -20,60,0, -30,95,0, // t2: feet 1..3 + }; + + int member_stop[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: + 0,30,0, 0,20,0, 0,15,0, // t0: thighs 1..3 + -15,-35,0, -20,-60,0, -15,-75,0, // t0: legs 1..3 + -35,35,0, -25,40,0, -40,65,0, // t0: feet 1..3 + // on the ground: + 0,30,0, 0,20,0, 0,15,0, // t1: thighs 1..3 + -15,-35,0, -20,-60,0, -15,-75,0, // t1: legs 1..3 + -35,35,0, -25,40,0, -40,65,0, // t1: feet 1..3 + // on the ground back: + 0,30,0, 0,20,0, 0,15,0, // t2: thighs 1..3 + -15,-35,0, -20,-60,0, -15,-75,0, // t2: legs 1..3 + -35,35,0, -25,40,0, -40,65,0, // t2: feet 1..3 + }; + + int member_spec[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // prepares the fire: + 0,20,0, 0,10,0, 0,50,0, // s0: thighs 1..3 + -50,-30,0, -20,-15,0, 35,-65,0, // s0: legs 1..3 + -5,-40,0, 20,-70,0, -10,-40,0, // s0: feet 1..3 + // shot: + 0,20,0, 0,10,0, 0,50,0, // s1: thighs 1..3 + -50,-30,0, -20,-15,0, 35,-65,0, // s1: legs 1..3 + -5,-40,0, 20,-70,0, -10,-40,0, // s1: feet 1..3 + // ends the fire: + 0,30,0, 0,20,0, 0,15,0, // s2: thighs 1..3 + -15,-50,0, -20,-60,0, -10,-75,0, // s2: legs 1..3 + -40,50,0, -25,15,0, -50,35,0, // s2: feet 1..3 + // burning: + 0,30,0, 0,20,0, 0,15,0, // s3: thighs 1..3 + -15,-35,0, -20,-60,0, -15,-75,0, // s3: legs 1..3 + -35,35,0, -25,40,0, -40,65,0, // s3: feet 1..3 + // destroyed: + 0,30,0, 0,20,0, 0,15,0, // s4: thighs 1..3 + -15,-35,0, -20,-60,0, -15,-75,0, // s4: legs 1..3 + -35,35,0, -25,40,0, -40,65,0, // s4: feet 1..3 + // back1 : + 0,30,0, 0,20,0, 0,15,0, // s5: thighs 1..3 + -15,-35,0, -20,-60,0, -15,-75,0, // s5: legs 1..3 + -35,35,0, -25,40,0, -40,65,0, // s5: feet 1..3 + // back2 : + 0,45,0, 0,45,0, 0,50,0, // s6: thighs 1..3 + -35,-70,0, -20,-85,-25, -25,-100,0, // s6: legs 1..3 + -110,75,-15, -130,80,-25, -125,40,0, // s6: feet 1..3 + // back3 : + 0,30,0, 0,20,0, 0,15,0, // s7: thighs 1..3 + -15,-35,0, -20,-60,0, -15,-75,0, // s7: legs 1..3 + -35,35,0, -25,40,0, -40,65,0, // s7: feet 1..3 + }; + + m_physics->SetType(TYPE_ROLLING); + + character = m_object->RetCharacter(); + character->wheelFront = 3.0f; + character->wheelBack = 3.0f; + character->wheelLeft = 5.0f; + character->wheelRight = 5.0f; + character->height = 1.2f; + + m_physics->SetLinMotionX(MO_ADVSPEED, 12.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 12.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 15.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 15.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 5.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 5.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 10.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 1.0f*Math::PI); + m_physics->SetCirMotionY(MO_RECSPEED, 1.0f*Math::PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 20.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 20.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 40.0f); + + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MA_MARCH+i] = member_march[i]; + } + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MA_STOP+i] = member_stop[i]; + } + for ( i=0 ; i<3*3*3*8 ; i++ ) + { + m_armAngles[3*3*3*3*MA_SPEC+i] = member_spec[i]; + } +} + + +// Management of an event. + +bool CMotionAnt::EventProcess(const Event &event) +{ + CMotion::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + if ( event.event == EVENT_KEYDOWN ) + { +#if ADJUST_ANGLE + int i; + + if ( event.param == 'A' ) m_armTimeIndex++; + if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0; + + if ( event.param == 'Q' ) m_armPartIndex++; + if ( m_armPartIndex >= 3 ) m_armPartIndex = 0; + + if ( event.param == 'W' ) m_armMemberIndex++; + if ( m_armMemberIndex >= 3 ) m_armMemberIndex = 0; + + i = m_armMemberIndex*3; + i += m_armPartIndex*3*3; + i += m_armTimeIndex*3*3*3; +//? i += 3*3*3*3; + + if ( event.param == 'E' ) m_armAngles[i+0] += 5; + if ( event.param == 'D' ) m_armAngles[i+0] -= 5; + if ( event.param == 'R' ) m_armAngles[i+1] += 5; + if ( event.param == 'F' ) m_armAngles[i+1] -= 5; + if ( event.param == 'T' ) m_armAngles[i+2] += 5; + if ( event.param == 'G' ) m_armAngles[i+2] -= 5; + + if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop; +#endif + } + + return true; +} + +// Management of an event. + +bool CMotionAnt::EventFrame(const Event &event) +{ + Math::Vector dir, pos, speed; + Math::Point dim; + float s, a, prog, time; + float tSt[9], tNd[9]; + int i, ii, st, nd, action; + bool bStop; + + if ( m_engine->RetPause() ) return true; + if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return true; + + s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.5f; + a = fabs(m_physics->RetCirMotionY(MO_MOTSPEED)*2.0f); + + if ( s == 0.0f && a != 0.0f ) a *= 1.5f; + + m_armTimeAbs += event.rTime; + m_armTimeMarch += (s)*event.rTime*0.15f; + m_armMember += (s+a)*event.rTime*0.15f; + + bStop = ( a == 0.0f && s == 0.0f ); // stopped? + + action = MA_MARCH; // walking + if ( s == 0.0f && a == 0.0f ) + { + action = MA_STOP; // stop + } + + if ( bStop ) + { + prog = Math::Mod(m_armTimeAbs, 2.0f)/10.0f; + a = Math::Mod(m_armMember, 1.0f); + a = (prog-a)*event.rTime*2.0f; // stop position is pleasantly + m_armMember += a; + } + + if ( m_object->RetRuin() ) // destroyed? + { + m_actionType = MAS_RUIN; + } + if ( m_object->RetBurn() ) // burning? + { + if ( m_object->RetFixed() ) + { + m_actionType = MAS_BURN; + } + else + { + m_actionType = -1; + } + } + + for ( i=0 ; i<6 ; i++ ) // the six legs + { + if ( m_actionType != -1 ) // special action in progress? + { + st = 3*3*3*3*MA_SPEC + 3*3*3*m_actionType + (i%3)*3; + nd = st; + time = event.rTime*m_actionTime; + m_armTimeAction = 0.0f; + } + else + { + if ( i < 3 ) prog = Math::Mod(m_armMember+(2.0f-(i%3))*0.33f+0.0f, 1.0f); + else prog = Math::Mod(m_armMember+(2.0f-(i%3))*0.33f+0.3f, 1.0f); + if ( m_bArmStop ) + { + prog = (float)m_armTimeIndex/3.0f; + } + if ( prog < 0.33f ) // t0..t1 ? + { + prog = prog/0.33f; // 0..1 + st = 0; // index start + nd = 1; // index end + } + else if ( prog < 0.67f ) // t1..t2 ? + { + prog = (prog-0.33f)/0.33f; // 0..1 + st = 1; // index start + nd = 2; // index end + } + else // t2..t0 ? + { + prog = (prog-0.67f)/0.33f; // 0..1 + st = 2; // index start + nd = 0; // index end + } + st = 3*3*3*3*action + st*3*3*3 + (i%3)*3; + nd = 3*3*3*3*action + nd*3*3*3 + (i%3)*3; + + // More and more soft ... + time = event.rTime*(10.0f+Math::Min(m_armTimeAction*100.0f, 200.0f)); + } + + tSt[0] = m_armAngles[st+ 0]; // x + tSt[1] = m_armAngles[st+ 1]; // y + tSt[2] = m_armAngles[st+ 2]; // z + tSt[3] = m_armAngles[st+ 9]; // x + tSt[4] = m_armAngles[st+10]; // y + tSt[5] = m_armAngles[st+11]; // z + tSt[6] = m_armAngles[st+18]; // x + tSt[7] = m_armAngles[st+19]; // y + tSt[8] = m_armAngles[st+20]; // z + + tNd[0] = m_armAngles[nd+ 0]; // x + tNd[1] = m_armAngles[nd+ 1]; // y + tNd[2] = m_armAngles[nd+ 2]; // z + tNd[3] = m_armAngles[nd+ 9]; // x + tNd[4] = m_armAngles[nd+10]; // y + tNd[5] = m_armAngles[nd+11]; // z + tNd[6] = m_armAngles[nd+18]; // x + tNd[7] = m_armAngles[nd+19]; // y + tNd[8] = m_armAngles[nd+20]; // z + + if ( m_actionType == MAS_BACK2 ) // on the back? + { + for ( ii=0 ; ii<9 ; ii++ ) + { + tSt[ii] += Math::Rand()*50.0f; + tNd[ii] = tSt[ii]; + } +//? time = 100.0f; + time = event.rTime*10.0f; + } + + if ( i < 3 ) // right leg (1..3) ? + { + m_object->SetAngleX(3+3*i+0, Math::Smooth(m_object->RetAngleX(3+3*i+0), Math::PropAngle(tSt[0], tNd[0], prog), time)); + m_object->SetAngleY(3+3*i+0, Math::Smooth(m_object->RetAngleY(3+3*i+0), Math::PropAngle(tSt[1], tNd[1], prog), time)); + m_object->SetAngleZ(3+3*i+0, Math::Smooth(m_object->RetAngleZ(3+3*i+0), Math::PropAngle(tSt[2], tNd[2], prog), time)); + m_object->SetAngleX(3+3*i+1, Math::Smooth(m_object->RetAngleX(3+3*i+1), Math::PropAngle(tSt[3], tNd[3], prog), time)); + m_object->SetAngleY(3+3*i+1, Math::Smooth(m_object->RetAngleY(3+3*i+1), Math::PropAngle(tSt[4], tNd[4], prog), time)); + m_object->SetAngleZ(3+3*i+1, Math::Smooth(m_object->RetAngleZ(3+3*i+1), Math::PropAngle(tSt[5], tNd[5], prog), time)); + m_object->SetAngleX(3+3*i+2, Math::Smooth(m_object->RetAngleX(3+3*i+2), Math::PropAngle(tSt[6], tNd[6], prog), time)); + m_object->SetAngleY(3+3*i+2, Math::Smooth(m_object->RetAngleY(3+3*i+2), Math::PropAngle(tSt[7], tNd[7], prog), time)); + m_object->SetAngleZ(3+3*i+2, Math::Smooth(m_object->RetAngleZ(3+3*i+2), Math::PropAngle(tSt[8], tNd[8], prog), time)); + } + else // left leg (4..6) ? + { + m_object->SetAngleX(3+3*i+0, Math::Smooth(m_object->RetAngleX(3+3*i+0), Math::PropAngle(-tSt[0], -tNd[0], prog), time)); + m_object->SetAngleY(3+3*i+0, Math::Smooth(m_object->RetAngleY(3+3*i+0), Math::PropAngle(-tSt[1], -tNd[1], prog), time)); + m_object->SetAngleZ(3+3*i+0, Math::Smooth(m_object->RetAngleZ(3+3*i+0), Math::PropAngle( tSt[2], tNd[2], prog), time)); + m_object->SetAngleX(3+3*i+1, Math::Smooth(m_object->RetAngleX(3+3*i+1), Math::PropAngle(-tSt[3], -tNd[3], prog), time)); + m_object->SetAngleY(3+3*i+1, Math::Smooth(m_object->RetAngleY(3+3*i+1), Math::PropAngle(-tSt[4], -tNd[4], prog), time)); + m_object->SetAngleZ(3+3*i+1, Math::Smooth(m_object->RetAngleZ(3+3*i+1), Math::PropAngle( tSt[5], tNd[5], prog), time)); + m_object->SetAngleX(3+3*i+2, Math::Smooth(m_object->RetAngleX(3+3*i+2), Math::PropAngle(-tSt[6], -tNd[6], prog), time)); + m_object->SetAngleY(3+3*i+2, Math::Smooth(m_object->RetAngleY(3+3*i+2), Math::PropAngle(-tSt[7], -tNd[7], prog), time)); + m_object->SetAngleZ(3+3*i+2, Math::Smooth(m_object->RetAngleZ(3+3*i+2), Math::PropAngle( tSt[8], tNd[8], prog), time)); + } + } + +#if ADJUST_ANGLE + if ( m_object->RetSelect() ) + { + char s[100]; + sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex); + m_engine->SetInfoText(4, s); + } +#endif + + if ( m_actionType == MAS_PREPARE ) // prepares the shooting? + { + prog = m_progress; + + dir.x = 0.0f; + dir.y = 0.0f; + dir.z = Math::PropAngle(0, -50, prog); + SetInclinaison(dir); + m_object->SetAngleZ(1, Math::PropAngle(0, 65, prog)); // head + m_object->SetAngleZ(2, Math::PropAngle(0, -95, prog)); // tail + } + else if ( m_actionType == MAS_FIRE ) // shooting? + { + if ( m_progress < 0.75f ) a = m_progress/0.75f; + else a = (1.0f-m_progress)/0.25f; + m_object->SetZoom(2, (a*0.5f)+1.0f); // tail + m_object->SetAngleX(2, (Math::Rand()-0.5f)*0.3f*a); + m_object->SetAngleY(2, (Math::Rand()-0.5f)*0.3f*a); + + dir.x = (Math::Rand()-0.5f)*0.02f*a; + dir.y = (Math::Rand()-0.5f)*0.05f*a; + dir.z = (Math::Rand()-0.5f)*0.03f*a; + SetCirVibration(dir); + } + else if ( m_actionType == MAS_TERMINATE ) // ends the shooting? + { + prog = 1.0f-m_progress; + + dir.x = 0.0f; + dir.y = 0.0f; + dir.z = Math::PropAngle(0, -50, prog); + SetInclinaison(dir); + m_object->SetAngleZ(1, Math::PropAngle(0, 65, prog)); // head + m_object->SetAngleZ(2, Math::PropAngle(0, -95, prog)); // tail + } + else if ( m_actionType == MAS_BURN ) // burning? + { + dir = Math::Vector(Math::PI, 0.0f, 0.0f); + SetCirVibration(dir); + dir = Math::Vector(0.0f, -1.5f, 0.0f); + SetLinVibration(dir); + dir = Math::Vector(0.0f, 0.0f, 0.0f); + SetInclinaison(dir); + + time = event.rTime*1.0f; + m_object->SetAngleZ(1, Math::Smooth(m_object->RetAngleZ(1), 0.0f, time)); // head + m_object->SetAngleZ(2, Math::Smooth(m_object->RetAngleZ(2), 0.0f, time)); // tail + } + else if ( m_actionType == MAS_RUIN ) // destroyed? + { + dir = Math::Vector(0.0f, 0.0f, 0.0f); + SetLinVibration(dir); + SetCirVibration(dir); + SetInclinaison(dir); + } + else if ( m_actionType == MAS_BACK1 ) // starts on the back? + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) + { + m_lastParticule = m_armTimeAbs; + + pos = m_object->RetPosition(0); + speed.x = (Math::Rand()-0.5f)*10.0f; + speed.z = (Math::Rand()-0.5f)*10.0f; + speed.y = Math::Rand()*5.0f; + dim.x = Math::Rand()*3.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + + if ( m_progress < 0.5f ) + { + dir.x = 0.0f; + dir.y = powf(m_progress/0.5f, 2.0f)*12.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + else + { + dir.x = 0.0f; + dir.y = powf(2.0f-m_progress/0.5f, 2.0f)*12.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + dir.x = m_progress*Math::PI; + dir.y = 0.0f; + dir.z = 0.0f; + SetCirVibration(dir); + + dir = Math::Vector(0.0f, 0.0f, 0.0f); + SetInclinaison(dir); + + if ( m_progress >= 1.0f ) + { + SetAction(MAS_BACK2, 55.0f+Math::Rand()*10.0f); + } + } + else if ( m_actionType == MAS_BACK2 ) // moves on the back? + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) + { + m_lastParticule = m_armTimeAbs; + + if ( rand()%10 == 0 ) + { + pos = m_object->RetPosition(0); + pos.x += (Math::Rand()-0.5f)*5.0f; + pos.z += (Math::Rand()-0.5f)*5.0f; + pos.y -= 1.0f; + speed.x = (Math::Rand()-0.5f)*2.0f; + speed.z = (Math::Rand()-0.5f)*2.0f; + speed.y = Math::Rand()*2.0f; + dim.x = Math::Rand()*1.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + } + + dir = Math::Vector(0.0f, -1.0f, 0.0f); + SetLinVibration(dir); + dir.x = sinf(m_armTimeAbs* 4.0f)*0.10f+ + sinf(m_armTimeAbs* 7.0f)*0.20f+ + sinf(m_armTimeAbs*10.0f)*0.40f+ + sinf(m_armTimeAbs*21.0f)*0.50f+Math::PI; + dir.y = sinf(m_armTimeAbs* 3.0f)*0.01f+ + sinf(m_armTimeAbs* 6.0f)*0.02f+ + sinf(m_armTimeAbs*11.0f)*0.04f+ + sinf(m_armTimeAbs*20.0f)*0.02f; + dir.z = sinf(m_armTimeAbs* 5.0f)*0.01f+ + sinf(m_armTimeAbs* 8.0f)*0.02f+ + sinf(m_armTimeAbs* 9.0f)*0.04f+ + sinf(m_armTimeAbs*23.0f)*0.03f; + SetCirVibration(dir); + dir = Math::Vector(0.0f, 0.0f, 0.0f); + SetInclinaison(dir); + + m_object->SetAngleY(1, sinf(m_armTimeAbs*8.0f)*0.7f); // head + m_object->SetAngleY(2, cosf(m_armTimeAbs*8.0f)*0.7f); // tail + m_object->SetAngleZ(1, 0.0f); // head + m_object->SetAngleZ(2, 0.0f); // tail + + if ( m_progress >= 1.0f ) + { + SetAction(MAS_BACK3, 0.4f); + } + } + else if ( m_actionType == MAS_BACK3 ) // goes back on the legs? + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) + { + m_lastParticule = m_armTimeAbs; + + pos = m_object->RetPosition(0); + speed.x = (Math::Rand()-0.5f)*10.0f; + speed.z = (Math::Rand()-0.5f)*10.0f; + speed.y = Math::Rand()*5.0f; + dim.x = Math::Rand()*3.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + + if ( m_progress < 0.5f ) + { + dir.x = 0.0f; + dir.y = powf(m_progress/0.5f, 2.0f)*5.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + else + { + dir.x = 0.0f; + dir.y = powf(2.0f-m_progress/0.5f, 2.0f)*5.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + dir.x = (1.0f-m_progress)*Math::PI; + dir.y = 0.0f; + dir.z = 0.0f; + SetCirVibration(dir); + + dir = Math::Vector(0.0f, 0.0f, 0.0f); + SetInclinaison(dir); + + if ( m_progress >= 1.0f ) + { + SetAction(-1); + m_object->SetFixed(false); // moving again + } + } + else + { + m_object->SetZoom(2, 1.0f); // tail + m_object->SetAngleX(2, 0.0f); + m_object->SetAngleY(2, 0.0f); + + if ( bStop ) + { + m_object->SetAngleZ(2, sinf(m_armTimeAbs*1.7f)*0.15f); // tail + + dir = Math::Vector(0.0f, 0.0f, 0.0f); + SetLinVibration(dir); + SetInclinaison(dir); + } + else + { + a = Math::Mod(m_armTimeMarch, 1.0f); + if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1 + else a = 3.0f-4.0f*a; // 1..-1 + dir.x = sinf(a)*0.05f; + + s = Math::Mod(m_armTimeMarch/2.0f, 1.0f); + if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1 + else s = 3.0f-4.0f*s; // 1..-1 + dir.z = sinf(s)*0.1f; + + dir.y = 0.0f; + SetInclinaison(dir); + + m_object->SetAngleZ(2, -sinf(a)*0.3f); // tail + + a = Math::Mod(m_armMember-0.1f, 1.0f); + if ( a < 0.33f ) + { + dir.y = -(1.0f-(a/0.33f))*0.3f; + } + else if ( a < 0.67f ) + { + dir.y = 0.0f; + } + else + { + dir.y = -(a-0.67f)/0.33f*0.3f; + } + dir.x = 0.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + + dir = Math::Vector(0.0f, 0.0f, 0.0f); + SetCirVibration(dir); + + m_object->SetAngleZ(1, sinf(m_armTimeAbs*1.4f)*0.20f); // head + m_object->SetAngleX(1, sinf(m_armTimeAbs*1.9f)*0.10f); // head + m_object->SetAngleY(1, sinf(m_armTimeAbs*2.1f)*0.50f); // head + } + + return true; +} + + diff --git a/src/object/motion/motionant.h b/src/object/motion/motionant.h index 71a11e4..8ddd789 100644 --- a/src/object/motion/motionant.h +++ b/src/object/motion/motionant.h @@ -1,73 +1,73 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motionant.h
-
-#pragma once
-
-
-#include "object/motion/motion.h"
-
-
-
-enum MotionAntAction
-{
- MA_MARCH = 0,
- MA_STOP = 1,
- MA_SPEC = 2
-};
-
-enum MotionAntSpecialAction
-{
- MAS_PREPARE = 0,
- MAS_FIRE = 1,
- MAS_TERMINATE = 2,
- MAS_BURN = 3,
- MAS_RUIN = 4,
- MAS_BACK1 = 5,
- MAS_BACK2 = 6,
- MAS_BACK3 = 7
-};
-
-
-class CMotionAnt : public CMotion
-{
-public:
- CMotionAnt(CInstanceManager* iMan, CObject* object);
- ~CMotionAnt();
-
- void DeleteObject(bool bAll=false);
- bool Create(Math::Vector pos, float angle, ObjectType type, float power);
- bool EventProcess(const Event &event);
-
-protected:
- void CreatePhysics();
- bool EventFrame(const Event &event);
-
-protected:
- float m_armMember;
- float m_armTimeAbs;
- float m_armTimeMarch;
- float m_armTimeAction;
- short m_armAngles[3*3*3*3*3 + 3*3*3*8];
- int m_armTimeIndex;
- int m_armPartIndex;
- int m_armMemberIndex;
- int m_armLastAction;
- bool m_bArmStop;
- float m_lastParticule;
-};
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionant.h + +#pragma once + + +#include "object/motion/motion.h" + + + +enum MotionAntAction +{ + MA_MARCH = 0, + MA_STOP = 1, + MA_SPEC = 2 +}; + +enum MotionAntSpecialAction +{ + MAS_PREPARE = 0, + MAS_FIRE = 1, + MAS_TERMINATE = 2, + MAS_BURN = 3, + MAS_RUIN = 4, + MAS_BACK1 = 5, + MAS_BACK2 = 6, + MAS_BACK3 = 7 +}; + + +class CMotionAnt : public CMotion +{ +public: + CMotionAnt(CInstanceManager* iMan, CObject* object); + ~CMotionAnt(); + + void DeleteObject(bool bAll=false); + bool Create(Math::Vector pos, float angle, ObjectType type, float power); + bool EventProcess(const Event &event); + +protected: + void CreatePhysics(); + bool EventFrame(const Event &event); + +protected: + float m_armMember; + float m_armTimeAbs; + float m_armTimeMarch; + float m_armTimeAction; + short m_armAngles[3*3*3*3*3 + 3*3*3*8]; + int m_armTimeIndex; + int m_armPartIndex; + int m_armMemberIndex; + int m_armLastAction; + bool m_bArmStop; + float m_lastParticule; +}; + diff --git a/src/object/motion/motionbee.cpp b/src/object/motion/motionbee.cpp index c5d9ed2..e5c6b24 100644 --- a/src/object/motion/motionbee.cpp +++ b/src/object/motion/motionbee.cpp @@ -1,644 +1,644 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motionbee.cpp
-
-
-#include <stdio.h>
-
-#include "object/motion/motionbee.h"
-
-#include "old/modfile.h"
-#include "physics/physics.h"
-
-
-
-#define ADJUST_ANGLE false // true -> adjusts the angles of the members
-const float START_TIME = 1000.0f; // beginning of the relative time
-
-
-
-// Object's constructor.
-
-CMotionBee::CMotionBee(CInstanceManager* iMan, CObject* object)
- : CMotion(iMan, object)
-{
- m_armMember = START_TIME;
- m_armTimeAbs = START_TIME;
- m_armTimeMarch = START_TIME;
- m_armTimeAction = START_TIME;
- m_armTimeIndex = 0;
- m_armPartIndex = 0;
- m_armMemberIndex = 0;
- m_armLastAction = -1;
- m_bArmStop = false;
-}
-
-// Object's destructor.
-
-CMotionBee::~CMotionBee()
-{
-}
-
-
-// Removes an object.
-
-void CMotionBee::DeleteObject(bool bAll)
-{
-}
-
-
-// Creates a vehicle traveling any lands on the ground.
-
-bool CMotionBee::Create(Math::Vector pos, float angle, ObjectType type,
- float power)
-{
- CModFile* pModFile;
- int rank;
-
- if ( m_engine->RetRestCreate() < 3+18+2 ) return false;
-
- pModFile = new CModFile(m_iMan);
-
- m_object->SetType(type);
-
- // Creates main base.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object
- m_object->SetObjectRank(0, rank);
-
- pModFile->ReadModel("objects\\bee1.mod");
- pModFile->CreateEngineObject(rank);
-
- m_object->SetPosition(0, pos);
- m_object->SetAngleY(0, angle);
-
- // A vehicle must have an obligatory collision
- // with a sphere of center (0, y, 0) (see GetCrashSphere).
- m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f);
- m_object->SetGlobalSphere(Math::Vector(-1.0f, 1.0f, 0.0f), 5.0f);
-
- // Creates the head.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\bee2.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(1.6f, 0.3f, 0.0f));
-
- // Creates the tail.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 0);
- pModFile->ReadModel("objects\\bee3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2, Math::Vector(-0.8f, 0.0f, 0.0f));
-
- // Creates a right-back thigh.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(3, rank);
- m_object->SetObjectParent(3, 0);
- pModFile->ReadModel("objects\\ant4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(3, Math::Vector(-0.3f, -0.1f, -0.2f));
-
- // Creates a right-back leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(4, rank);
- m_object->SetObjectParent(4, 3);
- pModFile->ReadModel("objects\\ant5.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(4, Math::Vector(0.0f, 0.0f, -1.0f));
-
- // Creates a right-back foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(5, rank);
- m_object->SetObjectParent(5, 4);
- pModFile->ReadModel("objects\\ant6.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(5, Math::Vector(0.0f, 0.0f, -2.0f));
-
- // Creates two middle-right thighs.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(6, rank);
- m_object->SetObjectParent(6, 0);
- pModFile->ReadModel("objects\\ant4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(6, Math::Vector(0.3f, -0.1f, -0.4f));
-
- // Creates two middle-right legs.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(7, rank);
- m_object->SetObjectParent(7, 6);
- pModFile->ReadModel("objects\\ant5.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(7, Math::Vector(0.0f, 0.0f, -1.0f));
-
- // Creates two middle-right feet.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(8, rank);
- m_object->SetObjectParent(8, 7);
- pModFile->ReadModel("objects\\ant6.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(8, Math::Vector(0.0f, 0.0f, -2.0f));
-
- // Creates the right front thigh.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(9, rank);
- m_object->SetObjectParent(9, 0);
- pModFile->ReadModel("objects\\ant4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(9, Math::Vector(1.0f, -0.1f, -0.7f));
-
- // Creates the right front leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(10, rank);
- m_object->SetObjectParent(10, 9);
- pModFile->ReadModel("objects\\ant5.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(10, Math::Vector(0.0f, 0.0f, -1.0f));
-
- // Creates the right front foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(11, rank);
- m_object->SetObjectParent(11, 10);
- pModFile->ReadModel("objects\\ant6.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(11, Math::Vector(0.0f, 0.0f, -2.0f));
-
- // Creates a left-back thigh.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(12, rank);
- m_object->SetObjectParent(12, 0);
- pModFile->ReadModel("objects\\ant4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(12, Math::Vector(-0.3f, -0.1f, 0.2f));
- m_object->SetAngleY(12, Math::PI);
-
- // Creates a left-back leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(13, rank);
- m_object->SetObjectParent(13, 12);
- pModFile->ReadModel("objects\\ant5.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(13, Math::Vector(0.0f, 0.0f, -1.0f));
-
- // Creates a left-back foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(14, rank);
- m_object->SetObjectParent(14, 13);
- pModFile->ReadModel("objects\\ant6.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(14, Math::Vector(0.0f, 0.0f, -2.0f));
-
- // Creates two middle-left thigh.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(15, rank);
- m_object->SetObjectParent(15, 0);
- pModFile->ReadModel("objects\\ant4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(15, Math::Vector(0.3f, -0.1f, 0.4f));
- m_object->SetAngleY(15, Math::PI);
-
- // Creates two middle-left legs.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(16, rank);
- m_object->SetObjectParent(16, 15);
- pModFile->ReadModel("objects\\ant5.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(16, Math::Vector(0.0f, 0.0f, -1.0f));
-
- // Creates two middle-left feet.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(17, rank);
- m_object->SetObjectParent(17, 16);
- pModFile->ReadModel("objects\\ant6.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(17, Math::Vector(0.0f, 0.0f, -2.0f));
-
- // Creates front-left thigh.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(18, rank);
- m_object->SetObjectParent(18, 0);
- pModFile->ReadModel("objects\\ant4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(18, Math::Vector(1.0f, -0.1f, 0.7f));
- m_object->SetAngleY(18, Math::PI);
-
- // Creates front-left leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(19, rank);
- m_object->SetObjectParent(19, 18);
- pModFile->ReadModel("objects\\ant5.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(19, Math::Vector(0.0f, 0.0f, -1.0f));
-
- // Creates front-left foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(20, rank);
- m_object->SetObjectParent(20, 19);
- pModFile->ReadModel("objects\\ant6.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(20, Math::Vector(0.0f, 0.0f, -2.0f));
-
- // Creates the right wing.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(21, rank);
- m_object->SetObjectParent(21, 0);
- pModFile->ReadModel("objects\\bee7.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(21, Math::Vector(0.8f, 0.4f, -0.5f));
-
- // Creates the left wing.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(22, rank);
- m_object->SetObjectParent(22, 0);
- pModFile->ReadModel("objects\\bee7.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(22, Math::Vector(0.8f, 0.4f, 0.5f));
-
- m_object->CreateShadowCircle(6.0f, 0.5f);
-
- CreatePhysics();
- m_object->SetFloorHeight(0.0f);
-
- pos = m_object->RetPosition(0);
- m_object->SetPosition(0, pos); // to display the shadows immediately
-
- m_engine->LoadAllTexture();
-
- delete pModFile;
- return true;
-}
-
-// Creates the physical object.
-
-void CMotionBee::CreatePhysics()
-{
- Character* character;
- int i;
-
- int member_march[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air:
- 0,45,0, 0,45,0, 0,50,0, // t0: thighs 1..3
- 30,-70,0, 20,-105,20, 25,-100,0, // t0: legs 1..3
- -70,75,0, -30,80,0, -80,80,0, // t0: feet 1..3
- // on the ground:
- 0,30,0, 0,20,0, 0,15,0, // t1: thighs 1..3
- -15,-50,0, -20,-60,0, -10,-75,0, // t1: legs 1..3
- -40,50,0, -25,15,0, -50,35,0, // t1: feet 1..3
- // on the ground back:
- 0,35,0, 0,30,0, 0,20,0, // t2: thighs 1..3
- -20,-15,0, -30,-55,0, -25,-70,15, // t2: legs 1..3
- -25,25,0, -20,60,0, -30,95,0, // t2: feet 1..3
- };
-
- int member_spec[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3, // ball carrier:
- 0,45,0, 0,45,0, 0,50,0, // s0: thighs 1..3
- -35,-70,0, -20,-85,-25, -25,-100,0, // s0: legs 1..3
- -110,75,-15, -130,80,-25, -125,40,0, // s0: feet 1..3
- // burning:
- 0,45,0, 0,45,0, 0,50,0, // s1: thighs 1..3
- -35,-70,0, -20,-85,-25, -25,-100,0, // s1: legs 1..3
- -110,75,-15, -130,80,-25, -125,40,0, // s1: feet 1..3
- // destroyed:
- 0,45,0, 0,45,0, 0,50,0, // s2: thighs 1..3
- -35,-70,0, -20,-85,-25, -25,-100,0, // s2: legs 1..3
- -110,75,-15, -130,80,-25, -125,40,0, // s2: feet 1..3
- };
-
- m_physics->SetType(TYPE_FLYING);
-
- character = m_object->RetCharacter();
- character->wheelFront = 3.0f;
- character->wheelBack = 3.0f;
- character->wheelLeft = 5.0f;
- character->wheelRight = 5.0f;
- character->height = 2.5f;
-
- m_physics->SetLinMotionX(MO_ADVSPEED, 50.0f);
- m_physics->SetLinMotionX(MO_RECSPEED, 50.0f);
- m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f);
- m_physics->SetLinMotionX(MO_RECACCEL, 20.0f);
- m_physics->SetLinMotionX(MO_STOACCEL, 20.0f);
- m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionX(MO_TERFORCE, 10.0f);
- m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f);
- m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f);
- m_physics->SetLinMotionY(MO_ADVSPEED, 60.0f);
- m_physics->SetLinMotionY(MO_RECSPEED, 60.0f);
- m_physics->SetLinMotionY(MO_ADVACCEL, 20.0f);
- m_physics->SetLinMotionY(MO_RECACCEL, 50.0f);
- m_physics->SetLinMotionY(MO_STOACCEL, 50.0f);
-
- m_physics->SetCirMotionY(MO_ADVSPEED, 1.0f*Math::PI);
- m_physics->SetCirMotionY(MO_RECSPEED, 1.0f*Math::PI);
- m_physics->SetCirMotionY(MO_ADVACCEL, 20.0f);
- m_physics->SetCirMotionY(MO_RECACCEL, 20.0f);
- m_physics->SetCirMotionY(MO_STOACCEL, 40.0f);
-
- for ( i=0 ; i<3*3*3*3 ; i++ )
- {
- m_armAngles[3*3*3*3*MB_MARCH+i] = member_march[i];
- }
- for ( i=0 ; i<3*3*3*3 ; i++ )
- {
- m_armAngles[3*3*3*3*MB_SPEC+i] = member_spec[i];
- }
-}
-
-
-// Management of an event.
-
-bool CMotionBee::EventProcess(const Event &event)
-{
- CMotion::EventProcess(event);
-
- if ( event.event == EVENT_FRAME )
- {
- return EventFrame(event);
- }
-
- if ( event.event == EVENT_KEYDOWN )
- {
-#if ADJUST_ANGLE
- int i;
-
- if ( event.param == 'A' ) m_armTimeIndex++;
- if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0;
-
- if ( event.param == 'Q' ) m_armPartIndex++;
- if ( m_armPartIndex >= 3 ) m_armPartIndex = 0;
-
- if ( event.param == 'W' ) m_armMemberIndex++;
- if ( m_armMemberIndex >= 3 ) m_armMemberIndex = 0;
-
- i = m_armMemberIndex*3;
- i += m_armPartIndex*3*3;
- i += m_armTimeIndex*3*3*3;
-//? i += 3*3*3*3;
-
- if ( event.param == 'E' ) m_armAngles[i+0] += 5;
- if ( event.param == 'D' ) m_armAngles[i+0] -= 5;
- if ( event.param == 'R' ) m_armAngles[i+1] += 5;
- if ( event.param == 'F' ) m_armAngles[i+1] -= 5;
- if ( event.param == 'T' ) m_armAngles[i+2] += 5;
- if ( event.param == 'G' ) m_armAngles[i+2] -= 5;
-
- if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop;
-#endif
- }
-
- return true;
-}
-
-// Management of an event.
-
-bool CMotionBee::EventFrame(const Event &event)
-{
- Math::Vector dir;
- float s, a, prog;
- int action, i, st, nd;
- bool bStop;
-
- if ( m_engine->RetPause() ) return true;
- if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return true;
-
- s = m_physics->RetLinMotionX(MO_MOTSPEED)*0.30f;
- a = fabs(m_physics->RetCirMotionY(MO_MOTSPEED)*2.00f);
-
- if ( s == 0.0f && a != 0.0f ) a *= 1.5f;
-
- m_armTimeAbs += event.rTime;
- m_armTimeMarch += (s)*event.rTime*0.15f;
- m_armMember += (s+a)*event.rTime*0.15f;
-
- bStop = ( a == 0.0f && s == 0.0f ); // stopped?
- if ( !m_physics->RetLand() ) bStop = true;
-
- if ( bStop )
- {
- prog = Math::Mod(m_armTimeAbs, 2.0f)/10.0f;
- a = Math::Mod(m_armMember, 1.0f);
- a = (prog-a)*event.rTime*2.0f; // stop position is pleasantly
- m_armMember += a;
- }
-
- action = MB_MARCH; // flying
-
- m_actionType = -1;
- if ( m_object->RetFret() != 0 ) m_actionType = MBS_HOLD; // carries the ball
-
- if ( m_object->RetRuin() ) // destroyed?
- {
- m_actionType = MBS_RUIN;
- }
- if ( m_object->RetBurn() ) // burning?
- {
- m_actionType = MBS_BURN;
- }
-
- for ( i=0 ; i<6 ; i++ ) // the six legs
- {
- if ( m_actionType != -1 ) // special action in progress?
- {
- st = 3*3*3*3*MB_SPEC + 3*3*3*m_actionType + (i%3)*3;
- nd = st;
- }
- else
- {
- if ( i < 3 ) prog = Math::Mod(m_armMember+(2.0f-(i%3))*0.33f+0.0f, 1.0f);
- else prog = Math::Mod(m_armMember+(2.0f-(i%3))*0.33f+0.3f, 1.0f);
- if ( m_bArmStop )
- {
- prog = (float)m_armTimeIndex/3.0f;
- }
- if ( prog < 0.33f ) // t0..t1 ?
- {
- prog = prog/0.33f; // 0..1
- st = 0; // index start
- nd = 1; // index end
- }
- else if ( prog < 0.67f ) // t1..t2 ?
- {
- prog = (prog-0.33f)/0.33f; // 0..1
- st = 1; // index start
- nd = 2; // index end
- }
- else // t2..t0 ?
- {
- prog = (prog-0.67f)/0.33f; // 0..1
- st = 2; // index start
- nd = 0; // index end
- }
- st = 3*3*3*3*action + st*3*3*3 + (i%3)*3;
- nd = 3*3*3*3*action + nd*3*3*3 + (i%3)*3;
- }
-
- if ( i < 3 ) // right leg (1..3) ?
- {
- m_object->SetAngleX(3+3*i+0, Math::PropAngle(m_armAngles[st+ 0], m_armAngles[nd+ 0], prog));
- m_object->SetAngleY(3+3*i+0, Math::PropAngle(m_armAngles[st+ 1], m_armAngles[nd+ 1], prog));
- m_object->SetAngleZ(3+3*i+0, Math::PropAngle(m_armAngles[st+ 2], m_armAngles[nd+ 2], prog));
- m_object->SetAngleX(3+3*i+1, Math::PropAngle(m_armAngles[st+ 9], m_armAngles[nd+ 9], prog));
- m_object->SetAngleY(3+3*i+1, Math::PropAngle(m_armAngles[st+10], m_armAngles[nd+10], prog));
- m_object->SetAngleZ(3+3*i+1, Math::PropAngle(m_armAngles[st+11], m_armAngles[nd+11], prog));
- m_object->SetAngleX(3+3*i+2, Math::PropAngle(m_armAngles[st+18], m_armAngles[nd+18], prog));
- m_object->SetAngleY(3+3*i+2, Math::PropAngle(m_armAngles[st+19], m_armAngles[nd+19], prog));
- m_object->SetAngleZ(3+3*i+2, Math::PropAngle(m_armAngles[st+20], m_armAngles[nd+20], prog));
- }
- else // left leg(4..6) ?
- {
- m_object->SetAngleX(3+3*i+0, Math::PropAngle( -m_armAngles[st+ 0], -m_armAngles[nd+ 0], prog));
- m_object->SetAngleY(3+3*i+0, Math::PropAngle(180-m_armAngles[st+ 1], 180-m_armAngles[nd+ 1], prog));
- m_object->SetAngleZ(3+3*i+0, Math::PropAngle( -m_armAngles[st+ 2], -m_armAngles[nd+ 2], prog));
- m_object->SetAngleX(3+3*i+1, Math::PropAngle( m_armAngles[st+ 9], m_armAngles[nd+ 9], prog));
- m_object->SetAngleY(3+3*i+1, Math::PropAngle( -m_armAngles[st+10], -m_armAngles[nd+10], prog));
- m_object->SetAngleZ(3+3*i+1, Math::PropAngle( -m_armAngles[st+11], -m_armAngles[nd+11], prog));
- m_object->SetAngleX(3+3*i+2, Math::PropAngle( m_armAngles[st+18], m_armAngles[nd+18], prog));
- m_object->SetAngleY(3+3*i+2, Math::PropAngle( -m_armAngles[st+19], -m_armAngles[nd+19], prog));
- m_object->SetAngleZ(3+3*i+2, Math::PropAngle( -m_armAngles[st+20], -m_armAngles[nd+20], prog));
- }
- }
-
-#if ADJUST_ANGLE
- if ( m_object->RetSelect() )
- {
- char s[100];
- sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex);
- m_engine->SetInfoText(4, s);
- }
-#endif
-
- if ( m_physics->RetLand() ) // on the ground?
- {
- if ( m_object->RetRuin() )
- {
- }
- else if ( bStop || m_object->RetBurn() )
- {
- m_object->SetAngleZ(2, sinf(m_armTimeAbs*1.7f)*0.15f+0.35f); // tail
- }
- else
- {
- a = Math::Mod(m_armTimeMarch, 1.0f);
- if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1
- else a = 3.0f-4.0f*a; // 1..-1
- dir.x = sinf(a)*0.05f;
-
- s = Math::Mod(m_armTimeMarch/2.0f, 1.0f);
- if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1
- else s = 3.0f-4.0f*s; // 1..-1
- dir.z = sinf(s)*0.1f;
-
- dir.y = 0.0f;
- m_object->SetInclinaison(dir);
-
- m_object->SetAngleZ(2, -sinf(a)*0.3f); // tail
-
- a = Math::Mod(m_armMember-0.1f, 1.0f);
- if ( a < 0.33f )
- {
- dir.y = -(1.0f-(a/0.33f))*0.3f;
- }
- else if ( a < 0.67f )
- {
- dir.y = 0.0f;
- }
- else
- {
- dir.y = -(a-0.67f)/0.33f*0.3f;
- }
- dir.x = 0.0f;
- dir.z = 0.0f;
- m_object->SetLinVibration(dir);
- }
- }
-
- if ( m_physics->RetLand() )
- {
- if ( bStop ) prog = 0.05f;
- else prog = 0.15f;
- }
- else
- {
- prog = 1.00f;
- }
-
-#if 0
- a = Math::Rand()*Math::PI/2.0f*prog;
- m_object->SetAngleX(21, a); // right wing
- a = -Math::Rand()*Math::PI/4.0f*prog;
- m_object->SetAngleY(21, a);
-
- a = -Math::Rand()*Math::PI/2.0f*prog;
- m_object->SetAngleX(22, a); // left wing
- a = Math::Rand()*Math::PI/4.0f*prog;
- m_object->SetAngleY(22, a);
-#else
- m_object->SetAngleX(21, (sinf(m_armTimeAbs*30.0f)+1.0f)*(Math::PI/4.0f)*prog);
- m_object->SetAngleY(21, -Math::Rand()*Math::PI/6.0f*prog);
-
- m_object->SetAngleX(22, -(sinf(m_armTimeAbs*30.0f)+1.0f)*(Math::PI/4.0f)*prog);
- m_object->SetAngleY(22, Math::Rand()*Math::PI/6.0f*prog);
-#endif
-
- m_object->SetAngleZ(1, sinf(m_armTimeAbs*1.4f)*0.20f); // head
- m_object->SetAngleX(1, sinf(m_armTimeAbs*1.9f)*0.10f); // head
- m_object->SetAngleY(1, sinf(m_armTimeAbs*2.1f)*0.50f); // head
-
-#if 0
- h = m_terrain->RetFloorHeight(RetPosition(0));
- radius = 4.0f+h/4.0f;
- color.r = 0.3f+h/80.0f;
- color.g = color.r;
- color.b = color.r;
- color.a = color.r;
- m_engine->SetObjectShadowRadius(m_objectPart[0].object, radius);
- m_engine->SetObjectShadowColor(m_objectPart[0].object, color);
-#endif
-
- return true;
-}
-
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionbee.cpp + + +#include <stdio.h> + +#include "object/motion/motionbee.h" + +#include "old/modfile.h" +#include "physics/physics.h" + + + +#define ADJUST_ANGLE false // true -> adjusts the angles of the members +const float START_TIME = 1000.0f; // beginning of the relative time + + + +// Object's constructor. + +CMotionBee::CMotionBee(CInstanceManager* iMan, CObject* object) + : CMotion(iMan, object) +{ + m_armMember = START_TIME; + m_armTimeAbs = START_TIME; + m_armTimeMarch = START_TIME; + m_armTimeAction = START_TIME; + m_armTimeIndex = 0; + m_armPartIndex = 0; + m_armMemberIndex = 0; + m_armLastAction = -1; + m_bArmStop = false; +} + +// Object's destructor. + +CMotionBee::~CMotionBee() +{ +} + + +// Removes an object. + +void CMotionBee::DeleteObject(bool bAll) +{ +} + + +// Creates a vehicle traveling any lands on the ground. + +bool CMotionBee::Create(Math::Vector pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + int rank; + + if ( m_engine->RetRestCreate() < 3+18+2 ) return false; + + pModFile = new CModFile(m_iMan); + + m_object->SetType(type); + + // Creates main base. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + + pModFile->ReadModel("objects\\bee1.mod"); + pModFile->CreateEngineObject(rank); + + m_object->SetPosition(0, pos); + m_object->SetAngleY(0, angle); + + // A vehicle must have an obligatory collision + // with a sphere of center (0, y, 0) (see GetCrashSphere). + m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f); + m_object->SetGlobalSphere(Math::Vector(-1.0f, 1.0f, 0.0f), 5.0f); + + // Creates the head. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\bee2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(1.6f, 0.3f, 0.0f)); + + // Creates the tail. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\bee3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, Math::Vector(-0.8f, 0.0f, 0.0f)); + + // Creates a right-back thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, Math::Vector(-0.3f, -0.1f, -0.2f)); + + // Creates a right-back leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(4, rank); + m_object->SetObjectParent(4, 3); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(4, Math::Vector(0.0f, 0.0f, -1.0f)); + + // Creates a right-back foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(5, rank); + m_object->SetObjectParent(5, 4); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(5, Math::Vector(0.0f, 0.0f, -2.0f)); + + // Creates two middle-right thighs. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, Math::Vector(0.3f, -0.1f, -0.4f)); + + // Creates two middle-right legs. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 6); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, Math::Vector(0.0f, 0.0f, -1.0f)); + + // Creates two middle-right feet. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 7); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, Math::Vector(0.0f, 0.0f, -2.0f)); + + // Creates the right front thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(9, rank); + m_object->SetObjectParent(9, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(9, Math::Vector(1.0f, -0.1f, -0.7f)); + + // Creates the right front leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(10, rank); + m_object->SetObjectParent(10, 9); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(10, Math::Vector(0.0f, 0.0f, -1.0f)); + + // Creates the right front foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(11, rank); + m_object->SetObjectParent(11, 10); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(11, Math::Vector(0.0f, 0.0f, -2.0f)); + + // Creates a left-back thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(12, rank); + m_object->SetObjectParent(12, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(12, Math::Vector(-0.3f, -0.1f, 0.2f)); + m_object->SetAngleY(12, Math::PI); + + // Creates a left-back leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(13, rank); + m_object->SetObjectParent(13, 12); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(13, Math::Vector(0.0f, 0.0f, -1.0f)); + + // Creates a left-back foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(14, rank); + m_object->SetObjectParent(14, 13); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(14, Math::Vector(0.0f, 0.0f, -2.0f)); + + // Creates two middle-left thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(15, rank); + m_object->SetObjectParent(15, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(15, Math::Vector(0.3f, -0.1f, 0.4f)); + m_object->SetAngleY(15, Math::PI); + + // Creates two middle-left legs. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(16, rank); + m_object->SetObjectParent(16, 15); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(16, Math::Vector(0.0f, 0.0f, -1.0f)); + + // Creates two middle-left feet. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(17, rank); + m_object->SetObjectParent(17, 16); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(17, Math::Vector(0.0f, 0.0f, -2.0f)); + + // Creates front-left thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(18, rank); + m_object->SetObjectParent(18, 0); + pModFile->ReadModel("objects\\ant4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(18, Math::Vector(1.0f, -0.1f, 0.7f)); + m_object->SetAngleY(18, Math::PI); + + // Creates front-left leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(19, rank); + m_object->SetObjectParent(19, 18); + pModFile->ReadModel("objects\\ant5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(19, Math::Vector(0.0f, 0.0f, -1.0f)); + + // Creates front-left foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(20, rank); + m_object->SetObjectParent(20, 19); + pModFile->ReadModel("objects\\ant6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(20, Math::Vector(0.0f, 0.0f, -2.0f)); + + // Creates the right wing. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(21, rank); + m_object->SetObjectParent(21, 0); + pModFile->ReadModel("objects\\bee7.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(21, Math::Vector(0.8f, 0.4f, -0.5f)); + + // Creates the left wing. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(22, rank); + m_object->SetObjectParent(22, 0); + pModFile->ReadModel("objects\\bee7.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(22, Math::Vector(0.8f, 0.4f, 0.5f)); + + m_object->CreateShadowCircle(6.0f, 0.5f); + + CreatePhysics(); + m_object->SetFloorHeight(0.0f); + + pos = m_object->RetPosition(0); + m_object->SetPosition(0, pos); // to display the shadows immediately + + m_engine->LoadAllTexture(); + + delete pModFile; + return true; +} + +// Creates the physical object. + +void CMotionBee::CreatePhysics() +{ + Character* character; + int i; + + int member_march[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: + 0,45,0, 0,45,0, 0,50,0, // t0: thighs 1..3 + 30,-70,0, 20,-105,20, 25,-100,0, // t0: legs 1..3 + -70,75,0, -30,80,0, -80,80,0, // t0: feet 1..3 + // on the ground: + 0,30,0, 0,20,0, 0,15,0, // t1: thighs 1..3 + -15,-50,0, -20,-60,0, -10,-75,0, // t1: legs 1..3 + -40,50,0, -25,15,0, -50,35,0, // t1: feet 1..3 + // on the ground back: + 0,35,0, 0,30,0, 0,20,0, // t2: thighs 1..3 + -20,-15,0, -30,-55,0, -25,-70,15, // t2: legs 1..3 + -25,25,0, -20,60,0, -30,95,0, // t2: feet 1..3 + }; + + int member_spec[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // ball carrier: + 0,45,0, 0,45,0, 0,50,0, // s0: thighs 1..3 + -35,-70,0, -20,-85,-25, -25,-100,0, // s0: legs 1..3 + -110,75,-15, -130,80,-25, -125,40,0, // s0: feet 1..3 + // burning: + 0,45,0, 0,45,0, 0,50,0, // s1: thighs 1..3 + -35,-70,0, -20,-85,-25, -25,-100,0, // s1: legs 1..3 + -110,75,-15, -130,80,-25, -125,40,0, // s1: feet 1..3 + // destroyed: + 0,45,0, 0,45,0, 0,50,0, // s2: thighs 1..3 + -35,-70,0, -20,-85,-25, -25,-100,0, // s2: legs 1..3 + -110,75,-15, -130,80,-25, -125,40,0, // s2: feet 1..3 + }; + + m_physics->SetType(TYPE_FLYING); + + character = m_object->RetCharacter(); + character->wheelFront = 3.0f; + character->wheelBack = 3.0f; + character->wheelLeft = 5.0f; + character->wheelRight = 5.0f; + character->height = 2.5f; + + m_physics->SetLinMotionX(MO_ADVSPEED, 50.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 50.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 20.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 10.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + m_physics->SetLinMotionY(MO_ADVSPEED, 60.0f); + m_physics->SetLinMotionY(MO_RECSPEED, 60.0f); + m_physics->SetLinMotionY(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionY(MO_RECACCEL, 50.0f); + m_physics->SetLinMotionY(MO_STOACCEL, 50.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 1.0f*Math::PI); + m_physics->SetCirMotionY(MO_RECSPEED, 1.0f*Math::PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 20.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 20.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 40.0f); + + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MB_MARCH+i] = member_march[i]; + } + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MB_SPEC+i] = member_spec[i]; + } +} + + +// Management of an event. + +bool CMotionBee::EventProcess(const Event &event) +{ + CMotion::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + if ( event.event == EVENT_KEYDOWN ) + { +#if ADJUST_ANGLE + int i; + + if ( event.param == 'A' ) m_armTimeIndex++; + if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0; + + if ( event.param == 'Q' ) m_armPartIndex++; + if ( m_armPartIndex >= 3 ) m_armPartIndex = 0; + + if ( event.param == 'W' ) m_armMemberIndex++; + if ( m_armMemberIndex >= 3 ) m_armMemberIndex = 0; + + i = m_armMemberIndex*3; + i += m_armPartIndex*3*3; + i += m_armTimeIndex*3*3*3; +//? i += 3*3*3*3; + + if ( event.param == 'E' ) m_armAngles[i+0] += 5; + if ( event.param == 'D' ) m_armAngles[i+0] -= 5; + if ( event.param == 'R' ) m_armAngles[i+1] += 5; + if ( event.param == 'F' ) m_armAngles[i+1] -= 5; + if ( event.param == 'T' ) m_armAngles[i+2] += 5; + if ( event.param == 'G' ) m_armAngles[i+2] -= 5; + + if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop; +#endif + } + + return true; +} + +// Management of an event. + +bool CMotionBee::EventFrame(const Event &event) +{ + Math::Vector dir; + float s, a, prog; + int action, i, st, nd; + bool bStop; + + if ( m_engine->RetPause() ) return true; + if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return true; + + s = m_physics->RetLinMotionX(MO_MOTSPEED)*0.30f; + a = fabs(m_physics->RetCirMotionY(MO_MOTSPEED)*2.00f); + + if ( s == 0.0f && a != 0.0f ) a *= 1.5f; + + m_armTimeAbs += event.rTime; + m_armTimeMarch += (s)*event.rTime*0.15f; + m_armMember += (s+a)*event.rTime*0.15f; + + bStop = ( a == 0.0f && s == 0.0f ); // stopped? + if ( !m_physics->RetLand() ) bStop = true; + + if ( bStop ) + { + prog = Math::Mod(m_armTimeAbs, 2.0f)/10.0f; + a = Math::Mod(m_armMember, 1.0f); + a = (prog-a)*event.rTime*2.0f; // stop position is pleasantly + m_armMember += a; + } + + action = MB_MARCH; // flying + + m_actionType = -1; + if ( m_object->RetFret() != 0 ) m_actionType = MBS_HOLD; // carries the ball + + if ( m_object->RetRuin() ) // destroyed? + { + m_actionType = MBS_RUIN; + } + if ( m_object->RetBurn() ) // burning? + { + m_actionType = MBS_BURN; + } + + for ( i=0 ; i<6 ; i++ ) // the six legs + { + if ( m_actionType != -1 ) // special action in progress? + { + st = 3*3*3*3*MB_SPEC + 3*3*3*m_actionType + (i%3)*3; + nd = st; + } + else + { + if ( i < 3 ) prog = Math::Mod(m_armMember+(2.0f-(i%3))*0.33f+0.0f, 1.0f); + else prog = Math::Mod(m_armMember+(2.0f-(i%3))*0.33f+0.3f, 1.0f); + if ( m_bArmStop ) + { + prog = (float)m_armTimeIndex/3.0f; + } + if ( prog < 0.33f ) // t0..t1 ? + { + prog = prog/0.33f; // 0..1 + st = 0; // index start + nd = 1; // index end + } + else if ( prog < 0.67f ) // t1..t2 ? + { + prog = (prog-0.33f)/0.33f; // 0..1 + st = 1; // index start + nd = 2; // index end + } + else // t2..t0 ? + { + prog = (prog-0.67f)/0.33f; // 0..1 + st = 2; // index start + nd = 0; // index end + } + st = 3*3*3*3*action + st*3*3*3 + (i%3)*3; + nd = 3*3*3*3*action + nd*3*3*3 + (i%3)*3; + } + + if ( i < 3 ) // right leg (1..3) ? + { + m_object->SetAngleX(3+3*i+0, Math::PropAngle(m_armAngles[st+ 0], m_armAngles[nd+ 0], prog)); + m_object->SetAngleY(3+3*i+0, Math::PropAngle(m_armAngles[st+ 1], m_armAngles[nd+ 1], prog)); + m_object->SetAngleZ(3+3*i+0, Math::PropAngle(m_armAngles[st+ 2], m_armAngles[nd+ 2], prog)); + m_object->SetAngleX(3+3*i+1, Math::PropAngle(m_armAngles[st+ 9], m_armAngles[nd+ 9], prog)); + m_object->SetAngleY(3+3*i+1, Math::PropAngle(m_armAngles[st+10], m_armAngles[nd+10], prog)); + m_object->SetAngleZ(3+3*i+1, Math::PropAngle(m_armAngles[st+11], m_armAngles[nd+11], prog)); + m_object->SetAngleX(3+3*i+2, Math::PropAngle(m_armAngles[st+18], m_armAngles[nd+18], prog)); + m_object->SetAngleY(3+3*i+2, Math::PropAngle(m_armAngles[st+19], m_armAngles[nd+19], prog)); + m_object->SetAngleZ(3+3*i+2, Math::PropAngle(m_armAngles[st+20], m_armAngles[nd+20], prog)); + } + else // left leg(4..6) ? + { + m_object->SetAngleX(3+3*i+0, Math::PropAngle( -m_armAngles[st+ 0], -m_armAngles[nd+ 0], prog)); + m_object->SetAngleY(3+3*i+0, Math::PropAngle(180-m_armAngles[st+ 1], 180-m_armAngles[nd+ 1], prog)); + m_object->SetAngleZ(3+3*i+0, Math::PropAngle( -m_armAngles[st+ 2], -m_armAngles[nd+ 2], prog)); + m_object->SetAngleX(3+3*i+1, Math::PropAngle( m_armAngles[st+ 9], m_armAngles[nd+ 9], prog)); + m_object->SetAngleY(3+3*i+1, Math::PropAngle( -m_armAngles[st+10], -m_armAngles[nd+10], prog)); + m_object->SetAngleZ(3+3*i+1, Math::PropAngle( -m_armAngles[st+11], -m_armAngles[nd+11], prog)); + m_object->SetAngleX(3+3*i+2, Math::PropAngle( m_armAngles[st+18], m_armAngles[nd+18], prog)); + m_object->SetAngleY(3+3*i+2, Math::PropAngle( -m_armAngles[st+19], -m_armAngles[nd+19], prog)); + m_object->SetAngleZ(3+3*i+2, Math::PropAngle( -m_armAngles[st+20], -m_armAngles[nd+20], prog)); + } + } + +#if ADJUST_ANGLE + if ( m_object->RetSelect() ) + { + char s[100]; + sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex); + m_engine->SetInfoText(4, s); + } +#endif + + if ( m_physics->RetLand() ) // on the ground? + { + if ( m_object->RetRuin() ) + { + } + else if ( bStop || m_object->RetBurn() ) + { + m_object->SetAngleZ(2, sinf(m_armTimeAbs*1.7f)*0.15f+0.35f); // tail + } + else + { + a = Math::Mod(m_armTimeMarch, 1.0f); + if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1 + else a = 3.0f-4.0f*a; // 1..-1 + dir.x = sinf(a)*0.05f; + + s = Math::Mod(m_armTimeMarch/2.0f, 1.0f); + if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1 + else s = 3.0f-4.0f*s; // 1..-1 + dir.z = sinf(s)*0.1f; + + dir.y = 0.0f; + m_object->SetInclinaison(dir); + + m_object->SetAngleZ(2, -sinf(a)*0.3f); // tail + + a = Math::Mod(m_armMember-0.1f, 1.0f); + if ( a < 0.33f ) + { + dir.y = -(1.0f-(a/0.33f))*0.3f; + } + else if ( a < 0.67f ) + { + dir.y = 0.0f; + } + else + { + dir.y = -(a-0.67f)/0.33f*0.3f; + } + dir.x = 0.0f; + dir.z = 0.0f; + m_object->SetLinVibration(dir); + } + } + + if ( m_physics->RetLand() ) + { + if ( bStop ) prog = 0.05f; + else prog = 0.15f; + } + else + { + prog = 1.00f; + } + +#if 0 + a = Math::Rand()*Math::PI/2.0f*prog; + m_object->SetAngleX(21, a); // right wing + a = -Math::Rand()*Math::PI/4.0f*prog; + m_object->SetAngleY(21, a); + + a = -Math::Rand()*Math::PI/2.0f*prog; + m_object->SetAngleX(22, a); // left wing + a = Math::Rand()*Math::PI/4.0f*prog; + m_object->SetAngleY(22, a); +#else + m_object->SetAngleX(21, (sinf(m_armTimeAbs*30.0f)+1.0f)*(Math::PI/4.0f)*prog); + m_object->SetAngleY(21, -Math::Rand()*Math::PI/6.0f*prog); + + m_object->SetAngleX(22, -(sinf(m_armTimeAbs*30.0f)+1.0f)*(Math::PI/4.0f)*prog); + m_object->SetAngleY(22, Math::Rand()*Math::PI/6.0f*prog); +#endif + + m_object->SetAngleZ(1, sinf(m_armTimeAbs*1.4f)*0.20f); // head + m_object->SetAngleX(1, sinf(m_armTimeAbs*1.9f)*0.10f); // head + m_object->SetAngleY(1, sinf(m_armTimeAbs*2.1f)*0.50f); // head + +#if 0 + h = m_terrain->RetFloorHeight(RetPosition(0)); + radius = 4.0f+h/4.0f; + color.r = 0.3f+h/80.0f; + color.g = color.r; + color.b = color.r; + color.a = color.r; + m_engine->SetObjectShadowRadius(m_objectPart[0].object, radius); + m_engine->SetObjectShadowColor(m_objectPart[0].object, color); +#endif + + return true; +} + + diff --git a/src/object/motion/motionbee.h b/src/object/motion/motionbee.h index 94ac7fa..aa8e5a6 100644 --- a/src/object/motion/motionbee.h +++ b/src/object/motion/motionbee.h @@ -1,66 +1,66 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motionbee.h
-
-#pragma once
-
-
-#include "object/motion/motion.h"
-
-
-
-enum MotionBeeAction
-{
- MB_MARCH = 0,
- MB_SPEC = 1
-};
-
-enum MotionBeeSpecialAction
-{
- MBS_HOLD = 0,
- MBS_BURN = 1,
- MBS_RUIN = 2
-};
-
-
-class CMotionBee : public CMotion
-{
-public:
- CMotionBee(CInstanceManager* iMan, CObject* object);
- ~CMotionBee();
-
- void DeleteObject(bool bAll=false);
- bool Create(Math::Vector pos, float angle, ObjectType type, float power);
- bool EventProcess(const Event &event);
-
-protected:
- void CreatePhysics();
- bool EventFrame(const Event &event);
-
-protected:
- float m_armMember;
- float m_armTimeAbs;
- float m_armTimeMarch;
- float m_armTimeAction;
- short m_armAngles[3*3*3*3*2];
- int m_armTimeIndex;
- int m_armPartIndex;
- int m_armMemberIndex;
- int m_armLastAction;
- bool m_bArmStop;
-};
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionbee.h + +#pragma once + + +#include "object/motion/motion.h" + + + +enum MotionBeeAction +{ + MB_MARCH = 0, + MB_SPEC = 1 +}; + +enum MotionBeeSpecialAction +{ + MBS_HOLD = 0, + MBS_BURN = 1, + MBS_RUIN = 2 +}; + + +class CMotionBee : public CMotion +{ +public: + CMotionBee(CInstanceManager* iMan, CObject* object); + ~CMotionBee(); + + void DeleteObject(bool bAll=false); + bool Create(Math::Vector pos, float angle, ObjectType type, float power); + bool EventProcess(const Event &event); + +protected: + void CreatePhysics(); + bool EventFrame(const Event &event); + +protected: + float m_armMember; + float m_armTimeAbs; + float m_armTimeMarch; + float m_armTimeAction; + short m_armAngles[3*3*3*3*2]; + int m_armTimeIndex; + int m_armPartIndex; + int m_armMemberIndex; + int m_armLastAction; + bool m_bArmStop; +}; + diff --git a/src/object/motion/motionhuman.cpp b/src/object/motion/motionhuman.cpp index 6bdcf7e..06db454 100644 --- a/src/object/motion/motionhuman.cpp +++ b/src/object/motion/motionhuman.cpp @@ -1,1770 +1,1770 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motionhuman.cpp
-
-
-#include <stdio.h>
-
-#include "object/motion/motionhuman.h"
-
-#include "old/modfile.h"
-#include "old/terrain.h"
-#include "old/water.h"
-#include "math/geometry.h"
-#include "object/robotmain.h"
-#include "physics/physics.h"
-
-
-
-#define ADJUST_ANGLE false // true -> adjusts the angles of the members
-const int ADJUST_ACTION = (3*3*3*3*MH_SPEC+3*3*3*MHS_SATCOM);
-
-const float START_TIME = 1000.0f; // beginning of the relative time
-
-
-
-// Object's constructor.
-
-CMotionHuman::CMotionHuman(CInstanceManager* iMan, CObject* object)
- : CMotion(iMan, object)
-{
- m_partiReactor = -1;
- m_armMember = START_TIME;
- m_armTimeAbs = START_TIME;
- m_armTimeAction = START_TIME;
- m_armTimeSwim = START_TIME;
- m_armTimeIndex = 0;
- m_armPartIndex = 0;
- m_armMemberIndex = 0;
- m_armLastAction = -1;
- m_bArmStop = false;
- m_lastSoundMarch = 0.0f;
- m_lastSoundHhh = 0.0f;
- m_time = 0.0f;
- m_tired = 0.0f;
- m_bDisplayPerso = false;
-}
-
-// Object's constructor.
-
-CMotionHuman::~CMotionHuman()
-{
-}
-
-
-// Removes an object.
-
-void CMotionHuman::DeleteObject(bool bAll)
-{
- if ( m_partiReactor != -1 )
- {
- m_particule->DeleteParticule(m_partiReactor);
- m_partiReactor = -1;
- }
-}
-
-
-// Starts an action.
-
-Error CMotionHuman::SetAction(int action, float time)
-{
- CMotion::SetAction(action, time);
- m_time = 0.0f;
- return ERR_OK;
-}
-
-
-// Creates cosmonaut on the ground.
-
-bool CMotionHuman::Create(Math::Vector pos, float angle, ObjectType type,
- float power)
-{
- CModFile* pModFile;
- char filename[100];
- int rank, option, face, glasses;
-
- if ( m_engine->RetRestCreate() < 16 ) return false;
-
- pModFile = new CModFile(m_iMan);
-
- m_object->SetType(type);
- option = m_object->RetOption();
-
- if ( m_main->RetGamerOnlyHead() )
- {
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object
- m_object->SetObjectRank(0, rank);
- face = m_main->RetGamerFace();
- sprintf(filename, "objects\\human2h%d.mod", face+1);
- pModFile->ReadModel(filename);
- pModFile->CreateEngineObject(rank);
-
- glasses = m_main->RetGamerGlasses();
- if ( glasses != 0 )
- {
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- sprintf(filename, "objects\\human2g%d.mod", glasses);
- pModFile->ReadModel(filename);
- pModFile->CreateEngineObject(rank);
- }
-
- CreatePhysics(type);
- m_object->SetFloorHeight(0.0f);
-
- m_engine->LoadAllTexture();
-
- delete pModFile;
- return true;
- }
-
- // Creates the main base.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object
- m_object->SetObjectRank(0, rank);
-
- if ( option == 0 ) // head in helmet?
- {
- pModFile->ReadModel("objects\\human1c.mod");
- }
- if ( option == 1 ) // head without helmet?
- {
- pModFile->ReadModel("objects\\human1h.mod");
- }
- if ( option == 2 ) // without a backpack?
- {
- pModFile->ReadModel("objects\\human1v.mod");
- }
- pModFile->CreateEngineObject(rank);
-
- m_object->SetPosition(0, pos);
- m_object->SetAngleY(0, angle);
-
- // A vehicle must have an obligatory collision with a sphere of center (0, y, 0) (see GetCrashSphere).
- m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 2.0f, SOUND_AIE, 0.20f);
- m_object->SetGlobalSphere(Math::Vector(0.0f, 1.0f, 0.0f), 4.0f);
-
- // Creates the head.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
-
- if ( type == OBJECT_HUMAN )
- {
- if ( option == 0 ) // head in helmet?
- {
- face = m_main->RetGamerFace();
- sprintf(filename, "objects\\human2c%d.mod", face+1);
- pModFile->ReadModel(filename);
- }
- if ( option == 1 || // head without helmet?
- option == 2 ) // without a backpack?
- {
- face = m_main->RetGamerFace();
- sprintf(filename, "objects\\human2h%d.mod", face+1);
- pModFile->ReadModel(filename);
- }
- }
- if ( type == OBJECT_TECH )
- {
- pModFile->ReadModel("objects\\human2t.mod");
- }
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(0.0f, 2.7f, 0.0f));
- if ( option == 1 || // head without helmet?
- option == 2 ) // without a backpack?
- {
- m_object->SetZoom(1, Math::Vector(1.0f, 1.05f, 1.0f));
- }
-
- // Creates the glasses.
- glasses = m_main->RetGamerGlasses();
- if ( glasses != 0 && type == OBJECT_HUMAN )
- {
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(15, rank);
- m_object->SetObjectParent(15, 1);
- sprintf(filename, "objects\\human2g%d.mod", glasses);
- pModFile->ReadModel(filename);
- pModFile->CreateEngineObject(rank);
- }
-
- // Creates the right arm.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 0);
- pModFile->ReadModel("objects\\human3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2, Math::Vector(0.0f, 2.3f, -1.2f));
- m_object->SetAngle(2, Math::Vector(90.0f*Math::PI/180.0f, 90.0f*Math::PI/180.0f, -50.0f*Math::PI/180.0f));
-
- // Creates the right forearm.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(3, rank);
- m_object->SetObjectParent(3, 2);
- pModFile->ReadModel("objects\\human4r.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(3, Math::Vector(1.3f, 0.0f, 0.0f));
- m_object->SetAngle(3, Math::Vector(0.0f*Math::PI/180.0f, -20.0f*Math::PI/180.0f, 0.0f*Math::PI/180.0f));
-
- // Creates right hand.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(4, rank);
- m_object->SetObjectParent(4, 3);
- pModFile->ReadModel("objects\\human5.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(4, Math::Vector(1.2f, 0.0f, 0.0f));
-
- // Creates the right thigh.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(5, rank);
- m_object->SetObjectParent(5, 0);
- pModFile->ReadModel("objects\\human6.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(5, Math::Vector(0.0f, 0.0f, -0.7f));
- m_object->SetAngle(5, Math::Vector(10.0f*Math::PI/180.0f, 0.0f*Math::PI/180.0f, 5.0f*Math::PI/180.0f));
-
- // Creates the right leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(6, rank);
- m_object->SetObjectParent(6, 5);
- pModFile->ReadModel("objects\\human7.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(6, Math::Vector(0.0f, -1.5f, 0.0f));
- m_object->SetAngle(6, Math::Vector(0.0f*Math::PI/180.0f, 0.0f*Math::PI/180.0f, -10.0f*Math::PI/180.0f));
-
- // Creates the right foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(7, rank);
- m_object->SetObjectParent(7, 6);
- pModFile->ReadModel("objects\\human8.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(7, Math::Vector(0.0f, -1.5f, 0.0f));
- m_object->SetAngle(7, Math::Vector(-10.0f*Math::PI/180.0f, 5.0f*Math::PI/180.0f, 5.0f*Math::PI/180.0f));
-
- // Creates the left arm.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(8, rank);
- m_object->SetObjectParent(8, 0);
- pModFile->ReadModel("objects\\human3.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(8, Math::Vector(0.0f, 2.3f, 1.2f));
- m_object->SetAngle(8, Math::Vector(-90.0f*Math::PI/180.0f, -90.0f*Math::PI/180.0f, -50.0f*Math::PI/180.0f));
-
- // Creates the left forearm.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(9, rank);
- m_object->SetObjectParent(9, 8);
- pModFile->ReadModel("objects\\human4l.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(9, Math::Vector(1.3f, 0.0f, 0.0f));
- m_object->SetAngle(9, Math::Vector(0.0f*Math::PI/180.0f, 20.0f*Math::PI/180.0f, 0.0f*Math::PI/180.0f));
-
- // Creates left hand.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(10, rank);
- m_object->SetObjectParent(10, 9);
- pModFile->ReadModel("objects\\human5.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(10, Math::Vector(1.2f, 0.0f, 0.0f));
-
- // Creates the left thigh.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(11, rank);
- m_object->SetObjectParent(11, 0);
- pModFile->ReadModel("objects\\human6.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(11, Math::Vector(0.0f, 0.0f, 0.7f));
- m_object->SetAngle(11, Math::Vector(-10.0f*Math::PI/180.0f, 0.0f*Math::PI/180.0f, 5.0f*Math::PI/180.0f));
-
- // Creates the left leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(12, rank);
- m_object->SetObjectParent(12, 11);
- pModFile->ReadModel("objects\\human7.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(12, Math::Vector(0.0f, -1.5f, 0.0f));
- m_object->SetAngle(12, Math::Vector(0.0f*Math::PI/180.0f, 0.0f*Math::PI/180.0f, -10.0f*Math::PI/180.0f));
-
- // Creates the left foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(13, rank);
- m_object->SetObjectParent(13, 12);
- pModFile->ReadModel("objects\\human8.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(13, Math::Vector(0.0f, -1.5f, 0.0f));
- m_object->SetAngle(13, Math::Vector(10.0f*Math::PI/180.0f, -5.0f*Math::PI/180.0f, 5.0f*Math::PI/180.0f));
-
- // Creates the neutron gun.
- if ( option != 2 ) // with backpack?
- {
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(14, rank);
- m_object->SetObjectParent(14, 0);
- pModFile->ReadModel("objects\\human9.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(14, Math::Vector(-1.5f, 0.3f, -1.35f));
- m_object->SetAngleZ(14, Math::PI);
- }
-
- m_object->CreateShadowCircle(2.0f, 0.8f);
-
- CreatePhysics(type);
- m_object->SetFloorHeight(0.0f);
-
- pos = m_object->RetPosition(0);
- m_object->SetPosition(0, pos); // to display the shadows immediately
-
- m_engine->LoadAllTexture();
-
- delete pModFile;
- return true;
-}
-
-// Creates the physical object.
-
-void CMotionHuman::CreatePhysics(ObjectType type)
-{
- Character* character;
- int i;
-
- int member_march[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air:
- 90,90,-50, 10,0,55, 0,0,0, // t0: arms/thighs/-
- 0,-20,0, -5,0,-110, 0,0,0, // t0: forearm/legs/-
- 0,0,0, -5,0,40, 0,0,0, // t0: hands/feet/-
- // on the ground:
- 125,115,-45, 10,0,50, 0,0,0, // t1: arms/thighs/-
- 0,-20,0, -5,0,-15, 0,0,0, // t1: forearm/legs/-
- 0,0,0, -5,0,0, 0,0,0, // t1: hands/feet/-
- // on the ground back:
- 25,55,-40, 10,0,-15, 0,0,0, // t2: arms/thighs/-
- 30,-50,40, -5,0,-55, 0,0,0, // t2: forearm/legs/-
- 0,0,0, -5,0,25, 0,0,0, // t2: hands/feet/-
- };
-
- int member_march_take[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air:
- 15,50,-50, 10,0,55, 0,0,0, // t0: arms/thighs/-
- 45,-70,10, -5,0,-110, 0,0,0, // t0: forearm/legs/-
- -10,25,0, -5,0,40, 0,0,0, // t0: hands/feet/-
- // on the ground:
- 15,50,-55, 10,0,50, 0,0,0, // t1: arms/thighs/-
- 45,-70,10, -5,0,-15, 0,0,0, // t1: forearm/legs/-
- -10,25,0, -5,0,0, 0,0,0, // t1: hands/feet/-
- // on the ground back:
- 15,50,-45, 10,0,-15, 0,0,0, // t2: arms/thighs/-
- 45,-70,10, -5,0,-55, 0,0,0, // t2: forearm/legs/-
- -10,25,0, -5,0,45, 0,0,0, // t2: hands/feet/-
- };
-
- int member_turn[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air:
- 90,90,-50, 10,0,30, 0,0,0, // t0: arms/thighs/-
- 0,-20,0, -5,0,-60, 0,0,0, // t0: forearm/legs/-
- 0,0,0, -5,0,30, 0,0,0, // t0: hands/feet/-
- // on the ground:
- 90,110,-45, 10,0,0, 0,0,0, // t1: arms/thighs/-
- 0,-20,0, -5,5,0, 0,0,0, // t1: forearm/legs/-
- 0,0,0, -5,10,0, 0,0,0, // t1: hands/feet/-
- // on the ground back:
- 90,70,-45, 10,0,0, 0,0,0, // t2: arms/thighs/-
- 0,-20,10, -5,-5,0, 0,0,0, // t2: forearm/legs/-
- 0,0,0, -5,-10,0, 0,0,0, // t2: hands/feet/-
- };
-
- int member_stop[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3,
- 90,90,-50, 10,0,5, 0,0,0, // arms/thighs/-
- 0,-20,0, 0,0,-10, 0,0,0, // forearm/legs/-
- 0,0,0, -10,5,5, 0,0,0, // hands/feet/-
- //
- 90,90,-55, 10,0,5, 0,0,0, // arms/thighs/-
- 0,-15,0, 0,0,-10, 0,0,0, // forearm/legs/-
- 0,0,0, -10,5,5, 0,0,0, // hands/feet/-
- //
- 90,90,-60, 10,0,5, 0,0,0, // arms/thighs/-
- 0,-10,0, 0,0,-10, 0,0,0, // forearm/legs/-
- 0,0,0, -10,5,5, 0,0,0, // hands/feet/-
- };
-
- int member_fly[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3,
- -5,90,-60, 20,5,-25, 0,0,0, // arms/thighs/-
- 85,-40,-25, 10,0,-30, 0,0,0, // forearm/legs/-
- 40,10,25, 0,15,0, 0,0,0, // hands/feet/-
- //
- -15,90,-40, 20,5,-35, 0,0,0, // arms/thighs/-
- 85,-40,-25, 10,0,-40, 0,0,0, // forearm/legs/-
- 45,5,20, 0,15,0, 0,0,0, // hands/feet/-
- //
- -25,90,-50, 20,5,-20, 0,0,0, // arms/thighs/-
- 85,-40,-25, 10,0,-10, 0,0,0, // forearm/legs/-
- 30,15,25, 0,15,0, 0,0,0, // hands/feet/-
- };
-
- int member_swim[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3,
-#if 1
- 130,-70,200, 10,20,55, 0,0,0, // arms/thighs/-
- 115,-125,0, -5,0,-110, 0,0,0, // forearm/legs/-
- 0,0,0, -5,10,-5, 0,0,0, // hands/feet/-
- //
- 130,-95,115,55,5,5, 0,0,0, // arms/thighs/-
- 75,-50,25, -5,0,-15, 0,0,0, // forearm/legs/-
- 0,0,0, -5,5,-30, 0,0,0, // hands/feet/-
- //
- 130,-100,220,5,0,0, 0,0,0, // arms/thighs/-
- 150,5,0, -5,0,-15, 0,0,0, // forearm/legs/-
- 0,0,0, -5,30,-20, 0,0,0, // hands/feet/-
-#endif
-#if 0
- 130,-70,200,5,0,0, 0,0,0, // arms/thighs/-
- 115,-125,0, -5,0,-15, 0,0,0, // forearm/legs/-
- 0,0,0, -5,30,-20, 0,0,0, // hands/feet/-
- //
- 130,-95,115, 10,20,55, 0,0,0, // arms/thighs/-
- 75,-50,25, -5,0,-110, 0,0,0, // forearm/legs/-
- 0,0,0, -5,10,-5, 0,0,0, // hands/feet/-
- //
- 130,-100,220, 55,5,5, 0,0,0, // arms/thighs/-
- 150,5,0, -5,0,-15, 0,0,0, // forearm/legs/-
- 0,0,0, -5,5,-30, 0,0,0, // hands/feet/-
-#endif
-#if 0
- 130,-70,200, 55,5,5, 0,0,0, // arms/thighs/-
- 115,-125,0, -5,0,-15, 0,0,0, // forearm/legs/-
- 0,0,0, -5,5,-30, 0,0,0, // hands/feet/-
- //
- 130,-95,115, 5,0,0, 0,0,0, // arms/thighs/-
- 75,-50,25, -5,0,-15, 0,0,0, // forearm/legs/-
- 0,0,0, -5,30,-20, 0,0,0, // hands/feet/-
- //
- 130,-100,220, 10,20,55, 0,0,0, // arms/thighs/-
- 150,5,0, -5,0,-110, 0,0,0, // forearm/legs/-
- 0,0,0, -5,10,-5, 0,0,0, // hands/feet/-
-#endif
- };
-
- int member_spec[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3, // shooting:
- 65,5,-20, 10,0,40, 0,0,0, // s0: arms/thighs/-
- -50,-30,50, 0,0,-70, 0,0,0, // s0: forearm/legs/-
- 0,50,0, -10,0,35, 0,0,0, // s0: hands/feet/-
- // takes weapon:
- 160,135,-20,10,0,5, 0,0,0, // s1: arms/thighs/-
- 10,-60,40, 0,0,-10, 0,0,0, // s1: forearm/legs/-
- 0,-5,-25, -10,5,5, 0,0,0, // s1: hands/feet/-
- // carries earth:
- 25,40,-40, 10,0,60, 0,0,0, // s2: arms/thighs/-
- 0,-45,0, 0,0,-120, 0,0,0, // s2: forearm/legs/-
- 0,15,5, -10,0,70, 0,0,0, // s2: hands/feet/-
- // carries in front:
- 25,20,5, 10,0,55, 0,0,0, // s3: arms/thighs/-
- -15,-30,10, 0,0,-110, 0,0,0, // s3: forearm/legs/-
- 0,0,0, -10,0,65, 0,0,0, // s3: hands/feet/-
- // carries vertically:
- -30,15,-5, 10,0,15, 0,0,0, // s4: arms/thighs/-
- 0,-15,15, 0,0,-30, 0,0,0, // s4: forearm/legs/-
- 35,0,-15, -10,0,25, 0,0,0, // s4: hands/feet/-
- // rises:
- 15,50,-50, 10,0,5, 0,0,0, // s5: arms/thighs/-
- 45,-70,10, 0,0,-10, 0,0,0, // s5: forearm/legs/-
- -10,25,0, -10,5,5, 0,0,0, // s5: hands/feet/-
- // wins:
- 90,90,-30, 20,0,5, 0,0,0, // s6: arms/thighs/-
- 0,-90,0, -10,0,-10, 0,0,0, // s6: forearm/legs/-
- 0,25,0, -10,5,5, 0,0,0, // s6: hands/feet/-
- // lose:
- -70,45,35, 10,0,40, 0,0,0, // s7: arms/thighs/-
- 15,-95,-5, 0,0,-70, 0,0,0, // s7: forearm/legs/-
- 0,0,0, -10,0,35, 0,0,0, // s7: hands/feet/-
- // shooting death (falls):
- 90,90,-50, 10,0,5, 0,0,0, // s8: arms/thighs/-
- 0,-20,0, 0,0,-10, 0,0,0, // s8: forearm/legs/-
- 0,0,0, -10,5,5, 0,0,0, // s8: hands/feet/-
- // shooting death (knees):
- 110,105,-5, 10,0,25, 0,0,0, // s9: arms/thighs/-
- 0,-40,20, 0,0,-120, 0,0,0, // s9: forearm/legs/-
- 0,0,0, -10,5,5, 0,0,0, // s9: hands/feet/-
- // shooting death (knees):
- 110,120,-25, 10,0,25, 0,0,0, // s10: arms/thighs/-
- 0,-40,20, 0,0,-120, 0,0,0, // s10: forearm/legs/-
- 0,0,0, -10,5,5, 0,0,0, // s10: hands/feet/-
- // shooting death (face down):
- 110,100,-25, 25,0,10, 0,0,0, // s11: arms/thighs/-
- 0,-40,20, 0,0,-25, 0,0,0, // s11: forearm/legs/-
- 0,0,0, -10,5,5, 0,0,0, // s11: hands/feet/-
- // shooting death (face down):
- 110,100,-25, 25,0,10, 0,0,0, // s12: arms/thighs/-
- 0,-40,20, 0,0,-25, 0,0,0, // s12: forearm/legs/-
- 0,0,0, -10,5,5, 0,0,0, // s12: hands/feet/-
- // drowned:
- 110,100,-25, 25,0,10, 0,0,0, // s13: arms/thighs/-
- 0,-40,20, 0,0,-25, 0,0,0, // s13: forearm/legs/-
- 0,0,0, -10,5,5, 0,0,0, // s13: hands/feet/-
- // puts / removes flag:
- 85,45,-50, 10,0,60, 0,0,0, // s14: arms/thighs/-
- -60,15,65, 0,0,-105, 0,0,0, // s14: forearm/legs/-
- 0,10,0, -10,0,60, 0,0,0, // s14: hands/feet/-
- // reads SatCom:
- 70,30,-20, 10,0,5, 0,0,0, // s15: arms/thighs/-
- 115,-65,60, 0,0,-10, 0,0,0, // s15: forearm/legs/-
- 0,20,0, -10,5,5, 0,0,0, // s15: hands/feet/-
- };
-
- m_physics->SetType(TYPE_FLYING);
-
- character = m_object->RetCharacter();
- character->wheelFront = 4.0f;
- character->wheelBack = 4.0f;
- character->wheelLeft = 4.0f;
- character->wheelRight = 4.0f;
- character->height = 3.5f;
-
- if ( type == OBJECT_HUMAN )
- {
- m_physics->SetLinMotionX(MO_ADVSPEED, 50.0f);
- m_physics->SetLinMotionX(MO_RECSPEED, 35.0f);
- m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f);
- m_physics->SetLinMotionX(MO_RECACCEL, 20.0f);
- m_physics->SetLinMotionX(MO_STOACCEL, 20.0f);
- m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionX(MO_TERFORCE, 70.0f);
- m_physics->SetLinMotionZ(MO_TERFORCE, 40.0f);
- m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f);
- m_physics->SetLinMotionY(MO_ADVSPEED, 60.0f);
- m_physics->SetLinMotionY(MO_RECSPEED, 60.0f);
- m_physics->SetLinMotionY(MO_ADVACCEL, 20.0f);
- m_physics->SetLinMotionY(MO_RECACCEL, 50.0f);
- m_physics->SetLinMotionY(MO_STOACCEL, 50.0f);
-
- m_physics->SetCirMotionY(MO_ADVSPEED, 0.8f*Math::PI);
- m_physics->SetCirMotionY(MO_RECSPEED, 0.8f*Math::PI);
- m_physics->SetCirMotionY(MO_ADVACCEL, 6.0f);
- m_physics->SetCirMotionY(MO_RECACCEL, 6.0f);
- m_physics->SetCirMotionY(MO_STOACCEL, 4.0f);
- }
- else
- {
- m_physics->SetLinMotionX(MO_ADVSPEED, 40.0f);
- m_physics->SetLinMotionX(MO_RECSPEED, 15.0f);
- m_physics->SetLinMotionX(MO_ADVACCEL, 8.0f);
- m_physics->SetLinMotionX(MO_RECACCEL, 8.0f);
- m_physics->SetLinMotionX(MO_STOACCEL, 8.0f);
- m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionX(MO_TERFORCE, 50.0f);
- m_physics->SetLinMotionZ(MO_TERFORCE, 50.0f);
- m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f);
- m_physics->SetLinMotionY(MO_ADVSPEED, 60.0f);
- m_physics->SetLinMotionY(MO_RECSPEED, 60.0f);
- m_physics->SetLinMotionY(MO_ADVACCEL, 20.0f);
- m_physics->SetLinMotionY(MO_RECACCEL, 50.0f);
- m_physics->SetLinMotionY(MO_STOACCEL, 50.0f);
-
- m_physics->SetCirMotionY(MO_ADVSPEED, 0.6f*Math::PI);
- m_physics->SetCirMotionY(MO_RECSPEED, 0.6f*Math::PI);
- m_physics->SetCirMotionY(MO_ADVACCEL, 4.0f);
- m_physics->SetCirMotionY(MO_RECACCEL, 4.0f);
- m_physics->SetCirMotionY(MO_STOACCEL, 3.0f);
- }
-
- for ( i=0 ; i<3*3*3*3 ; i++ )
- {
- m_armAngles[3*3*3*3*MH_MARCH+i] = member_march[i];
- }
- for ( i=0 ; i<3*3*3*3 ; i++ )
- {
- m_armAngles[3*3*3*3*MH_MARCHTAKE+i] = member_march_take[i];
- }
- for ( i=0 ; i<3*3*3*3 ; i++ )
- {
- m_armAngles[3*3*3*3*MH_TURN+i] = member_turn[i];
- }
- for ( i=0 ; i<3*3*3*3 ; i++ )
- {
- m_armAngles[3*3*3*3*MH_STOP+i] = member_stop[i];
- }
- for ( i=0 ; i<3*3*3*3 ; i++ )
- {
- m_armAngles[3*3*3*3*MH_FLY+i] = member_fly[i];
- }
- for ( i=0 ; i<3*3*3*3 ; i++ )
- {
- m_armAngles[3*3*3*3*MH_SWIM+i] = member_swim[i];
- }
- for ( i=0 ; i<3*3*3*16 ; i++ )
- {
- m_armAngles[3*3*3*3*MH_SPEC+i] = member_spec[i];
- }
-}
-
-
-// Management of an event.
-
-bool CMotionHuman::EventProcess(const Event &event)
-{
- CMotion::EventProcess(event);
-
- if ( event.event == EVENT_FRAME )
- {
- return EventFrame(event);
- }
-
- if ( event.event == EVENT_KEYDOWN )
- {
-#if ADJUST_ANGLE
- int i;
-
- if ( event.param == 'A' ) m_armTimeIndex++;
- if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0;
-
- if ( event.param == 'Q' ) m_armPartIndex++;
- if ( m_armPartIndex >= 3 ) m_armPartIndex = 0;
-
- if ( event.param == 'W' ) m_armMemberIndex++;
- if ( m_armMemberIndex >= 3 ) m_armMemberIndex = 0;
-
- i = m_armMemberIndex*3;
- i += m_armPartIndex*3*3;
- i += m_armTimeIndex*3*3*3;
- i += ADJUST_ACTION;
-
- if ( event.param == 'E' ) m_armAngles[i+0] += 5;
- if ( event.param == 'D' ) m_armAngles[i+0] -= 5;
- if ( event.param == 'R' ) m_armAngles[i+1] += 5;
- if ( event.param == 'F' ) m_armAngles[i+1] -= 5;
- if ( event.param == 'T' ) m_armAngles[i+2] += 5;
- if ( event.param == 'G' ) m_armAngles[i+2] -= 5;
-
- if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop;
-
- if ( event.param == 'Y' )
- {
- char s[100];
- sprintf(s, "index dans table = %d %d %d\n", i, i+9, i+18);
- OutputDebugString(s);
- }
-#endif
- }
-
- return true;
-}
-
-// Management of an event.
-
-bool CMotionHuman::EventFrame(const Event &event)
-{
- Math::Matrix* mat;
- Math::Vector dir, actual, pos, speed, pf;
- Math::Point center, dim, p2;
- float s, a, prog, rTime[2], lTime[2], time, rot, hr, hl;
- float al, ar, af;
- float tSt[9], tNd[9];
- float aa, bb, shield, deadFactor, level;
- int i, ii, st, nd, action, legAction, armAction;
- bool bOnBoard, bSwim, bStop;
-
- if ( m_engine->RetPause() )
- {
- if ( m_actionType == MHS_SATCOM )
- {
- m_progress += event.rTime*m_actionTime;
- }
- else
- {
- return true;
- }
- }
-
- bOnBoard = false;
- if ( m_object->RetSelect() &&
- m_camera->RetType() == CAMERA_ONBOARD )
- {
- bOnBoard = true;
- }
-
- if ( m_bDisplayPerso && m_main->RetGamerOnlyHead() )
- {
- m_time += event.rTime;
- m_object->SetLinVibration(Math::Vector(0.0f, -0.55f, 0.0f));
- m_object->SetCirVibration(Math::Vector(0.0f, m_main->RetPersoAngle(), 0.0f));
- return true;
- }
- if ( m_bDisplayPerso )
- {
- m_object->SetCirVibration(Math::Vector(0.0f, m_main->RetPersoAngle()+0.2f, 0.0f));
- }
-
- shield = m_object->RetShield();
- shield += event.rTime*(1.0f/120.0f); // regeneration in 120 seconds
- if ( shield > 1.0f ) shield = 1.0f;
- m_object->SetShield(shield);
-
- bSwim = m_physics->RetSwim();
-
-#if 0
- rot = m_physics->RetCirMotionY(MO_MOTSPEED);
- s = m_physics->RetLinMotionX(MO_REASPEED)*2.0f;
- a = m_physics->RetLinMotionX(MO_TERSPEED);
- if ( a < 0.0f ) // rises?
- {
- if ( s > 0.0f && s < 20.0f ) s = 20.0f; // moving slowly?
-//? if ( s < 0.0f && s > -10.0f ) s = 0.0f; // falling slowly?
- }
- if ( a > 0.0f && !bSwim ) // falls?
- {
- if ( s > 0.0f && s < 10.0f ) s = 0.0f; // moving slowly?
-//? if ( s < 0.0f && s > -5.0f ) s = -5.0f; // falling slowly?
- }
- a = fabs(rot*12.0f);
-
- if ( !m_physics->RetLand() && !bSwim ) // in flight?
- {
- s = 0.0f;
- }
-
- if ( m_object->RetFret() != 0 ) // carries something?
- {
- s *= 1.3f;
- }
-#else
- rot = m_physics->RetCirMotionY(MO_MOTSPEED);
-#if 0
- s = m_physics->RetLinMotionX(MO_REASPEED);
-#else
- a = m_physics->RetLinMotionX(MO_REASPEED);
- s = m_physics->RetLinMotionX(MO_MOTSPEED)*0.2f;
- if ( fabs(a) > fabs(s) ) s = a; // the highest value
-#endif
- a = m_physics->RetLinMotionX(MO_TERSPEED);
- if ( a < 0.0f ) // rises?
- {
- a += m_physics->RetLinMotionX(MO_TERSLIDE);
- if ( a < 0.0f ) s -= a;
- }
- if ( a > 0.0f ) // falls?
- {
- a -= m_physics->RetLinMotionX(MO_TERSLIDE);
- if ( a > 0.0f ) s -= a;
- }
- s *= 2.0f;
- a = fabs(rot*12.0f);
-
- if ( !m_physics->RetLand() && !bSwim ) // in flight?
- {
- s = 0.0f;
- }
-
- if ( m_object->RetFret() != 0 ) // carries something?
- {
- s *= 1.3f;
- }
-#endif
-
- m_time += event.rTime;
- m_armTimeAbs += event.rTime;
- m_armTimeAction += event.rTime;
- m_armMember += s*event.rTime*0.05f;
-
- // Fatigue management when short.
- if ( m_physics->RetLand() && s != 0.0f ) // on the ground?
- {
- m_tired += event.rTime*0.1f;
- if ( m_tired > 1.0f )
- {
- m_tired = 1.0f;
- if ( m_lastSoundHhh > 3.0f ) m_lastSoundHhh = 0.5f;
- }
- }
- else
- {
- m_tired -= event.rTime*0.2f;
- if ( m_tired < 0.0f ) m_tired = 0.0f;
- }
-
- if ( bSwim ) // swims?
- {
- s += fabs(m_physics->RetLinMotionY(MO_REASPEED)*2.0f);
- a *= 2.0f;
- m_armTimeSwim += Math::Min(Math::Max(s,a,3.0f),15.0f)*event.rTime*0.05f;
- }
-
- bStop = ( s == 0.0f ); // stop?
- prog = 0.0f;
-
- if ( m_physics->RetLand() ) // on the ground?
- {
- if ( s == 0.0f && a == 0.0f )
- {
- action = MH_STOP; // stop
- rTime[0] = rTime[1] = m_armTimeAbs*0.21f;
- lTime[0] = lTime[1] = m_armTimeAbs*0.25f;
- m_armMember = START_TIME;
- }
- else
- {
- if ( s == 0.0f )
- {
- action = MH_TURN; // turn
- rTime[0] = rTime[1] = m_armTimeAbs;
- lTime[0] = lTime[1] = m_armTimeAbs+0.5f;
- if ( rot < 0.0f )
- {
- rTime[1] = 1000000.0f-rTime[1];
- }
- else
- {
- lTime[1] = 1000000.0f-lTime[1];
- }
- m_armMember = START_TIME;
- }
- else
- {
- action = MH_MARCH; // walking
- if ( m_object->RetFret() != 0 ) action = MH_MARCHTAKE; // take walking
- rTime[0] = rTime[1] = m_armMember;
- lTime[0] = lTime[1] = m_armMember+0.5f;
- }
- }
- if ( bSwim )
- {
- rTime[0] *= 0.6f;
- rTime[1] *= 0.6f;
- lTime[0] = rTime[0]+0.5f;
- lTime[1] = rTime[1]+0.5f;
- }
- }
- else
- {
- if ( bSwim )
- {
- action = MH_SWIM; // swim
- rTime[0] = rTime[1] = m_armTimeSwim;
- lTime[0] = lTime[1] = m_armTimeSwim;
- }
- else
- {
- action = MH_FLY; // fly
- rTime[0] = rTime[1] = m_armTimeAbs*0.30f;
- lTime[0] = lTime[1] = m_armTimeAbs*0.31f;
- m_armMember = START_TIME;
- }
- }
-
- if ( action != m_armLastAction )
- {
- m_armLastAction = action;
- m_armTimeAction = 0.0f;
- }
-
- armAction = action;
- legAction = action;
-
- if ( m_object->RetFret() != 0 ) // carries something?
- {
- armAction = MH_MARCHTAKE; // take walking
- }
-
- if ( m_physics->RetLand() ) // on the ground?
- {
- a = m_object->RetAngleY(0);
- pos = m_object->RetPosition(0);
- m_terrain->MoveOnFloor(pos);
-
- pf.x = pos.x+cosf(a+Math::PI*1.5f)*0.7f;
- pf.y = pos.y;
- pf.z = pos.z-sinf(a+Math::PI*1.5f)*0.7f;
- m_terrain->MoveOnFloor(pf);
- al = atanf((pf.y-pos.y)/0.7f); // angle for left leg
-
- pf = pos;
- pf.x = pos.x+cosf(a+Math::PI*0.5f)*0.7f;
- pf.y = pos.y;
- pf.z = pos.z-sinf(a+Math::PI*0.5f)*0.7f;
- m_terrain->MoveOnFloor(pf);
- ar = atanf((pf.y-pos.y)/0.7f); // angle to right leg
-
- pf.x = pos.x+cosf(a+Math::PI)*0.3f;
- pf.y = pos.y;
- pf.z = pos.z-sinf(a+Math::PI)*0.3f;
- m_terrain->MoveOnFloor(pf);
- af = atanf((pf.y-pos.y)/0.3f); // angle for feet
- }
- else
- {
- al = 0.0f;
- ar = 0.0f;
- af = 0.0f;
- }
-
- for ( i=0 ; i<4 ; i++ ) // 4 members
- {
- if ( m_bArmStop ) // focus?
- {
- st = ADJUST_ACTION + (i%2)*3;
- nd = st;
- time = 100.0f;
- m_armTimeAction = 0.0f;
- }
- else if ( m_actionType != -1 ) // special action in progress?
- {
- st = 3*3*3*3*MH_SPEC + 3*3*3*m_actionType + (i%2)*3;
- nd = st;
- time = event.rTime*m_actionTime;
- m_armTimeAction = 0.0f;
- }
- else
- {
- if ( i < 2 ) prog = Math::Mod(rTime[i%2], 1.0f);
- else prog = Math::Mod(lTime[i%2], 1.0f);
- if ( prog < 0.25f ) // t0..t1 ?
- {
- prog = prog/0.25f; // 0..1
- st = 0; // index start
- nd = 1; // index end
- }
- else if ( prog < 0.75f ) // t1..t2 ?
- {
- prog = (prog-0.25f)/0.50f; // 0..1
- st = 1; // index start
- nd = 2; // index end
- }
- else // t2..t0 ?
- {
- prog = (prog-0.75f)/0.25f; // 0..1
- st = 2; // index start
- nd = 0; // index end
- }
- if ( i%2 == 0 ) // arm?
- {
- st = 3*3*3*3*armAction + st*3*3*3 + (i%2)*3;
- nd = 3*3*3*3*armAction + nd*3*3*3 + (i%2)*3;
- }
- else // leg?
- {
- st = 3*3*3*3*legAction + st*3*3*3 + (i%2)*3;
- nd = 3*3*3*3*legAction + nd*3*3*3 + (i%2)*3;
- }
-
- // Less soft ...
- time = event.rTime*(5.0f+Math::Min(m_armTimeAction*50.0f, 100.0f));
- if ( bSwim ) time *= 0.25f;
- }
-
- tSt[0] = m_armAngles[st+ 0]; // x
- tSt[1] = m_armAngles[st+ 1]; // y
- tSt[2] = m_armAngles[st+ 2]; // z
- tSt[3] = m_armAngles[st+ 9]; // x
- tSt[4] = m_armAngles[st+10]; // y
- tSt[5] = m_armAngles[st+11]; // z
- tSt[6] = m_armAngles[st+18]; // x
- tSt[7] = m_armAngles[st+19]; // y
- tSt[8] = m_armAngles[st+20]; // z
-
- tNd[0] = m_armAngles[nd+ 0]; // x
- tNd[1] = m_armAngles[nd+ 1]; // y
- tNd[2] = m_armAngles[nd+ 2]; // z
- tNd[3] = m_armAngles[nd+ 9]; // x
- tNd[4] = m_armAngles[nd+10]; // y
- tNd[5] = m_armAngles[nd+11]; // z
- tNd[6] = m_armAngles[nd+18]; // x
- tNd[7] = m_armAngles[nd+19]; // y
- tNd[8] = m_armAngles[nd+20]; // z
-
- aa = 0.5f;
- if ( i%2 == 0 ) // arm?
- {
- if ( m_object->RetFret() == 0 ) // does nothing?
- {
- aa = 2.0f; // moves a lot
- }
- else
- {
- aa = 0.0f; // immobile
- }
- }
-
- if ( i < 2 ) // left?
- {
- bb = sinf(m_time*1.1f)*aa; tSt[0] += bb; tNd[0] += bb;
- bb = sinf(m_time*1.0f)*aa; tSt[1] += bb; tNd[1] += bb;
- bb = sinf(m_time*1.2f)*aa; tSt[2] += bb; tNd[2] += bb;
- bb = sinf(m_time*2.5f)*aa; tSt[3] += bb; tNd[3] += bb;
- bb = sinf(m_time*2.0f)*aa; tSt[4] += bb; tNd[4] += bb;
- bb = sinf(m_time*3.8f)*aa; tSt[5] += bb; tNd[5] += bb;
- bb = sinf(m_time*3.0f)*aa; tSt[6] += bb; tNd[6] += bb;
- bb = sinf(m_time*2.3f)*aa; tSt[7] += bb; tNd[7] += bb;
- bb = sinf(m_time*4.0f)*aa; tSt[8] += bb; tNd[8] += bb;
- }
- else // right?
- {
- bb = sinf(m_time*0.9f)*aa; tSt[0] += bb; tNd[0] += bb;
- bb = sinf(m_time*1.2f)*aa; tSt[1] += bb; tNd[1] += bb;
- bb = sinf(m_time*1.4f)*aa; tSt[2] += bb; tNd[2] += bb;
- bb = sinf(m_time*2.9f)*aa; tSt[3] += bb; tNd[3] += bb;
- bb = sinf(m_time*1.4f)*aa; tSt[4] += bb; tNd[4] += bb;
- bb = sinf(m_time*3.1f)*aa; tSt[5] += bb; tNd[5] += bb;
- bb = sinf(m_time*3.7f)*aa; tSt[6] += bb; tNd[6] += bb;
- bb = sinf(m_time*2.0f)*aa; tSt[7] += bb; tNd[7] += bb;
- bb = sinf(m_time*3.1f)*aa; tSt[8] += bb; tNd[8] += bb;
- }
-
-#if 1
- if ( i%2 == 1 && // leg?
- m_actionType == -1 ) // no special action?
- {
- if ( i == 1 ) // right leg?
- {
- ii = 5;
- a = ar*0.25f;
- }
- else
- {
- ii = 11;
- a = al*0.25f;
- }
- if ( a < -0.2f ) a = -0.2f;
- if ( a > 0.2f ) a = 0.2f;
-
- pos = m_object->RetPosition(ii+0);
- pos.y = 0.0f+a;
- m_object->SetPosition(ii+0, pos); // lengthens / shortcuts thigh
-
- pos = m_object->RetPosition(ii+1);
- pos.y = -1.5f+a;
- m_object->SetPosition(ii+1, pos); // lengthens / shortcuts leg
-
- pos = m_object->RetPosition(ii+2);
- pos.y = -1.5f+a;
- m_object->SetPosition(ii+2, pos); // lengthens / shortcuts foot
-
- if ( i == 1 ) // right leg?
- {
- aa = (ar*180.0f/Math::PI*0.5f);
- }
- else // left leg?
- {
- aa = (al*180.0f/Math::PI*0.5f);
- }
- tSt[6] += aa;
- tNd[6] += aa; // increases the angle X of the foot
-
- if ( i == 1 ) // right leg?
- {
- aa = (ar*180.0f/Math::PI);
- }
- else // left leg?
- {
- aa = (al*180.0f/Math::PI);
- }
- if ( aa < 0.0f ) aa = 0.0f;
- if ( aa > 30.0f ) aa = 30.0f;
-
- tSt[2] += aa;
- tNd[2] += aa; // increases the angle Z of the thigh
- tSt[5] -= aa*2;
- tNd[5] -= aa*2; // increases the angle Z of the leg
- tSt[8] += aa;
- tNd[8] += aa; // increases the angle Z of the foot
-
- aa = (af*180.0f/Math::PI)*0.7f;
- if ( aa < -30.0f ) aa = -30.0f;
- if ( aa > 30.0f ) aa = 30.0f;
-
- tSt[8] -= aa;
- tNd[8] -= aa; // increases the angle Z of the foot
- }
-#endif
-
- if ( m_actionType == MHS_DEADw ) // drowned?
- {
- if ( m_progress < 0.5f )
- {
- deadFactor = m_progress/0.5f;
- }
- else
- {
- deadFactor = 1.0f-(m_progress-0.5f)/0.5f;
- }
- if ( deadFactor < 0.0f ) deadFactor = 0.0f;
- if ( deadFactor > 1.0f ) deadFactor = 1.0f;
-
- for ( ii=0 ; ii<9 ; ii++ )
- {
- tSt[ii] += Math::Rand()*20.0f*deadFactor;
- tNd[ii] = tSt[ii];
- }
- time = 100.0f;
- }
-
- if ( i < 2 ) // right member (0..1) ?
- {
- m_object->SetAngleX(2+3*i+0, Math::Smooth(m_object->RetAngleX(2+3*i+0), Math::PropAngle(tSt[0], tNd[0], prog), time));
- m_object->SetAngleY(2+3*i+0, Math::Smooth(m_object->RetAngleY(2+3*i+0), Math::PropAngle(tSt[1], tNd[1], prog), time));
- m_object->SetAngleZ(2+3*i+0, Math::Smooth(m_object->RetAngleZ(2+3*i+0), Math::PropAngle(tSt[2], tNd[2], prog), time));
- m_object->SetAngleX(2+3*i+1, Math::Smooth(m_object->RetAngleX(2+3*i+1), Math::PropAngle(tSt[3], tNd[3], prog), time));
- m_object->SetAngleY(2+3*i+1, Math::Smooth(m_object->RetAngleY(2+3*i+1), Math::PropAngle(tSt[4], tNd[4], prog), time));
- m_object->SetAngleZ(2+3*i+1, Math::Smooth(m_object->RetAngleZ(2+3*i+1), Math::PropAngle(tSt[5], tNd[5], prog), time));
- m_object->SetAngleX(2+3*i+2, Math::Smooth(m_object->RetAngleX(2+3*i+2), Math::PropAngle(tSt[6], tNd[6], prog), time));
- m_object->SetAngleY(2+3*i+2, Math::Smooth(m_object->RetAngleY(2+3*i+2), Math::PropAngle(tSt[7], tNd[7], prog), time));
- m_object->SetAngleZ(2+3*i+2, Math::Smooth(m_object->RetAngleZ(2+3*i+2), Math::PropAngle(tSt[8], tNd[8], prog), time));
- }
- else // left member (2..3) ?
- {
- m_object->SetAngleX(2+3*i+0, Math::Smooth(m_object->RetAngleX(2+3*i+0), Math::PropAngle(-tSt[0], -tNd[0], prog), time));
- m_object->SetAngleY(2+3*i+0, Math::Smooth(m_object->RetAngleY(2+3*i+0), Math::PropAngle(-tSt[1], -tNd[1], prog), time));
- m_object->SetAngleZ(2+3*i+0, Math::Smooth(m_object->RetAngleZ(2+3*i+0), Math::PropAngle( tSt[2], tNd[2], prog), time));
- m_object->SetAngleX(2+3*i+1, Math::Smooth(m_object->RetAngleX(2+3*i+1), Math::PropAngle(-tSt[3], -tNd[3], prog), time));
- m_object->SetAngleY(2+3*i+1, Math::Smooth(m_object->RetAngleY(2+3*i+1), Math::PropAngle(-tSt[4], -tNd[4], prog), time));
- m_object->SetAngleZ(2+3*i+1, Math::Smooth(m_object->RetAngleZ(2+3*i+1), Math::PropAngle( tSt[5], tNd[5], prog), time));
- m_object->SetAngleX(2+3*i+2, Math::Smooth(m_object->RetAngleX(2+3*i+2), Math::PropAngle(-tSt[6], -tNd[6], prog), time));
- m_object->SetAngleY(2+3*i+2, Math::Smooth(m_object->RetAngleY(2+3*i+2), Math::PropAngle(-tSt[7], -tNd[7], prog), time));
- m_object->SetAngleZ(2+3*i+2, Math::Smooth(m_object->RetAngleZ(2+3*i+2), Math::PropAngle( tSt[8], tNd[8], prog), time));
- }
- }
-
-#if ADJUST_ANGLE
- if ( m_object->RetSelect() )
- {
- char s[100];
- sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex);
- m_engine->SetInfoText(4, s);
- }
-#endif
-
- // calculates the height lowering as a function
- // of the position of the legs.
- hr = 1.5f*(1.0f-cosf(m_object->RetAngleZ(5))) +
- 1.5f*(1.0f-cosf(m_object->RetAngleZ(5)+m_object->RetAngleZ(6)));
- a = 1.0f*sinf(m_object->RetAngleZ(5)+m_object->RetAngleZ(6)+m_object->RetAngleZ(7));
- if ( a < 0.0f ) hr += a;
-
- hl = 1.5f*(1.0f-cosf(m_object->RetAngleZ(11))) +
- 1.5f*(1.0f-cosf(m_object->RetAngleZ(11)+m_object->RetAngleZ(12)));
- a = 1.0f*sinf(m_object->RetAngleZ(11)+m_object->RetAngleZ(12)+m_object->RetAngleZ(13));
- if ( a < 0.0f ) hl += a;
-
- hr = Math::Min(hr, hl);
-
- if ( m_actionType == MHS_FIRE ) // shooting?
- {
- time = event.rTime*m_actionTime;
-
- dir.x = (Math::Rand()-0.5f)/8.0f;
- dir.z = (Math::Rand()-0.5f)/8.0f;
- dir.y = -0.5f; // slightly lower
- actual = m_object->RetLinVibration();
- dir.x = Math::Smooth(actual.x, dir.x, time);
-//? dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.y = -hr;
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetLinVibration(dir);
-
- dir.x = 0.0f;
- dir.y = (Math::Rand()-0.5f)/3.0f;
- dir.z = -0.1f; // slightly leaning forward
- actual = m_object->RetInclinaison();
- dir.x = Math::Smooth(actual.x, dir.x, time);
- dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetInclinaison(dir);
- }
- else if ( m_actionType == MHS_TAKE || // carrying?
- m_actionType == MHS_TAKEOTHER ) // flag?
- {
- time = event.rTime*m_actionTime*2.0f;
-
- dir.x = 0.0f;
- dir.z = 0.0f;
- dir.y = -1.5f; // slightly lower
- actual = m_object->RetLinVibration();
- dir.x = Math::Smooth(actual.x, dir.x, time);
-//? dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.y = -hr;
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetLinVibration(dir);
-
- dir.x = 0.0f;
- dir.y = 0.0f;
- dir.z = -0.2f;
- actual = m_object->RetInclinaison();
- dir.x = Math::Smooth(actual.x, dir.x, time);
- dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetInclinaison(dir);
- }
- else if ( m_actionType == MHS_TAKEHIGH ) // carrying?
- {
- time = event.rTime*m_actionTime*2.0f;
-
- dir.x = 0.4f; // slightly forward
- dir.z = 0.0f;
- dir.y = 0.0f;
- actual = m_object->RetLinVibration();
- dir.x = Math::Smooth(actual.x, dir.x, time);
-//? dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.y = -hr;
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetLinVibration(dir);
-
- dir.x = 0.0f;
- dir.y = 0.0f;
- dir.z = -0.2f;
- actual = m_object->RetInclinaison();
- dir.x = Math::Smooth(actual.x, dir.x, time);
- dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetInclinaison(dir);
- }
- else if ( m_actionType == MHS_FLAG ) // flag?
- {
- time = event.rTime*m_actionTime*2.0f;
-
- dir.x = 0.0f;
- dir.z = 0.0f;
- dir.y = -2.0f; // slightly lower
- actual = m_object->RetLinVibration();
- dir.x = Math::Smooth(actual.x, dir.x, time);
-//? dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.y = -hr;
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetLinVibration(dir);
-
- dir.x = 0.0f;
- dir.y = 0.0f;
- dir.z = -0.4f;
- actual = m_object->RetInclinaison();
- dir.x = Math::Smooth(actual.x, dir.x, time);
- dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetInclinaison(dir);
- }
- else if ( m_actionType == MHS_DEADg ) // shooting death (falls)?
- {
- if ( m_physics->RetLand() ) // on the ground?
- {
- SetAction(MHS_DEADg1, 0.5f); // knees
- }
- }
- else if ( m_actionType == MHS_DEADg1 ) // shooting death (knees)?
- {
- prog = m_progress;
- if ( prog >= 1.0f )
- {
- prog = 1.0f;
-
- for ( i=0 ; i<10 ; i++ )
- {
- pos = m_object->RetPosition(0);
- pos.x += (Math::Rand()-0.5f)*4.0f;
- pos.z += (Math::Rand()-0.5f)*4.0f;
- m_terrain->MoveOnFloor(pos);
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 1.2f+Math::Rand()*1.2f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.0f);
- }
- m_sound->Play(SOUND_BOUMv, m_object->RetPosition(0));
-
- SetAction(MHS_DEADg2, 1.0f); // expects knees
- }
-
- time = 100.0f;
-
- dir.x = 0.0f;
- dir.z = 0.0f;
- dir.y = -1.5f*prog;
- actual = m_object->RetLinVibration();
- dir.x = Math::Smooth(actual.x, dir.x, time);
- dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetLinVibration(dir);
-
- dir.x = 0.0f;
- dir.y = 0.0f;
- dir.z = -(20.0f*Math::PI/180.0f)*prog;
- actual = m_object->RetInclinaison();
- dir.x = Math::Smooth(actual.x, dir.x, time);
- dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetInclinaison(dir);
- }
- else if ( m_actionType == MHS_DEADg2 ) // shooting death (knees)?
- {
- if ( m_progress >= 1.0f )
- {
- SetAction(MHS_DEADg3, 1.0f); // face down
- }
-
- time = 100.0f;
-
- dir.x = 0.0f;
- dir.z = 0.0f;
- dir.y = -1.5f;
- actual = m_object->RetLinVibration();
- dir.x = Math::Smooth(actual.x, dir.x, time);
- dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetLinVibration(dir);
-
- dir.x = 0.0f;
- dir.y = 0.0f;
- dir.z = -(20.0f*Math::PI/180.0f);
- actual = m_object->RetInclinaison();
- dir.x = Math::Smooth(actual.x, dir.x, time);
- dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetInclinaison(dir);
- }
- else if ( m_actionType == MHS_DEADg3 ) // shooting death (face down)?
- {
- prog = m_progress;
- if ( prog >= 1.0f )
- {
- prog = 1.0f;
-
- for ( i=0 ; i<20 ; i++ )
- {
- pos = m_object->RetPosition(0);
- pos.x += (Math::Rand()-0.5f)*8.0f;
- pos.z += (Math::Rand()-0.5f)*8.0f;
- m_terrain->MoveOnFloor(pos);
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = 2.0f+Math::Rand()*1.5f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.0f);
- }
- m_sound->Play(SOUND_BOUMv, m_object->RetPosition(0));
-
- SetAction(MHS_DEADg4, 3.0f); // expects face down
- }
-
- time = 100.0f;
- prog = powf(prog, 3.0f);
-
- dir.y = -(1.5f+1.5f*prog);
- dir.x = 0.0f;
- dir.z = 0.0f;
- actual = m_object->RetLinVibration();
- dir.x = Math::Smooth(actual.x, dir.x, time);
- dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetLinVibration(dir);
-
- dir.z = -((20.0f*Math::PI/180.0f)+(70.0f*Math::PI/180.0f)*prog);
- dir.x = 0.0f;
- dir.y = 0.0f;
- actual = m_object->RetInclinaison();
- dir.x = Math::Smooth(actual.x, dir.x, time);
- dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetInclinaison(dir);
- }
- else if ( m_actionType == MHS_DEADg4 ) // shooting death (face down)?
- {
- if ( m_progress >= 1.0f )
- {
- m_object->SetEnable(false);
- }
-
- time = 100.0f;
-
- dir.y = -(1.5f+1.5f);
- dir.x = 0.0f;
- dir.z = 0.0f;
- actual = m_object->RetLinVibration();
- dir.x = Math::Smooth(actual.x, dir.x, time);
- dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetLinVibration(dir);
-
- dir.z = -((20.0f*Math::PI/180.0f)+(70.0f*Math::PI/180.0f));
- dir.x = 0.0f;
- dir.y = 0.0f;
- actual = m_object->RetInclinaison();
- dir.x = Math::Smooth(actual.x, dir.x, time);
- dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetInclinaison(dir);
- }
- else if ( m_actionType == MHS_DEADw ) // drowned?
- {
- pos = m_object->RetPosition(0);
- level = m_water->RetLevel()-0.5f;
- if ( pos.y < level )
- {
- pos.y += 4.0f*event.rTime; // back to the surface
- if ( pos.y > level ) pos.y = level;
- m_object->SetPosition(0, pos);
- }
- if ( pos.y > level )
- {
- pos.y -= 10.0f*event.rTime; // down quickly
- if ( pos.y < level ) pos.y = level;
- m_object->SetPosition(0, pos);
- }
-
- prog = m_progress;
- if ( prog >= 1.0f )
- {
- prog = 1.0f;
- if ( pos.y >= level ) m_object->SetEnable(false);
- }
-
- prog *= 2.0f;
- if ( prog > 1.0f ) prog = 1.0f;
-
- time = 100.0f;
-
- dir.z = -(90.0f*Math::PI/180.0f)*prog;
- dir.x = Math::Rand()*0.3f*deadFactor;
- dir.y = Math::Rand()*0.3f*deadFactor;
- actual = m_object->RetInclinaison();
- dir.x = Math::Smooth(actual.x, dir.x, time);
- dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.z = Math::Smooth(actual.z, dir.z, time);
- m_object->SetInclinaison(dir);
-
- m_object->SetCirVibration(Math::Vector(0.0f, 0.0f, 0.0f));
- }
- else if ( m_actionType == MHS_LOST ) // lost?
- {
- time = m_time;
- if ( time < 10.0f ) time *= time/10.0f; // starts slowly
-
- dir.x = time*2.0f;
- dir.y = sinf(m_time*0.8f)*0.8f;
- dir.z = sinf(m_time*0.6f)*0.5f;
- m_object->SetInclinaison(dir);
- SetInclinaison(dir);
-
-//? dir.x = -(sinf(time*0.05f+Math::PI*1.5f)+1.0f)*100.0f;
- // original code: Math::Min(time/30.0f) (?) changed to time/30.0f
- dir.x = -(powf(time/30.0f, 4.0f))*1000.0f; // from the distance
- dir.y = 0.0f;
- dir.z = 0.0f;
- m_object->SetLinVibration(dir);
- SetLinVibration(dir);
-
- mat = m_object->RetWorldMatrix(0);
- pos = Math::Vector(0.5f, 3.7f, 0.0f);
- pos.x += (Math::Rand()-0.5f)*1.0f;
- pos.y += (Math::Rand()-0.5f)*1.0f;
- pos.z += (Math::Rand()-0.5f)*1.0f;
- pos = Transform(*mat, pos);
- speed.x = (Math::Rand()-0.5f)*0.5f;
- speed.y = (Math::Rand()-0.5f)*0.5f;
- speed.z = (Math::Rand()-0.5f)*0.5f;
- dim.x = 0.5f+Math::Rand()*0.5f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTILENS1, 5.0f, 0.0f, 0.0f);
- }
- else if ( m_actionType == MHS_SATCOM ) // look at the SatCom?
- {
- SetCirVibration(Math::Vector(0.0f, 0.0f, 0.0f));
- SetLinVibration(Math::Vector(0.0f, 0.0f, 0.0f));
- SetInclinaison(Math::Vector(0.0f, 0.0f, 0.0f));
- }
- else
- {
- if ( m_physics->RetLand() ) // on the ground?
- {
- time = event.rTime*8.0f;
- if ( bSwim ) time *= 0.25f;
-
- if ( action == MH_MARCH ) // walking?
- {
- dir.x = sinf(Math::Mod(rTime[0]+0.5f, 1.0f)*Math::PI*2.0f)*0.10f;
- dir.y = sinf(Math::Mod(rTime[0]+0.6f, 1.0f)*Math::PI*2.0f)*0.20f;
- s = m_physics->RetLinMotionX(MO_REASPEED)*0.03f;
- }
- else if ( action == MH_MARCHTAKE ) // takes walking?
- {
- dir.x = sinf(Math::Mod(rTime[0]+0.5f, 1.0f)*Math::PI*2.0f)*0.10f;
- dir.y = sinf(Math::Mod(rTime[0]+0.6f, 1.0f)*Math::PI*2.0f)*0.15f;
- s = m_physics->RetLinMotionX(MO_REASPEED)*0.02f;
- }
- else
- {
- dir.x = 0.0f;
- dir.y = 0.0f;
- s = m_physics->RetLinMotionX(MO_REASPEED)*0.03f;
- }
-
- if ( s < 0.0f ) s *= 0.5f;
- dir.z = -s*0.7f;
-
- actual = m_object->RetInclinaison();
- dir.x = Math::Smooth(actual.x, dir.x, time);
- dir.y = Math::Smooth(actual.y, dir.y, time);
- dir.z = Math::Smooth(actual.z, dir.z, time);
- if ( bOnBoard ) dir *= 0.3f;
- m_object->SetInclinaison(dir);
- SetInclinaison(dir);
-
- if ( action == MH_MARCH ) // walking?
- {
- p2.x = 0.0f;
- p2.y = sinf(Math::Mod(rTime[0]+0.5f, 1.0f)*Math::PI*2.0f)*0.5f;
- p2 = Math::RotatePoint(-m_object->RetAngleY(0), p2);
- dir.x = p2.x;
- dir.z = p2.y;
- dir.y = sinf(Math::Mod(rTime[0]*2.0f, 1.0f)*Math::PI*2.0f)*0.3f;
- }
- else if ( action == MH_MARCHTAKE ) // takes walking?
- {
- p2.x = 0.0f;
- p2.y = sinf(Math::Mod(rTime[0]+0.5f, 1.0f)*Math::PI*2.0f)*0.25f;
- p2 = Math::RotatePoint(-m_object->RetAngleY(0), p2);
- dir.x = p2.x;
- dir.z = p2.y;
- dir.y = sinf(Math::Mod(rTime[0]*2.0f, 1.0f)*Math::PI*2.0f)*0.05f-0.3f;
- }
- else
- {
- dir.x = 0.0f;
- dir.z = 0.0f;
- dir.y = 0.0f;
- }
-
- actual = m_object->RetLinVibration();
- dir.x = Math::Smooth(actual.x, dir.x, time);
- if ( action == MH_MARCHTAKE ) // takes walking?
- {
- dir.y = -hr;
- }
- else
- {
- s = Math::Min(m_armTimeAction, 1.0f);
- dir.y = Math::Smooth(actual.y, dir.y, time)*s;
- dir.y += -hr*(1.0f-s);
- }
- dir.z = Math::Smooth(actual.z, dir.z, time);
- if ( bOnBoard ) dir *= 0.3f;
- m_object->SetLinVibration(dir);
-
- dir.x = 0.0f;
- dir.z = 0.0f;
- dir.y = 0.0f;
- SetCirVibration(dir);
- }
- }
-
- // Management of the head.
- if ( m_actionType == MHS_TAKE || // takes?
- m_actionType == MHS_FLAG ) // takes?
- {
- m_object->SetAngleZ(1, Math::Smooth(m_object->RetAngleZ(1), sinf(m_armTimeAbs*1.0f)*0.2f-0.6f, event.rTime*5.0f));
- m_object->SetAngleX(1, sinf(m_armTimeAbs*1.1f)*0.1f);
- m_object->SetAngleY(1, Math::Smooth(m_object->RetAngleY(1), sinf(m_armTimeAbs*1.3f)*0.2f+rot*0.3f, event.rTime*5.0f));
- }
- else if ( m_actionType == MHS_TAKEOTHER || // takes?
- m_actionType == MHS_TAKEHIGH ) // takes?
- {
- m_object->SetAngleZ(1, Math::Smooth(m_object->RetAngleZ(1), sinf(m_armTimeAbs*1.0f)*0.2f-0.3f, event.rTime*5.0f));
- m_object->SetAngleX(1, sinf(m_armTimeAbs*1.1f)*0.1f);
- m_object->SetAngleY(1, Math::Smooth(m_object->RetAngleY(1), sinf(m_armTimeAbs*1.3f)*0.2f+rot*0.3f, event.rTime*5.0f));
- }
- else if ( m_actionType == MHS_WIN ) // win
- {
- float factor = 0.6f+(sinf(m_armTimeAbs*0.5f)*0.40f);
- m_object->SetAngleZ(1, sinf(m_armTimeAbs*5.0f)*0.20f*factor);
- m_object->SetAngleX(1, sinf(m_armTimeAbs*0.6f)*0.10f);
- m_object->SetAngleY(1, sinf(m_armTimeAbs*1.5f)*0.15f);
- }
- else if ( m_actionType == MHS_LOST ) // lost?
- {
- float factor = 0.6f+(sinf(m_armTimeAbs*0.5f)*0.40f);
- m_object->SetAngleZ(1, sinf(m_armTimeAbs*0.6f)*0.10f);
- m_object->SetAngleX(1, sinf(m_armTimeAbs*0.7f)*0.10f);
- m_object->SetAngleY(1, sinf(m_armTimeAbs*3.0f)*0.30f*factor);
- }
- else if ( m_object->RetDead() ) // dead?
- {
- }
- else
- {
- m_object->SetAngleZ(1, Math::Smooth(m_object->RetAngleZ(1), sinf(m_armTimeAbs*1.0f)*0.2f, event.rTime*5.0f));
- m_object->SetAngleX(1, sinf(m_armTimeAbs*1.1f)*0.1f);
- m_object->SetAngleY(1, Math::Smooth(m_object->RetAngleY(1), sinf(m_armTimeAbs*1.3f)*0.2f+rot*0.3f, event.rTime*5.0f));
- }
-
- if ( bOnBoard )
- {
- m_object->SetAngleZ(1, 0.0f);
- m_object->SetAngleX(1, 0.0f);
- m_object->SetAngleY(1, 0.0f);
- }
-
- // Steps sound effects.
- if ( legAction == MH_MARCH ||
- legAction == MH_MARCHTAKE )
- {
- Sound sound[2];
- float speed, synchro, volume[2], freq[2], hard, level;
-
- speed = m_physics->RetLinMotionX(MO_REASPEED);
-
- if ( m_object->RetFret() == 0 )
- {
- if ( speed > 0.0f ) synchro = 0.21f; // synchro forward
- else synchro = 0.29f; // synchro backward
- }
- else
- {
- if ( speed > 0.0f ) synchro = 0.15f; // synchro forward
- else synchro = 0.35f; // synchro backward
- }
- time = rTime[1]+synchro;
-
- if ( fabs(m_lastSoundMarch-time) > 0.4f &&
- Math::Mod(time, 0.5f) < 0.1f )
- {
- volume[0] = 0.5f;
- freq[0] = 1.0f;
- if ( m_object->RetFret() != 0 )
- {
-//? volume[0] *= 2.0f;
- freq[0] = 0.7f;
- }
- volume[1] = volume[0];
- freq[1] = freq[0];
- sound[0] = SOUND_CLICK;
- sound[1] = SOUND_CLICK;
-
- pos = m_object->RetPosition(0);
-
- level = m_water->RetLevel();
- if ( pos.y <= level+3.0f ) // underwater?
- {
- sound[0] = SOUND_STEPw;
- }
- else
- {
- hard = m_terrain->RetHardness(pos);
-
- if ( hard >= 0.875 )
- {
- sound[0] = SOUND_STEPm; // metal
- }
- else
- {
- hard /= 0.875;
- sound[0] = SOUND_STEPs; // smooth
- sound[1] = SOUND_STEPh; // hard
-
- volume[0] *= 1.0f-hard;
- volume[1] *= hard;
- if ( hard < 0.5f )
- {
- volume[0] *= 1.0f+hard*2.0f;
- volume[1] *= 1.0f+hard*2.0f;
- }
- else
- {
- volume[0] *= 3.0f-hard*2.0f;
- volume[1] *= 3.0f-hard*2.0f;
- }
- freq[0] *= 1.0f+hard;
- freq[1] *= 0.5f+hard;
- }
- }
-
- if ( sound[0] != SOUND_CLICK )
- {
- m_sound->Play(sound[0], pos, volume[0], freq[0]);
- }
- if ( sound[1] != SOUND_CLICK )
- {
- m_sound->Play(sound[1], pos, volume[1], freq[1]);
- }
- m_lastSoundMarch = time;
- }
- }
-
- if ( legAction == MH_SWIM )
- {
- time = rTime[0]+0.5f;
-
- if ( fabs(m_lastSoundMarch-time) > 0.9f &&
- Math::Mod(time, 1.0f) < 0.1f )
- {
- m_sound->Play(SOUND_SWIM, m_object->RetPosition(0), 0.5f);
- m_lastSoundMarch = time;
- }
- }
-
- m_lastSoundHhh -= event.rTime;
- if ( m_lastSoundHhh <= 0.0f &&
- m_object->RetSelect() &&
- m_object->RetOption() == 0 ) // helmet?
- {
- m_sound->Play(SOUND_HUMAN1, m_object->RetPosition(0), (0.5f+m_tired*0.2f));
- m_lastSoundHhh = (4.0f-m_tired*2.5f)+(4.0f-m_tired*2.5f)*Math::Rand();
- }
-
- return true;
-}
-
-
-// Management of the display mode when customizing the personal.
-
-void CMotionHuman::StartDisplayPerso()
-{
- m_bDisplayPerso = true;
-}
-
-void CMotionHuman::StopDisplayPerso()
-{
- m_bDisplayPerso = false;
-}
-
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionhuman.cpp + + +#include <stdio.h> + +#include "object/motion/motionhuman.h" + +#include "old/modfile.h" +#include "old/terrain.h" +#include "old/water.h" +#include "math/geometry.h" +#include "object/robotmain.h" +#include "physics/physics.h" + + + +#define ADJUST_ANGLE false // true -> adjusts the angles of the members +const int ADJUST_ACTION = (3*3*3*3*MH_SPEC+3*3*3*MHS_SATCOM); + +const float START_TIME = 1000.0f; // beginning of the relative time + + + +// Object's constructor. + +CMotionHuman::CMotionHuman(CInstanceManager* iMan, CObject* object) + : CMotion(iMan, object) +{ + m_partiReactor = -1; + m_armMember = START_TIME; + m_armTimeAbs = START_TIME; + m_armTimeAction = START_TIME; + m_armTimeSwim = START_TIME; + m_armTimeIndex = 0; + m_armPartIndex = 0; + m_armMemberIndex = 0; + m_armLastAction = -1; + m_bArmStop = false; + m_lastSoundMarch = 0.0f; + m_lastSoundHhh = 0.0f; + m_time = 0.0f; + m_tired = 0.0f; + m_bDisplayPerso = false; +} + +// Object's constructor. + +CMotionHuman::~CMotionHuman() +{ +} + + +// Removes an object. + +void CMotionHuman::DeleteObject(bool bAll) +{ + if ( m_partiReactor != -1 ) + { + m_particule->DeleteParticule(m_partiReactor); + m_partiReactor = -1; + } +} + + +// Starts an action. + +Error CMotionHuman::SetAction(int action, float time) +{ + CMotion::SetAction(action, time); + m_time = 0.0f; + return ERR_OK; +} + + +// Creates cosmonaut on the ground. + +bool CMotionHuman::Create(Math::Vector pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + char filename[100]; + int rank, option, face, glasses; + + if ( m_engine->RetRestCreate() < 16 ) return false; + + pModFile = new CModFile(m_iMan); + + m_object->SetType(type); + option = m_object->RetOption(); + + if ( m_main->RetGamerOnlyHead() ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + face = m_main->RetGamerFace(); + sprintf(filename, "objects\\human2h%d.mod", face+1); + pModFile->ReadModel(filename); + pModFile->CreateEngineObject(rank); + + glasses = m_main->RetGamerGlasses(); + if ( glasses != 0 ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + sprintf(filename, "objects\\human2g%d.mod", glasses); + pModFile->ReadModel(filename); + pModFile->CreateEngineObject(rank); + } + + CreatePhysics(type); + m_object->SetFloorHeight(0.0f); + + m_engine->LoadAllTexture(); + + delete pModFile; + return true; + } + + // Creates the main base. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + + if ( option == 0 ) // head in helmet? + { + pModFile->ReadModel("objects\\human1c.mod"); + } + if ( option == 1 ) // head without helmet? + { + pModFile->ReadModel("objects\\human1h.mod"); + } + if ( option == 2 ) // without a backpack? + { + pModFile->ReadModel("objects\\human1v.mod"); + } + pModFile->CreateEngineObject(rank); + + m_object->SetPosition(0, pos); + m_object->SetAngleY(0, angle); + + // A vehicle must have an obligatory collision with a sphere of center (0, y, 0) (see GetCrashSphere). + m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 2.0f, SOUND_AIE, 0.20f); + m_object->SetGlobalSphere(Math::Vector(0.0f, 1.0f, 0.0f), 4.0f); + + // Creates the head. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + + if ( type == OBJECT_HUMAN ) + { + if ( option == 0 ) // head in helmet? + { + face = m_main->RetGamerFace(); + sprintf(filename, "objects\\human2c%d.mod", face+1); + pModFile->ReadModel(filename); + } + if ( option == 1 || // head without helmet? + option == 2 ) // without a backpack? + { + face = m_main->RetGamerFace(); + sprintf(filename, "objects\\human2h%d.mod", face+1); + pModFile->ReadModel(filename); + } + } + if ( type == OBJECT_TECH ) + { + pModFile->ReadModel("objects\\human2t.mod"); + } + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(0.0f, 2.7f, 0.0f)); + if ( option == 1 || // head without helmet? + option == 2 ) // without a backpack? + { + m_object->SetZoom(1, Math::Vector(1.0f, 1.05f, 1.0f)); + } + + // Creates the glasses. + glasses = m_main->RetGamerGlasses(); + if ( glasses != 0 && type == OBJECT_HUMAN ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(15, rank); + m_object->SetObjectParent(15, 1); + sprintf(filename, "objects\\human2g%d.mod", glasses); + pModFile->ReadModel(filename); + pModFile->CreateEngineObject(rank); + } + + // Creates the right arm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\human3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, Math::Vector(0.0f, 2.3f, -1.2f)); + m_object->SetAngle(2, Math::Vector(90.0f*Math::PI/180.0f, 90.0f*Math::PI/180.0f, -50.0f*Math::PI/180.0f)); + + // Creates the right forearm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 2); + pModFile->ReadModel("objects\\human4r.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, Math::Vector(1.3f, 0.0f, 0.0f)); + m_object->SetAngle(3, Math::Vector(0.0f*Math::PI/180.0f, -20.0f*Math::PI/180.0f, 0.0f*Math::PI/180.0f)); + + // Creates right hand. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(4, rank); + m_object->SetObjectParent(4, 3); + pModFile->ReadModel("objects\\human5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(4, Math::Vector(1.2f, 0.0f, 0.0f)); + + // Creates the right thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(5, rank); + m_object->SetObjectParent(5, 0); + pModFile->ReadModel("objects\\human6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(5, Math::Vector(0.0f, 0.0f, -0.7f)); + m_object->SetAngle(5, Math::Vector(10.0f*Math::PI/180.0f, 0.0f*Math::PI/180.0f, 5.0f*Math::PI/180.0f)); + + // Creates the right leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 5); + pModFile->ReadModel("objects\\human7.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, Math::Vector(0.0f, -1.5f, 0.0f)); + m_object->SetAngle(6, Math::Vector(0.0f*Math::PI/180.0f, 0.0f*Math::PI/180.0f, -10.0f*Math::PI/180.0f)); + + // Creates the right foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 6); + pModFile->ReadModel("objects\\human8.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, Math::Vector(0.0f, -1.5f, 0.0f)); + m_object->SetAngle(7, Math::Vector(-10.0f*Math::PI/180.0f, 5.0f*Math::PI/180.0f, 5.0f*Math::PI/180.0f)); + + // Creates the left arm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 0); + pModFile->ReadModel("objects\\human3.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, Math::Vector(0.0f, 2.3f, 1.2f)); + m_object->SetAngle(8, Math::Vector(-90.0f*Math::PI/180.0f, -90.0f*Math::PI/180.0f, -50.0f*Math::PI/180.0f)); + + // Creates the left forearm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(9, rank); + m_object->SetObjectParent(9, 8); + pModFile->ReadModel("objects\\human4l.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(9, Math::Vector(1.3f, 0.0f, 0.0f)); + m_object->SetAngle(9, Math::Vector(0.0f*Math::PI/180.0f, 20.0f*Math::PI/180.0f, 0.0f*Math::PI/180.0f)); + + // Creates left hand. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(10, rank); + m_object->SetObjectParent(10, 9); + pModFile->ReadModel("objects\\human5.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(10, Math::Vector(1.2f, 0.0f, 0.0f)); + + // Creates the left thigh. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(11, rank); + m_object->SetObjectParent(11, 0); + pModFile->ReadModel("objects\\human6.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(11, Math::Vector(0.0f, 0.0f, 0.7f)); + m_object->SetAngle(11, Math::Vector(-10.0f*Math::PI/180.0f, 0.0f*Math::PI/180.0f, 5.0f*Math::PI/180.0f)); + + // Creates the left leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(12, rank); + m_object->SetObjectParent(12, 11); + pModFile->ReadModel("objects\\human7.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(12, Math::Vector(0.0f, -1.5f, 0.0f)); + m_object->SetAngle(12, Math::Vector(0.0f*Math::PI/180.0f, 0.0f*Math::PI/180.0f, -10.0f*Math::PI/180.0f)); + + // Creates the left foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(13, rank); + m_object->SetObjectParent(13, 12); + pModFile->ReadModel("objects\\human8.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(13, Math::Vector(0.0f, -1.5f, 0.0f)); + m_object->SetAngle(13, Math::Vector(10.0f*Math::PI/180.0f, -5.0f*Math::PI/180.0f, 5.0f*Math::PI/180.0f)); + + // Creates the neutron gun. + if ( option != 2 ) // with backpack? + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(14, rank); + m_object->SetObjectParent(14, 0); + pModFile->ReadModel("objects\\human9.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(14, Math::Vector(-1.5f, 0.3f, -1.35f)); + m_object->SetAngleZ(14, Math::PI); + } + + m_object->CreateShadowCircle(2.0f, 0.8f); + + CreatePhysics(type); + m_object->SetFloorHeight(0.0f); + + pos = m_object->RetPosition(0); + m_object->SetPosition(0, pos); // to display the shadows immediately + + m_engine->LoadAllTexture(); + + delete pModFile; + return true; +} + +// Creates the physical object. + +void CMotionHuman::CreatePhysics(ObjectType type) +{ + Character* character; + int i; + + int member_march[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: + 90,90,-50, 10,0,55, 0,0,0, // t0: arms/thighs/- + 0,-20,0, -5,0,-110, 0,0,0, // t0: forearm/legs/- + 0,0,0, -5,0,40, 0,0,0, // t0: hands/feet/- + // on the ground: + 125,115,-45, 10,0,50, 0,0,0, // t1: arms/thighs/- + 0,-20,0, -5,0,-15, 0,0,0, // t1: forearm/legs/- + 0,0,0, -5,0,0, 0,0,0, // t1: hands/feet/- + // on the ground back: + 25,55,-40, 10,0,-15, 0,0,0, // t2: arms/thighs/- + 30,-50,40, -5,0,-55, 0,0,0, // t2: forearm/legs/- + 0,0,0, -5,0,25, 0,0,0, // t2: hands/feet/- + }; + + int member_march_take[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: + 15,50,-50, 10,0,55, 0,0,0, // t0: arms/thighs/- + 45,-70,10, -5,0,-110, 0,0,0, // t0: forearm/legs/- + -10,25,0, -5,0,40, 0,0,0, // t0: hands/feet/- + // on the ground: + 15,50,-55, 10,0,50, 0,0,0, // t1: arms/thighs/- + 45,-70,10, -5,0,-15, 0,0,0, // t1: forearm/legs/- + -10,25,0, -5,0,0, 0,0,0, // t1: hands/feet/- + // on the ground back: + 15,50,-45, 10,0,-15, 0,0,0, // t2: arms/thighs/- + 45,-70,10, -5,0,-55, 0,0,0, // t2: forearm/legs/- + -10,25,0, -5,0,45, 0,0,0, // t2: hands/feet/- + }; + + int member_turn[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: + 90,90,-50, 10,0,30, 0,0,0, // t0: arms/thighs/- + 0,-20,0, -5,0,-60, 0,0,0, // t0: forearm/legs/- + 0,0,0, -5,0,30, 0,0,0, // t0: hands/feet/- + // on the ground: + 90,110,-45, 10,0,0, 0,0,0, // t1: arms/thighs/- + 0,-20,0, -5,5,0, 0,0,0, // t1: forearm/legs/- + 0,0,0, -5,10,0, 0,0,0, // t1: hands/feet/- + // on the ground back: + 90,70,-45, 10,0,0, 0,0,0, // t2: arms/thighs/- + 0,-20,10, -5,-5,0, 0,0,0, // t2: forearm/legs/- + 0,0,0, -5,-10,0, 0,0,0, // t2: hands/feet/- + }; + + int member_stop[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, + 90,90,-50, 10,0,5, 0,0,0, // arms/thighs/- + 0,-20,0, 0,0,-10, 0,0,0, // forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // hands/feet/- + // + 90,90,-55, 10,0,5, 0,0,0, // arms/thighs/- + 0,-15,0, 0,0,-10, 0,0,0, // forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // hands/feet/- + // + 90,90,-60, 10,0,5, 0,0,0, // arms/thighs/- + 0,-10,0, 0,0,-10, 0,0,0, // forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // hands/feet/- + }; + + int member_fly[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, + -5,90,-60, 20,5,-25, 0,0,0, // arms/thighs/- + 85,-40,-25, 10,0,-30, 0,0,0, // forearm/legs/- + 40,10,25, 0,15,0, 0,0,0, // hands/feet/- + // + -15,90,-40, 20,5,-35, 0,0,0, // arms/thighs/- + 85,-40,-25, 10,0,-40, 0,0,0, // forearm/legs/- + 45,5,20, 0,15,0, 0,0,0, // hands/feet/- + // + -25,90,-50, 20,5,-20, 0,0,0, // arms/thighs/- + 85,-40,-25, 10,0,-10, 0,0,0, // forearm/legs/- + 30,15,25, 0,15,0, 0,0,0, // hands/feet/- + }; + + int member_swim[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, +#if 1 + 130,-70,200, 10,20,55, 0,0,0, // arms/thighs/- + 115,-125,0, -5,0,-110, 0,0,0, // forearm/legs/- + 0,0,0, -5,10,-5, 0,0,0, // hands/feet/- + // + 130,-95,115,55,5,5, 0,0,0, // arms/thighs/- + 75,-50,25, -5,0,-15, 0,0,0, // forearm/legs/- + 0,0,0, -5,5,-30, 0,0,0, // hands/feet/- + // + 130,-100,220,5,0,0, 0,0,0, // arms/thighs/- + 150,5,0, -5,0,-15, 0,0,0, // forearm/legs/- + 0,0,0, -5,30,-20, 0,0,0, // hands/feet/- +#endif +#if 0 + 130,-70,200,5,0,0, 0,0,0, // arms/thighs/- + 115,-125,0, -5,0,-15, 0,0,0, // forearm/legs/- + 0,0,0, -5,30,-20, 0,0,0, // hands/feet/- + // + 130,-95,115, 10,20,55, 0,0,0, // arms/thighs/- + 75,-50,25, -5,0,-110, 0,0,0, // forearm/legs/- + 0,0,0, -5,10,-5, 0,0,0, // hands/feet/- + // + 130,-100,220, 55,5,5, 0,0,0, // arms/thighs/- + 150,5,0, -5,0,-15, 0,0,0, // forearm/legs/- + 0,0,0, -5,5,-30, 0,0,0, // hands/feet/- +#endif +#if 0 + 130,-70,200, 55,5,5, 0,0,0, // arms/thighs/- + 115,-125,0, -5,0,-15, 0,0,0, // forearm/legs/- + 0,0,0, -5,5,-30, 0,0,0, // hands/feet/- + // + 130,-95,115, 5,0,0, 0,0,0, // arms/thighs/- + 75,-50,25, -5,0,-15, 0,0,0, // forearm/legs/- + 0,0,0, -5,30,-20, 0,0,0, // hands/feet/- + // + 130,-100,220, 10,20,55, 0,0,0, // arms/thighs/- + 150,5,0, -5,0,-110, 0,0,0, // forearm/legs/- + 0,0,0, -5,10,-5, 0,0,0, // hands/feet/- +#endif + }; + + int member_spec[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // shooting: + 65,5,-20, 10,0,40, 0,0,0, // s0: arms/thighs/- + -50,-30,50, 0,0,-70, 0,0,0, // s0: forearm/legs/- + 0,50,0, -10,0,35, 0,0,0, // s0: hands/feet/- + // takes weapon: + 160,135,-20,10,0,5, 0,0,0, // s1: arms/thighs/- + 10,-60,40, 0,0,-10, 0,0,0, // s1: forearm/legs/- + 0,-5,-25, -10,5,5, 0,0,0, // s1: hands/feet/- + // carries earth: + 25,40,-40, 10,0,60, 0,0,0, // s2: arms/thighs/- + 0,-45,0, 0,0,-120, 0,0,0, // s2: forearm/legs/- + 0,15,5, -10,0,70, 0,0,0, // s2: hands/feet/- + // carries in front: + 25,20,5, 10,0,55, 0,0,0, // s3: arms/thighs/- + -15,-30,10, 0,0,-110, 0,0,0, // s3: forearm/legs/- + 0,0,0, -10,0,65, 0,0,0, // s3: hands/feet/- + // carries vertically: + -30,15,-5, 10,0,15, 0,0,0, // s4: arms/thighs/- + 0,-15,15, 0,0,-30, 0,0,0, // s4: forearm/legs/- + 35,0,-15, -10,0,25, 0,0,0, // s4: hands/feet/- + // rises: + 15,50,-50, 10,0,5, 0,0,0, // s5: arms/thighs/- + 45,-70,10, 0,0,-10, 0,0,0, // s5: forearm/legs/- + -10,25,0, -10,5,5, 0,0,0, // s5: hands/feet/- + // wins: + 90,90,-30, 20,0,5, 0,0,0, // s6: arms/thighs/- + 0,-90,0, -10,0,-10, 0,0,0, // s6: forearm/legs/- + 0,25,0, -10,5,5, 0,0,0, // s6: hands/feet/- + // lose: + -70,45,35, 10,0,40, 0,0,0, // s7: arms/thighs/- + 15,-95,-5, 0,0,-70, 0,0,0, // s7: forearm/legs/- + 0,0,0, -10,0,35, 0,0,0, // s7: hands/feet/- + // shooting death (falls): + 90,90,-50, 10,0,5, 0,0,0, // s8: arms/thighs/- + 0,-20,0, 0,0,-10, 0,0,0, // s8: forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // s8: hands/feet/- + // shooting death (knees): + 110,105,-5, 10,0,25, 0,0,0, // s9: arms/thighs/- + 0,-40,20, 0,0,-120, 0,0,0, // s9: forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // s9: hands/feet/- + // shooting death (knees): + 110,120,-25, 10,0,25, 0,0,0, // s10: arms/thighs/- + 0,-40,20, 0,0,-120, 0,0,0, // s10: forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // s10: hands/feet/- + // shooting death (face down): + 110,100,-25, 25,0,10, 0,0,0, // s11: arms/thighs/- + 0,-40,20, 0,0,-25, 0,0,0, // s11: forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // s11: hands/feet/- + // shooting death (face down): + 110,100,-25, 25,0,10, 0,0,0, // s12: arms/thighs/- + 0,-40,20, 0,0,-25, 0,0,0, // s12: forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // s12: hands/feet/- + // drowned: + 110,100,-25, 25,0,10, 0,0,0, // s13: arms/thighs/- + 0,-40,20, 0,0,-25, 0,0,0, // s13: forearm/legs/- + 0,0,0, -10,5,5, 0,0,0, // s13: hands/feet/- + // puts / removes flag: + 85,45,-50, 10,0,60, 0,0,0, // s14: arms/thighs/- + -60,15,65, 0,0,-105, 0,0,0, // s14: forearm/legs/- + 0,10,0, -10,0,60, 0,0,0, // s14: hands/feet/- + // reads SatCom: + 70,30,-20, 10,0,5, 0,0,0, // s15: arms/thighs/- + 115,-65,60, 0,0,-10, 0,0,0, // s15: forearm/legs/- + 0,20,0, -10,5,5, 0,0,0, // s15: hands/feet/- + }; + + m_physics->SetType(TYPE_FLYING); + + character = m_object->RetCharacter(); + character->wheelFront = 4.0f; + character->wheelBack = 4.0f; + character->wheelLeft = 4.0f; + character->wheelRight = 4.0f; + character->height = 3.5f; + + if ( type == OBJECT_HUMAN ) + { + m_physics->SetLinMotionX(MO_ADVSPEED, 50.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 35.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 20.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 70.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 40.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + m_physics->SetLinMotionY(MO_ADVSPEED, 60.0f); + m_physics->SetLinMotionY(MO_RECSPEED, 60.0f); + m_physics->SetLinMotionY(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionY(MO_RECACCEL, 50.0f); + m_physics->SetLinMotionY(MO_STOACCEL, 50.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.8f*Math::PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.8f*Math::PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 6.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 6.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 4.0f); + } + else + { + m_physics->SetLinMotionX(MO_ADVSPEED, 40.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 15.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 8.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 8.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 8.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 50.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 50.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + m_physics->SetLinMotionY(MO_ADVSPEED, 60.0f); + m_physics->SetLinMotionY(MO_RECSPEED, 60.0f); + m_physics->SetLinMotionY(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionY(MO_RECACCEL, 50.0f); + m_physics->SetLinMotionY(MO_STOACCEL, 50.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.6f*Math::PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.6f*Math::PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 4.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 4.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 3.0f); + } + + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MH_MARCH+i] = member_march[i]; + } + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MH_MARCHTAKE+i] = member_march_take[i]; + } + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MH_TURN+i] = member_turn[i]; + } + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MH_STOP+i] = member_stop[i]; + } + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MH_FLY+i] = member_fly[i]; + } + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[3*3*3*3*MH_SWIM+i] = member_swim[i]; + } + for ( i=0 ; i<3*3*3*16 ; i++ ) + { + m_armAngles[3*3*3*3*MH_SPEC+i] = member_spec[i]; + } +} + + +// Management of an event. + +bool CMotionHuman::EventProcess(const Event &event) +{ + CMotion::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + if ( event.event == EVENT_KEYDOWN ) + { +#if ADJUST_ANGLE + int i; + + if ( event.param == 'A' ) m_armTimeIndex++; + if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0; + + if ( event.param == 'Q' ) m_armPartIndex++; + if ( m_armPartIndex >= 3 ) m_armPartIndex = 0; + + if ( event.param == 'W' ) m_armMemberIndex++; + if ( m_armMemberIndex >= 3 ) m_armMemberIndex = 0; + + i = m_armMemberIndex*3; + i += m_armPartIndex*3*3; + i += m_armTimeIndex*3*3*3; + i += ADJUST_ACTION; + + if ( event.param == 'E' ) m_armAngles[i+0] += 5; + if ( event.param == 'D' ) m_armAngles[i+0] -= 5; + if ( event.param == 'R' ) m_armAngles[i+1] += 5; + if ( event.param == 'F' ) m_armAngles[i+1] -= 5; + if ( event.param == 'T' ) m_armAngles[i+2] += 5; + if ( event.param == 'G' ) m_armAngles[i+2] -= 5; + + if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop; + + if ( event.param == 'Y' ) + { + char s[100]; + sprintf(s, "index dans table = %d %d %d\n", i, i+9, i+18); + OutputDebugString(s); + } +#endif + } + + return true; +} + +// Management of an event. + +bool CMotionHuman::EventFrame(const Event &event) +{ + Math::Matrix* mat; + Math::Vector dir, actual, pos, speed, pf; + Math::Point center, dim, p2; + float s, a, prog, rTime[2], lTime[2], time, rot, hr, hl; + float al, ar, af; + float tSt[9], tNd[9]; + float aa, bb, shield, deadFactor, level; + int i, ii, st, nd, action, legAction, armAction; + bool bOnBoard, bSwim, bStop; + + if ( m_engine->RetPause() ) + { + if ( m_actionType == MHS_SATCOM ) + { + m_progress += event.rTime*m_actionTime; + } + else + { + return true; + } + } + + bOnBoard = false; + if ( m_object->RetSelect() && + m_camera->RetType() == CAMERA_ONBOARD ) + { + bOnBoard = true; + } + + if ( m_bDisplayPerso && m_main->RetGamerOnlyHead() ) + { + m_time += event.rTime; + m_object->SetLinVibration(Math::Vector(0.0f, -0.55f, 0.0f)); + m_object->SetCirVibration(Math::Vector(0.0f, m_main->RetPersoAngle(), 0.0f)); + return true; + } + if ( m_bDisplayPerso ) + { + m_object->SetCirVibration(Math::Vector(0.0f, m_main->RetPersoAngle()+0.2f, 0.0f)); + } + + shield = m_object->RetShield(); + shield += event.rTime*(1.0f/120.0f); // regeneration in 120 seconds + if ( shield > 1.0f ) shield = 1.0f; + m_object->SetShield(shield); + + bSwim = m_physics->RetSwim(); + +#if 0 + rot = m_physics->RetCirMotionY(MO_MOTSPEED); + s = m_physics->RetLinMotionX(MO_REASPEED)*2.0f; + a = m_physics->RetLinMotionX(MO_TERSPEED); + if ( a < 0.0f ) // rises? + { + if ( s > 0.0f && s < 20.0f ) s = 20.0f; // moving slowly? +//? if ( s < 0.0f && s > -10.0f ) s = 0.0f; // falling slowly? + } + if ( a > 0.0f && !bSwim ) // falls? + { + if ( s > 0.0f && s < 10.0f ) s = 0.0f; // moving slowly? +//? if ( s < 0.0f && s > -5.0f ) s = -5.0f; // falling slowly? + } + a = fabs(rot*12.0f); + + if ( !m_physics->RetLand() && !bSwim ) // in flight? + { + s = 0.0f; + } + + if ( m_object->RetFret() != 0 ) // carries something? + { + s *= 1.3f; + } +#else + rot = m_physics->RetCirMotionY(MO_MOTSPEED); +#if 0 + s = m_physics->RetLinMotionX(MO_REASPEED); +#else + a = m_physics->RetLinMotionX(MO_REASPEED); + s = m_physics->RetLinMotionX(MO_MOTSPEED)*0.2f; + if ( fabs(a) > fabs(s) ) s = a; // the highest value +#endif + a = m_physics->RetLinMotionX(MO_TERSPEED); + if ( a < 0.0f ) // rises? + { + a += m_physics->RetLinMotionX(MO_TERSLIDE); + if ( a < 0.0f ) s -= a; + } + if ( a > 0.0f ) // falls? + { + a -= m_physics->RetLinMotionX(MO_TERSLIDE); + if ( a > 0.0f ) s -= a; + } + s *= 2.0f; + a = fabs(rot*12.0f); + + if ( !m_physics->RetLand() && !bSwim ) // in flight? + { + s = 0.0f; + } + + if ( m_object->RetFret() != 0 ) // carries something? + { + s *= 1.3f; + } +#endif + + m_time += event.rTime; + m_armTimeAbs += event.rTime; + m_armTimeAction += event.rTime; + m_armMember += s*event.rTime*0.05f; + + // Fatigue management when short. + if ( m_physics->RetLand() && s != 0.0f ) // on the ground? + { + m_tired += event.rTime*0.1f; + if ( m_tired > 1.0f ) + { + m_tired = 1.0f; + if ( m_lastSoundHhh > 3.0f ) m_lastSoundHhh = 0.5f; + } + } + else + { + m_tired -= event.rTime*0.2f; + if ( m_tired < 0.0f ) m_tired = 0.0f; + } + + if ( bSwim ) // swims? + { + s += fabs(m_physics->RetLinMotionY(MO_REASPEED)*2.0f); + a *= 2.0f; + m_armTimeSwim += Math::Min(Math::Max(s,a,3.0f),15.0f)*event.rTime*0.05f; + } + + bStop = ( s == 0.0f ); // stop? + prog = 0.0f; + + if ( m_physics->RetLand() ) // on the ground? + { + if ( s == 0.0f && a == 0.0f ) + { + action = MH_STOP; // stop + rTime[0] = rTime[1] = m_armTimeAbs*0.21f; + lTime[0] = lTime[1] = m_armTimeAbs*0.25f; + m_armMember = START_TIME; + } + else + { + if ( s == 0.0f ) + { + action = MH_TURN; // turn + rTime[0] = rTime[1] = m_armTimeAbs; + lTime[0] = lTime[1] = m_armTimeAbs+0.5f; + if ( rot < 0.0f ) + { + rTime[1] = 1000000.0f-rTime[1]; + } + else + { + lTime[1] = 1000000.0f-lTime[1]; + } + m_armMember = START_TIME; + } + else + { + action = MH_MARCH; // walking + if ( m_object->RetFret() != 0 ) action = MH_MARCHTAKE; // take walking + rTime[0] = rTime[1] = m_armMember; + lTime[0] = lTime[1] = m_armMember+0.5f; + } + } + if ( bSwim ) + { + rTime[0] *= 0.6f; + rTime[1] *= 0.6f; + lTime[0] = rTime[0]+0.5f; + lTime[1] = rTime[1]+0.5f; + } + } + else + { + if ( bSwim ) + { + action = MH_SWIM; // swim + rTime[0] = rTime[1] = m_armTimeSwim; + lTime[0] = lTime[1] = m_armTimeSwim; + } + else + { + action = MH_FLY; // fly + rTime[0] = rTime[1] = m_armTimeAbs*0.30f; + lTime[0] = lTime[1] = m_armTimeAbs*0.31f; + m_armMember = START_TIME; + } + } + + if ( action != m_armLastAction ) + { + m_armLastAction = action; + m_armTimeAction = 0.0f; + } + + armAction = action; + legAction = action; + + if ( m_object->RetFret() != 0 ) // carries something? + { + armAction = MH_MARCHTAKE; // take walking + } + + if ( m_physics->RetLand() ) // on the ground? + { + a = m_object->RetAngleY(0); + pos = m_object->RetPosition(0); + m_terrain->MoveOnFloor(pos); + + pf.x = pos.x+cosf(a+Math::PI*1.5f)*0.7f; + pf.y = pos.y; + pf.z = pos.z-sinf(a+Math::PI*1.5f)*0.7f; + m_terrain->MoveOnFloor(pf); + al = atanf((pf.y-pos.y)/0.7f); // angle for left leg + + pf = pos; + pf.x = pos.x+cosf(a+Math::PI*0.5f)*0.7f; + pf.y = pos.y; + pf.z = pos.z-sinf(a+Math::PI*0.5f)*0.7f; + m_terrain->MoveOnFloor(pf); + ar = atanf((pf.y-pos.y)/0.7f); // angle to right leg + + pf.x = pos.x+cosf(a+Math::PI)*0.3f; + pf.y = pos.y; + pf.z = pos.z-sinf(a+Math::PI)*0.3f; + m_terrain->MoveOnFloor(pf); + af = atanf((pf.y-pos.y)/0.3f); // angle for feet + } + else + { + al = 0.0f; + ar = 0.0f; + af = 0.0f; + } + + for ( i=0 ; i<4 ; i++ ) // 4 members + { + if ( m_bArmStop ) // focus? + { + st = ADJUST_ACTION + (i%2)*3; + nd = st; + time = 100.0f; + m_armTimeAction = 0.0f; + } + else if ( m_actionType != -1 ) // special action in progress? + { + st = 3*3*3*3*MH_SPEC + 3*3*3*m_actionType + (i%2)*3; + nd = st; + time = event.rTime*m_actionTime; + m_armTimeAction = 0.0f; + } + else + { + if ( i < 2 ) prog = Math::Mod(rTime[i%2], 1.0f); + else prog = Math::Mod(lTime[i%2], 1.0f); + if ( prog < 0.25f ) // t0..t1 ? + { + prog = prog/0.25f; // 0..1 + st = 0; // index start + nd = 1; // index end + } + else if ( prog < 0.75f ) // t1..t2 ? + { + prog = (prog-0.25f)/0.50f; // 0..1 + st = 1; // index start + nd = 2; // index end + } + else // t2..t0 ? + { + prog = (prog-0.75f)/0.25f; // 0..1 + st = 2; // index start + nd = 0; // index end + } + if ( i%2 == 0 ) // arm? + { + st = 3*3*3*3*armAction + st*3*3*3 + (i%2)*3; + nd = 3*3*3*3*armAction + nd*3*3*3 + (i%2)*3; + } + else // leg? + { + st = 3*3*3*3*legAction + st*3*3*3 + (i%2)*3; + nd = 3*3*3*3*legAction + nd*3*3*3 + (i%2)*3; + } + + // Less soft ... + time = event.rTime*(5.0f+Math::Min(m_armTimeAction*50.0f, 100.0f)); + if ( bSwim ) time *= 0.25f; + } + + tSt[0] = m_armAngles[st+ 0]; // x + tSt[1] = m_armAngles[st+ 1]; // y + tSt[2] = m_armAngles[st+ 2]; // z + tSt[3] = m_armAngles[st+ 9]; // x + tSt[4] = m_armAngles[st+10]; // y + tSt[5] = m_armAngles[st+11]; // z + tSt[6] = m_armAngles[st+18]; // x + tSt[7] = m_armAngles[st+19]; // y + tSt[8] = m_armAngles[st+20]; // z + + tNd[0] = m_armAngles[nd+ 0]; // x + tNd[1] = m_armAngles[nd+ 1]; // y + tNd[2] = m_armAngles[nd+ 2]; // z + tNd[3] = m_armAngles[nd+ 9]; // x + tNd[4] = m_armAngles[nd+10]; // y + tNd[5] = m_armAngles[nd+11]; // z + tNd[6] = m_armAngles[nd+18]; // x + tNd[7] = m_armAngles[nd+19]; // y + tNd[8] = m_armAngles[nd+20]; // z + + aa = 0.5f; + if ( i%2 == 0 ) // arm? + { + if ( m_object->RetFret() == 0 ) // does nothing? + { + aa = 2.0f; // moves a lot + } + else + { + aa = 0.0f; // immobile + } + } + + if ( i < 2 ) // left? + { + bb = sinf(m_time*1.1f)*aa; tSt[0] += bb; tNd[0] += bb; + bb = sinf(m_time*1.0f)*aa; tSt[1] += bb; tNd[1] += bb; + bb = sinf(m_time*1.2f)*aa; tSt[2] += bb; tNd[2] += bb; + bb = sinf(m_time*2.5f)*aa; tSt[3] += bb; tNd[3] += bb; + bb = sinf(m_time*2.0f)*aa; tSt[4] += bb; tNd[4] += bb; + bb = sinf(m_time*3.8f)*aa; tSt[5] += bb; tNd[5] += bb; + bb = sinf(m_time*3.0f)*aa; tSt[6] += bb; tNd[6] += bb; + bb = sinf(m_time*2.3f)*aa; tSt[7] += bb; tNd[7] += bb; + bb = sinf(m_time*4.0f)*aa; tSt[8] += bb; tNd[8] += bb; + } + else // right? + { + bb = sinf(m_time*0.9f)*aa; tSt[0] += bb; tNd[0] += bb; + bb = sinf(m_time*1.2f)*aa; tSt[1] += bb; tNd[1] += bb; + bb = sinf(m_time*1.4f)*aa; tSt[2] += bb; tNd[2] += bb; + bb = sinf(m_time*2.9f)*aa; tSt[3] += bb; tNd[3] += bb; + bb = sinf(m_time*1.4f)*aa; tSt[4] += bb; tNd[4] += bb; + bb = sinf(m_time*3.1f)*aa; tSt[5] += bb; tNd[5] += bb; + bb = sinf(m_time*3.7f)*aa; tSt[6] += bb; tNd[6] += bb; + bb = sinf(m_time*2.0f)*aa; tSt[7] += bb; tNd[7] += bb; + bb = sinf(m_time*3.1f)*aa; tSt[8] += bb; tNd[8] += bb; + } + +#if 1 + if ( i%2 == 1 && // leg? + m_actionType == -1 ) // no special action? + { + if ( i == 1 ) // right leg? + { + ii = 5; + a = ar*0.25f; + } + else + { + ii = 11; + a = al*0.25f; + } + if ( a < -0.2f ) a = -0.2f; + if ( a > 0.2f ) a = 0.2f; + + pos = m_object->RetPosition(ii+0); + pos.y = 0.0f+a; + m_object->SetPosition(ii+0, pos); // lengthens / shortcuts thigh + + pos = m_object->RetPosition(ii+1); + pos.y = -1.5f+a; + m_object->SetPosition(ii+1, pos); // lengthens / shortcuts leg + + pos = m_object->RetPosition(ii+2); + pos.y = -1.5f+a; + m_object->SetPosition(ii+2, pos); // lengthens / shortcuts foot + + if ( i == 1 ) // right leg? + { + aa = (ar*180.0f/Math::PI*0.5f); + } + else // left leg? + { + aa = (al*180.0f/Math::PI*0.5f); + } + tSt[6] += aa; + tNd[6] += aa; // increases the angle X of the foot + + if ( i == 1 ) // right leg? + { + aa = (ar*180.0f/Math::PI); + } + else // left leg? + { + aa = (al*180.0f/Math::PI); + } + if ( aa < 0.0f ) aa = 0.0f; + if ( aa > 30.0f ) aa = 30.0f; + + tSt[2] += aa; + tNd[2] += aa; // increases the angle Z of the thigh + tSt[5] -= aa*2; + tNd[5] -= aa*2; // increases the angle Z of the leg + tSt[8] += aa; + tNd[8] += aa; // increases the angle Z of the foot + + aa = (af*180.0f/Math::PI)*0.7f; + if ( aa < -30.0f ) aa = -30.0f; + if ( aa > 30.0f ) aa = 30.0f; + + tSt[8] -= aa; + tNd[8] -= aa; // increases the angle Z of the foot + } +#endif + + if ( m_actionType == MHS_DEADw ) // drowned? + { + if ( m_progress < 0.5f ) + { + deadFactor = m_progress/0.5f; + } + else + { + deadFactor = 1.0f-(m_progress-0.5f)/0.5f; + } + if ( deadFactor < 0.0f ) deadFactor = 0.0f; + if ( deadFactor > 1.0f ) deadFactor = 1.0f; + + for ( ii=0 ; ii<9 ; ii++ ) + { + tSt[ii] += Math::Rand()*20.0f*deadFactor; + tNd[ii] = tSt[ii]; + } + time = 100.0f; + } + + if ( i < 2 ) // right member (0..1) ? + { + m_object->SetAngleX(2+3*i+0, Math::Smooth(m_object->RetAngleX(2+3*i+0), Math::PropAngle(tSt[0], tNd[0], prog), time)); + m_object->SetAngleY(2+3*i+0, Math::Smooth(m_object->RetAngleY(2+3*i+0), Math::PropAngle(tSt[1], tNd[1], prog), time)); + m_object->SetAngleZ(2+3*i+0, Math::Smooth(m_object->RetAngleZ(2+3*i+0), Math::PropAngle(tSt[2], tNd[2], prog), time)); + m_object->SetAngleX(2+3*i+1, Math::Smooth(m_object->RetAngleX(2+3*i+1), Math::PropAngle(tSt[3], tNd[3], prog), time)); + m_object->SetAngleY(2+3*i+1, Math::Smooth(m_object->RetAngleY(2+3*i+1), Math::PropAngle(tSt[4], tNd[4], prog), time)); + m_object->SetAngleZ(2+3*i+1, Math::Smooth(m_object->RetAngleZ(2+3*i+1), Math::PropAngle(tSt[5], tNd[5], prog), time)); + m_object->SetAngleX(2+3*i+2, Math::Smooth(m_object->RetAngleX(2+3*i+2), Math::PropAngle(tSt[6], tNd[6], prog), time)); + m_object->SetAngleY(2+3*i+2, Math::Smooth(m_object->RetAngleY(2+3*i+2), Math::PropAngle(tSt[7], tNd[7], prog), time)); + m_object->SetAngleZ(2+3*i+2, Math::Smooth(m_object->RetAngleZ(2+3*i+2), Math::PropAngle(tSt[8], tNd[8], prog), time)); + } + else // left member (2..3) ? + { + m_object->SetAngleX(2+3*i+0, Math::Smooth(m_object->RetAngleX(2+3*i+0), Math::PropAngle(-tSt[0], -tNd[0], prog), time)); + m_object->SetAngleY(2+3*i+0, Math::Smooth(m_object->RetAngleY(2+3*i+0), Math::PropAngle(-tSt[1], -tNd[1], prog), time)); + m_object->SetAngleZ(2+3*i+0, Math::Smooth(m_object->RetAngleZ(2+3*i+0), Math::PropAngle( tSt[2], tNd[2], prog), time)); + m_object->SetAngleX(2+3*i+1, Math::Smooth(m_object->RetAngleX(2+3*i+1), Math::PropAngle(-tSt[3], -tNd[3], prog), time)); + m_object->SetAngleY(2+3*i+1, Math::Smooth(m_object->RetAngleY(2+3*i+1), Math::PropAngle(-tSt[4], -tNd[4], prog), time)); + m_object->SetAngleZ(2+3*i+1, Math::Smooth(m_object->RetAngleZ(2+3*i+1), Math::PropAngle( tSt[5], tNd[5], prog), time)); + m_object->SetAngleX(2+3*i+2, Math::Smooth(m_object->RetAngleX(2+3*i+2), Math::PropAngle(-tSt[6], -tNd[6], prog), time)); + m_object->SetAngleY(2+3*i+2, Math::Smooth(m_object->RetAngleY(2+3*i+2), Math::PropAngle(-tSt[7], -tNd[7], prog), time)); + m_object->SetAngleZ(2+3*i+2, Math::Smooth(m_object->RetAngleZ(2+3*i+2), Math::PropAngle( tSt[8], tNd[8], prog), time)); + } + } + +#if ADJUST_ANGLE + if ( m_object->RetSelect() ) + { + char s[100]; + sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex); + m_engine->SetInfoText(4, s); + } +#endif + + // calculates the height lowering as a function + // of the position of the legs. + hr = 1.5f*(1.0f-cosf(m_object->RetAngleZ(5))) + + 1.5f*(1.0f-cosf(m_object->RetAngleZ(5)+m_object->RetAngleZ(6))); + a = 1.0f*sinf(m_object->RetAngleZ(5)+m_object->RetAngleZ(6)+m_object->RetAngleZ(7)); + if ( a < 0.0f ) hr += a; + + hl = 1.5f*(1.0f-cosf(m_object->RetAngleZ(11))) + + 1.5f*(1.0f-cosf(m_object->RetAngleZ(11)+m_object->RetAngleZ(12))); + a = 1.0f*sinf(m_object->RetAngleZ(11)+m_object->RetAngleZ(12)+m_object->RetAngleZ(13)); + if ( a < 0.0f ) hl += a; + + hr = Math::Min(hr, hl); + + if ( m_actionType == MHS_FIRE ) // shooting? + { + time = event.rTime*m_actionTime; + + dir.x = (Math::Rand()-0.5f)/8.0f; + dir.z = (Math::Rand()-0.5f)/8.0f; + dir.y = -0.5f; // slightly lower + actual = m_object->RetLinVibration(); + dir.x = Math::Smooth(actual.x, dir.x, time); +//? dir.y = Math::Smooth(actual.y, dir.y, time); + dir.y = -hr; + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetLinVibration(dir); + + dir.x = 0.0f; + dir.y = (Math::Rand()-0.5f)/3.0f; + dir.z = -0.1f; // slightly leaning forward + actual = m_object->RetInclinaison(); + dir.x = Math::Smooth(actual.x, dir.x, time); + dir.y = Math::Smooth(actual.y, dir.y, time); + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + } + else if ( m_actionType == MHS_TAKE || // carrying? + m_actionType == MHS_TAKEOTHER ) // flag? + { + time = event.rTime*m_actionTime*2.0f; + + dir.x = 0.0f; + dir.z = 0.0f; + dir.y = -1.5f; // slightly lower + actual = m_object->RetLinVibration(); + dir.x = Math::Smooth(actual.x, dir.x, time); +//? dir.y = Math::Smooth(actual.y, dir.y, time); + dir.y = -hr; + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetLinVibration(dir); + + dir.x = 0.0f; + dir.y = 0.0f; + dir.z = -0.2f; + actual = m_object->RetInclinaison(); + dir.x = Math::Smooth(actual.x, dir.x, time); + dir.y = Math::Smooth(actual.y, dir.y, time); + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + } + else if ( m_actionType == MHS_TAKEHIGH ) // carrying? + { + time = event.rTime*m_actionTime*2.0f; + + dir.x = 0.4f; // slightly forward + dir.z = 0.0f; + dir.y = 0.0f; + actual = m_object->RetLinVibration(); + dir.x = Math::Smooth(actual.x, dir.x, time); +//? dir.y = Math::Smooth(actual.y, dir.y, time); + dir.y = -hr; + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetLinVibration(dir); + + dir.x = 0.0f; + dir.y = 0.0f; + dir.z = -0.2f; + actual = m_object->RetInclinaison(); + dir.x = Math::Smooth(actual.x, dir.x, time); + dir.y = Math::Smooth(actual.y, dir.y, time); + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + } + else if ( m_actionType == MHS_FLAG ) // flag? + { + time = event.rTime*m_actionTime*2.0f; + + dir.x = 0.0f; + dir.z = 0.0f; + dir.y = -2.0f; // slightly lower + actual = m_object->RetLinVibration(); + dir.x = Math::Smooth(actual.x, dir.x, time); +//? dir.y = Math::Smooth(actual.y, dir.y, time); + dir.y = -hr; + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetLinVibration(dir); + + dir.x = 0.0f; + dir.y = 0.0f; + dir.z = -0.4f; + actual = m_object->RetInclinaison(); + dir.x = Math::Smooth(actual.x, dir.x, time); + dir.y = Math::Smooth(actual.y, dir.y, time); + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + } + else if ( m_actionType == MHS_DEADg ) // shooting death (falls)? + { + if ( m_physics->RetLand() ) // on the ground? + { + SetAction(MHS_DEADg1, 0.5f); // knees + } + } + else if ( m_actionType == MHS_DEADg1 ) // shooting death (knees)? + { + prog = m_progress; + if ( prog >= 1.0f ) + { + prog = 1.0f; + + for ( i=0 ; i<10 ; i++ ) + { + pos = m_object->RetPosition(0); + pos.x += (Math::Rand()-0.5f)*4.0f; + pos.z += (Math::Rand()-0.5f)*4.0f; + m_terrain->MoveOnFloor(pos); + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 1.2f+Math::Rand()*1.2f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.0f); + } + m_sound->Play(SOUND_BOUMv, m_object->RetPosition(0)); + + SetAction(MHS_DEADg2, 1.0f); // expects knees + } + + time = 100.0f; + + dir.x = 0.0f; + dir.z = 0.0f; + dir.y = -1.5f*prog; + actual = m_object->RetLinVibration(); + dir.x = Math::Smooth(actual.x, dir.x, time); + dir.y = Math::Smooth(actual.y, dir.y, time); + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetLinVibration(dir); + + dir.x = 0.0f; + dir.y = 0.0f; + dir.z = -(20.0f*Math::PI/180.0f)*prog; + actual = m_object->RetInclinaison(); + dir.x = Math::Smooth(actual.x, dir.x, time); + dir.y = Math::Smooth(actual.y, dir.y, time); + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + } + else if ( m_actionType == MHS_DEADg2 ) // shooting death (knees)? + { + if ( m_progress >= 1.0f ) + { + SetAction(MHS_DEADg3, 1.0f); // face down + } + + time = 100.0f; + + dir.x = 0.0f; + dir.z = 0.0f; + dir.y = -1.5f; + actual = m_object->RetLinVibration(); + dir.x = Math::Smooth(actual.x, dir.x, time); + dir.y = Math::Smooth(actual.y, dir.y, time); + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetLinVibration(dir); + + dir.x = 0.0f; + dir.y = 0.0f; + dir.z = -(20.0f*Math::PI/180.0f); + actual = m_object->RetInclinaison(); + dir.x = Math::Smooth(actual.x, dir.x, time); + dir.y = Math::Smooth(actual.y, dir.y, time); + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + } + else if ( m_actionType == MHS_DEADg3 ) // shooting death (face down)? + { + prog = m_progress; + if ( prog >= 1.0f ) + { + prog = 1.0f; + + for ( i=0 ; i<20 ; i++ ) + { + pos = m_object->RetPosition(0); + pos.x += (Math::Rand()-0.5f)*8.0f; + pos.z += (Math::Rand()-0.5f)*8.0f; + m_terrain->MoveOnFloor(pos); + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = 2.0f+Math::Rand()*1.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f, 0.0f, 0.0f); + } + m_sound->Play(SOUND_BOUMv, m_object->RetPosition(0)); + + SetAction(MHS_DEADg4, 3.0f); // expects face down + } + + time = 100.0f; + prog = powf(prog, 3.0f); + + dir.y = -(1.5f+1.5f*prog); + dir.x = 0.0f; + dir.z = 0.0f; + actual = m_object->RetLinVibration(); + dir.x = Math::Smooth(actual.x, dir.x, time); + dir.y = Math::Smooth(actual.y, dir.y, time); + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetLinVibration(dir); + + dir.z = -((20.0f*Math::PI/180.0f)+(70.0f*Math::PI/180.0f)*prog); + dir.x = 0.0f; + dir.y = 0.0f; + actual = m_object->RetInclinaison(); + dir.x = Math::Smooth(actual.x, dir.x, time); + dir.y = Math::Smooth(actual.y, dir.y, time); + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + } + else if ( m_actionType == MHS_DEADg4 ) // shooting death (face down)? + { + if ( m_progress >= 1.0f ) + { + m_object->SetEnable(false); + } + + time = 100.0f; + + dir.y = -(1.5f+1.5f); + dir.x = 0.0f; + dir.z = 0.0f; + actual = m_object->RetLinVibration(); + dir.x = Math::Smooth(actual.x, dir.x, time); + dir.y = Math::Smooth(actual.y, dir.y, time); + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetLinVibration(dir); + + dir.z = -((20.0f*Math::PI/180.0f)+(70.0f*Math::PI/180.0f)); + dir.x = 0.0f; + dir.y = 0.0f; + actual = m_object->RetInclinaison(); + dir.x = Math::Smooth(actual.x, dir.x, time); + dir.y = Math::Smooth(actual.y, dir.y, time); + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + } + else if ( m_actionType == MHS_DEADw ) // drowned? + { + pos = m_object->RetPosition(0); + level = m_water->RetLevel()-0.5f; + if ( pos.y < level ) + { + pos.y += 4.0f*event.rTime; // back to the surface + if ( pos.y > level ) pos.y = level; + m_object->SetPosition(0, pos); + } + if ( pos.y > level ) + { + pos.y -= 10.0f*event.rTime; // down quickly + if ( pos.y < level ) pos.y = level; + m_object->SetPosition(0, pos); + } + + prog = m_progress; + if ( prog >= 1.0f ) + { + prog = 1.0f; + if ( pos.y >= level ) m_object->SetEnable(false); + } + + prog *= 2.0f; + if ( prog > 1.0f ) prog = 1.0f; + + time = 100.0f; + + dir.z = -(90.0f*Math::PI/180.0f)*prog; + dir.x = Math::Rand()*0.3f*deadFactor; + dir.y = Math::Rand()*0.3f*deadFactor; + actual = m_object->RetInclinaison(); + dir.x = Math::Smooth(actual.x, dir.x, time); + dir.y = Math::Smooth(actual.y, dir.y, time); + dir.z = Math::Smooth(actual.z, dir.z, time); + m_object->SetInclinaison(dir); + + m_object->SetCirVibration(Math::Vector(0.0f, 0.0f, 0.0f)); + } + else if ( m_actionType == MHS_LOST ) // lost? + { + time = m_time; + if ( time < 10.0f ) time *= time/10.0f; // starts slowly + + dir.x = time*2.0f; + dir.y = sinf(m_time*0.8f)*0.8f; + dir.z = sinf(m_time*0.6f)*0.5f; + m_object->SetInclinaison(dir); + SetInclinaison(dir); + +//? dir.x = -(sinf(time*0.05f+Math::PI*1.5f)+1.0f)*100.0f; + // original code: Math::Min(time/30.0f) (?) changed to time/30.0f + dir.x = -(powf(time/30.0f, 4.0f))*1000.0f; // from the distance + dir.y = 0.0f; + dir.z = 0.0f; + m_object->SetLinVibration(dir); + SetLinVibration(dir); + + mat = m_object->RetWorldMatrix(0); + pos = Math::Vector(0.5f, 3.7f, 0.0f); + pos.x += (Math::Rand()-0.5f)*1.0f; + pos.y += (Math::Rand()-0.5f)*1.0f; + pos.z += (Math::Rand()-0.5f)*1.0f; + pos = Transform(*mat, pos); + speed.x = (Math::Rand()-0.5f)*0.5f; + speed.y = (Math::Rand()-0.5f)*0.5f; + speed.z = (Math::Rand()-0.5f)*0.5f; + dim.x = 0.5f+Math::Rand()*0.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTILENS1, 5.0f, 0.0f, 0.0f); + } + else if ( m_actionType == MHS_SATCOM ) // look at the SatCom? + { + SetCirVibration(Math::Vector(0.0f, 0.0f, 0.0f)); + SetLinVibration(Math::Vector(0.0f, 0.0f, 0.0f)); + SetInclinaison(Math::Vector(0.0f, 0.0f, 0.0f)); + } + else + { + if ( m_physics->RetLand() ) // on the ground? + { + time = event.rTime*8.0f; + if ( bSwim ) time *= 0.25f; + + if ( action == MH_MARCH ) // walking? + { + dir.x = sinf(Math::Mod(rTime[0]+0.5f, 1.0f)*Math::PI*2.0f)*0.10f; + dir.y = sinf(Math::Mod(rTime[0]+0.6f, 1.0f)*Math::PI*2.0f)*0.20f; + s = m_physics->RetLinMotionX(MO_REASPEED)*0.03f; + } + else if ( action == MH_MARCHTAKE ) // takes walking? + { + dir.x = sinf(Math::Mod(rTime[0]+0.5f, 1.0f)*Math::PI*2.0f)*0.10f; + dir.y = sinf(Math::Mod(rTime[0]+0.6f, 1.0f)*Math::PI*2.0f)*0.15f; + s = m_physics->RetLinMotionX(MO_REASPEED)*0.02f; + } + else + { + dir.x = 0.0f; + dir.y = 0.0f; + s = m_physics->RetLinMotionX(MO_REASPEED)*0.03f; + } + + if ( s < 0.0f ) s *= 0.5f; + dir.z = -s*0.7f; + + actual = m_object->RetInclinaison(); + dir.x = Math::Smooth(actual.x, dir.x, time); + dir.y = Math::Smooth(actual.y, dir.y, time); + dir.z = Math::Smooth(actual.z, dir.z, time); + if ( bOnBoard ) dir *= 0.3f; + m_object->SetInclinaison(dir); + SetInclinaison(dir); + + if ( action == MH_MARCH ) // walking? + { + p2.x = 0.0f; + p2.y = sinf(Math::Mod(rTime[0]+0.5f, 1.0f)*Math::PI*2.0f)*0.5f; + p2 = Math::RotatePoint(-m_object->RetAngleY(0), p2); + dir.x = p2.x; + dir.z = p2.y; + dir.y = sinf(Math::Mod(rTime[0]*2.0f, 1.0f)*Math::PI*2.0f)*0.3f; + } + else if ( action == MH_MARCHTAKE ) // takes walking? + { + p2.x = 0.0f; + p2.y = sinf(Math::Mod(rTime[0]+0.5f, 1.0f)*Math::PI*2.0f)*0.25f; + p2 = Math::RotatePoint(-m_object->RetAngleY(0), p2); + dir.x = p2.x; + dir.z = p2.y; + dir.y = sinf(Math::Mod(rTime[0]*2.0f, 1.0f)*Math::PI*2.0f)*0.05f-0.3f; + } + else + { + dir.x = 0.0f; + dir.z = 0.0f; + dir.y = 0.0f; + } + + actual = m_object->RetLinVibration(); + dir.x = Math::Smooth(actual.x, dir.x, time); + if ( action == MH_MARCHTAKE ) // takes walking? + { + dir.y = -hr; + } + else + { + s = Math::Min(m_armTimeAction, 1.0f); + dir.y = Math::Smooth(actual.y, dir.y, time)*s; + dir.y += -hr*(1.0f-s); + } + dir.z = Math::Smooth(actual.z, dir.z, time); + if ( bOnBoard ) dir *= 0.3f; + m_object->SetLinVibration(dir); + + dir.x = 0.0f; + dir.z = 0.0f; + dir.y = 0.0f; + SetCirVibration(dir); + } + } + + // Management of the head. + if ( m_actionType == MHS_TAKE || // takes? + m_actionType == MHS_FLAG ) // takes? + { + m_object->SetAngleZ(1, Math::Smooth(m_object->RetAngleZ(1), sinf(m_armTimeAbs*1.0f)*0.2f-0.6f, event.rTime*5.0f)); + m_object->SetAngleX(1, sinf(m_armTimeAbs*1.1f)*0.1f); + m_object->SetAngleY(1, Math::Smooth(m_object->RetAngleY(1), sinf(m_armTimeAbs*1.3f)*0.2f+rot*0.3f, event.rTime*5.0f)); + } + else if ( m_actionType == MHS_TAKEOTHER || // takes? + m_actionType == MHS_TAKEHIGH ) // takes? + { + m_object->SetAngleZ(1, Math::Smooth(m_object->RetAngleZ(1), sinf(m_armTimeAbs*1.0f)*0.2f-0.3f, event.rTime*5.0f)); + m_object->SetAngleX(1, sinf(m_armTimeAbs*1.1f)*0.1f); + m_object->SetAngleY(1, Math::Smooth(m_object->RetAngleY(1), sinf(m_armTimeAbs*1.3f)*0.2f+rot*0.3f, event.rTime*5.0f)); + } + else if ( m_actionType == MHS_WIN ) // win + { + float factor = 0.6f+(sinf(m_armTimeAbs*0.5f)*0.40f); + m_object->SetAngleZ(1, sinf(m_armTimeAbs*5.0f)*0.20f*factor); + m_object->SetAngleX(1, sinf(m_armTimeAbs*0.6f)*0.10f); + m_object->SetAngleY(1, sinf(m_armTimeAbs*1.5f)*0.15f); + } + else if ( m_actionType == MHS_LOST ) // lost? + { + float factor = 0.6f+(sinf(m_armTimeAbs*0.5f)*0.40f); + m_object->SetAngleZ(1, sinf(m_armTimeAbs*0.6f)*0.10f); + m_object->SetAngleX(1, sinf(m_armTimeAbs*0.7f)*0.10f); + m_object->SetAngleY(1, sinf(m_armTimeAbs*3.0f)*0.30f*factor); + } + else if ( m_object->RetDead() ) // dead? + { + } + else + { + m_object->SetAngleZ(1, Math::Smooth(m_object->RetAngleZ(1), sinf(m_armTimeAbs*1.0f)*0.2f, event.rTime*5.0f)); + m_object->SetAngleX(1, sinf(m_armTimeAbs*1.1f)*0.1f); + m_object->SetAngleY(1, Math::Smooth(m_object->RetAngleY(1), sinf(m_armTimeAbs*1.3f)*0.2f+rot*0.3f, event.rTime*5.0f)); + } + + if ( bOnBoard ) + { + m_object->SetAngleZ(1, 0.0f); + m_object->SetAngleX(1, 0.0f); + m_object->SetAngleY(1, 0.0f); + } + + // Steps sound effects. + if ( legAction == MH_MARCH || + legAction == MH_MARCHTAKE ) + { + Sound sound[2]; + float speed, synchro, volume[2], freq[2], hard, level; + + speed = m_physics->RetLinMotionX(MO_REASPEED); + + if ( m_object->RetFret() == 0 ) + { + if ( speed > 0.0f ) synchro = 0.21f; // synchro forward + else synchro = 0.29f; // synchro backward + } + else + { + if ( speed > 0.0f ) synchro = 0.15f; // synchro forward + else synchro = 0.35f; // synchro backward + } + time = rTime[1]+synchro; + + if ( fabs(m_lastSoundMarch-time) > 0.4f && + Math::Mod(time, 0.5f) < 0.1f ) + { + volume[0] = 0.5f; + freq[0] = 1.0f; + if ( m_object->RetFret() != 0 ) + { +//? volume[0] *= 2.0f; + freq[0] = 0.7f; + } + volume[1] = volume[0]; + freq[1] = freq[0]; + sound[0] = SOUND_CLICK; + sound[1] = SOUND_CLICK; + + pos = m_object->RetPosition(0); + + level = m_water->RetLevel(); + if ( pos.y <= level+3.0f ) // underwater? + { + sound[0] = SOUND_STEPw; + } + else + { + hard = m_terrain->RetHardness(pos); + + if ( hard >= 0.875 ) + { + sound[0] = SOUND_STEPm; // metal + } + else + { + hard /= 0.875; + sound[0] = SOUND_STEPs; // smooth + sound[1] = SOUND_STEPh; // hard + + volume[0] *= 1.0f-hard; + volume[1] *= hard; + if ( hard < 0.5f ) + { + volume[0] *= 1.0f+hard*2.0f; + volume[1] *= 1.0f+hard*2.0f; + } + else + { + volume[0] *= 3.0f-hard*2.0f; + volume[1] *= 3.0f-hard*2.0f; + } + freq[0] *= 1.0f+hard; + freq[1] *= 0.5f+hard; + } + } + + if ( sound[0] != SOUND_CLICK ) + { + m_sound->Play(sound[0], pos, volume[0], freq[0]); + } + if ( sound[1] != SOUND_CLICK ) + { + m_sound->Play(sound[1], pos, volume[1], freq[1]); + } + m_lastSoundMarch = time; + } + } + + if ( legAction == MH_SWIM ) + { + time = rTime[0]+0.5f; + + if ( fabs(m_lastSoundMarch-time) > 0.9f && + Math::Mod(time, 1.0f) < 0.1f ) + { + m_sound->Play(SOUND_SWIM, m_object->RetPosition(0), 0.5f); + m_lastSoundMarch = time; + } + } + + m_lastSoundHhh -= event.rTime; + if ( m_lastSoundHhh <= 0.0f && + m_object->RetSelect() && + m_object->RetOption() == 0 ) // helmet? + { + m_sound->Play(SOUND_HUMAN1, m_object->RetPosition(0), (0.5f+m_tired*0.2f)); + m_lastSoundHhh = (4.0f-m_tired*2.5f)+(4.0f-m_tired*2.5f)*Math::Rand(); + } + + return true; +} + + +// Management of the display mode when customizing the personal. + +void CMotionHuman::StartDisplayPerso() +{ + m_bDisplayPerso = true; +} + +void CMotionHuman::StopDisplayPerso() +{ + m_bDisplayPerso = false; +} + + diff --git a/src/object/motion/motionhuman.h b/src/object/motion/motionhuman.h index ab7b0f9..b365a77 100644 --- a/src/object/motion/motionhuman.h +++ b/src/object/motion/motionhuman.h @@ -1,94 +1,94 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motionhuman.h
-
-#pragma once
-
-
-#include "object/motion/motion.h"
-
-
-
-enum MotionHumanAction
-{
- MH_MARCH = 0,
- MH_MARCHTAKE = 1,
- MH_TURN = 2,
- MH_STOP = 3,
- MH_FLY = 4,
- MH_SWIM = 5,
- MH_SPEC = 6
-};
-
-enum MotionHumanSpecialAction
-{
- MHS_FIRE = 0,
- MHS_GUN = 1,
- MHS_TAKE = 2,
- MHS_TAKEOTHER = 3,
- MHS_TAKEHIGH = 4,
- MHS_UPRIGHT = 5,
- MHS_WIN = 6,
- MHS_LOST = 7,
- MHS_DEADg = 8,
- MHS_DEADg1 = 9,
- MHS_DEADg2 = 10,
- MHS_DEADg3 = 11,
- MHS_DEADg4 = 12,
- MHS_DEADw = 13,
- MHS_FLAG = 14,
- MHS_SATCOM = 15
-};
-
-
-class CMotionHuman : public CMotion
-{
-public:
- CMotionHuman(CInstanceManager* iMan, CObject* object);
- ~CMotionHuman();
-
- void DeleteObject(bool bAll=false);
- bool Create(Math::Vector pos, float angle, ObjectType type, float power);
- bool EventProcess(const Event &event);
- Error SetAction(int action, float time=0.2f);
-
- void StartDisplayPerso();
- void StopDisplayPerso();
-
-protected:
- void CreatePhysics(ObjectType type);
- bool EventFrame(const Event &event);
-
-protected:
- int m_partiReactor;
- float m_armMember;
- float m_armTimeAbs;
- float m_armTimeAction;
- float m_armTimeSwim;
- short m_armAngles[3*3*3*3*7 + 3*3*3*16];
- int m_armTimeIndex;
- int m_armPartIndex;
- int m_armMemberIndex;
- int m_armLastAction;
- bool m_bArmStop;
- float m_lastSoundMarch;
- float m_lastSoundHhh;
- float m_time;
- float m_tired;
- bool m_bDisplayPerso;
-};
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionhuman.h + +#pragma once + + +#include "object/motion/motion.h" + + + +enum MotionHumanAction +{ + MH_MARCH = 0, + MH_MARCHTAKE = 1, + MH_TURN = 2, + MH_STOP = 3, + MH_FLY = 4, + MH_SWIM = 5, + MH_SPEC = 6 +}; + +enum MotionHumanSpecialAction +{ + MHS_FIRE = 0, + MHS_GUN = 1, + MHS_TAKE = 2, + MHS_TAKEOTHER = 3, + MHS_TAKEHIGH = 4, + MHS_UPRIGHT = 5, + MHS_WIN = 6, + MHS_LOST = 7, + MHS_DEADg = 8, + MHS_DEADg1 = 9, + MHS_DEADg2 = 10, + MHS_DEADg3 = 11, + MHS_DEADg4 = 12, + MHS_DEADw = 13, + MHS_FLAG = 14, + MHS_SATCOM = 15 +}; + + +class CMotionHuman : public CMotion +{ +public: + CMotionHuman(CInstanceManager* iMan, CObject* object); + ~CMotionHuman(); + + void DeleteObject(bool bAll=false); + bool Create(Math::Vector pos, float angle, ObjectType type, float power); + bool EventProcess(const Event &event); + Error SetAction(int action, float time=0.2f); + + void StartDisplayPerso(); + void StopDisplayPerso(); + +protected: + void CreatePhysics(ObjectType type); + bool EventFrame(const Event &event); + +protected: + int m_partiReactor; + float m_armMember; + float m_armTimeAbs; + float m_armTimeAction; + float m_armTimeSwim; + short m_armAngles[3*3*3*3*7 + 3*3*3*16]; + int m_armTimeIndex; + int m_armPartIndex; + int m_armMemberIndex; + int m_armLastAction; + bool m_bArmStop; + float m_lastSoundMarch; + float m_lastSoundHhh; + float m_time; + float m_tired; + bool m_bDisplayPerso; +}; + diff --git a/src/object/motion/motionmother.cpp b/src/object/motion/motionmother.cpp index 26e28d5..0b783a3 100644 --- a/src/object/motion/motionmother.cpp +++ b/src/object/motion/motionmother.cpp @@ -1,524 +1,524 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motionmother.cpp
-
-
-#include <stdio.h>
-
-#include "object/motion/motionmother.h"
-
-#include "old/modfile.h"
-#include "physics/physics.h"
-
-
-
-#define ADJUST_ANGLE false // true -> adjusts the angles of the members
-const float START_TIME = 1000.0f; // beginning of the relative time
-
-
-
-// Object's constructor.
-
-CMotionMother::CMotionMother(CInstanceManager* iMan, CObject* object)
- : CMotion(iMan, object)
-{
- m_armMember = START_TIME;
- m_armTimeAbs = START_TIME;
- m_armTimeMarch = START_TIME;
- m_armTimeAction = START_TIME;
- m_armTimeIndex = 0;
- m_armPartIndex = 0;
- m_armMemberIndex = 0;
- m_armLastAction = -1;
- m_specAction = -1;
- m_bArmStop = false;
-}
-
-// Object's destructor.
-
-CMotionMother::~CMotionMother()
-{
-}
-
-
-// Removes an object.
-
-void CMotionMother::DeleteObject(bool bAll)
-{
-}
-
-
-// Creates a vehicle traveling any lands on the ground.
-
-bool CMotionMother::Create(Math::Vector pos, float angle, ObjectType type,
- float power)
-{
- CModFile* pModFile;
- int rank;
-
- if ( m_engine->RetRestCreate() < 2+12+6 ) return false;
-
- pModFile = new CModFile(m_iMan);
-
- m_object->SetType(type);
-
- // Creates main base.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object
- m_object->SetObjectRank(0, rank);
-
- pModFile->ReadModel("objects\\mother1.mod");
- pModFile->CreateEngineObject(rank);
-
- m_object->SetPosition(0, pos);
- m_object->SetAngleY(0, angle);
-
- // A vehicle must have a obligatory collision
- //with a sphere of center (0, y, 0) (see GetCrashSphere).
- m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 20.0f, SOUND_BOUM, 0.20f);
- m_object->SetGlobalSphere(Math::Vector(-2.0f, 10.0f, 0.0f), 25.0f);
-
- // Creates the head.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\mother2.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(16.0f, 3.0f, 0.0f));
-
- // Creates a right-back leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 0);
- pModFile->ReadModel("objects\\mother3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2, Math::Vector(-5.0f, -1.0f, -12.0f));
-
- // Creates a right-back foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(3, rank);
- m_object->SetObjectParent(3, 2);
- pModFile->ReadModel("objects\\mother4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(3, Math::Vector(0.0f, 0.0f, -8.5f));
-
- // Creates a middle-right leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(4, rank);
- m_object->SetObjectParent(4, 0);
- pModFile->ReadModel("objects\\mother3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(4, Math::Vector(3.5f, -1.0f, -12.0f));
-
- // Creates a middle-right foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(5, rank);
- m_object->SetObjectParent(5, 4);
- pModFile->ReadModel("objects\\mother4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(5, Math::Vector(0.0f, 0.0f, -8.5f));
-
- // Creates a right-front leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(6, rank);
- m_object->SetObjectParent(6, 0);
- pModFile->ReadModel("objects\\mother3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(6, Math::Vector(10.0f, -1.0f, -10.0f));
-
- // Creates a right-front foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(7, rank);
- m_object->SetObjectParent(7, 6);
- pModFile->ReadModel("objects\\mother4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(7, Math::Vector(0.0f, 0.0f, -8.5f));
-
- // Creates a left-back leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(8, rank);
- m_object->SetObjectParent(8, 0);
- pModFile->ReadModel("objects\\mother3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(8, Math::Vector(-5.0f, -1.0f, 12.0f));
- m_object->SetAngleY(8, Math::PI);
-
- // Creates a left-back foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(9, rank);
- m_object->SetObjectParent(9, 8);
- pModFile->ReadModel("objects\\mother4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(9, Math::Vector(0.0f, 0.0f, -8.5f));
-
- // Creates a middle-left leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(10, rank);
- m_object->SetObjectParent(10, 0);
- pModFile->ReadModel("objects\\mother3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(10, Math::Vector(3.5f, -1.0f, 12.0f));
- m_object->SetAngleY(10, Math::PI);
-
- // Creates a middle-left foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(11, rank);
- m_object->SetObjectParent(11, 10);
- pModFile->ReadModel("objects\\mother4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(11, Math::Vector(0.0f, 0.0f, -8.5f));
-
- // Creates a left-front leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(12, rank);
- m_object->SetObjectParent(12, 0);
- pModFile->ReadModel("objects\\mother3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(12, Math::Vector(10.0f, -1.0f, 10.0f));
- m_object->SetAngleY(12, Math::PI);
-
- // Creates a left-front foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(13, rank);
- m_object->SetObjectParent(13, 12);
- pModFile->ReadModel("objects\\mother4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(13, Math::Vector(0.0f, 0.0f, -8.5f));
-
- // Creates the right antenna.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(14, rank);
- m_object->SetObjectParent(14, 1);
- pModFile->ReadModel("objects\\mother5.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(14, Math::Vector(6.0f, 1.0f, -2.5f));
-
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(15, rank);
- m_object->SetObjectParent(15, 14);
- pModFile->ReadModel("objects\\mother6.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(15, Math::Vector(8.0f, 0.0f, 0.0f));
-
- // Creates the left antenna.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(16, rank);
- m_object->SetObjectParent(16, 1);
- pModFile->ReadModel("objects\\mother5.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(16, Math::Vector(6.0f, 1.0f, 2.5f));
-
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(17, rank);
- m_object->SetObjectParent(17, 16);
- pModFile->ReadModel("objects\\mother6.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(17, Math::Vector(8.0f, 0.0f, 0.0f));
-
- // Creates the right claw.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(18, rank);
- m_object->SetObjectParent(18, 1);
- pModFile->ReadModel("objects\\mother7.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(18, Math::Vector(-4.0f, -3.5f, -8.0f));
- m_object->SetZoomX(18, 1.2f);
-
- // Creates the left claw.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(19, rank);
- m_object->SetObjectParent(19, 1);
- pModFile->ReadModel("objects\\mother7.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(19, Math::Vector(-4.0f, -3.5f, 8.0f));
- m_object->SetZoomX(19, 1.2f);
-
- m_object->CreateShadowCircle(18.0f, 0.8f);
-
- CreatePhysics();
- m_object->SetFloorHeight(0.0f);
-
- pos = m_object->RetPosition(0);
- m_object->SetPosition(0, pos); // to display the shadows immediately
-
- m_engine->LoadAllTexture();
-
- delete pModFile;
- return true;
-}
-
-// Creates the physics of the object.
-
-void CMotionMother::CreatePhysics()
-{
- Character* character;
- int i;
-
- int member[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air:
- 30,30,10, 35,-15,10, 35,-35,10, // t0: legs 1..3
- -80,-45,-35, -115,-40,-35, -90,10,-55, // t0: feet 1..3
- 0,0,0, 0,0,0, 0,0,0, // t0: unused
- // on the ground:
- 15,-5,10, 10,-30,10, 5,-50,10, // t1: legs 1..3
- -90,-15,-15, -110,-55,-35, -75,-75,-30, // t1: feet 1..3
- 0,0,0, 0,0,0, 0,0,0, // t1: unused
- // on the ground back:
- 0,40,10, 5,5,10, 0,-15,10, // t2: legs 1..3
- -45,0,-55, -65,10,-50, -125,-85,-45, // t2: feet 1..3
- 0,0,0, 0,0,0, 0,0,0, // t2: unused
- };
-
- m_physics->SetType(TYPE_ROLLING);
-
- character = m_object->RetCharacter();
- character->wheelFront = 10.0f;
- character->wheelBack = 10.0f;
- character->wheelLeft = 20.0f;
- character->wheelRight = 20.0f;
- character->height = 3.0f;
-
- m_physics->SetLinMotionX(MO_ADVSPEED, 8.0f);
- m_physics->SetLinMotionX(MO_RECSPEED, 8.0f);
- m_physics->SetLinMotionX(MO_ADVACCEL, 10.0f);
- m_physics->SetLinMotionX(MO_RECACCEL, 10.0f);
- m_physics->SetLinMotionX(MO_STOACCEL, 40.0f);
- m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionX(MO_TERFORCE, 30.0f);
- m_physics->SetLinMotionZ(MO_TERFORCE, 20.0f);
- m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f);
-
- m_physics->SetCirMotionY(MO_ADVSPEED, 0.1f*Math::PI);
- m_physics->SetCirMotionY(MO_RECSPEED, 0.1f*Math::PI);
- m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f);
- m_physics->SetCirMotionY(MO_RECACCEL, 10.0f);
- m_physics->SetCirMotionY(MO_STOACCEL, 20.0f);
-
- for ( i=0 ; i<3*3*3*3 ; i++ )
- {
- m_armAngles[i] = member[i];
- }
-}
-
-
-// Management of an event.
-
-bool CMotionMother::EventProcess(const Event &event)
-{
- CMotion::EventProcess(event);
-
- if ( event.event == EVENT_FRAME )
- {
- return EventFrame(event);
- }
-
- if ( event.event == EVENT_KEYDOWN )
- {
-#if ADJUST_ANGLE
- int i;
-
- if ( event.param == 'A' ) m_armTimeIndex++;
- if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0;
-
- if ( event.param == 'Q' ) m_armPartIndex++;
- if ( m_armPartIndex >= 3 ) m_armPartIndex = 0;
-
- if ( event.param == 'W' ) m_armMemberIndex++;
- if ( m_armMemberIndex >= 3 ) m_armMemberIndex = 0;
-
- i = m_armMemberIndex*3;
- i += m_armPartIndex*3*3;
- i += m_armTimeIndex*3*3*3;
-//? i += 3*3*3*3;
-
- if ( event.param == 'E' ) m_armAngles[i+0] += 5;
- if ( event.param == 'D' ) m_armAngles[i+0] -= 5;
- if ( event.param == 'R' ) m_armAngles[i+1] += 5;
- if ( event.param == 'F' ) m_armAngles[i+1] -= 5;
- if ( event.param == 'T' ) m_armAngles[i+2] += 5;
- if ( event.param == 'G' ) m_armAngles[i+2] -= 5;
-
- if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop;
-#endif
- }
-
- return true;
-}
-
-// Management of an event.
-
-bool CMotionMother::EventFrame(const Event &event)
-{
- Math::Vector dir;
- float s, a, prog;
- int i, st, nd;
- bool bStop;
-
- if ( m_engine->RetPause() ) return true;
- if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return true;
-
- s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.5f;
- a = fabs(m_physics->RetCirMotionY(MO_MOTSPEED)*26.0f);
-
- if ( s == 0.0f && a != 0.0f ) a *= 1.5f;
-
- m_armTimeAbs += event.rTime;
- m_armTimeMarch += (s)*event.rTime*0.05f;
- m_armMember += (s+a)*event.rTime*0.05f;
-
- bStop = ( a == 0.0f && s == 0.0f ); // stop?
-
- if ( bStop )
- {
- prog = Math::Mod(m_armTimeAbs, 2.0f)/10.0f;
- a = Math::Mod(m_armMember, 1.0f);
- a = (prog-a)*event.rTime*1.0f; // stop position just pleasantly
- m_armMember += a;
- }
-
- for ( i=0 ; i<6 ; i++ ) // the six legs
- {
- if ( i < 3 ) prog = Math::Mod(m_armMember+(2.0f-(i%3))*0.33f+0.0f, 1.0f);
- else prog = Math::Mod(m_armMember+(2.0f-(i%3))*0.33f+0.3f, 1.0f);
- if ( m_bArmStop )
- {
- prog = (float)m_armTimeIndex/3.0f;
- }
- if ( prog < 0.33f ) // t0..t1 ?
- {
- prog = prog/0.33f; // 0..1
- st = 0; // index start
- nd = 1; // index end
- }
- else if ( prog < 0.67f ) // t1..t2 ?
- {
- prog = (prog-0.33f)/0.33f; // 0..1
- st = 1; // index start
- nd = 2; // index end
- }
- else // t2..t0 ?
- {
- prog = (prog-0.67f)/0.33f; // 0..1
- st = 2; // index start
- nd = 0; // index end
- }
- st = st*27+(i%3)*3;
- nd = nd*27+(i%3)*3;
- if ( i < 3 ) // right leg (1..3) ?
- {
- m_object->SetAngleX(2+2*i+0, Math::PropAngle(m_armAngles[st+ 0], m_armAngles[nd+ 0], prog));
- m_object->SetAngleY(2+2*i+0, Math::PropAngle(m_armAngles[st+ 1], m_armAngles[nd+ 1], prog));
- m_object->SetAngleZ(2+2*i+0, Math::PropAngle(m_armAngles[st+ 2], m_armAngles[nd+ 2], prog));
- m_object->SetAngleX(2+2*i+1, Math::PropAngle(m_armAngles[st+ 9], m_armAngles[nd+ 9], prog));
- m_object->SetAngleY(2+2*i+1, Math::PropAngle(m_armAngles[st+10], m_armAngles[nd+10], prog));
- m_object->SetAngleZ(2+2*i+1, Math::PropAngle(m_armAngles[st+11], m_armAngles[nd+11], prog));
- }
- else // left leg (4..6) ?
- {
- m_object->SetAngleX(2+2*i+0, Math::PropAngle( m_armAngles[st+ 0], m_armAngles[nd+ 0], prog));
- m_object->SetAngleY(2+2*i+0, Math::PropAngle(180-m_armAngles[st+ 1], 180-m_armAngles[nd+ 1], prog));
- m_object->SetAngleZ(2+2*i+0, Math::PropAngle( -m_armAngles[st+ 2], -m_armAngles[nd+ 2], prog));
- m_object->SetAngleX(2+2*i+1, Math::PropAngle( m_armAngles[st+ 9], m_armAngles[nd+ 9], prog));
- m_object->SetAngleY(2+2*i+1, Math::PropAngle( -m_armAngles[st+10], -m_armAngles[nd+10], prog));
- m_object->SetAngleZ(2+2*i+1, Math::PropAngle( -m_armAngles[st+11], -m_armAngles[nd+11], prog));
- }
- }
-
-#if ADJUST_ANGLE
- if ( m_object->RetSelect() )
- {
- char s[100];
- sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex);
- m_engine->SetInfoText(4, s);
- }
-#endif
-
- if ( !bStop && !m_object->RetRuin() )
- {
- a = Math::Mod(m_armTimeMarch, 1.0f);
- if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1
- else a = 3.0f-4.0f*a; // 1..-1
- dir.x = sinf(a)*0.03f;
-
- s = Math::Mod(m_armTimeMarch/2.0f, 1.0f);
- if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1
- else s = 3.0f-4.0f*s; // 1..-1
- dir.z = sinf(s)*0.05f;
-
- dir.y = 0.0f;
- m_object->SetInclinaison(dir);
-
- a = Math::Mod(m_armMember-0.1f, 1.0f);
- if ( a < 0.33f )
- {
- dir.y = -(1.0f-(a/0.33f))*0.3f;
- }
- else if ( a < 0.67f )
- {
- dir.y = 0.0f;
- }
- else
- {
- dir.y = -(a-0.67f)/0.33f*0.3f;
- }
- dir.x = 0.0f;
- dir.z = 0.0f;
- m_object->SetLinVibration(dir);
- }
-
- m_object->SetAngleZ(1, sinf(m_armTimeAbs*0.5f)*0.20f); // head
- m_object->SetAngleX(1, sinf(m_armTimeAbs*0.6f)*0.10f); // head
- m_object->SetAngleY(1, sinf(m_armTimeAbs*0.7f)*0.20f); // head
-
- m_object->SetAngleZ(14, 0.50f);
- m_object->SetAngleZ(16, 0.50f);
- m_object->SetAngleY(14, 0.80f+sinf(m_armTimeAbs*1.1f)*0.53f); // right antenna
- m_object->SetAngleY(15, 0.70f-sinf(m_armTimeAbs*1.7f)*0.43f);
- m_object->SetAngleY(16, -0.80f+sinf(m_armTimeAbs*0.9f)*0.53f); // left antenna
- m_object->SetAngleY(17, -0.70f-sinf(m_armTimeAbs*1.3f)*0.43f);
-
- m_object->SetAngleY(18, sinf(m_armTimeAbs*1.1f)*0.20f); // right claw
- m_object->SetAngleZ(18, -0.20f);
- m_object->SetAngleY(19, sinf(m_armTimeAbs*0.9f)*0.20f); // left claw
- m_object->SetAngleZ(19, -0.20f);
-
- return true;
-}
-
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionmother.cpp + + +#include <stdio.h> + +#include "object/motion/motionmother.h" + +#include "old/modfile.h" +#include "physics/physics.h" + + + +#define ADJUST_ANGLE false // true -> adjusts the angles of the members +const float START_TIME = 1000.0f; // beginning of the relative time + + + +// Object's constructor. + +CMotionMother::CMotionMother(CInstanceManager* iMan, CObject* object) + : CMotion(iMan, object) +{ + m_armMember = START_TIME; + m_armTimeAbs = START_TIME; + m_armTimeMarch = START_TIME; + m_armTimeAction = START_TIME; + m_armTimeIndex = 0; + m_armPartIndex = 0; + m_armMemberIndex = 0; + m_armLastAction = -1; + m_specAction = -1; + m_bArmStop = false; +} + +// Object's destructor. + +CMotionMother::~CMotionMother() +{ +} + + +// Removes an object. + +void CMotionMother::DeleteObject(bool bAll) +{ +} + + +// Creates a vehicle traveling any lands on the ground. + +bool CMotionMother::Create(Math::Vector pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + int rank; + + if ( m_engine->RetRestCreate() < 2+12+6 ) return false; + + pModFile = new CModFile(m_iMan); + + m_object->SetType(type); + + // Creates main base. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + + pModFile->ReadModel("objects\\mother1.mod"); + pModFile->CreateEngineObject(rank); + + m_object->SetPosition(0, pos); + m_object->SetAngleY(0, angle); + + // A vehicle must have a obligatory collision + //with a sphere of center (0, y, 0) (see GetCrashSphere). + m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 20.0f, SOUND_BOUM, 0.20f); + m_object->SetGlobalSphere(Math::Vector(-2.0f, 10.0f, 0.0f), 25.0f); + + // Creates the head. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\mother2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(16.0f, 3.0f, 0.0f)); + + // Creates a right-back leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\mother3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, Math::Vector(-5.0f, -1.0f, -12.0f)); + + // Creates a right-back foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 2); + pModFile->ReadModel("objects\\mother4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, Math::Vector(0.0f, 0.0f, -8.5f)); + + // Creates a middle-right leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(4, rank); + m_object->SetObjectParent(4, 0); + pModFile->ReadModel("objects\\mother3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(4, Math::Vector(3.5f, -1.0f, -12.0f)); + + // Creates a middle-right foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(5, rank); + m_object->SetObjectParent(5, 4); + pModFile->ReadModel("objects\\mother4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(5, Math::Vector(0.0f, 0.0f, -8.5f)); + + // Creates a right-front leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\mother3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, Math::Vector(10.0f, -1.0f, -10.0f)); + + // Creates a right-front foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 6); + pModFile->ReadModel("objects\\mother4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, Math::Vector(0.0f, 0.0f, -8.5f)); + + // Creates a left-back leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 0); + pModFile->ReadModel("objects\\mother3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, Math::Vector(-5.0f, -1.0f, 12.0f)); + m_object->SetAngleY(8, Math::PI); + + // Creates a left-back foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(9, rank); + m_object->SetObjectParent(9, 8); + pModFile->ReadModel("objects\\mother4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(9, Math::Vector(0.0f, 0.0f, -8.5f)); + + // Creates a middle-left leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(10, rank); + m_object->SetObjectParent(10, 0); + pModFile->ReadModel("objects\\mother3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(10, Math::Vector(3.5f, -1.0f, 12.0f)); + m_object->SetAngleY(10, Math::PI); + + // Creates a middle-left foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(11, rank); + m_object->SetObjectParent(11, 10); + pModFile->ReadModel("objects\\mother4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(11, Math::Vector(0.0f, 0.0f, -8.5f)); + + // Creates a left-front leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(12, rank); + m_object->SetObjectParent(12, 0); + pModFile->ReadModel("objects\\mother3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(12, Math::Vector(10.0f, -1.0f, 10.0f)); + m_object->SetAngleY(12, Math::PI); + + // Creates a left-front foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(13, rank); + m_object->SetObjectParent(13, 12); + pModFile->ReadModel("objects\\mother4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(13, Math::Vector(0.0f, 0.0f, -8.5f)); + + // Creates the right antenna. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(14, rank); + m_object->SetObjectParent(14, 1); + pModFile->ReadModel("objects\\mother5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(14, Math::Vector(6.0f, 1.0f, -2.5f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(15, rank); + m_object->SetObjectParent(15, 14); + pModFile->ReadModel("objects\\mother6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(15, Math::Vector(8.0f, 0.0f, 0.0f)); + + // Creates the left antenna. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(16, rank); + m_object->SetObjectParent(16, 1); + pModFile->ReadModel("objects\\mother5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(16, Math::Vector(6.0f, 1.0f, 2.5f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(17, rank); + m_object->SetObjectParent(17, 16); + pModFile->ReadModel("objects\\mother6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(17, Math::Vector(8.0f, 0.0f, 0.0f)); + + // Creates the right claw. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(18, rank); + m_object->SetObjectParent(18, 1); + pModFile->ReadModel("objects\\mother7.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(18, Math::Vector(-4.0f, -3.5f, -8.0f)); + m_object->SetZoomX(18, 1.2f); + + // Creates the left claw. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(19, rank); + m_object->SetObjectParent(19, 1); + pModFile->ReadModel("objects\\mother7.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(19, Math::Vector(-4.0f, -3.5f, 8.0f)); + m_object->SetZoomX(19, 1.2f); + + m_object->CreateShadowCircle(18.0f, 0.8f); + + CreatePhysics(); + m_object->SetFloorHeight(0.0f); + + pos = m_object->RetPosition(0); + m_object->SetPosition(0, pos); // to display the shadows immediately + + m_engine->LoadAllTexture(); + + delete pModFile; + return true; +} + +// Creates the physics of the object. + +void CMotionMother::CreatePhysics() +{ + Character* character; + int i; + + int member[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: + 30,30,10, 35,-15,10, 35,-35,10, // t0: legs 1..3 + -80,-45,-35, -115,-40,-35, -90,10,-55, // t0: feet 1..3 + 0,0,0, 0,0,0, 0,0,0, // t0: unused + // on the ground: + 15,-5,10, 10,-30,10, 5,-50,10, // t1: legs 1..3 + -90,-15,-15, -110,-55,-35, -75,-75,-30, // t1: feet 1..3 + 0,0,0, 0,0,0, 0,0,0, // t1: unused + // on the ground back: + 0,40,10, 5,5,10, 0,-15,10, // t2: legs 1..3 + -45,0,-55, -65,10,-50, -125,-85,-45, // t2: feet 1..3 + 0,0,0, 0,0,0, 0,0,0, // t2: unused + }; + + m_physics->SetType(TYPE_ROLLING); + + character = m_object->RetCharacter(); + character->wheelFront = 10.0f; + character->wheelBack = 10.0f; + character->wheelLeft = 20.0f; + character->wheelRight = 20.0f; + character->height = 3.0f; + + m_physics->SetLinMotionX(MO_ADVSPEED, 8.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 8.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 10.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 10.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 30.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 20.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.1f*Math::PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.1f*Math::PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 10.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 20.0f); + + for ( i=0 ; i<3*3*3*3 ; i++ ) + { + m_armAngles[i] = member[i]; + } +} + + +// Management of an event. + +bool CMotionMother::EventProcess(const Event &event) +{ + CMotion::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + if ( event.event == EVENT_KEYDOWN ) + { +#if ADJUST_ANGLE + int i; + + if ( event.param == 'A' ) m_armTimeIndex++; + if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0; + + if ( event.param == 'Q' ) m_armPartIndex++; + if ( m_armPartIndex >= 3 ) m_armPartIndex = 0; + + if ( event.param == 'W' ) m_armMemberIndex++; + if ( m_armMemberIndex >= 3 ) m_armMemberIndex = 0; + + i = m_armMemberIndex*3; + i += m_armPartIndex*3*3; + i += m_armTimeIndex*3*3*3; +//? i += 3*3*3*3; + + if ( event.param == 'E' ) m_armAngles[i+0] += 5; + if ( event.param == 'D' ) m_armAngles[i+0] -= 5; + if ( event.param == 'R' ) m_armAngles[i+1] += 5; + if ( event.param == 'F' ) m_armAngles[i+1] -= 5; + if ( event.param == 'T' ) m_armAngles[i+2] += 5; + if ( event.param == 'G' ) m_armAngles[i+2] -= 5; + + if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop; +#endif + } + + return true; +} + +// Management of an event. + +bool CMotionMother::EventFrame(const Event &event) +{ + Math::Vector dir; + float s, a, prog; + int i, st, nd; + bool bStop; + + if ( m_engine->RetPause() ) return true; + if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return true; + + s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.5f; + a = fabs(m_physics->RetCirMotionY(MO_MOTSPEED)*26.0f); + + if ( s == 0.0f && a != 0.0f ) a *= 1.5f; + + m_armTimeAbs += event.rTime; + m_armTimeMarch += (s)*event.rTime*0.05f; + m_armMember += (s+a)*event.rTime*0.05f; + + bStop = ( a == 0.0f && s == 0.0f ); // stop? + + if ( bStop ) + { + prog = Math::Mod(m_armTimeAbs, 2.0f)/10.0f; + a = Math::Mod(m_armMember, 1.0f); + a = (prog-a)*event.rTime*1.0f; // stop position just pleasantly + m_armMember += a; + } + + for ( i=0 ; i<6 ; i++ ) // the six legs + { + if ( i < 3 ) prog = Math::Mod(m_armMember+(2.0f-(i%3))*0.33f+0.0f, 1.0f); + else prog = Math::Mod(m_armMember+(2.0f-(i%3))*0.33f+0.3f, 1.0f); + if ( m_bArmStop ) + { + prog = (float)m_armTimeIndex/3.0f; + } + if ( prog < 0.33f ) // t0..t1 ? + { + prog = prog/0.33f; // 0..1 + st = 0; // index start + nd = 1; // index end + } + else if ( prog < 0.67f ) // t1..t2 ? + { + prog = (prog-0.33f)/0.33f; // 0..1 + st = 1; // index start + nd = 2; // index end + } + else // t2..t0 ? + { + prog = (prog-0.67f)/0.33f; // 0..1 + st = 2; // index start + nd = 0; // index end + } + st = st*27+(i%3)*3; + nd = nd*27+(i%3)*3; + if ( i < 3 ) // right leg (1..3) ? + { + m_object->SetAngleX(2+2*i+0, Math::PropAngle(m_armAngles[st+ 0], m_armAngles[nd+ 0], prog)); + m_object->SetAngleY(2+2*i+0, Math::PropAngle(m_armAngles[st+ 1], m_armAngles[nd+ 1], prog)); + m_object->SetAngleZ(2+2*i+0, Math::PropAngle(m_armAngles[st+ 2], m_armAngles[nd+ 2], prog)); + m_object->SetAngleX(2+2*i+1, Math::PropAngle(m_armAngles[st+ 9], m_armAngles[nd+ 9], prog)); + m_object->SetAngleY(2+2*i+1, Math::PropAngle(m_armAngles[st+10], m_armAngles[nd+10], prog)); + m_object->SetAngleZ(2+2*i+1, Math::PropAngle(m_armAngles[st+11], m_armAngles[nd+11], prog)); + } + else // left leg (4..6) ? + { + m_object->SetAngleX(2+2*i+0, Math::PropAngle( m_armAngles[st+ 0], m_armAngles[nd+ 0], prog)); + m_object->SetAngleY(2+2*i+0, Math::PropAngle(180-m_armAngles[st+ 1], 180-m_armAngles[nd+ 1], prog)); + m_object->SetAngleZ(2+2*i+0, Math::PropAngle( -m_armAngles[st+ 2], -m_armAngles[nd+ 2], prog)); + m_object->SetAngleX(2+2*i+1, Math::PropAngle( m_armAngles[st+ 9], m_armAngles[nd+ 9], prog)); + m_object->SetAngleY(2+2*i+1, Math::PropAngle( -m_armAngles[st+10], -m_armAngles[nd+10], prog)); + m_object->SetAngleZ(2+2*i+1, Math::PropAngle( -m_armAngles[st+11], -m_armAngles[nd+11], prog)); + } + } + +#if ADJUST_ANGLE + if ( m_object->RetSelect() ) + { + char s[100]; + sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex); + m_engine->SetInfoText(4, s); + } +#endif + + if ( !bStop && !m_object->RetRuin() ) + { + a = Math::Mod(m_armTimeMarch, 1.0f); + if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1 + else a = 3.0f-4.0f*a; // 1..-1 + dir.x = sinf(a)*0.03f; + + s = Math::Mod(m_armTimeMarch/2.0f, 1.0f); + if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1 + else s = 3.0f-4.0f*s; // 1..-1 + dir.z = sinf(s)*0.05f; + + dir.y = 0.0f; + m_object->SetInclinaison(dir); + + a = Math::Mod(m_armMember-0.1f, 1.0f); + if ( a < 0.33f ) + { + dir.y = -(1.0f-(a/0.33f))*0.3f; + } + else if ( a < 0.67f ) + { + dir.y = 0.0f; + } + else + { + dir.y = -(a-0.67f)/0.33f*0.3f; + } + dir.x = 0.0f; + dir.z = 0.0f; + m_object->SetLinVibration(dir); + } + + m_object->SetAngleZ(1, sinf(m_armTimeAbs*0.5f)*0.20f); // head + m_object->SetAngleX(1, sinf(m_armTimeAbs*0.6f)*0.10f); // head + m_object->SetAngleY(1, sinf(m_armTimeAbs*0.7f)*0.20f); // head + + m_object->SetAngleZ(14, 0.50f); + m_object->SetAngleZ(16, 0.50f); + m_object->SetAngleY(14, 0.80f+sinf(m_armTimeAbs*1.1f)*0.53f); // right antenna + m_object->SetAngleY(15, 0.70f-sinf(m_armTimeAbs*1.7f)*0.43f); + m_object->SetAngleY(16, -0.80f+sinf(m_armTimeAbs*0.9f)*0.53f); // left antenna + m_object->SetAngleY(17, -0.70f-sinf(m_armTimeAbs*1.3f)*0.43f); + + m_object->SetAngleY(18, sinf(m_armTimeAbs*1.1f)*0.20f); // right claw + m_object->SetAngleZ(18, -0.20f); + m_object->SetAngleY(19, sinf(m_armTimeAbs*0.9f)*0.20f); // left claw + m_object->SetAngleZ(19, -0.20f); + + return true; +} + + diff --git a/src/object/motion/motionmother.h b/src/object/motion/motionmother.h index 7d67f5b..5060315 100644 --- a/src/object/motion/motionmother.h +++ b/src/object/motion/motionmother.h @@ -1,54 +1,54 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motionmother.h
-
-#pragma once
-
-
-#include "object/motion/motion.h"
-
-
-
-class CMotionMother : public CMotion
-{
-public:
- CMotionMother(CInstanceManager* iMan, CObject* object);
- ~CMotionMother();
-
- void DeleteObject(bool bAll=false);
- bool Create(Math::Vector pos, float angle, ObjectType type, float power);
- bool EventProcess(const Event &event);
-
-protected:
- void CreatePhysics();
- bool EventFrame(const Event &event);
-
-protected:
- float m_armMember;
- float m_armTimeAbs;
- float m_armTimeMarch;
- float m_armTimeAction;
- short m_armAngles[3*3*3*3*10];
- int m_armTimeIndex;
- int m_armPartIndex;
- int m_armMemberIndex;
- int m_armLastAction;
- int m_specAction;
- float m_specTime;
- bool m_bArmStop;
-};
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionmother.h + +#pragma once + + +#include "object/motion/motion.h" + + + +class CMotionMother : public CMotion +{ +public: + CMotionMother(CInstanceManager* iMan, CObject* object); + ~CMotionMother(); + + void DeleteObject(bool bAll=false); + bool Create(Math::Vector pos, float angle, ObjectType type, float power); + bool EventProcess(const Event &event); + +protected: + void CreatePhysics(); + bool EventFrame(const Event &event); + +protected: + float m_armMember; + float m_armTimeAbs; + float m_armTimeMarch; + float m_armTimeAction; + short m_armAngles[3*3*3*3*10]; + int m_armTimeIndex; + int m_armPartIndex; + int m_armMemberIndex; + int m_armLastAction; + int m_specAction; + float m_specTime; + bool m_bArmStop; +}; + diff --git a/src/object/motion/motionspider.cpp b/src/object/motion/motionspider.cpp index fa5d649..be16e08 100644 --- a/src/object/motion/motionspider.cpp +++ b/src/object/motion/motionspider.cpp @@ -1,759 +1,759 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motionspider.cpp
-
-
-#include <stdio.h>
-
-#include "object/motion/motionspider.h"
-
-#include "old/modfile.h"
-#include "old/particule.h"
-#include "physics/physics.h"
-
-
-
-#define ADJUST_ANGLE false // true -> adjusts the angles of the members
-const float START_TIME = 1000.0f; // beginning of the relative time
-
-
-
-// Object's constructor.
-
-CMotionSpider::CMotionSpider(CInstanceManager* iMan, CObject* object)
- : CMotion(iMan, object)
-{
- m_armMember = START_TIME;
- m_armTimeAbs = START_TIME;
- m_armTimeMarch = START_TIME;
- m_armTimeAction = START_TIME;
- m_armTimeIndex = 0;
- m_armPartIndex = 0;
- m_armMemberIndex = 0;
- m_armLastAction = -1;
- m_bArmStop = false;
- m_lastParticule = 0.0f;
-}
-
-// Object's destructor.
-
-CMotionSpider::~CMotionSpider()
-{
-}
-
-
-// Removes an object.
-
-void CMotionSpider::DeleteObject(bool bAll)
-{
-}
-
-
-// Creates a vehicle traveling any lands on the ground.
-
-bool CMotionSpider::Create(Math::Vector pos, float angle, ObjectType type,
- float power)
-{
- CModFile* pModFile;
- int rank, i, j, parent;
- char name[50];
-
- float table[] =
- {
- // x y z
- 0.6f, 0.0f, 0.0f, // back leg
- 0.0f, 0.0f, -2.0f,
- 0.0f, 0.0f, -2.0f,
- 0.0f, 0.0f, -2.0f,
-
- 0.8f, 0.0f, -0.2f, // middle-back leg
- 0.0f, 0.0f, -2.0f,
- 0.0f, 0.0f, -2.0f,
- 0.0f, 0.0f, -2.0f,
-
- 1.0f, 0.0f, -0.2f, // middle-front leg
- 0.0f, 0.0f, -2.0f,
- 0.0f, 0.0f, -2.0f,
- 0.0f, 0.0f, -2.0f,
-
- 1.2f, 0.0f, 0.0f, // front leg
- 0.0f, 0.0f, -2.0f,
- 0.0f, 0.0f, -2.0f,
- 0.0f, 0.0f, -2.0f,
- };
-
- if ( m_engine->RetRestCreate() < 3+32+2 ) return false;
-
- pModFile = new CModFile(m_iMan);
-
- m_object->SetType(type);
-
- // Creates the main base.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object
- m_object->SetObjectRank(0, rank);
- pModFile->ReadModel("objects\\spider0.mod"); // doesn't exist
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(0, pos);
- m_object->SetAngleY(0, angle);
-
- // A vehicle must have a obligatory collision
- // with a sphere of center (0, y, 0) (see GetCrashSphere).
- m_object->CreateCrashSphere(Math::Vector(0.0f, -2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f);
- m_object->SetGlobalSphere(Math::Vector(-0.5f, 1.0f, 0.0f), 4.0f);
-
- // Creates the abdomen.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\spider1.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(1.0f, 0.0f, 0.0f));
-
- // Creates the head.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 0);
- pModFile->ReadModel("objects\\spider2.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2, Math::Vector(1.0f, 0.0f, 0.0f));
-
- // Creates legs.
- for ( i=0 ; i<4 ; i++ )
- {
- for ( j=0 ; j<4 ; j++ )
- {
- sprintf(name, "objects\\spider%d.mod", j+3); // 3..6
-
- // Creates the right leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(3+i*4+j, rank);
- if ( j == 0 ) parent = 0;
- else parent = 3+i*4+j-1;
- m_object->SetObjectParent(3+i*4+j, parent);
- pModFile->ReadModel(name);
- pModFile->CreateEngineObject(rank);
- pos.x = table[i*12+j*3+0];
- pos.y = table[i*12+j*3+1];
- pos.z = table[i*12+j*3+2];
- m_object->SetPosition(3+i*4+j, pos);
-
- // Creates the left leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(19+i*4+j, rank);
- if ( j == 0 ) parent = 0;
- else parent = 19+i*4+j-1;
- m_object->SetObjectParent(19+i*4+j, parent);
- pModFile->ReadModel(name);
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- pos.x = table[i*12+j*3+0];
- pos.y = table[i*12+j*3+1];
- pos.z = -table[i*12+j*3+2];
- m_object->SetPosition(19+i*4+j, pos);
- }
- }
-
- // Creates the right mandible.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(35, rank);
- m_object->SetObjectParent(35, 1);
- pModFile->ReadModel("objects\\spider7.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(35, Math::Vector(0.0f, 0.0f, -0.3f));
-
- // Creates the left mandible.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(36, rank);
- m_object->SetObjectParent(36, 1);
- pModFile->ReadModel("objects\\spider7.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(36, Math::Vector(0.0f, 0.0f, 0.3f));
-
- m_object->CreateShadowCircle(4.0f, 0.5f);
-
- CreatePhysics();
- m_object->SetFloorHeight(0.0f);
-
- pos = m_object->RetPosition(0);
- m_object->SetPosition(0, pos); // to display the shadows immediately
-
- m_engine->LoadAllTexture();
-
- delete pModFile;
- return true;
-}
-
-// Creates the physics of the object.
-
-void CMotionSpider::CreatePhysics()
-{
- Character* character;
- int i;
-
- int member_march[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4, // in the air:
- 60,25,0, 60,0,0, 60,-25,0, 60,-50,0, // t0: thighs 1..4
- -35,40,0, -35,0,0, -35,0,0, -35,-40,0, // t0: legs 1..4
- -65,0,-30, -65,0,0, -65,0,0, -65,0,30, // t0: feet 1..4
- 25,0,0, 25,0,0, 25,0,0, 25,0,0, // t0: fingers 1..4
- // on the ground:
- 30,15,0, 30,-10,0, 30,-35,0, 30,-60,0, // t1: thighs 1..4
- -10,40,0, -45,0,0, -45,0,0, -45,-40,0, // t1: legs 1..4
- -90,0,0, -20,0,0, -20,0,0, -20,0,0, // t1: feet 1..4
- -5,0,0, -5,0,0, -5,0,0, -5,0,0, // t1: fingers 1..4
- // on the ground back:
- 35,35,0, 40,10,0, 40,-15,0, 40,-40,0, // t2: thighs 1..4
- -35,40,0, -35,0,0, -35,0,0, -25,-40,0, // t2: legs 1..4
- -50,-25,-30, -65,0,0, -65,0,0, -90,0,30, // t2: feet 1..4
- -5,0,0, -5,0,0, -5,0,0, -5,0,0, // t2: fingers 1..4
- };
-
- int member_stop[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4, // in the air:
- 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // t0: thighs 1..4
- -35,40,0, -45,0,0, -45,0,0, -45,-40,0, // t0: legs 1..4
- -50,-25,-30, -20,0,0, -20,0,0, -20,0,30, // t0: feet 1..4
- -5,0,0, -5,0,0, -5,0,0, -5,0,0, // t0: fingers 1..4
- // on the ground:
- 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // t1: thighs 1..4
- -30,40,0, -40,0,0, -40,0,0, -40,-40,0, // t1: legs 1..4
- -55,-25,-30, -25,0,0, -25,0,0, -25,0,0, // t1: feet 1..4
- -5,0,0, -5,0,0, -5,0,0, -5,0,0, // t1: fingers 1..4
- // on the ground back:
- 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // t2: thighs 1..4
- -30,40,0, -40,0,0, -40,0,0, -40,-40,0, // t2: legs 1..4
- -50,-25,-30, -20,0,0, -20,0,0, -20,0,30, // t2: feet 1..4
- -10,0,0, -10,0,0, -10,0,0, -10,0,0, // t2: fingers 1..4
- };
-
- int member_spec[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4, // burning:
- 30,25,0, 30,0,0, 30,-25,0, 30,-50,0, // s0: thighs 1..4
- -45,0,0, -45,0,0, -45,0,0, -45,0,0, // s0: legs 1..4
- -20,0,0, -20,0,0, -20,0,0, -20,0,0, // s0: feet 1..4
- -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s0: fingers 1..4
- // destroyed:
- 30,25,0, 30,0,0, 30,-25,0, 30,-50,0, // s1: thighs 1..4
- -45,0,0, -45,0,0, -45,0,0, -45,0,0, // s1: legs 1..4
- -20,0,0, -20,0,0, -20,0,0, -20,0,0, // s1: feet 1..4
- -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s1: fingers 1..4
- // explodes:
- 40,25,0, 40,0,0, 40,-25,0, 40,-50,0, // s2: thighs 1..4
- -55,0,0, -55,0,0, -55,0,0, -55,0,0, // s2: legs 1..4
- -30,0,0, -30,0,0, -30,0,0, -30,0,0, // s2: feet 1..4
- -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s2: fingers 1..4
- // back1 :
- 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // s3: thighs 1..4
- -30,40,0, -40,0,0, -40,0,0, -40,-40,0, // s3: legs 1..4
- -55,-25,-30, -25,0,0, -25,0,0, -25,0,0, // s3: feet 1..4
- -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s3: fingers 1..4
- // back2 :
- 15,35,0, 15,0,0, 15,-25,0, 15,-50,0, // s4: thighs 1..4
- -60,40,0, -60,0,0, -60,0,0, -60,-40,0, // s4: legs 1..4
- -65,-25,-30, -65,0,0, -65,0,0, -65,0,0, // s4: feet 1..4
- -15,0,0, -15,0,0, -15,0,0, -15,0,0, // s4: fingers 1..4
- // back3 :
- 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // s5: thighs 1..4
- -30,40,0, -40,0,0, -40,0,0, -40,-40,0, // s5: legs 1..4
- -55,-25,-30, -25,0,0, -25,0,0, -25,0,0, // s5: feet 1..4
- -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s5: fingers 1..4
- };
-
- m_physics->SetType(TYPE_ROLLING);
-
- character = m_object->RetCharacter();
- character->wheelFront = 4.0f;
- character->wheelBack = 4.0f;
- character->wheelLeft = 6.0f;
- character->wheelRight = 6.0f;
- character->height = 0.6f;
-
- m_physics->SetLinMotionX(MO_ADVSPEED, 12.0f);
- m_physics->SetLinMotionX(MO_RECSPEED, 12.0f);
- m_physics->SetLinMotionX(MO_ADVACCEL, 15.0f);
- m_physics->SetLinMotionX(MO_RECACCEL, 15.0f);
- m_physics->SetLinMotionX(MO_STOACCEL, 40.0f);
- m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionX(MO_TERFORCE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERFORCE, 5.0f);
- m_physics->SetLinMotionZ(MO_MOTACCEL, 10.0f);
-
- m_physics->SetCirMotionY(MO_ADVSPEED, 1.0f*Math::PI);
- m_physics->SetCirMotionY(MO_RECSPEED, 1.0f*Math::PI);
- m_physics->SetCirMotionY(MO_ADVACCEL, 20.0f);
- m_physics->SetCirMotionY(MO_RECACCEL, 20.0f);
- m_physics->SetCirMotionY(MO_STOACCEL, 40.0f);
-
- for ( i=0 ; i<3*4*4*3 ; i++ )
- {
- m_armAngles[3*4*4*3*MS_MARCH+i] = member_march[i];
- }
- for ( i=0 ; i<3*4*4*3 ; i++ )
- {
- m_armAngles[3*4*4*3*MS_STOP+i] = member_stop[i];
- }
- for ( i=0 ; i<3*4*4*6 ; i++ )
- {
- m_armAngles[3*4*4*3*MS_SPEC+i] = member_spec[i];
- }
-}
-
-
-// Management of an event.
-
-bool CMotionSpider::EventProcess(const Event &event)
-{
- CMotion::EventProcess(event);
-
- if ( event.event == EVENT_FRAME )
- {
- return EventFrame(event);
- }
-
- if ( event.event == EVENT_KEYDOWN )
- {
-#if ADJUST_ANGLE
- int i;
-
- if ( event.param == 'A' ) m_armTimeIndex++;
- if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0;
-
- if ( event.param == 'Q' ) m_armPartIndex++;
- if ( m_armPartIndex >= 4 ) m_armPartIndex = 0;
-
- if ( event.param == 'W' ) m_armMemberIndex++;
- if ( m_armMemberIndex >= 4 ) m_armMemberIndex = 0;
-
- i = m_armMemberIndex*3;
- i += m_armPartIndex*3*4;
- i += m_armTimeIndex*3*4*4;
-
- if ( event.param == 'E' ) m_armAngles[i+0] += 5;
- if ( event.param == 'D' ) m_armAngles[i+0] -= 5;
- if ( event.param == 'R' ) m_armAngles[i+1] += 5;
- if ( event.param == 'F' ) m_armAngles[i+1] -= 5;
- if ( event.param == 'T' ) m_armAngles[i+2] += 5;
- if ( event.param == 'G' ) m_armAngles[i+2] -= 5;
- if ( event.param == 'Z' ) m_armAngles[i+3] += 5;
- if ( event.param == 'H' ) m_armAngles[i+3] -= 5;
-
- if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop;
-#endif
- }
-
- return true;
-}
-
-// Management of an event.
-
-bool CMotionSpider::EventFrame(const Event &event)
-{
- Math::Vector dir, pos, speed;
- Math::Point dim;
- float s, a, prog, time;
- float tSt[12], tNd[12];
- int i, ii, st, nd, action;
- bool bStop;
-
- if ( m_engine->RetPause() ) return true;
- if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return true;
-
- s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.5f;
- a = fabs(m_physics->RetCirMotionY(MO_MOTSPEED)*2.0f);
-
- if ( s == 0.0f && a != 0.0f ) a *= 1.5f;
-
- m_armTimeAbs += event.rTime;
- m_armTimeAction += event.rTime;
- m_armTimeMarch += (s)*event.rTime*0.15f;
- m_armMember += (s+a)*event.rTime*0.15f;
-
- bStop = ( a == 0.0f && s == 0.0f ); // stop?
-
- action = MS_MARCH; // waslking
- if ( s == 0.0f && a == 0.0f )
- {
- action = MS_STOP; // stop
- }
-
- if ( bStop )
- {
- prog = Math::Mod(m_armTimeAbs, 2.0f)/10.0f;
- a = Math::Mod(m_armMember, 1.0f);
- a = (prog-a)*event.rTime*2.0f; // stop position just pleasantly
- m_armMember += a;
- }
-
- if ( m_object->RetRuin() ) // destroyed?
- {
- m_actionType = MSS_RUIN;
- }
- if ( m_object->RetBurn() ) // burning?
- {
- if ( m_object->RetFixed() )
- {
- m_actionType = MSS_BURN;
- }
- else
- {
- m_actionType = -1;
- }
- }
-
- for ( i=0 ; i<8 ; i++ ) // the 8 legs
- {
- if ( m_actionType != -1 ) // special action in progress?
- {
- st = 3*4*4*3*MS_SPEC + 3*4*4*m_actionType + (i%4)*3;
- nd = st;
- time = event.rTime*m_actionTime;
- m_armTimeAction = 0.0f;
- }
- else
- {
-//? if ( i < 4 ) prog = Math::Mod(m_armMember+(2.0f-(i%4))*0.25f+0.0f, 1.0f);
-//? else prog = Math::Mod(m_armMember+(2.0f-(i%4))*0.25f+0.3f, 1.0f);
- if ( i < 4 ) prog = Math::Mod(m_armMember+(2.0f-(i%4))*0.25f+0.0f, 1.0f);
- else prog = Math::Mod(m_armMember+(2.0f-(i%4))*0.25f+0.5f, 1.0f);
- if ( m_bArmStop )
- {
- prog = (float)m_armTimeIndex/3.0f;
- action = MS_MARCH;
- }
- if ( prog < 0.33f ) // t0..t1 ?
- {
- prog = prog/0.33f; // 0..1
- st = 0; // index start
- nd = 1; // index end
- }
- else if ( prog < 0.67f ) // t1..t2 ?
- {
- prog = (prog-0.33f)/0.33f; // 0..1
- st = 1; // index start
- nd = 2; // index end
- }
- else // t2..t0 ?
- {
- prog = (prog-0.67f)/0.33f; // 0..1
- st = 2; // index start
- nd = 0; // index end
- }
- st = 3*4*4*3*action + st*3*4*4 + (i%4)*3;
- nd = 3*4*4*3*action + nd*3*4*4 + (i%4)*3;
-
- // Less and less soft ...
-//? time = event.rTime*(2.0f+Math::Min(m_armTimeAction*20.0f, 40.0f));
- time = event.rTime*10.0f;
- }
-
- tSt[ 0] = m_armAngles[st+ 0]; // x
- tSt[ 1] = m_armAngles[st+ 1]; // y
- tSt[ 2] = m_armAngles[st+ 2]; // z
- tSt[ 3] = m_armAngles[st+12]; // x
- tSt[ 4] = m_armAngles[st+13]; // y
- tSt[ 5] = m_armAngles[st+14]; // z
- tSt[ 6] = m_armAngles[st+24]; // x
- tSt[ 7] = m_armAngles[st+25]; // y
- tSt[ 8] = m_armAngles[st+26]; // z
- tSt[ 9] = m_armAngles[st+36]; // x
- tSt[10] = m_armAngles[st+37]; // y
- tSt[11] = m_armAngles[st+38]; // z
-
- tNd[ 0] = m_armAngles[nd+ 0]; // x
- tNd[ 1] = m_armAngles[nd+ 1]; // y
- tNd[ 2] = m_armAngles[nd+ 2]; // z
- tNd[ 3] = m_armAngles[nd+12]; // x
- tNd[ 4] = m_armAngles[nd+13]; // y
- tNd[ 5] = m_armAngles[nd+14]; // z
- tNd[ 6] = m_armAngles[nd+24]; // x
- tNd[ 7] = m_armAngles[nd+25]; // y
- tNd[ 8] = m_armAngles[nd+26]; // z
- tNd[ 9] = m_armAngles[nd+36]; // z
- tNd[10] = m_armAngles[nd+37]; // z
- tNd[11] = m_armAngles[nd+38]; // z
-
- if ( m_actionType == MSS_BACK2 ) // on the back?
- {
- for ( ii=0 ; ii<12 ; ii++ )
- {
- tSt[ii] += Math::Rand()*20.0f;
- tNd[ii] = tSt[ii];
- }
-//? time = 100.0f;
- time = event.rTime*10.0f;
- }
-
- if ( i < 4 ) // right leg (1..4) ?
- {
- m_object->SetAngleX(3+4*i+0, Math::Smooth(m_object->RetAngleX(3+4*i+0), Math::PropAngle(tSt[ 0], tNd[ 0], prog), time));
- m_object->SetAngleY(3+4*i+0, Math::Smooth(m_object->RetAngleY(3+4*i+0), Math::PropAngle(tSt[ 1], tNd[ 1], prog), time));
- m_object->SetAngleZ(3+4*i+0, Math::Smooth(m_object->RetAngleZ(3+4*i+0), Math::PropAngle(tSt[ 2], tNd[ 2], prog), time));
- m_object->SetAngleX(3+4*i+1, Math::Smooth(m_object->RetAngleX(3+4*i+1), Math::PropAngle(tSt[ 3], tNd[ 3], prog), time));
- m_object->SetAngleY(3+4*i+1, Math::Smooth(m_object->RetAngleY(3+4*i+1), Math::PropAngle(tSt[ 4], tNd[ 4], prog), time));
- m_object->SetAngleZ(3+4*i+1, Math::Smooth(m_object->RetAngleZ(3+4*i+1), Math::PropAngle(tSt[ 5], tNd[ 5], prog), time));
- m_object->SetAngleX(3+4*i+2, Math::Smooth(m_object->RetAngleX(3+4*i+2), Math::PropAngle(tSt[ 6], tNd[ 6], prog), time));
- m_object->SetAngleY(3+4*i+2, Math::Smooth(m_object->RetAngleY(3+4*i+2), Math::PropAngle(tSt[ 7], tNd[ 7], prog), time));
- m_object->SetAngleZ(3+4*i+2, Math::Smooth(m_object->RetAngleZ(3+4*i+2), Math::PropAngle(tSt[ 8], tNd[ 8], prog), time));
- m_object->SetAngleX(3+4*i+3, Math::Smooth(m_object->RetAngleX(3+4*i+3), Math::PropAngle(tSt[ 9], tNd[ 9], prog), time));
- m_object->SetAngleY(3+4*i+3, Math::Smooth(m_object->RetAngleY(3+4*i+3), Math::PropAngle(tSt[10], tNd[10], prog), time));
- m_object->SetAngleZ(3+4*i+3, Math::Smooth(m_object->RetAngleZ(3+4*i+3), Math::PropAngle(tSt[11], tNd[11], prog), time));
- }
- else // left leg (5..8) ?
- {
- m_object->SetAngleX(3+4*i+0, Math::Smooth(m_object->RetAngleX(3+4*i+0), Math::PropAngle(-tSt[ 0], -tNd[ 0], prog), time));
- m_object->SetAngleY(3+4*i+0, Math::Smooth(m_object->RetAngleY(3+4*i+0), Math::PropAngle(-tSt[ 1], -tNd[ 1], prog), time));
- m_object->SetAngleZ(3+4*i+0, Math::Smooth(m_object->RetAngleZ(3+4*i+0), Math::PropAngle( tSt[ 2], tNd[ 2], prog), time));
- m_object->SetAngleX(3+4*i+1, Math::Smooth(m_object->RetAngleX(3+4*i+1), Math::PropAngle(-tSt[ 3], -tNd[ 3], prog), time));
- m_object->SetAngleY(3+4*i+1, Math::Smooth(m_object->RetAngleY(3+4*i+1), Math::PropAngle(-tSt[ 4], -tNd[ 4], prog), time));
- m_object->SetAngleZ(3+4*i+1, Math::Smooth(m_object->RetAngleZ(3+4*i+1), Math::PropAngle( tSt[ 5], tNd[ 5], prog), time));
- m_object->SetAngleX(3+4*i+2, Math::Smooth(m_object->RetAngleX(3+4*i+2), Math::PropAngle(-tSt[ 6], -tNd[ 6], prog), time));
- m_object->SetAngleY(3+4*i+2, Math::Smooth(m_object->RetAngleY(3+4*i+2), Math::PropAngle(-tSt[ 7], -tNd[ 7], prog), time));
- m_object->SetAngleZ(3+4*i+2, Math::Smooth(m_object->RetAngleZ(3+4*i+2), Math::PropAngle( tSt[ 8], tNd[ 8], prog), time));
- m_object->SetAngleX(3+4*i+3, Math::Smooth(m_object->RetAngleX(3+4*i+3), Math::PropAngle(-tSt[ 9], -tNd[ 9], prog), time));
- m_object->SetAngleY(3+4*i+3, Math::Smooth(m_object->RetAngleY(3+4*i+3), Math::PropAngle(-tSt[10], -tNd[10], prog), time));
- m_object->SetAngleZ(3+4*i+3, Math::Smooth(m_object->RetAngleZ(3+4*i+3), Math::PropAngle( tSt[11], tNd[11], prog), time));
- }
- }
-
-#if ADJUST_ANGLE
- if ( m_object->RetSelect() )
- {
- char s[100];
- sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex);
- m_engine->SetInfoText(4, s);
- }
-#endif
-
- if ( m_actionType == MSS_BURN ) // burning?
- {
- dir = Math::Vector(Math::PI, 0.0f, 0.0f);
- SetCirVibration(dir);
- dir = Math::Vector(0.0f, 0.0f, 0.0f);
- SetLinVibration(dir);
- SetInclinaison(dir);
-
- time = event.rTime*1.0f;
- m_object->SetAngleZ(1, Math::Smooth(m_object->RetAngleZ(1), 0.0f, time)); // head
- }
- else if ( m_actionType == MSS_RUIN ) // destroyed?
- {
- dir = Math::Vector(0.0f, 0.0f, 0.0f);
- SetLinVibration(dir);
- SetCirVibration(dir);
- SetInclinaison(dir);
- }
- else if ( m_actionType == MSS_EXPLO ) // exploded?
- {
- m_object->SetZoomY(1, 1.0f+m_progress);
- m_object->SetZoomZ(1, 1.0f+m_progress);
- m_object->SetZoomX(1, 1.0f+m_progress/2.0f);
-
- dir.x = (Math::Rand()-0.5f)*0.1f*m_progress;
- dir.y = (Math::Rand()-0.5f)*0.1f*m_progress;
- dir.z = (Math::Rand()-0.5f)*0.1f*m_progress;
- m_object->SetCirVibration(dir);
- }
- else if ( m_actionType == MSS_BACK1 ) // turns on the back?
- {
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs )
- {
- m_lastParticule = m_armTimeAbs;
-
- pos = m_object->RetPosition(0);
- speed.x = (Math::Rand()-0.5f)*10.0f;
- speed.z = (Math::Rand()-0.5f)*10.0f;
- speed.y = Math::Rand()*5.0f;
- dim.x = Math::Rand()*3.0f+2.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f);
- }
-
- if ( m_progress < 0.5f )
- {
- dir.x = 0.0f;
- dir.y = powf(m_progress/0.5f, 2.0f)*12.0f;
- dir.z = 0.0f;
- SetLinVibration(dir);
- }
- else
- {
- dir.x = 0.0f;
- dir.y = powf(2.0f-m_progress/0.5f, 2.0f)*12.0f;
- dir.z = 0.0f;
- SetLinVibration(dir);
- }
- dir.x = m_progress*Math::PI;
- dir.y = 0.0f;
- dir.z = 0.0f;
- SetCirVibration(dir);
-
- dir = Math::Vector(0.0f, 0.0f, 0.0f);
- SetInclinaison(dir);
-
- if ( m_progress >= 1.0f )
- {
- SetAction(MSS_BACK2, 55.0f+Math::Rand()*10.0f);
- }
- }
- else if ( m_actionType == MSS_BACK2 ) // moves on the back?
- {
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs )
- {
- m_lastParticule = m_armTimeAbs;
-
- if ( rand()%10 == 0 )
- {
- pos = m_object->RetPosition(0);
- pos.x += (Math::Rand()-0.5f)*8.0f;
- pos.z += (Math::Rand()-0.5f)*8.0f;
- pos.y -= 1.0f;
- speed.x = (Math::Rand()-0.5f)*2.0f;
- speed.z = (Math::Rand()-0.5f)*2.0f;
- speed.y = Math::Rand()*2.0f;
- dim.x = Math::Rand()*1.0f+1.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f);
- }
- }
-
- dir = Math::Vector(0.0f, 0.0f, 0.0f);
- SetLinVibration(dir);
- dir.x = sinf(m_armTimeAbs* 3.0f)*0.20f+
- sinf(m_armTimeAbs* 6.0f)*0.20f+
- sinf(m_armTimeAbs*10.0f)*0.20f+
- sinf(m_armTimeAbs*17.0f)*0.30f+Math::PI;
- dir.y = sinf(m_armTimeAbs* 4.0f)*0.02f+
- sinf(m_armTimeAbs* 5.0f)*0.02f+
- sinf(m_armTimeAbs*11.0f)*0.02f+
- sinf(m_armTimeAbs*18.0f)*0.03f;
- dir.z = sinf(m_armTimeAbs* 2.0f)*0.02f+
- sinf(m_armTimeAbs* 7.0f)*0.02f+
- sinf(m_armTimeAbs*13.0f)*0.02f+
- sinf(m_armTimeAbs*15.0f)*0.03f;
- SetCirVibration(dir);
- dir = Math::Vector(0.0f, 0.0f, 0.0f);
- SetInclinaison(dir);
-
- m_object->SetAngleY(1, sinf(m_armTimeAbs*5.0f)*0.05f); // tail
- m_object->SetAngleY(2, cosf(m_armTimeAbs*5.0f)*0.20f); // head
- m_object->SetAngleZ(1, 0.4f); // tail
- m_object->SetAngleZ(2, 0.0f); // head
-
- if ( m_progress >= 1.0f )
- {
- SetAction(MSS_BACK3, 0.4f);
- }
- }
- else if ( m_actionType == MSS_BACK3 ) // recovers on the legs?
- {
- if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs )
- {
- m_lastParticule = m_armTimeAbs;
-
- pos = m_object->RetPosition(0);
- speed.x = (Math::Rand()-0.5f)*10.0f;
- speed.z = (Math::Rand()-0.5f)*10.0f;
- speed.y = Math::Rand()*5.0f;
- dim.x = Math::Rand()*3.0f+2.0f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f);
- }
-
- if ( m_progress < 0.5f )
- {
- dir.x = 0.0f;
- dir.y = powf(m_progress/0.5f, 2.0f)*5.0f;
- dir.z = 0.0f;
- SetLinVibration(dir);
- }
- else
- {
- dir.x = 0.0f;
- dir.y = powf(2.0f-m_progress/0.5f, 2.0f)*5.0f;
- dir.z = 0.0f;
- SetLinVibration(dir);
- }
- dir.x = (1.0f-m_progress)*Math::PI;
- dir.y = 0.0f;
- dir.z = 0.0f;
- SetCirVibration(dir);
-
- dir = Math::Vector(0.0f, 0.0f, 0.0f);
- SetInclinaison(dir);
-
- if ( m_progress >= 1.0f )
- {
- SetAction(-1);
- m_object->SetFixed(false); // moving again
- }
- }
- else
- {
- if ( bStop )
- {
- dir = Math::Vector(0.0f, 0.0f, 0.0f);
- SetInclinaison(dir);
- }
- else
- {
- a = Math::Mod(m_armMember, 1.0f);
- if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1
- else a = 3.0f-4.0f*a; // 1..-1
- dir.x = sinf(a)*0.05f;
-
- s = Math::Mod(m_armMember/2.0f, 1.0f);
- if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1
- else s = 3.0f-4.0f*s; // 1..-1
- dir.z = sinf(s)*0.1f;
-
- dir.y = 0.0f;
- SetInclinaison(dir);
- }
-
- dir = Math::Vector(0.0f, 0.0f, 0.0f);
- SetLinVibration(dir);
- SetCirVibration(dir);
-
- m_object->SetAngleZ(1, sinf(m_armTimeAbs*1.7f)*0.02f); // tail
- m_object->SetAngleX(1, sinf(m_armTimeAbs*1.3f)*0.05f);
- m_object->SetAngleY(1, sinf(m_armTimeAbs*2.4f)*0.10f);
- m_object->SetZoom(1, 1.0f+sinf(m_armTimeAbs*3.3f)*0.05f);
-
- m_object->SetAngleZ(2, sinf(m_armTimeAbs*1.4f)*0.20f); // head
- m_object->SetAngleX(2, sinf(m_armTimeAbs*1.9f)*0.10f);
- m_object->SetAngleY(2, sinf(m_armTimeAbs*2.1f)*0.10f);
-
- m_object->SetAngleY(35, sinf(m_armTimeAbs*3.1f)*0.20f); // mandible
- m_object->SetAngleY(36, -sinf(m_armTimeAbs*3.1f)*0.20f); // mandible
- }
-
- return true;
-}
-
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionspider.cpp + + +#include <stdio.h> + +#include "object/motion/motionspider.h" + +#include "old/modfile.h" +#include "old/particule.h" +#include "physics/physics.h" + + + +#define ADJUST_ANGLE false // true -> adjusts the angles of the members +const float START_TIME = 1000.0f; // beginning of the relative time + + + +// Object's constructor. + +CMotionSpider::CMotionSpider(CInstanceManager* iMan, CObject* object) + : CMotion(iMan, object) +{ + m_armMember = START_TIME; + m_armTimeAbs = START_TIME; + m_armTimeMarch = START_TIME; + m_armTimeAction = START_TIME; + m_armTimeIndex = 0; + m_armPartIndex = 0; + m_armMemberIndex = 0; + m_armLastAction = -1; + m_bArmStop = false; + m_lastParticule = 0.0f; +} + +// Object's destructor. + +CMotionSpider::~CMotionSpider() +{ +} + + +// Removes an object. + +void CMotionSpider::DeleteObject(bool bAll) +{ +} + + +// Creates a vehicle traveling any lands on the ground. + +bool CMotionSpider::Create(Math::Vector pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + int rank, i, j, parent; + char name[50]; + + float table[] = + { + // x y z + 0.6f, 0.0f, 0.0f, // back leg + 0.0f, 0.0f, -2.0f, + 0.0f, 0.0f, -2.0f, + 0.0f, 0.0f, -2.0f, + + 0.8f, 0.0f, -0.2f, // middle-back leg + 0.0f, 0.0f, -2.0f, + 0.0f, 0.0f, -2.0f, + 0.0f, 0.0f, -2.0f, + + 1.0f, 0.0f, -0.2f, // middle-front leg + 0.0f, 0.0f, -2.0f, + 0.0f, 0.0f, -2.0f, + 0.0f, 0.0f, -2.0f, + + 1.2f, 0.0f, 0.0f, // front leg + 0.0f, 0.0f, -2.0f, + 0.0f, 0.0f, -2.0f, + 0.0f, 0.0f, -2.0f, + }; + + if ( m_engine->RetRestCreate() < 3+32+2 ) return false; + + pModFile = new CModFile(m_iMan); + + m_object->SetType(type); + + // Creates the main base. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + pModFile->ReadModel("objects\\spider0.mod"); // doesn't exist + pModFile->CreateEngineObject(rank); + m_object->SetPosition(0, pos); + m_object->SetAngleY(0, angle); + + // A vehicle must have a obligatory collision + // with a sphere of center (0, y, 0) (see GetCrashSphere). + m_object->CreateCrashSphere(Math::Vector(0.0f, -2.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f); + m_object->SetGlobalSphere(Math::Vector(-0.5f, 1.0f, 0.0f), 4.0f); + + // Creates the abdomen. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\spider1.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(1.0f, 0.0f, 0.0f)); + + // Creates the head. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\spider2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, Math::Vector(1.0f, 0.0f, 0.0f)); + + // Creates legs. + for ( i=0 ; i<4 ; i++ ) + { + for ( j=0 ; j<4 ; j++ ) + { + sprintf(name, "objects\\spider%d.mod", j+3); // 3..6 + + // Creates the right leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3+i*4+j, rank); + if ( j == 0 ) parent = 0; + else parent = 3+i*4+j-1; + m_object->SetObjectParent(3+i*4+j, parent); + pModFile->ReadModel(name); + pModFile->CreateEngineObject(rank); + pos.x = table[i*12+j*3+0]; + pos.y = table[i*12+j*3+1]; + pos.z = table[i*12+j*3+2]; + m_object->SetPosition(3+i*4+j, pos); + + // Creates the left leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(19+i*4+j, rank); + if ( j == 0 ) parent = 0; + else parent = 19+i*4+j-1; + m_object->SetObjectParent(19+i*4+j, parent); + pModFile->ReadModel(name); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + pos.x = table[i*12+j*3+0]; + pos.y = table[i*12+j*3+1]; + pos.z = -table[i*12+j*3+2]; + m_object->SetPosition(19+i*4+j, pos); + } + } + + // Creates the right mandible. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(35, rank); + m_object->SetObjectParent(35, 1); + pModFile->ReadModel("objects\\spider7.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(35, Math::Vector(0.0f, 0.0f, -0.3f)); + + // Creates the left mandible. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(36, rank); + m_object->SetObjectParent(36, 1); + pModFile->ReadModel("objects\\spider7.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(36, Math::Vector(0.0f, 0.0f, 0.3f)); + + m_object->CreateShadowCircle(4.0f, 0.5f); + + CreatePhysics(); + m_object->SetFloorHeight(0.0f); + + pos = m_object->RetPosition(0); + m_object->SetPosition(0, pos); // to display the shadows immediately + + m_engine->LoadAllTexture(); + + delete pModFile; + return true; +} + +// Creates the physics of the object. + +void CMotionSpider::CreatePhysics() +{ + Character* character; + int i; + + int member_march[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4, // in the air: + 60,25,0, 60,0,0, 60,-25,0, 60,-50,0, // t0: thighs 1..4 + -35,40,0, -35,0,0, -35,0,0, -35,-40,0, // t0: legs 1..4 + -65,0,-30, -65,0,0, -65,0,0, -65,0,30, // t0: feet 1..4 + 25,0,0, 25,0,0, 25,0,0, 25,0,0, // t0: fingers 1..4 + // on the ground: + 30,15,0, 30,-10,0, 30,-35,0, 30,-60,0, // t1: thighs 1..4 + -10,40,0, -45,0,0, -45,0,0, -45,-40,0, // t1: legs 1..4 + -90,0,0, -20,0,0, -20,0,0, -20,0,0, // t1: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // t1: fingers 1..4 + // on the ground back: + 35,35,0, 40,10,0, 40,-15,0, 40,-40,0, // t2: thighs 1..4 + -35,40,0, -35,0,0, -35,0,0, -25,-40,0, // t2: legs 1..4 + -50,-25,-30, -65,0,0, -65,0,0, -90,0,30, // t2: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // t2: fingers 1..4 + }; + + int member_stop[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4, // in the air: + 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // t0: thighs 1..4 + -35,40,0, -45,0,0, -45,0,0, -45,-40,0, // t0: legs 1..4 + -50,-25,-30, -20,0,0, -20,0,0, -20,0,30, // t0: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // t0: fingers 1..4 + // on the ground: + 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // t1: thighs 1..4 + -30,40,0, -40,0,0, -40,0,0, -40,-40,0, // t1: legs 1..4 + -55,-25,-30, -25,0,0, -25,0,0, -25,0,0, // t1: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // t1: fingers 1..4 + // on the ground back: + 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // t2: thighs 1..4 + -30,40,0, -40,0,0, -40,0,0, -40,-40,0, // t2: legs 1..4 + -50,-25,-30, -20,0,0, -20,0,0, -20,0,30, // t2: feet 1..4 + -10,0,0, -10,0,0, -10,0,0, -10,0,0, // t2: fingers 1..4 + }; + + int member_spec[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, x4,y4,z4, // burning: + 30,25,0, 30,0,0, 30,-25,0, 30,-50,0, // s0: thighs 1..4 + -45,0,0, -45,0,0, -45,0,0, -45,0,0, // s0: legs 1..4 + -20,0,0, -20,0,0, -20,0,0, -20,0,0, // s0: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s0: fingers 1..4 + // destroyed: + 30,25,0, 30,0,0, 30,-25,0, 30,-50,0, // s1: thighs 1..4 + -45,0,0, -45,0,0, -45,0,0, -45,0,0, // s1: legs 1..4 + -20,0,0, -20,0,0, -20,0,0, -20,0,0, // s1: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s1: fingers 1..4 + // explodes: + 40,25,0, 40,0,0, 40,-25,0, 40,-50,0, // s2: thighs 1..4 + -55,0,0, -55,0,0, -55,0,0, -55,0,0, // s2: legs 1..4 + -30,0,0, -30,0,0, -30,0,0, -30,0,0, // s2: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s2: fingers 1..4 + // back1 : + 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // s3: thighs 1..4 + -30,40,0, -40,0,0, -40,0,0, -40,-40,0, // s3: legs 1..4 + -55,-25,-30, -25,0,0, -25,0,0, -25,0,0, // s3: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s3: fingers 1..4 + // back2 : + 15,35,0, 15,0,0, 15,-25,0, 15,-50,0, // s4: thighs 1..4 + -60,40,0, -60,0,0, -60,0,0, -60,-40,0, // s4: legs 1..4 + -65,-25,-30, -65,0,0, -65,0,0, -65,0,0, // s4: feet 1..4 + -15,0,0, -15,0,0, -15,0,0, -15,0,0, // s4: fingers 1..4 + // back3 : + 35,35,0, 30,0,0, 30,-25,0, 30,-50,0, // s5: thighs 1..4 + -30,40,0, -40,0,0, -40,0,0, -40,-40,0, // s5: legs 1..4 + -55,-25,-30, -25,0,0, -25,0,0, -25,0,0, // s5: feet 1..4 + -5,0,0, -5,0,0, -5,0,0, -5,0,0, // s5: fingers 1..4 + }; + + m_physics->SetType(TYPE_ROLLING); + + character = m_object->RetCharacter(); + character->wheelFront = 4.0f; + character->wheelBack = 4.0f; + character->wheelLeft = 6.0f; + character->wheelRight = 6.0f; + character->height = 0.6f; + + m_physics->SetLinMotionX(MO_ADVSPEED, 12.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 12.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 15.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 15.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 5.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 5.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 10.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 1.0f*Math::PI); + m_physics->SetCirMotionY(MO_RECSPEED, 1.0f*Math::PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 20.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 20.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 40.0f); + + for ( i=0 ; i<3*4*4*3 ; i++ ) + { + m_armAngles[3*4*4*3*MS_MARCH+i] = member_march[i]; + } + for ( i=0 ; i<3*4*4*3 ; i++ ) + { + m_armAngles[3*4*4*3*MS_STOP+i] = member_stop[i]; + } + for ( i=0 ; i<3*4*4*6 ; i++ ) + { + m_armAngles[3*4*4*3*MS_SPEC+i] = member_spec[i]; + } +} + + +// Management of an event. + +bool CMotionSpider::EventProcess(const Event &event) +{ + CMotion::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + if ( event.event == EVENT_KEYDOWN ) + { +#if ADJUST_ANGLE + int i; + + if ( event.param == 'A' ) m_armTimeIndex++; + if ( m_armTimeIndex >= 3 ) m_armTimeIndex = 0; + + if ( event.param == 'Q' ) m_armPartIndex++; + if ( m_armPartIndex >= 4 ) m_armPartIndex = 0; + + if ( event.param == 'W' ) m_armMemberIndex++; + if ( m_armMemberIndex >= 4 ) m_armMemberIndex = 0; + + i = m_armMemberIndex*3; + i += m_armPartIndex*3*4; + i += m_armTimeIndex*3*4*4; + + if ( event.param == 'E' ) m_armAngles[i+0] += 5; + if ( event.param == 'D' ) m_armAngles[i+0] -= 5; + if ( event.param == 'R' ) m_armAngles[i+1] += 5; + if ( event.param == 'F' ) m_armAngles[i+1] -= 5; + if ( event.param == 'T' ) m_armAngles[i+2] += 5; + if ( event.param == 'G' ) m_armAngles[i+2] -= 5; + if ( event.param == 'Z' ) m_armAngles[i+3] += 5; + if ( event.param == 'H' ) m_armAngles[i+3] -= 5; + + if ( event.param == 'Y' ) m_bArmStop = !m_bArmStop; +#endif + } + + return true; +} + +// Management of an event. + +bool CMotionSpider::EventFrame(const Event &event) +{ + Math::Vector dir, pos, speed; + Math::Point dim; + float s, a, prog, time; + float tSt[12], tNd[12]; + int i, ii, st, nd, action; + bool bStop; + + if ( m_engine->RetPause() ) return true; + if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return true; + + s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.5f; + a = fabs(m_physics->RetCirMotionY(MO_MOTSPEED)*2.0f); + + if ( s == 0.0f && a != 0.0f ) a *= 1.5f; + + m_armTimeAbs += event.rTime; + m_armTimeAction += event.rTime; + m_armTimeMarch += (s)*event.rTime*0.15f; + m_armMember += (s+a)*event.rTime*0.15f; + + bStop = ( a == 0.0f && s == 0.0f ); // stop? + + action = MS_MARCH; // waslking + if ( s == 0.0f && a == 0.0f ) + { + action = MS_STOP; // stop + } + + if ( bStop ) + { + prog = Math::Mod(m_armTimeAbs, 2.0f)/10.0f; + a = Math::Mod(m_armMember, 1.0f); + a = (prog-a)*event.rTime*2.0f; // stop position just pleasantly + m_armMember += a; + } + + if ( m_object->RetRuin() ) // destroyed? + { + m_actionType = MSS_RUIN; + } + if ( m_object->RetBurn() ) // burning? + { + if ( m_object->RetFixed() ) + { + m_actionType = MSS_BURN; + } + else + { + m_actionType = -1; + } + } + + for ( i=0 ; i<8 ; i++ ) // the 8 legs + { + if ( m_actionType != -1 ) // special action in progress? + { + st = 3*4*4*3*MS_SPEC + 3*4*4*m_actionType + (i%4)*3; + nd = st; + time = event.rTime*m_actionTime; + m_armTimeAction = 0.0f; + } + else + { +//? if ( i < 4 ) prog = Math::Mod(m_armMember+(2.0f-(i%4))*0.25f+0.0f, 1.0f); +//? else prog = Math::Mod(m_armMember+(2.0f-(i%4))*0.25f+0.3f, 1.0f); + if ( i < 4 ) prog = Math::Mod(m_armMember+(2.0f-(i%4))*0.25f+0.0f, 1.0f); + else prog = Math::Mod(m_armMember+(2.0f-(i%4))*0.25f+0.5f, 1.0f); + if ( m_bArmStop ) + { + prog = (float)m_armTimeIndex/3.0f; + action = MS_MARCH; + } + if ( prog < 0.33f ) // t0..t1 ? + { + prog = prog/0.33f; // 0..1 + st = 0; // index start + nd = 1; // index end + } + else if ( prog < 0.67f ) // t1..t2 ? + { + prog = (prog-0.33f)/0.33f; // 0..1 + st = 1; // index start + nd = 2; // index end + } + else // t2..t0 ? + { + prog = (prog-0.67f)/0.33f; // 0..1 + st = 2; // index start + nd = 0; // index end + } + st = 3*4*4*3*action + st*3*4*4 + (i%4)*3; + nd = 3*4*4*3*action + nd*3*4*4 + (i%4)*3; + + // Less and less soft ... +//? time = event.rTime*(2.0f+Math::Min(m_armTimeAction*20.0f, 40.0f)); + time = event.rTime*10.0f; + } + + tSt[ 0] = m_armAngles[st+ 0]; // x + tSt[ 1] = m_armAngles[st+ 1]; // y + tSt[ 2] = m_armAngles[st+ 2]; // z + tSt[ 3] = m_armAngles[st+12]; // x + tSt[ 4] = m_armAngles[st+13]; // y + tSt[ 5] = m_armAngles[st+14]; // z + tSt[ 6] = m_armAngles[st+24]; // x + tSt[ 7] = m_armAngles[st+25]; // y + tSt[ 8] = m_armAngles[st+26]; // z + tSt[ 9] = m_armAngles[st+36]; // x + tSt[10] = m_armAngles[st+37]; // y + tSt[11] = m_armAngles[st+38]; // z + + tNd[ 0] = m_armAngles[nd+ 0]; // x + tNd[ 1] = m_armAngles[nd+ 1]; // y + tNd[ 2] = m_armAngles[nd+ 2]; // z + tNd[ 3] = m_armAngles[nd+12]; // x + tNd[ 4] = m_armAngles[nd+13]; // y + tNd[ 5] = m_armAngles[nd+14]; // z + tNd[ 6] = m_armAngles[nd+24]; // x + tNd[ 7] = m_armAngles[nd+25]; // y + tNd[ 8] = m_armAngles[nd+26]; // z + tNd[ 9] = m_armAngles[nd+36]; // z + tNd[10] = m_armAngles[nd+37]; // z + tNd[11] = m_armAngles[nd+38]; // z + + if ( m_actionType == MSS_BACK2 ) // on the back? + { + for ( ii=0 ; ii<12 ; ii++ ) + { + tSt[ii] += Math::Rand()*20.0f; + tNd[ii] = tSt[ii]; + } +//? time = 100.0f; + time = event.rTime*10.0f; + } + + if ( i < 4 ) // right leg (1..4) ? + { + m_object->SetAngleX(3+4*i+0, Math::Smooth(m_object->RetAngleX(3+4*i+0), Math::PropAngle(tSt[ 0], tNd[ 0], prog), time)); + m_object->SetAngleY(3+4*i+0, Math::Smooth(m_object->RetAngleY(3+4*i+0), Math::PropAngle(tSt[ 1], tNd[ 1], prog), time)); + m_object->SetAngleZ(3+4*i+0, Math::Smooth(m_object->RetAngleZ(3+4*i+0), Math::PropAngle(tSt[ 2], tNd[ 2], prog), time)); + m_object->SetAngleX(3+4*i+1, Math::Smooth(m_object->RetAngleX(3+4*i+1), Math::PropAngle(tSt[ 3], tNd[ 3], prog), time)); + m_object->SetAngleY(3+4*i+1, Math::Smooth(m_object->RetAngleY(3+4*i+1), Math::PropAngle(tSt[ 4], tNd[ 4], prog), time)); + m_object->SetAngleZ(3+4*i+1, Math::Smooth(m_object->RetAngleZ(3+4*i+1), Math::PropAngle(tSt[ 5], tNd[ 5], prog), time)); + m_object->SetAngleX(3+4*i+2, Math::Smooth(m_object->RetAngleX(3+4*i+2), Math::PropAngle(tSt[ 6], tNd[ 6], prog), time)); + m_object->SetAngleY(3+4*i+2, Math::Smooth(m_object->RetAngleY(3+4*i+2), Math::PropAngle(tSt[ 7], tNd[ 7], prog), time)); + m_object->SetAngleZ(3+4*i+2, Math::Smooth(m_object->RetAngleZ(3+4*i+2), Math::PropAngle(tSt[ 8], tNd[ 8], prog), time)); + m_object->SetAngleX(3+4*i+3, Math::Smooth(m_object->RetAngleX(3+4*i+3), Math::PropAngle(tSt[ 9], tNd[ 9], prog), time)); + m_object->SetAngleY(3+4*i+3, Math::Smooth(m_object->RetAngleY(3+4*i+3), Math::PropAngle(tSt[10], tNd[10], prog), time)); + m_object->SetAngleZ(3+4*i+3, Math::Smooth(m_object->RetAngleZ(3+4*i+3), Math::PropAngle(tSt[11], tNd[11], prog), time)); + } + else // left leg (5..8) ? + { + m_object->SetAngleX(3+4*i+0, Math::Smooth(m_object->RetAngleX(3+4*i+0), Math::PropAngle(-tSt[ 0], -tNd[ 0], prog), time)); + m_object->SetAngleY(3+4*i+0, Math::Smooth(m_object->RetAngleY(3+4*i+0), Math::PropAngle(-tSt[ 1], -tNd[ 1], prog), time)); + m_object->SetAngleZ(3+4*i+0, Math::Smooth(m_object->RetAngleZ(3+4*i+0), Math::PropAngle( tSt[ 2], tNd[ 2], prog), time)); + m_object->SetAngleX(3+4*i+1, Math::Smooth(m_object->RetAngleX(3+4*i+1), Math::PropAngle(-tSt[ 3], -tNd[ 3], prog), time)); + m_object->SetAngleY(3+4*i+1, Math::Smooth(m_object->RetAngleY(3+4*i+1), Math::PropAngle(-tSt[ 4], -tNd[ 4], prog), time)); + m_object->SetAngleZ(3+4*i+1, Math::Smooth(m_object->RetAngleZ(3+4*i+1), Math::PropAngle( tSt[ 5], tNd[ 5], prog), time)); + m_object->SetAngleX(3+4*i+2, Math::Smooth(m_object->RetAngleX(3+4*i+2), Math::PropAngle(-tSt[ 6], -tNd[ 6], prog), time)); + m_object->SetAngleY(3+4*i+2, Math::Smooth(m_object->RetAngleY(3+4*i+2), Math::PropAngle(-tSt[ 7], -tNd[ 7], prog), time)); + m_object->SetAngleZ(3+4*i+2, Math::Smooth(m_object->RetAngleZ(3+4*i+2), Math::PropAngle( tSt[ 8], tNd[ 8], prog), time)); + m_object->SetAngleX(3+4*i+3, Math::Smooth(m_object->RetAngleX(3+4*i+3), Math::PropAngle(-tSt[ 9], -tNd[ 9], prog), time)); + m_object->SetAngleY(3+4*i+3, Math::Smooth(m_object->RetAngleY(3+4*i+3), Math::PropAngle(-tSt[10], -tNd[10], prog), time)); + m_object->SetAngleZ(3+4*i+3, Math::Smooth(m_object->RetAngleZ(3+4*i+3), Math::PropAngle( tSt[11], tNd[11], prog), time)); + } + } + +#if ADJUST_ANGLE + if ( m_object->RetSelect() ) + { + char s[100]; + sprintf(s, "A:time=%d Q:part=%d W:member=%d", m_armTimeIndex, m_armPartIndex, m_armMemberIndex); + m_engine->SetInfoText(4, s); + } +#endif + + if ( m_actionType == MSS_BURN ) // burning? + { + dir = Math::Vector(Math::PI, 0.0f, 0.0f); + SetCirVibration(dir); + dir = Math::Vector(0.0f, 0.0f, 0.0f); + SetLinVibration(dir); + SetInclinaison(dir); + + time = event.rTime*1.0f; + m_object->SetAngleZ(1, Math::Smooth(m_object->RetAngleZ(1), 0.0f, time)); // head + } + else if ( m_actionType == MSS_RUIN ) // destroyed? + { + dir = Math::Vector(0.0f, 0.0f, 0.0f); + SetLinVibration(dir); + SetCirVibration(dir); + SetInclinaison(dir); + } + else if ( m_actionType == MSS_EXPLO ) // exploded? + { + m_object->SetZoomY(1, 1.0f+m_progress); + m_object->SetZoomZ(1, 1.0f+m_progress); + m_object->SetZoomX(1, 1.0f+m_progress/2.0f); + + dir.x = (Math::Rand()-0.5f)*0.1f*m_progress; + dir.y = (Math::Rand()-0.5f)*0.1f*m_progress; + dir.z = (Math::Rand()-0.5f)*0.1f*m_progress; + m_object->SetCirVibration(dir); + } + else if ( m_actionType == MSS_BACK1 ) // turns on the back? + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) + { + m_lastParticule = m_armTimeAbs; + + pos = m_object->RetPosition(0); + speed.x = (Math::Rand()-0.5f)*10.0f; + speed.z = (Math::Rand()-0.5f)*10.0f; + speed.y = Math::Rand()*5.0f; + dim.x = Math::Rand()*3.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + + if ( m_progress < 0.5f ) + { + dir.x = 0.0f; + dir.y = powf(m_progress/0.5f, 2.0f)*12.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + else + { + dir.x = 0.0f; + dir.y = powf(2.0f-m_progress/0.5f, 2.0f)*12.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + dir.x = m_progress*Math::PI; + dir.y = 0.0f; + dir.z = 0.0f; + SetCirVibration(dir); + + dir = Math::Vector(0.0f, 0.0f, 0.0f); + SetInclinaison(dir); + + if ( m_progress >= 1.0f ) + { + SetAction(MSS_BACK2, 55.0f+Math::Rand()*10.0f); + } + } + else if ( m_actionType == MSS_BACK2 ) // moves on the back? + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) + { + m_lastParticule = m_armTimeAbs; + + if ( rand()%10 == 0 ) + { + pos = m_object->RetPosition(0); + pos.x += (Math::Rand()-0.5f)*8.0f; + pos.z += (Math::Rand()-0.5f)*8.0f; + pos.y -= 1.0f; + speed.x = (Math::Rand()-0.5f)*2.0f; + speed.z = (Math::Rand()-0.5f)*2.0f; + speed.y = Math::Rand()*2.0f; + dim.x = Math::Rand()*1.0f+1.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + } + + dir = Math::Vector(0.0f, 0.0f, 0.0f); + SetLinVibration(dir); + dir.x = sinf(m_armTimeAbs* 3.0f)*0.20f+ + sinf(m_armTimeAbs* 6.0f)*0.20f+ + sinf(m_armTimeAbs*10.0f)*0.20f+ + sinf(m_armTimeAbs*17.0f)*0.30f+Math::PI; + dir.y = sinf(m_armTimeAbs* 4.0f)*0.02f+ + sinf(m_armTimeAbs* 5.0f)*0.02f+ + sinf(m_armTimeAbs*11.0f)*0.02f+ + sinf(m_armTimeAbs*18.0f)*0.03f; + dir.z = sinf(m_armTimeAbs* 2.0f)*0.02f+ + sinf(m_armTimeAbs* 7.0f)*0.02f+ + sinf(m_armTimeAbs*13.0f)*0.02f+ + sinf(m_armTimeAbs*15.0f)*0.03f; + SetCirVibration(dir); + dir = Math::Vector(0.0f, 0.0f, 0.0f); + SetInclinaison(dir); + + m_object->SetAngleY(1, sinf(m_armTimeAbs*5.0f)*0.05f); // tail + m_object->SetAngleY(2, cosf(m_armTimeAbs*5.0f)*0.20f); // head + m_object->SetAngleZ(1, 0.4f); // tail + m_object->SetAngleZ(2, 0.0f); // head + + if ( m_progress >= 1.0f ) + { + SetAction(MSS_BACK3, 0.4f); + } + } + else if ( m_actionType == MSS_BACK3 ) // recovers on the legs? + { + if ( m_lastParticule+m_engine->ParticuleAdapt(0.05f) <= m_armTimeAbs ) + { + m_lastParticule = m_armTimeAbs; + + pos = m_object->RetPosition(0); + speed.x = (Math::Rand()-0.5f)*10.0f; + speed.z = (Math::Rand()-0.5f)*10.0f; + speed.y = Math::Rand()*5.0f; + dim.x = Math::Rand()*3.0f+2.0f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + + if ( m_progress < 0.5f ) + { + dir.x = 0.0f; + dir.y = powf(m_progress/0.5f, 2.0f)*5.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + else + { + dir.x = 0.0f; + dir.y = powf(2.0f-m_progress/0.5f, 2.0f)*5.0f; + dir.z = 0.0f; + SetLinVibration(dir); + } + dir.x = (1.0f-m_progress)*Math::PI; + dir.y = 0.0f; + dir.z = 0.0f; + SetCirVibration(dir); + + dir = Math::Vector(0.0f, 0.0f, 0.0f); + SetInclinaison(dir); + + if ( m_progress >= 1.0f ) + { + SetAction(-1); + m_object->SetFixed(false); // moving again + } + } + else + { + if ( bStop ) + { + dir = Math::Vector(0.0f, 0.0f, 0.0f); + SetInclinaison(dir); + } + else + { + a = Math::Mod(m_armMember, 1.0f); + if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1 + else a = 3.0f-4.0f*a; // 1..-1 + dir.x = sinf(a)*0.05f; + + s = Math::Mod(m_armMember/2.0f, 1.0f); + if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1 + else s = 3.0f-4.0f*s; // 1..-1 + dir.z = sinf(s)*0.1f; + + dir.y = 0.0f; + SetInclinaison(dir); + } + + dir = Math::Vector(0.0f, 0.0f, 0.0f); + SetLinVibration(dir); + SetCirVibration(dir); + + m_object->SetAngleZ(1, sinf(m_armTimeAbs*1.7f)*0.02f); // tail + m_object->SetAngleX(1, sinf(m_armTimeAbs*1.3f)*0.05f); + m_object->SetAngleY(1, sinf(m_armTimeAbs*2.4f)*0.10f); + m_object->SetZoom(1, 1.0f+sinf(m_armTimeAbs*3.3f)*0.05f); + + m_object->SetAngleZ(2, sinf(m_armTimeAbs*1.4f)*0.20f); // head + m_object->SetAngleX(2, sinf(m_armTimeAbs*1.9f)*0.10f); + m_object->SetAngleY(2, sinf(m_armTimeAbs*2.1f)*0.10f); + + m_object->SetAngleY(35, sinf(m_armTimeAbs*3.1f)*0.20f); // mandible + m_object->SetAngleY(36, -sinf(m_armTimeAbs*3.1f)*0.20f); // mandible + } + + return true; +} + + diff --git a/src/object/motion/motionspider.h b/src/object/motion/motionspider.h index 6b34974..e9f052c 100644 --- a/src/object/motion/motionspider.h +++ b/src/object/motion/motionspider.h @@ -1,71 +1,71 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motionspider.h
-
-#pragma once
-
-
-#include "object/motion/motion.h"
-
-
-
-enum MotionSpiderAction
-{
- MS_MARCH = 0,
- MS_STOP = 1,
- MS_SPEC = 2
-};
-
-enum MotionSpiderSpecialAction
-{
- MSS_BURN = 0,
- MSS_RUIN = 1,
- MSS_EXPLO = 2,
- MSS_BACK1 = 3,
- MSS_BACK2 = 4,
- MSS_BACK3 = 5
-};
-
-
-class CMotionSpider : public CMotion
-{
-public:
- CMotionSpider(CInstanceManager* iMan, CObject* object);
- ~CMotionSpider();
-
- void DeleteObject(bool bAll=false);
- bool Create(Math::Vector pos, float angle, ObjectType type, float power);
- bool EventProcess(const Event &event);
-
-protected:
- void CreatePhysics();
- bool EventFrame(const Event &event);
-
-protected:
- float m_armMember;
- float m_armTimeAbs;
- float m_armTimeMarch;
- float m_armTimeAction;
- short m_armAngles[3*4*4*3*3 + 3*4*4*6];
- int m_armTimeIndex;
- int m_armPartIndex;
- int m_armMemberIndex;
- int m_armLastAction;
- bool m_bArmStop;
- float m_lastParticule;
-};
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionspider.h + +#pragma once + + +#include "object/motion/motion.h" + + + +enum MotionSpiderAction +{ + MS_MARCH = 0, + MS_STOP = 1, + MS_SPEC = 2 +}; + +enum MotionSpiderSpecialAction +{ + MSS_BURN = 0, + MSS_RUIN = 1, + MSS_EXPLO = 2, + MSS_BACK1 = 3, + MSS_BACK2 = 4, + MSS_BACK3 = 5 +}; + + +class CMotionSpider : public CMotion +{ +public: + CMotionSpider(CInstanceManager* iMan, CObject* object); + ~CMotionSpider(); + + void DeleteObject(bool bAll=false); + bool Create(Math::Vector pos, float angle, ObjectType type, float power); + bool EventProcess(const Event &event); + +protected: + void CreatePhysics(); + bool EventFrame(const Event &event); + +protected: + float m_armMember; + float m_armTimeAbs; + float m_armTimeMarch; + float m_armTimeAction; + short m_armAngles[3*4*4*3*3 + 3*4*4*6]; + int m_armTimeIndex; + int m_armPartIndex; + int m_armMemberIndex; + int m_armLastAction; + bool m_bArmStop; + float m_lastParticule; +}; + diff --git a/src/object/motion/motiontoto.cpp b/src/object/motion/motiontoto.cpp index 71e872a..f64570e 100644 --- a/src/object/motion/motiontoto.cpp +++ b/src/object/motion/motiontoto.cpp @@ -1,869 +1,869 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motiontoto.cpp
-
-
-#include <stdio.h>
-
-#include "object/motion/motiontoto.h"
-
-#include "math/geometry.h"
-#include "old/terrain.h"
-#include "old/water.h"
-#include "old/modfile.h"
-#include "object/robotmain.h"
-
-
-
-const float START_TIME = 1000.0f; // beginning of the relative time
-
-
-
-// Object's constructor.
-
-CMotionToto::CMotionToto(CInstanceManager* iMan, CObject* object)
- : CMotion(iMan, object)
-{
- m_time = 0.0f;
- m_bDisplayInfo = false;
- m_bQuickPos = false;
- m_bStartAction = false;
- m_speedAction = 20.0f;
- m_soundChannel = -1;
- m_clownRadius = 0.0f;
- m_clownDelay = 0.0f;
- m_clownTime = 0.0f;
- m_blinkTime = 0.0f;
- m_blinkProgress = -1.0f;
- m_lastMotorParticule = 0.0f;
- m_type = OBJECT_NULL;
- m_mousePos = Math::Point(0.0f, 0.0f);
-}
-
-// Object's destructor.
-
-CMotionToto::~CMotionToto()
-{
-}
-
-
-// Removes an object.
-
-void CMotionToto::DeleteObject(bool bAll)
-{
- if ( m_soundChannel != -1 )
- {
- m_sound->Stop(m_soundChannel);
- m_soundChannel = -1;
- }
-}
-
-
-// Creates a vehicle traveling any lands on the ground.
-
-bool CMotionToto::Create(Math::Vector pos, float angle, ObjectType type,
- float power)
-{
- CModFile* pModFile;
- int rank;
-
- if ( m_engine->RetRestCreate() < 10 ) return false;
-
- pModFile = new CModFile(m_iMan);
-
- m_object->SetType(type);
-
- // Creates the head.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object
- m_object->SetObjectRank(0, rank);
- pModFile->ReadModel("objects\\toto1.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(0, pos);
- m_object->SetAngleY(0, angle);
-
- // Creates mouth.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\toto2.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(1.00f, 0.17f, 0.00f));
-
- // Creates the left eye.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 0);
- pModFile->ReadModel("objects\\toto3.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2, Math::Vector(0.85f, 1.04f, 0.25f));
- m_object->SetAngleY(2, -20.0f*Math::PI/180.0f);
-
- // Creates the right eye.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(3, rank);
- m_object->SetObjectParent(3, 0);
- pModFile->ReadModel("objects\\toto3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(3, Math::Vector(0.85f, 1.04f, -0.25f));
- m_object->SetAngleY(3, 20.0f*Math::PI/180.0f);
-
- // Creates left antenna.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(4, rank);
- m_object->SetObjectParent(4, 0);
- pModFile->ReadModel("objects\\toto4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(4, Math::Vector(0.0f, 1.9f, 0.3f));
- m_object->SetAngleX(4, 30.0f*Math::PI/180.0f);
-
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(5, rank);
- m_object->SetObjectParent(5, 4);
- pModFile->ReadModel("objects\\toto4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(5, Math::Vector(0.0f, 0.67f, 0.0f));
- m_object->SetAngleX(5, 30.0f*Math::PI/180.0f);
-
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(6, rank);
- m_object->SetObjectParent(6, 5);
- pModFile->ReadModel("objects\\toto5.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(6, Math::Vector(0.0f, 0.70f, 0.0f));
- m_object->SetAngleX(6, 30.0f*Math::PI/180.0f);
-
- // Creates right antenna.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(7, rank);
- m_object->SetObjectParent(7, 0);
- pModFile->ReadModel("objects\\toto4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(7, Math::Vector(0.0f, 1.9f, -0.3f));
- m_object->SetAngleX(7, -30.0f*Math::PI/180.0f);
-
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(8, rank);
- m_object->SetObjectParent(8, 7);
- pModFile->ReadModel("objects\\toto4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(8, Math::Vector(0.0f, 0.67f, 0.0f));
- m_object->SetAngleX(8, -30.0f*Math::PI/180.0f);
-
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(9, rank);
- m_object->SetObjectParent(9, 8);
- pModFile->ReadModel("objects\\toto5.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(9, Math::Vector(0.0f, 0.70f, 0.0f));
- m_object->SetAngleX(9, -30.0f*Math::PI/180.0f);
-
- m_object->SetZoom(0, 0.5f); // is little
- m_object->SetFloorHeight(0.0f);
-
- pos = m_object->RetPosition(0);
- m_object->SetPosition(0, pos); // to display the shadows immediately
-
- m_engine->LoadAllTexture();
-
- delete pModFile;
- return true;
-}
-
-
-// Beginning of the display of informations, with foo in the left margin.
-
-void CMotionToto::StartDisplayInfo()
-{
-return;
-//?
- m_bDisplayInfo = true;
-
- m_actionType = -1;
- m_actionTime = 0.0f;
- m_progress = 0.0f;
-
- m_object->SetAngleY(0, 0.0f);
- m_mousePos = Math::Point(0.5f, 0.5f);
-}
-
-// End of the display of informations.
-
-void CMotionToto::StopDisplayInfo()
-{
- m_bDisplayInfo = false;
- m_bQuickPos = true;
-}
-
-// Gives the position of the mouse.
-
-void CMotionToto::SetMousePos(Math::Point pos)
-{
- m_mousePos = pos;
-}
-
-
-// Management of an event.
-
-bool CMotionToto::EventProcess(const Event &event)
-{
- CMotion::EventProcess(event);
-
- if ( event.event == EVENT_FRAME )
- {
- return EventFrame(event);
- }
-
- return true;
-}
-
-// Management of an event.
-
-bool CMotionToto::EventFrame(const Event &event)
-{
- Math::Matrix* mat;
- Math::Vector eye, lookat, dir, perp, nPos, aPos, pos, speed;
- Math::Vector vibLin, vibCir, dirSpeed, aAntenna;
- Math::Point dim;
- POINT wDim;
- ParticuleType type;
- float progress, focus, distance, shift, verti, level, zoom;
- float aAngle, nAngle, mAngle, angle, linSpeed, cirSpeed;
- int sheet, i, r;
- bool bHidden;
-
- if ( m_engine->RetPause() &&
- !m_main->RetInfoLock() ) return true;
-
- if ( m_bDisplayInfo ) // "looks" mouse?
- {
- bHidden = false;
- }
- else
- {
- bHidden = false;
-
- if ( m_main->RetMovieLock() ) // current movie?
- {
- bHidden = true;
- }
- if ( !m_engine->RetTotoMode() )
- {
- if ( !m_main->RetEditLock() ) // current edition?
- {
- bHidden = true;
- }
- }
- }
-
- if ( bHidden )
- {
- nPos = m_object->RetPosition(0);
- m_terrain->MoveOnFloor(nPos, true);
- nPos.y -= 100.0f; // hidden under the ground!
- m_object->SetPosition(0, nPos);
- return true;
- }
-
- m_time += event.rTime;
- m_blinkTime -= event.rTime;
-
- progress = 0.0f;
- if ( m_actionType != -1 ) // current action?
- {
- if ( m_progress < 0.15f )
- {
- progress = m_progress/0.15f;
- }
- else if ( m_progress < 0.85f )
- {
- progress = 1.0f;
- }
- else
- {
- progress = (1.0f-m_progress)/0.15f;
- }
- }
-
- if ( m_progress >= 1.0f )
- {
- m_actionType = -1; // action ended
- m_actionTime = 0.0f;
- m_progress = 0.0f;
-
- m_clownTime = 0.0f;
- m_clownDelay = 0.0f;
- }
-
- focus = m_engine->RetFocus();
- eye = m_engine->RetEyePt();
- lookat = m_engine->RetLookatPt();
-
- vibLin = Math::Vector(0.0f, 0.0f, 0.0f);
- vibCir = Math::Vector(0.0f, 0.0f, 0.0f);
- aAntenna = Math::Vector(0.0f, 0.0f, 0.0f);
- aAntenna.x += 30.0f*Math::PI/180.0f;
-
- // Calculates the new position.
- if ( m_bDisplayInfo )
- {
- wDim = m_engine->RetDim();
- nPos.x = -4.0f*((float)wDim.x/(float)wDim.y)/(640.0f/480.0f);
- nPos.y = -0.5f;
- nPos.z = 7.0f; // in the left margin
-
- linSpeed = 0.0f;
- }
- else
- {
-#if 0
- distance = 30.0f-progress*24.5f; // remoteness
- shift = 18.0f-progress*15.4f; // shift is left
- verti = 10.0f-progress* 9.6f; // shift at the top
-#else
- distance = 30.0f-progress*18.0f; // remoteness
- shift = 18.0f-progress*11.0f; // shift is left
- verti = 10.0f-progress* 8.0f; // shift at the top
-#endif
-
- if ( m_actionType == -1 &&
- (m_type == OBJECT_HUMAN ||
- m_type == OBJECT_TECH ||
- m_type == OBJECT_MOBILEwa ||
- m_type == OBJECT_MOBILEta ||
- m_type == OBJECT_MOBILEfa ||
- m_type == OBJECT_MOBILEia ||
- m_type == OBJECT_MOBILEwc ||
- m_type == OBJECT_MOBILEtc ||
- m_type == OBJECT_MOBILEfc ||
- m_type == OBJECT_MOBILEic ||
- m_type == OBJECT_MOBILEwi ||
- m_type == OBJECT_MOBILEti ||
- m_type == OBJECT_MOBILEfi ||
- m_type == OBJECT_MOBILEii ||
- m_type == OBJECT_MOBILEws ||
- m_type == OBJECT_MOBILEts ||
- m_type == OBJECT_MOBILEfs ||
- m_type == OBJECT_MOBILEis ||
- m_type == OBJECT_MOBILErt ||
- m_type == OBJECT_MOBILErc ||
- m_type == OBJECT_MOBILErr ||
- m_type == OBJECT_MOBILErs ||
- m_type == OBJECT_MOBILEsa ||
- m_type == OBJECT_MOBILEwt ||
- m_type == OBJECT_MOBILEtt ||
- m_type == OBJECT_MOBILEft ||
- m_type == OBJECT_MOBILEit ||
- m_type == OBJECT_MOBILEdr ) ) // vehicle?
- {
- m_clownTime += event.rTime;
- if ( m_clownTime >= m_clownDelay )
- {
- if ( rand()%10 < 2 )
- {
- m_clownRadius = 2.0f+Math::Rand()*10.0f;
-//? m_clownDelay = m_clownRadius/(2.0f+Math::Rand()*2.0f);
- m_clownDelay = 1.5f+Math::Rand()*1.0f;
- }
- else
- {
- m_clownRadius = 0.0f;
- m_clownDelay = 2.0f+Math::Rand()*2.0f;
- }
- pos = m_object->RetPosition(0);
- if ( pos.y < m_water->RetLevel() ) // underwater?
- {
- m_clownRadius /= 1.5f;
- m_clownDelay *= 2.0f;
- }
- m_clownTime = 0.0f;
- }
- else
- {
- distance -= m_clownRadius*sinf(m_clownTime*Math::PI*2.0f/m_clownDelay);
- shift -= m_clownRadius-m_clownRadius*cosf(m_clownTime*Math::PI*2.0f/m_clownDelay);
- }
-
- verti += (18.0f-shift)*0.2f;
- }
-
- distance /= focus;
-//? shift *= focus;
- verti /= focus;
-
- dir = Normalize(lookat-eye);
- nPos = eye + dir*distance;
-
- perp.x = -dir.z;
- perp.y = dir.y;
- perp.z = dir.x;
- nPos = nPos + perp*shift;
-
- nPos.y += verti;
-
- if ( m_bQuickPos ) // immediately in place?
- {
- m_bQuickPos = false;
- linSpeed = 0.0f;
- }
- else
- {
- aPos = m_object->RetPosition(0);
- if ( m_actionType == -1 )
- {
- level = 4.0f;
- }
- else
- {
- if ( m_bStartAction )
- {
- m_bStartAction = false;
- m_speedAction = Math::Distance(nPos, aPos)/15.0f;
- if ( m_speedAction < 20.0f ) m_speedAction = 20.0f;
- }
- level = m_speedAction;
- }
- if ( level > 1.0f/event.rTime ) level = 1.0f/event.rTime;
- nPos = aPos + (nPos-aPos)*event.rTime*level; // progression aPos -> nPos
-
- linSpeed = Math::DistanceProjected(nPos, aPos)/event.rTime;
- dirSpeed = (nPos-aPos)/event.rTime;
- nPos.y -= linSpeed*0.015f*(1.0f-progress); // at ground level if moving fast
- }
- }
-
- // Calculate the new angle.
- nAngle = Math::NormAngle(Math::RotateAngle(eye.x-lookat.x, lookat.z-eye.z)-0.9f);
- if ( linSpeed == 0.0f || m_actionType != -1 )
- {
- mAngle = nAngle;
- }
- else
- {
- mAngle = Math::NormAngle(Math::RotateAngle(dirSpeed.x, -dirSpeed.z));
- }
- level = Math::Min(linSpeed*0.1f, 1.0f);
- nAngle = nAngle*(1.0f-level) + mAngle*level;
- aAngle = Math::NormAngle(m_object->RetAngleY(0));
-
- if ( nAngle < aAngle )
- {
- if ( nAngle+Math::PI*2.0f-aAngle < aAngle-nAngle ) nAngle += Math::PI*2.0f;
- }
- else
- {
- if ( aAngle+Math::PI*2.0f-nAngle < nAngle-aAngle ) aAngle += Math::PI*2.0f;
- }
- nAngle = aAngle + (nAngle-aAngle)*event.rTime*4.0f;
-
- // Leans quotes if running.
- cirSpeed = (aAngle-nAngle)/event.rTime;
- angle = cirSpeed*0.3f*(1.0f-progress);
- if ( angle > 0.7f ) angle = 0.7f;
- if ( angle < -0.7f ) angle = -0.7f;
- vibCir.x += angle*1.5f;
- aAntenna.x += fabs(angle)*0.8f; // deviates
-
- // Leans forward so quickly advance.
- angle = linSpeed*0.10f*(1.0f-progress);
- if ( angle > 1.0f ) angle = 1.0f;
- vibCir.z -= angle/2.0f; // leans forward
- aAntenna.z -= angle; // leans forward
-
- // Calculates the residual motion.
-#if 1
- vibLin.y += (sinf(m_time*2.00f)*0.5f+
- sinf(m_time*2.11f)*0.2f)*(1.0f-progress);
-
- vibCir.z += sinf(m_time*Math::PI* 2.01f)*(Math::PI/ 75.0f)+
- sinf(m_time*Math::PI* 2.51f)*(Math::PI/100.0f)+
- sinf(m_time*Math::PI*19.01f)*(Math::PI/200.0f);
-
- vibCir.x += sinf(m_time*Math::PI* 2.03f)*(Math::PI/ 75.0f)+
- sinf(m_time*Math::PI* 2.52f)*(Math::PI/100.0f)+
- sinf(m_time*Math::PI*19.53f)*(Math::PI/200.0f);
-
- vibCir.y += (sinf(m_time*Math::PI* 1.07f)*(Math::PI/ 10.0f)+
- sinf(m_time*Math::PI* 1.19f)*(Math::PI/ 17.0f)+
- sinf(m_time*Math::PI* 1.57f)*(Math::PI/ 31.0f))*(1.0f-progress);
-#endif
-
- // Calculates the animations in action.
- if ( m_actionType == MT_ERROR ) // no-no?
- {
- vibCir.y += progress*sinf(m_progress*Math::PI*11.0f)*1.0f;
- vibCir.z -= progress*0.5f; // leans forward
-
- aAntenna.x -= progress*0.4f; // narrows
- aAntenna.z += progress*1.0f; // leaning back
- }
-
- if ( m_actionType == MT_WARNING ) // warning?
- {
- vibCir.x += progress*sinf(m_progress*Math::PI*17.0f)*0.5f;
-
- aAntenna.x += progress*sinf(m_progress*Math::PI*17.0f)*0.5f; // deviates
- aAntenna.z += progress*cosf(m_progress*Math::PI*17.0f)*0.5f; // turns
- }
-
- if ( m_actionType == MT_INFO ) // yes-yes?
- {
- vibCir.z += progress*sinf(m_progress*Math::PI*19.0f)*0.7f;
-
- aAntenna.x -= progress*0.2f; // narrows
- aAntenna.z -= progress*cosf(m_progress*Math::PI*19.0f)*0.9f; // turns
- }
-
- if ( m_actionType == MT_MESSAGE ) // message?
- {
- vibCir.x += progress*sinf(m_progress*Math::PI*15.0f)*0.3f;
- vibCir.z += progress*cosf(m_progress*Math::PI*15.0f)*0.3f;
-
- aAntenna.x -= progress*0.4f; // narrows
- aAntenna.z -= progress*cosf(m_progress*Math::PI*19.0f)*0.8f;
- }
-
- // Initialize the object.
- if ( m_bDisplayInfo ) // "looks" mouse?
- {
- if ( m_mousePos.x < 0.15f )
- {
- progress = 1.0f-m_mousePos.x/0.15f;
- vibCir.y += progress*Math::PI/2.0f;
- }
- else
- {
- progress = (m_mousePos.x-0.15f)/0.85f;
- vibCir.y -= progress*Math::PI/3.0f;
- }
-
- angle = Math::RotateAngle(m_mousePos.x-0.1f, m_mousePos.y-0.5f-vibLin.y*0.2f);
- if ( angle < Math::PI )
- {
- if ( angle > Math::PI*0.5f ) angle = Math::PI-angle;
- if ( angle > Math::PI*0.3f ) angle = Math::PI*0.3f;
- vibCir.z += angle;
- }
- else
- {
- angle = Math::PI*2.0f-angle;
- if ( angle > Math::PI*0.5f ) angle = Math::PI-angle;
- if ( angle > Math::PI*0.3f ) angle = Math::PI*0.3f;
- vibCir.z -= angle;
- }
- }
- else
- {
- nPos.y += vibLin.y;
- level = m_terrain->RetFloorLevel(nPos);
- if ( nPos.y < level+2.0f )
- {
- nPos.y = level+2.0f; // just above the ground
- }
- nPos.y -= vibLin.y;
- }
- m_object->SetPosition(0, nPos);
- m_object->SetAngleY(0, nAngle);
-
- SetLinVibration(vibLin);
- SetCirVibration(vibCir);
-
- // Calculates the residual movement of the antennas.
- pos = aAntenna*0.40f;
- pos.x += sinf(m_time*Math::PI*2.07f)*(Math::PI/50.0f)+
- sinf(m_time*Math::PI*2.59f)*(Math::PI/70.0f)+
- sinf(m_time*Math::PI*2.67f)*(Math::PI/90.0f);
-
- pos.y += sinf(m_time*Math::PI*2.22f)*(Math::PI/50.0f)+
- sinf(m_time*Math::PI*2.36f)*(Math::PI/70.0f)+
- sinf(m_time*Math::PI*3.01f)*(Math::PI/90.0f);
-
- pos.z += sinf(m_time*Math::PI*2.11f)*(Math::PI/50.0f)+
- sinf(m_time*Math::PI*2.83f)*(Math::PI/70.0f)+
- sinf(m_time*Math::PI*3.09f)*(Math::PI/90.0f);
-
- m_object->SetAngle(4, pos); // left antenna
- m_object->SetAngle(5, pos); // left antenna
- m_object->SetAngle(6, pos); // left antenna
-
- pos = aAntenna*0.40f;
- pos.x = -pos.x;
- pos.x += sinf(m_time*Math::PI*2.33f)*(Math::PI/50.0f)+
- sinf(m_time*Math::PI*2.19f)*(Math::PI/70.0f)+
- sinf(m_time*Math::PI*2.07f)*(Math::PI/90.0f);
-
- pos.y += sinf(m_time*Math::PI*2.44f)*(Math::PI/50.0f)+
- sinf(m_time*Math::PI*2.77f)*(Math::PI/70.0f)+
- sinf(m_time*Math::PI*3.22f)*(Math::PI/90.0f);
-
- pos.z += sinf(m_time*Math::PI*2.05f)*(Math::PI/50.0f)+
- sinf(m_time*Math::PI*2.38f)*(Math::PI/70.0f)+
- sinf(m_time*Math::PI*2.79f)*(Math::PI/90.0f);
-
- m_object->SetAngle(7, pos); // right antenna
- m_object->SetAngle(8, pos); // right antenna
- m_object->SetAngle(9, pos); // right antenna
-
- // Movement of the mouth.
- if ( m_actionType == MT_ERROR ) // no-no?
- {
- m_object->SetAngleX(1, 0.0f);
- m_object->SetAngleZ(1, 0.2f+sinf(m_time*10.0f)*0.2f);
- m_object->SetZoomY(1, 2.0f+sinf(m_time*10.0f));
- m_object->SetZoomZ(1, 1.0f);
- }
- else if ( m_actionType == MT_WARNING ) // warning?
- {
- m_object->SetAngleX(1, 15.0f*Math::PI/180.0f);
- m_object->SetAngleZ(1, 0.0f);
- m_object->SetZoomY(1, 1.0f);
- m_object->SetZoomZ(1, 1.0f);
- }
- else if ( m_actionType == MT_INFO ) // yes-yes?
- {
- m_object->SetAngleX(1, 0.0f);
- m_object->SetAngleZ(1, 0.0f);
- m_object->SetZoomY(1, 1.0f);
- m_object->SetZoomZ(1, 0.7f+sinf(m_time*10.0f)*0.3f);
- }
- else if ( m_actionType == MT_MESSAGE ) // message?
- {
- m_object->SetAngleX(1, 0.0f);
- m_object->SetAngleZ(1, 0.0f);
- m_object->SetZoomY(1, 1.0f);
- m_object->SetZoomZ(1, 0.8f+sinf(m_time*7.0f)*0.2f);
- }
- else
- {
- m_object->SetAngleX(1, 0.0f);
- m_object->SetAngleZ(1, 0.0f);
- m_object->SetZoomY(1, 1.0f);
- m_object->SetZoomZ(1, 1.0f);
- }
-
- // Eye blinking management.
- if ( m_blinkTime <= 0.0f && m_blinkProgress == -1.0f )
- {
- m_blinkProgress = 0.0f;
- }
-
- if ( m_blinkProgress >= 0.0f )
- {
- m_blinkProgress += event.rTime*3.2f;
-
- if ( m_blinkProgress < 1.0f )
- {
- if ( m_blinkProgress < 0.5f ) zoom = m_blinkProgress/0.5f;
- else zoom = 2.0f-m_blinkProgress/0.5f;
- m_object->SetZoomY(2, 1.0f-zoom*0.9f);
- m_object->SetZoomY(3, 1.0f-zoom*0.9f);
- }
- else
- {
- m_blinkProgress = -1.0f;
- m_blinkTime = 0.1f+Math::Rand()*4.0f;
- m_object->SetZoomY(2, 1.0f);
- m_object->SetZoomY(3, 1.0f);
- }
- }
-
- if ( m_actionType == MT_ERROR ) // no-no?
- {
- m_object->SetAngleX(2, -30.0f*Math::PI/180.0f);
- m_object->SetAngleX(3, 30.0f*Math::PI/180.0f);
- }
- else if ( m_actionType == MT_WARNING ) // warning?
- {
- m_object->SetAngleX(2, -15.0f*Math::PI/180.0f);
- m_object->SetAngleX(3, 15.0f*Math::PI/180.0f);
- }
- else if ( m_actionType == MT_INFO ) // yes-yes?
- {
- m_object->SetAngleX(2, 40.0f*Math::PI/180.0f);
- m_object->SetAngleX(3, -40.0f*Math::PI/180.0f);
- }
- else if ( m_actionType == MT_MESSAGE ) // message?
- {
- m_object->SetAngleX(2, 20.0f*Math::PI/180.0f);
- m_object->SetAngleX(3, -20.0f*Math::PI/180.0f);
- }
- else
- {
- m_object->SetAngleX(2, 0.0f);
- m_object->SetAngleX(3, 0.0f);
- }
-
- mat = m_object->RetWorldMatrix(0); // must be done every time!
-
- // Generates particles.
- if ( m_time-m_lastMotorParticule >= m_engine->ParticuleAdapt(0.05f) )
- {
- m_lastMotorParticule = m_time;
-
- if ( m_bDisplayInfo ) sheet = SH_FRONT;
- else sheet = SH_WORLD;
-
- pos = m_object->RetPosition(0);
- if ( !m_bDisplayInfo &&
- pos.y < m_water->RetLevel() ) // underwater?
- {
- float t = Math::Mod(m_time, 3.5f);
- if ( t >= 2.2f || ( t >= 1.2f && t <= 1.4f ) ) // breathe?
- {
- pos = Math::Vector(1.0f, 0.2f, 0.0f);
- pos.z += (Math::Rand()-0.5f)*0.5f;
-
- speed = pos;
- speed.y += 5.0f+Math::Rand()*5.0f;
- speed.x += Math::Rand()*2.0f;
- speed.z += (Math::Rand()-0.5f)*2.0f;
-
- pos = Transform(*mat, pos);
- speed = Transform(*mat, speed)-pos;
-
- dim.x = 0.12f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIBUBBLE, 3.0f, 0.0f, 0.0f);
- }
- }
- else // out of water?
- {
- pos = Math::Vector(0.0f, -0.5f, 0.0f);
- pos.z += (Math::Rand()-0.5f)*0.5f;
-
- speed = pos;
- speed.y -= (1.5f+Math::Rand()*1.5f) + vibLin.y;
- speed.x += (Math::Rand()-0.5f)*2.0f;
- speed.z += (Math::Rand()-0.5f)*2.0f;
-
-// mat = m_object->RetWorldMatrix(0);
- pos = Transform(*mat, pos);
- speed = Transform(*mat, speed)-pos;
-
- dim.x = (Math::Rand()*0.4f+0.4f)*(1.0f+Math::Min(linSpeed*0.1f, 5.0f));
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTITOTO, 1.0f+Math::Rand()*1.0f, 0.0f, 1.0f, sheet);
- }
-
- if ( m_actionType != -1 && // current action?
- m_progress <= 0.85f )
- {
- pos.x = (Math::Rand()-0.5f)*1.0f;
- pos.y = (Math::Rand()-0.5f)*1.0f+3.5f;
- pos.z = (Math::Rand()-0.5f)*1.0f;
- pos = Transform(*mat, pos);
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = (Math::Rand()*0.3f+0.3f);
- dim.y = dim.x;
- if ( m_actionType == MT_ERROR ) type = PARTIERROR;
- if ( m_actionType == MT_WARNING ) type = PARTIWARNING;
- if ( m_actionType == MT_INFO ) type = PARTIINFO;
- if ( m_actionType == MT_MESSAGE ) type = PARTIWARNING;
- m_particule->CreateParticule(pos, speed, dim, type, 0.5f+Math::Rand()*0.5f, 0.0f, 1.0f, sheet);
-
- pos.x = 0.50f+(Math::Rand()-0.5f)*0.80f;
- pos.y = 0.86f+(Math::Rand()-0.5f)*0.08f;
- pos.z = 0.00f;
- dim.x = (Math::Rand()*0.04f+0.04f);
- dim.y = dim.x/0.75f;
- m_particule->CreateParticule(pos, speed, dim, type, 0.5f+Math::Rand()*0.5f, 0.0f, 1.0f, SH_INTERFACE);
- }
-
-//? if ( m_bDisplayInfo && m_main->RetGlint() )
- if ( false )
- {
- pos.x = (Math::Rand()-0.5f)*1.4f;
- pos.y = (Math::Rand()-0.5f)*1.4f+3.5f;
- pos.z = (Math::Rand()-0.5f)*1.4f;
- pos = Transform(*mat, pos);
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = (Math::Rand()*0.5f+0.5f);
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIERROR, 0.5f+Math::Rand()*0.5f, 0.0f, 1.0f, sheet);
-
- for ( i=0 ; i<10 ; i++ )
- {
- pos.x = 0.60f+(Math::Rand()-0.5f)*0.76f;
- pos.y = 0.47f+(Math::Rand()-0.5f)*0.90f;
- pos.z = 0.00f;
- r = rand()%4;
- if ( r == 0 ) pos.x = 0.21f; // the left edge
- else if ( r == 1 ) pos.x = 0.98f; // the right edge
- else if ( r == 2 ) pos.y = 0.02f; // on the lower edge
- else pos.y = 0.92f; // on the upper edge
- dim.x = (Math::Rand()*0.02f+0.02f);
- dim.y = dim.x/0.75f;
- m_particule->CreateParticule(pos, speed, dim, PARTIERROR, 0.5f+Math::Rand()*0.5f, 0.0f, 1.0f, SH_INTERFACE);
- }
- }
- }
-
- // Move the sound.
- if ( m_soundChannel != -1 )
- {
- if ( !m_sound->Position(m_soundChannel, m_object->RetPosition(0)) )
- {
- m_soundChannel = -1;
- }
- }
-
- return true;
-}
-
-
-// Starts an action.
-
-Error CMotionToto::SetAction(int action, float time)
-{
- Sound sound;
-
- CMotion::SetAction(action, time);
-
- m_bStartAction = true;
-
- sound = SOUND_CLICK;
- if ( action == MT_ERROR ) sound = SOUND_ERROR;
- if ( action == MT_WARNING ) sound = SOUND_WARNING;
- if ( action == MT_INFO ) sound = SOUND_INFO;
- if ( action == MT_MESSAGE ) sound = SOUND_MESSAGE;
-
- if ( sound != SOUND_CLICK )
- {
- m_soundChannel = m_sound->Play(sound, m_object->RetPosition(0));
- }
-
- return ERR_OK;
-}
-
-// Specifies the type of the object is attached to toto.
-
-void CMotionToto::SetLinkType(ObjectType type)
-{
- m_type = type;
-}
-
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motiontoto.cpp + + +#include <stdio.h> + +#include "object/motion/motiontoto.h" + +#include "math/geometry.h" +#include "old/terrain.h" +#include "old/water.h" +#include "old/modfile.h" +#include "object/robotmain.h" + + + +const float START_TIME = 1000.0f; // beginning of the relative time + + + +// Object's constructor. + +CMotionToto::CMotionToto(CInstanceManager* iMan, CObject* object) + : CMotion(iMan, object) +{ + m_time = 0.0f; + m_bDisplayInfo = false; + m_bQuickPos = false; + m_bStartAction = false; + m_speedAction = 20.0f; + m_soundChannel = -1; + m_clownRadius = 0.0f; + m_clownDelay = 0.0f; + m_clownTime = 0.0f; + m_blinkTime = 0.0f; + m_blinkProgress = -1.0f; + m_lastMotorParticule = 0.0f; + m_type = OBJECT_NULL; + m_mousePos = Math::Point(0.0f, 0.0f); +} + +// Object's destructor. + +CMotionToto::~CMotionToto() +{ +} + + +// Removes an object. + +void CMotionToto::DeleteObject(bool bAll) +{ + if ( m_soundChannel != -1 ) + { + m_sound->Stop(m_soundChannel); + m_soundChannel = -1; + } +} + + +// Creates a vehicle traveling any lands on the ground. + +bool CMotionToto::Create(Math::Vector pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + int rank; + + if ( m_engine->RetRestCreate() < 10 ) return false; + + pModFile = new CModFile(m_iMan); + + m_object->SetType(type); + + // Creates the head. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + pModFile->ReadModel("objects\\toto1.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(0, pos); + m_object->SetAngleY(0, angle); + + // Creates mouth. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\toto2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(1.00f, 0.17f, 0.00f)); + + // Creates the left eye. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\toto3.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, Math::Vector(0.85f, 1.04f, 0.25f)); + m_object->SetAngleY(2, -20.0f*Math::PI/180.0f); + + // Creates the right eye. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 0); + pModFile->ReadModel("objects\\toto3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, Math::Vector(0.85f, 1.04f, -0.25f)); + m_object->SetAngleY(3, 20.0f*Math::PI/180.0f); + + // Creates left antenna. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(4, rank); + m_object->SetObjectParent(4, 0); + pModFile->ReadModel("objects\\toto4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(4, Math::Vector(0.0f, 1.9f, 0.3f)); + m_object->SetAngleX(4, 30.0f*Math::PI/180.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(5, rank); + m_object->SetObjectParent(5, 4); + pModFile->ReadModel("objects\\toto4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(5, Math::Vector(0.0f, 0.67f, 0.0f)); + m_object->SetAngleX(5, 30.0f*Math::PI/180.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 5); + pModFile->ReadModel("objects\\toto5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, Math::Vector(0.0f, 0.70f, 0.0f)); + m_object->SetAngleX(6, 30.0f*Math::PI/180.0f); + + // Creates right antenna. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\toto4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, Math::Vector(0.0f, 1.9f, -0.3f)); + m_object->SetAngleX(7, -30.0f*Math::PI/180.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 7); + pModFile->ReadModel("objects\\toto4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, Math::Vector(0.0f, 0.67f, 0.0f)); + m_object->SetAngleX(8, -30.0f*Math::PI/180.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(9, rank); + m_object->SetObjectParent(9, 8); + pModFile->ReadModel("objects\\toto5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(9, Math::Vector(0.0f, 0.70f, 0.0f)); + m_object->SetAngleX(9, -30.0f*Math::PI/180.0f); + + m_object->SetZoom(0, 0.5f); // is little + m_object->SetFloorHeight(0.0f); + + pos = m_object->RetPosition(0); + m_object->SetPosition(0, pos); // to display the shadows immediately + + m_engine->LoadAllTexture(); + + delete pModFile; + return true; +} + + +// Beginning of the display of informations, with foo in the left margin. + +void CMotionToto::StartDisplayInfo() +{ +return; +//? + m_bDisplayInfo = true; + + m_actionType = -1; + m_actionTime = 0.0f; + m_progress = 0.0f; + + m_object->SetAngleY(0, 0.0f); + m_mousePos = Math::Point(0.5f, 0.5f); +} + +// End of the display of informations. + +void CMotionToto::StopDisplayInfo() +{ + m_bDisplayInfo = false; + m_bQuickPos = true; +} + +// Gives the position of the mouse. + +void CMotionToto::SetMousePos(Math::Point pos) +{ + m_mousePos = pos; +} + + +// Management of an event. + +bool CMotionToto::EventProcess(const Event &event) +{ + CMotion::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + return true; +} + +// Management of an event. + +bool CMotionToto::EventFrame(const Event &event) +{ + Math::Matrix* mat; + Math::Vector eye, lookat, dir, perp, nPos, aPos, pos, speed; + Math::Vector vibLin, vibCir, dirSpeed, aAntenna; + Math::Point dim; + POINT wDim; + ParticuleType type; + float progress, focus, distance, shift, verti, level, zoom; + float aAngle, nAngle, mAngle, angle, linSpeed, cirSpeed; + int sheet, i, r; + bool bHidden; + + if ( m_engine->RetPause() && + !m_main->RetInfoLock() ) return true; + + if ( m_bDisplayInfo ) // "looks" mouse? + { + bHidden = false; + } + else + { + bHidden = false; + + if ( m_main->RetMovieLock() ) // current movie? + { + bHidden = true; + } + if ( !m_engine->RetTotoMode() ) + { + if ( !m_main->RetEditLock() ) // current edition? + { + bHidden = true; + } + } + } + + if ( bHidden ) + { + nPos = m_object->RetPosition(0); + m_terrain->MoveOnFloor(nPos, true); + nPos.y -= 100.0f; // hidden under the ground! + m_object->SetPosition(0, nPos); + return true; + } + + m_time += event.rTime; + m_blinkTime -= event.rTime; + + progress = 0.0f; + if ( m_actionType != -1 ) // current action? + { + if ( m_progress < 0.15f ) + { + progress = m_progress/0.15f; + } + else if ( m_progress < 0.85f ) + { + progress = 1.0f; + } + else + { + progress = (1.0f-m_progress)/0.15f; + } + } + + if ( m_progress >= 1.0f ) + { + m_actionType = -1; // action ended + m_actionTime = 0.0f; + m_progress = 0.0f; + + m_clownTime = 0.0f; + m_clownDelay = 0.0f; + } + + focus = m_engine->RetFocus(); + eye = m_engine->RetEyePt(); + lookat = m_engine->RetLookatPt(); + + vibLin = Math::Vector(0.0f, 0.0f, 0.0f); + vibCir = Math::Vector(0.0f, 0.0f, 0.0f); + aAntenna = Math::Vector(0.0f, 0.0f, 0.0f); + aAntenna.x += 30.0f*Math::PI/180.0f; + + // Calculates the new position. + if ( m_bDisplayInfo ) + { + wDim = m_engine->RetDim(); + nPos.x = -4.0f*((float)wDim.x/(float)wDim.y)/(640.0f/480.0f); + nPos.y = -0.5f; + nPos.z = 7.0f; // in the left margin + + linSpeed = 0.0f; + } + else + { +#if 0 + distance = 30.0f-progress*24.5f; // remoteness + shift = 18.0f-progress*15.4f; // shift is left + verti = 10.0f-progress* 9.6f; // shift at the top +#else + distance = 30.0f-progress*18.0f; // remoteness + shift = 18.0f-progress*11.0f; // shift is left + verti = 10.0f-progress* 8.0f; // shift at the top +#endif + + if ( m_actionType == -1 && + (m_type == OBJECT_HUMAN || + m_type == OBJECT_TECH || + m_type == OBJECT_MOBILEwa || + m_type == OBJECT_MOBILEta || + m_type == OBJECT_MOBILEfa || + m_type == OBJECT_MOBILEia || + m_type == OBJECT_MOBILEwc || + m_type == OBJECT_MOBILEtc || + m_type == OBJECT_MOBILEfc || + m_type == OBJECT_MOBILEic || + m_type == OBJECT_MOBILEwi || + m_type == OBJECT_MOBILEti || + m_type == OBJECT_MOBILEfi || + m_type == OBJECT_MOBILEii || + m_type == OBJECT_MOBILEws || + m_type == OBJECT_MOBILEts || + m_type == OBJECT_MOBILEfs || + m_type == OBJECT_MOBILEis || + m_type == OBJECT_MOBILErt || + m_type == OBJECT_MOBILErc || + m_type == OBJECT_MOBILErr || + m_type == OBJECT_MOBILErs || + m_type == OBJECT_MOBILEsa || + m_type == OBJECT_MOBILEwt || + m_type == OBJECT_MOBILEtt || + m_type == OBJECT_MOBILEft || + m_type == OBJECT_MOBILEit || + m_type == OBJECT_MOBILEdr ) ) // vehicle? + { + m_clownTime += event.rTime; + if ( m_clownTime >= m_clownDelay ) + { + if ( rand()%10 < 2 ) + { + m_clownRadius = 2.0f+Math::Rand()*10.0f; +//? m_clownDelay = m_clownRadius/(2.0f+Math::Rand()*2.0f); + m_clownDelay = 1.5f+Math::Rand()*1.0f; + } + else + { + m_clownRadius = 0.0f; + m_clownDelay = 2.0f+Math::Rand()*2.0f; + } + pos = m_object->RetPosition(0); + if ( pos.y < m_water->RetLevel() ) // underwater? + { + m_clownRadius /= 1.5f; + m_clownDelay *= 2.0f; + } + m_clownTime = 0.0f; + } + else + { + distance -= m_clownRadius*sinf(m_clownTime*Math::PI*2.0f/m_clownDelay); + shift -= m_clownRadius-m_clownRadius*cosf(m_clownTime*Math::PI*2.0f/m_clownDelay); + } + + verti += (18.0f-shift)*0.2f; + } + + distance /= focus; +//? shift *= focus; + verti /= focus; + + dir = Normalize(lookat-eye); + nPos = eye + dir*distance; + + perp.x = -dir.z; + perp.y = dir.y; + perp.z = dir.x; + nPos = nPos + perp*shift; + + nPos.y += verti; + + if ( m_bQuickPos ) // immediately in place? + { + m_bQuickPos = false; + linSpeed = 0.0f; + } + else + { + aPos = m_object->RetPosition(0); + if ( m_actionType == -1 ) + { + level = 4.0f; + } + else + { + if ( m_bStartAction ) + { + m_bStartAction = false; + m_speedAction = Math::Distance(nPos, aPos)/15.0f; + if ( m_speedAction < 20.0f ) m_speedAction = 20.0f; + } + level = m_speedAction; + } + if ( level > 1.0f/event.rTime ) level = 1.0f/event.rTime; + nPos = aPos + (nPos-aPos)*event.rTime*level; // progression aPos -> nPos + + linSpeed = Math::DistanceProjected(nPos, aPos)/event.rTime; + dirSpeed = (nPos-aPos)/event.rTime; + nPos.y -= linSpeed*0.015f*(1.0f-progress); // at ground level if moving fast + } + } + + // Calculate the new angle. + nAngle = Math::NormAngle(Math::RotateAngle(eye.x-lookat.x, lookat.z-eye.z)-0.9f); + if ( linSpeed == 0.0f || m_actionType != -1 ) + { + mAngle = nAngle; + } + else + { + mAngle = Math::NormAngle(Math::RotateAngle(dirSpeed.x, -dirSpeed.z)); + } + level = Math::Min(linSpeed*0.1f, 1.0f); + nAngle = nAngle*(1.0f-level) + mAngle*level; + aAngle = Math::NormAngle(m_object->RetAngleY(0)); + + if ( nAngle < aAngle ) + { + if ( nAngle+Math::PI*2.0f-aAngle < aAngle-nAngle ) nAngle += Math::PI*2.0f; + } + else + { + if ( aAngle+Math::PI*2.0f-nAngle < nAngle-aAngle ) aAngle += Math::PI*2.0f; + } + nAngle = aAngle + (nAngle-aAngle)*event.rTime*4.0f; + + // Leans quotes if running. + cirSpeed = (aAngle-nAngle)/event.rTime; + angle = cirSpeed*0.3f*(1.0f-progress); + if ( angle > 0.7f ) angle = 0.7f; + if ( angle < -0.7f ) angle = -0.7f; + vibCir.x += angle*1.5f; + aAntenna.x += fabs(angle)*0.8f; // deviates + + // Leans forward so quickly advance. + angle = linSpeed*0.10f*(1.0f-progress); + if ( angle > 1.0f ) angle = 1.0f; + vibCir.z -= angle/2.0f; // leans forward + aAntenna.z -= angle; // leans forward + + // Calculates the residual motion. +#if 1 + vibLin.y += (sinf(m_time*2.00f)*0.5f+ + sinf(m_time*2.11f)*0.2f)*(1.0f-progress); + + vibCir.z += sinf(m_time*Math::PI* 2.01f)*(Math::PI/ 75.0f)+ + sinf(m_time*Math::PI* 2.51f)*(Math::PI/100.0f)+ + sinf(m_time*Math::PI*19.01f)*(Math::PI/200.0f); + + vibCir.x += sinf(m_time*Math::PI* 2.03f)*(Math::PI/ 75.0f)+ + sinf(m_time*Math::PI* 2.52f)*(Math::PI/100.0f)+ + sinf(m_time*Math::PI*19.53f)*(Math::PI/200.0f); + + vibCir.y += (sinf(m_time*Math::PI* 1.07f)*(Math::PI/ 10.0f)+ + sinf(m_time*Math::PI* 1.19f)*(Math::PI/ 17.0f)+ + sinf(m_time*Math::PI* 1.57f)*(Math::PI/ 31.0f))*(1.0f-progress); +#endif + + // Calculates the animations in action. + if ( m_actionType == MT_ERROR ) // no-no? + { + vibCir.y += progress*sinf(m_progress*Math::PI*11.0f)*1.0f; + vibCir.z -= progress*0.5f; // leans forward + + aAntenna.x -= progress*0.4f; // narrows + aAntenna.z += progress*1.0f; // leaning back + } + + if ( m_actionType == MT_WARNING ) // warning? + { + vibCir.x += progress*sinf(m_progress*Math::PI*17.0f)*0.5f; + + aAntenna.x += progress*sinf(m_progress*Math::PI*17.0f)*0.5f; // deviates + aAntenna.z += progress*cosf(m_progress*Math::PI*17.0f)*0.5f; // turns + } + + if ( m_actionType == MT_INFO ) // yes-yes? + { + vibCir.z += progress*sinf(m_progress*Math::PI*19.0f)*0.7f; + + aAntenna.x -= progress*0.2f; // narrows + aAntenna.z -= progress*cosf(m_progress*Math::PI*19.0f)*0.9f; // turns + } + + if ( m_actionType == MT_MESSAGE ) // message? + { + vibCir.x += progress*sinf(m_progress*Math::PI*15.0f)*0.3f; + vibCir.z += progress*cosf(m_progress*Math::PI*15.0f)*0.3f; + + aAntenna.x -= progress*0.4f; // narrows + aAntenna.z -= progress*cosf(m_progress*Math::PI*19.0f)*0.8f; + } + + // Initialize the object. + if ( m_bDisplayInfo ) // "looks" mouse? + { + if ( m_mousePos.x < 0.15f ) + { + progress = 1.0f-m_mousePos.x/0.15f; + vibCir.y += progress*Math::PI/2.0f; + } + else + { + progress = (m_mousePos.x-0.15f)/0.85f; + vibCir.y -= progress*Math::PI/3.0f; + } + + angle = Math::RotateAngle(m_mousePos.x-0.1f, m_mousePos.y-0.5f-vibLin.y*0.2f); + if ( angle < Math::PI ) + { + if ( angle > Math::PI*0.5f ) angle = Math::PI-angle; + if ( angle > Math::PI*0.3f ) angle = Math::PI*0.3f; + vibCir.z += angle; + } + else + { + angle = Math::PI*2.0f-angle; + if ( angle > Math::PI*0.5f ) angle = Math::PI-angle; + if ( angle > Math::PI*0.3f ) angle = Math::PI*0.3f; + vibCir.z -= angle; + } + } + else + { + nPos.y += vibLin.y; + level = m_terrain->RetFloorLevel(nPos); + if ( nPos.y < level+2.0f ) + { + nPos.y = level+2.0f; // just above the ground + } + nPos.y -= vibLin.y; + } + m_object->SetPosition(0, nPos); + m_object->SetAngleY(0, nAngle); + + SetLinVibration(vibLin); + SetCirVibration(vibCir); + + // Calculates the residual movement of the antennas. + pos = aAntenna*0.40f; + pos.x += sinf(m_time*Math::PI*2.07f)*(Math::PI/50.0f)+ + sinf(m_time*Math::PI*2.59f)*(Math::PI/70.0f)+ + sinf(m_time*Math::PI*2.67f)*(Math::PI/90.0f); + + pos.y += sinf(m_time*Math::PI*2.22f)*(Math::PI/50.0f)+ + sinf(m_time*Math::PI*2.36f)*(Math::PI/70.0f)+ + sinf(m_time*Math::PI*3.01f)*(Math::PI/90.0f); + + pos.z += sinf(m_time*Math::PI*2.11f)*(Math::PI/50.0f)+ + sinf(m_time*Math::PI*2.83f)*(Math::PI/70.0f)+ + sinf(m_time*Math::PI*3.09f)*(Math::PI/90.0f); + + m_object->SetAngle(4, pos); // left antenna + m_object->SetAngle(5, pos); // left antenna + m_object->SetAngle(6, pos); // left antenna + + pos = aAntenna*0.40f; + pos.x = -pos.x; + pos.x += sinf(m_time*Math::PI*2.33f)*(Math::PI/50.0f)+ + sinf(m_time*Math::PI*2.19f)*(Math::PI/70.0f)+ + sinf(m_time*Math::PI*2.07f)*(Math::PI/90.0f); + + pos.y += sinf(m_time*Math::PI*2.44f)*(Math::PI/50.0f)+ + sinf(m_time*Math::PI*2.77f)*(Math::PI/70.0f)+ + sinf(m_time*Math::PI*3.22f)*(Math::PI/90.0f); + + pos.z += sinf(m_time*Math::PI*2.05f)*(Math::PI/50.0f)+ + sinf(m_time*Math::PI*2.38f)*(Math::PI/70.0f)+ + sinf(m_time*Math::PI*2.79f)*(Math::PI/90.0f); + + m_object->SetAngle(7, pos); // right antenna + m_object->SetAngle(8, pos); // right antenna + m_object->SetAngle(9, pos); // right antenna + + // Movement of the mouth. + if ( m_actionType == MT_ERROR ) // no-no? + { + m_object->SetAngleX(1, 0.0f); + m_object->SetAngleZ(1, 0.2f+sinf(m_time*10.0f)*0.2f); + m_object->SetZoomY(1, 2.0f+sinf(m_time*10.0f)); + m_object->SetZoomZ(1, 1.0f); + } + else if ( m_actionType == MT_WARNING ) // warning? + { + m_object->SetAngleX(1, 15.0f*Math::PI/180.0f); + m_object->SetAngleZ(1, 0.0f); + m_object->SetZoomY(1, 1.0f); + m_object->SetZoomZ(1, 1.0f); + } + else if ( m_actionType == MT_INFO ) // yes-yes? + { + m_object->SetAngleX(1, 0.0f); + m_object->SetAngleZ(1, 0.0f); + m_object->SetZoomY(1, 1.0f); + m_object->SetZoomZ(1, 0.7f+sinf(m_time*10.0f)*0.3f); + } + else if ( m_actionType == MT_MESSAGE ) // message? + { + m_object->SetAngleX(1, 0.0f); + m_object->SetAngleZ(1, 0.0f); + m_object->SetZoomY(1, 1.0f); + m_object->SetZoomZ(1, 0.8f+sinf(m_time*7.0f)*0.2f); + } + else + { + m_object->SetAngleX(1, 0.0f); + m_object->SetAngleZ(1, 0.0f); + m_object->SetZoomY(1, 1.0f); + m_object->SetZoomZ(1, 1.0f); + } + + // Eye blinking management. + if ( m_blinkTime <= 0.0f && m_blinkProgress == -1.0f ) + { + m_blinkProgress = 0.0f; + } + + if ( m_blinkProgress >= 0.0f ) + { + m_blinkProgress += event.rTime*3.2f; + + if ( m_blinkProgress < 1.0f ) + { + if ( m_blinkProgress < 0.5f ) zoom = m_blinkProgress/0.5f; + else zoom = 2.0f-m_blinkProgress/0.5f; + m_object->SetZoomY(2, 1.0f-zoom*0.9f); + m_object->SetZoomY(3, 1.0f-zoom*0.9f); + } + else + { + m_blinkProgress = -1.0f; + m_blinkTime = 0.1f+Math::Rand()*4.0f; + m_object->SetZoomY(2, 1.0f); + m_object->SetZoomY(3, 1.0f); + } + } + + if ( m_actionType == MT_ERROR ) // no-no? + { + m_object->SetAngleX(2, -30.0f*Math::PI/180.0f); + m_object->SetAngleX(3, 30.0f*Math::PI/180.0f); + } + else if ( m_actionType == MT_WARNING ) // warning? + { + m_object->SetAngleX(2, -15.0f*Math::PI/180.0f); + m_object->SetAngleX(3, 15.0f*Math::PI/180.0f); + } + else if ( m_actionType == MT_INFO ) // yes-yes? + { + m_object->SetAngleX(2, 40.0f*Math::PI/180.0f); + m_object->SetAngleX(3, -40.0f*Math::PI/180.0f); + } + else if ( m_actionType == MT_MESSAGE ) // message? + { + m_object->SetAngleX(2, 20.0f*Math::PI/180.0f); + m_object->SetAngleX(3, -20.0f*Math::PI/180.0f); + } + else + { + m_object->SetAngleX(2, 0.0f); + m_object->SetAngleX(3, 0.0f); + } + + mat = m_object->RetWorldMatrix(0); // must be done every time! + + // Generates particles. + if ( m_time-m_lastMotorParticule >= m_engine->ParticuleAdapt(0.05f) ) + { + m_lastMotorParticule = m_time; + + if ( m_bDisplayInfo ) sheet = SH_FRONT; + else sheet = SH_WORLD; + + pos = m_object->RetPosition(0); + if ( !m_bDisplayInfo && + pos.y < m_water->RetLevel() ) // underwater? + { + float t = Math::Mod(m_time, 3.5f); + if ( t >= 2.2f || ( t >= 1.2f && t <= 1.4f ) ) // breathe? + { + pos = Math::Vector(1.0f, 0.2f, 0.0f); + pos.z += (Math::Rand()-0.5f)*0.5f; + + speed = pos; + speed.y += 5.0f+Math::Rand()*5.0f; + speed.x += Math::Rand()*2.0f; + speed.z += (Math::Rand()-0.5f)*2.0f; + + pos = Transform(*mat, pos); + speed = Transform(*mat, speed)-pos; + + dim.x = 0.12f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIBUBBLE, 3.0f, 0.0f, 0.0f); + } + } + else // out of water? + { + pos = Math::Vector(0.0f, -0.5f, 0.0f); + pos.z += (Math::Rand()-0.5f)*0.5f; + + speed = pos; + speed.y -= (1.5f+Math::Rand()*1.5f) + vibLin.y; + speed.x += (Math::Rand()-0.5f)*2.0f; + speed.z += (Math::Rand()-0.5f)*2.0f; + +// mat = m_object->RetWorldMatrix(0); + pos = Transform(*mat, pos); + speed = Transform(*mat, speed)-pos; + + dim.x = (Math::Rand()*0.4f+0.4f)*(1.0f+Math::Min(linSpeed*0.1f, 5.0f)); + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTITOTO, 1.0f+Math::Rand()*1.0f, 0.0f, 1.0f, sheet); + } + + if ( m_actionType != -1 && // current action? + m_progress <= 0.85f ) + { + pos.x = (Math::Rand()-0.5f)*1.0f; + pos.y = (Math::Rand()-0.5f)*1.0f+3.5f; + pos.z = (Math::Rand()-0.5f)*1.0f; + pos = Transform(*mat, pos); + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = (Math::Rand()*0.3f+0.3f); + dim.y = dim.x; + if ( m_actionType == MT_ERROR ) type = PARTIERROR; + if ( m_actionType == MT_WARNING ) type = PARTIWARNING; + if ( m_actionType == MT_INFO ) type = PARTIINFO; + if ( m_actionType == MT_MESSAGE ) type = PARTIWARNING; + m_particule->CreateParticule(pos, speed, dim, type, 0.5f+Math::Rand()*0.5f, 0.0f, 1.0f, sheet); + + pos.x = 0.50f+(Math::Rand()-0.5f)*0.80f; + pos.y = 0.86f+(Math::Rand()-0.5f)*0.08f; + pos.z = 0.00f; + dim.x = (Math::Rand()*0.04f+0.04f); + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, type, 0.5f+Math::Rand()*0.5f, 0.0f, 1.0f, SH_INTERFACE); + } + +//? if ( m_bDisplayInfo && m_main->RetGlint() ) + if ( false ) + { + pos.x = (Math::Rand()-0.5f)*1.4f; + pos.y = (Math::Rand()-0.5f)*1.4f+3.5f; + pos.z = (Math::Rand()-0.5f)*1.4f; + pos = Transform(*mat, pos); + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = (Math::Rand()*0.5f+0.5f); + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIERROR, 0.5f+Math::Rand()*0.5f, 0.0f, 1.0f, sheet); + + for ( i=0 ; i<10 ; i++ ) + { + pos.x = 0.60f+(Math::Rand()-0.5f)*0.76f; + pos.y = 0.47f+(Math::Rand()-0.5f)*0.90f; + pos.z = 0.00f; + r = rand()%4; + if ( r == 0 ) pos.x = 0.21f; // the left edge + else if ( r == 1 ) pos.x = 0.98f; // the right edge + else if ( r == 2 ) pos.y = 0.02f; // on the lower edge + else pos.y = 0.92f; // on the upper edge + dim.x = (Math::Rand()*0.02f+0.02f); + dim.y = dim.x/0.75f; + m_particule->CreateParticule(pos, speed, dim, PARTIERROR, 0.5f+Math::Rand()*0.5f, 0.0f, 1.0f, SH_INTERFACE); + } + } + } + + // Move the sound. + if ( m_soundChannel != -1 ) + { + if ( !m_sound->Position(m_soundChannel, m_object->RetPosition(0)) ) + { + m_soundChannel = -1; + } + } + + return true; +} + + +// Starts an action. + +Error CMotionToto::SetAction(int action, float time) +{ + Sound sound; + + CMotion::SetAction(action, time); + + m_bStartAction = true; + + sound = SOUND_CLICK; + if ( action == MT_ERROR ) sound = SOUND_ERROR; + if ( action == MT_WARNING ) sound = SOUND_WARNING; + if ( action == MT_INFO ) sound = SOUND_INFO; + if ( action == MT_MESSAGE ) sound = SOUND_MESSAGE; + + if ( sound != SOUND_CLICK ) + { + m_soundChannel = m_sound->Play(sound, m_object->RetPosition(0)); + } + + return ERR_OK; +} + +// Specifies the type of the object is attached to toto. + +void CMotionToto::SetLinkType(ObjectType type) +{ + m_type = type; +} + + diff --git a/src/object/motion/motiontoto.h b/src/object/motion/motiontoto.h index 8edeec0..9df2d99 100644 --- a/src/object/motion/motiontoto.h +++ b/src/object/motion/motiontoto.h @@ -1,70 +1,70 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motiontoto.h
-
-#pragma once
-
-
-#include "object/motion/motion.h"
-
-
-
-enum MotionTotoAction
-{
- MT_ERROR = 0,
- MT_WARNING = 1,
- MT_INFO = 2,
- MT_MESSAGE = 3
-};
-
-
-class CMotionToto : public CMotion
-{
-public:
- CMotionToto(CInstanceManager* iMan, CObject* object);
- ~CMotionToto();
-
- void DeleteObject(bool bAll=false);
- bool Create(Math::Vector pos, float angle, ObjectType type, float power);
- bool EventProcess(const Event &event);
- Error SetAction(int action, float time=0.2f);
- void SetLinkType(ObjectType type);
-
- void StartDisplayInfo();
- void StopDisplayInfo();
- void SetMousePos(Math::Point pos);
-
-protected:
- bool EventFrame(const Event &event);
-
-protected:
- float m_time;
- float m_lastMotorParticule;
- bool m_bDisplayInfo;
- bool m_bQuickPos;
- bool m_bStartAction;
- float m_speedAction;
- float m_clownRadius;
- float m_clownDelay;
- float m_clownTime;
- float m_blinkTime;
- float m_blinkProgress;
- int m_soundChannel;
- ObjectType m_type;
- Math::Point m_mousePos;
-};
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motiontoto.h + +#pragma once + + +#include "object/motion/motion.h" + + + +enum MotionTotoAction +{ + MT_ERROR = 0, + MT_WARNING = 1, + MT_INFO = 2, + MT_MESSAGE = 3 +}; + + +class CMotionToto : public CMotion +{ +public: + CMotionToto(CInstanceManager* iMan, CObject* object); + ~CMotionToto(); + + void DeleteObject(bool bAll=false); + bool Create(Math::Vector pos, float angle, ObjectType type, float power); + bool EventProcess(const Event &event); + Error SetAction(int action, float time=0.2f); + void SetLinkType(ObjectType type); + + void StartDisplayInfo(); + void StopDisplayInfo(); + void SetMousePos(Math::Point pos); + +protected: + bool EventFrame(const Event &event); + +protected: + float m_time; + float m_lastMotorParticule; + bool m_bDisplayInfo; + bool m_bQuickPos; + bool m_bStartAction; + float m_speedAction; + float m_clownRadius; + float m_clownDelay; + float m_clownTime; + float m_blinkTime; + float m_blinkProgress; + int m_soundChannel; + ObjectType m_type; + Math::Point m_mousePos; +}; + diff --git a/src/object/motion/motionvehicle.cpp b/src/object/motion/motionvehicle.cpp index 6f96991..ff05695 100644 --- a/src/object/motion/motionvehicle.cpp +++ b/src/object/motion/motionvehicle.cpp @@ -1,2073 +1,2073 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motionvehicle.cpp
-
-
-#include <stdio.h>
-
-#include "object/motion/motionvehicle.h"
-
-#include "old/modfile.h"
-#include "old/particule.h"
-#include "old/terrain.h"
-#include "math/geometry.h"
-#include "object/brain.h"
-#include "physics/physics.h"
-
-
-
-
-
-
-// Object's constructor.
-
-CMotionVehicle::CMotionVehicle(CInstanceManager* iMan, CObject* object)
- : CMotion(iMan, object)
-{
- int i;
-
- for ( i=0 ; i<4 ; i++ )
- {
- m_wheelTurn[i] = 0.0f;
- }
- for ( i=0 ; i<3 ; i++ )
- {
- m_flyPaw[i] = 0.0f;
- }
- m_posTrackLeft = 0.0f;
- m_posTrackRight = 0.0f;
- m_partiReactor = -1;
- m_armTimeAbs = 1000.0f;
- m_armMember = 1000.0f;
- m_canonTime = 0.0f;
- m_lastTimeCanon = 0.0f;
- m_wheelLastPos = Math::Vector(0.0f, 0.0f, 0.0f);
- m_wheelLastAngle = Math::Vector(0.0f, 0.0f, 0.0f);
- m_posKey = Math::Vector(0.0f, 0.0f, 0.0f);
- m_bFlyFix = false;
-
- m_bTraceDown = false;
- m_traceColor = 1; // black
- m_traceWidth = 0.5f;
-}
-
-// Object's destructor.
-
-CMotionVehicle::~CMotionVehicle()
-{
-}
-
-
-// Removes an object.
-
-void CMotionVehicle::DeleteObject(bool bAll)
-{
- if ( m_partiReactor != -1 )
- {
- m_particule->DeleteParticule(m_partiReactor);
- m_partiReactor = -1;
- }
-}
-
-
-// Creates a vehicle traveling any lands on the ground.
-
-bool CMotionVehicle::Create(Math::Vector pos, float angle, ObjectType type,
- float power)
-{
- CModFile* pModFile;
- CObject* pPower;
- int rank, i, j, parent;
- D3DCOLORVALUE color;
- char name[50];
-
- if ( m_engine->RetRestCreate() < 1+5+18+1 ) return false;
-
- pModFile = new CModFile(m_iMan);
-
- m_object->SetType(type);
-
- // Creates the main base.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object
- m_object->SetObjectRank(0, rank);
-
- if ( type == OBJECT_MOBILEfa ||
- type == OBJECT_MOBILEfc ||
- type == OBJECT_MOBILEfi ||
- type == OBJECT_MOBILEfs )
- {
- pModFile->ReadModel("objects\\lem1f.mod");
- }
- if ( type == OBJECT_MOBILEta ||
- type == OBJECT_MOBILEtc ||
- type == OBJECT_MOBILEti ||
- type == OBJECT_MOBILEts )
- {
- pModFile->ReadModel("objects\\lem1t.mod");
- }
- if ( type == OBJECT_MOBILEwa ||
- type == OBJECT_MOBILEwc ||
- type == OBJECT_MOBILEwi ||
- type == OBJECT_MOBILEws )
- {
- if ( m_object->RetTrainer() )
- {
- pModFile->ReadModel("objects\\lem1wt.mod");
- }
- else
- {
- pModFile->ReadModel("objects\\lem1w.mod");
- }
- }
- if ( type == OBJECT_MOBILEia ||
- type == OBJECT_MOBILEic ||
- type == OBJECT_MOBILEii ||
- type == OBJECT_MOBILEis )
- {
- pModFile->ReadModel("objects\\lem1i.mod");
- }
- if ( type == OBJECT_MOBILErt ||
- type == OBJECT_MOBILErc ||
- type == OBJECT_MOBILErr ||
- type == OBJECT_MOBILErs )
- {
- pModFile->ReadModel("objects\\roller1.mod");
- }
- if ( type == OBJECT_MOBILEsa )
- {
- pModFile->ReadModel("objects\\subm1.mod");
- }
- if ( type == OBJECT_MOBILEtg )
- {
- pModFile->ReadModel("objects\\target.mod");
- }
- if ( type == OBJECT_MOBILEwt )
- {
- pModFile->ReadModel("objects\\trainerw.mod");
- }
- if ( type == OBJECT_MOBILEft )
- {
- pModFile->ReadModel("objects\\trainerf.mod");
- }
- if ( type == OBJECT_MOBILEtt )
- {
- pModFile->ReadModel("objects\\trainert.mod");
- }
- if ( type == OBJECT_MOBILEit )
- {
- pModFile->ReadModel("objects\\traineri.mod");
- }
- if ( type == OBJECT_MOBILEdr )
- {
- pModFile->ReadModel("objects\\drawer1.mod");
- }
- if ( type == OBJECT_APOLLO2 )
- {
- pModFile->ReadModel("objects\\apolloj1.mod");
- }
- pModFile->CreateEngineObject(rank);
-
- m_object->SetPosition(0, pos);
- m_object->SetAngleY(0, angle);
-
- // A vehicle must have a obligatory collision
- // with a sphere of center (0, y, 0) (see GetCrashSphere).
- if ( type == OBJECT_MOBILErt ||
- type == OBJECT_MOBILErc ||
- type == OBJECT_MOBILErr ||
- type == OBJECT_MOBILErs )
- {
- m_object->CreateCrashSphere(Math::Vector(0.0f, 4.0f, 0.0f), 6.5f, SOUND_BOUMm, 0.45f);
- m_object->SetGlobalSphere(Math::Vector(0.0f, 3.0f, 0.0f), 7.0f);
- }
- else if ( type == OBJECT_MOBILEsa )
- {
- m_object->CreateCrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 4.5f, SOUND_BOUMm, 0.45f);
- m_object->SetGlobalSphere(Math::Vector(0.0f, 3.0f, 0.0f), 6.0f);
- }
- else if ( type == OBJECT_MOBILEdr )
- {
- m_object->CreateCrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f);
- m_object->SetGlobalSphere(Math::Vector(0.0f, 3.0f, 0.0f), 7.0f);
- }
- else if ( type == OBJECT_APOLLO2 )
- {
- m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 8.0f, SOUND_BOUMm, 0.45f);
- }
- else
- {
- m_object->CreateCrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 4.5f, SOUND_BOUMm, 0.45f);
- m_object->SetGlobalSphere(Math::Vector(0.0f, 4.0f, 0.0f), 6.0f);
- }
-
- if ( type == OBJECT_MOBILEfa ||
- type == OBJECT_MOBILEta ||
- type == OBJECT_MOBILEwa ||
- type == OBJECT_MOBILEia )
- {
- // Creates the arm.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\lem2.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(0.0f, 5.3f, 0.0f));
- m_object->SetAngleZ(1, ARM_NEUTRAL_ANGLE1);
-
- // Creates the forearm.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 1);
- pModFile->ReadModel("objects\\lem3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2, Math::Vector(5.0f, 0.0f, 0.0f));
- m_object->SetAngleZ(2, ARM_NEUTRAL_ANGLE2);
-
- // Creates the hand.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(3, rank);
- m_object->SetObjectParent(3, 2);
- pModFile->ReadModel("objects\\lem4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(3, Math::Vector(3.5f, 0.0f, 0.0f));
- m_object->SetAngleZ(3, ARM_NEUTRAL_ANGLE3);
- m_object->SetAngleX(3, Math::PI/2.0f);
-
- // Creates the close clamp.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(4, rank);
- m_object->SetObjectParent(4, 3);
- pModFile->ReadModel("objects\\lem5.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(4, Math::Vector(1.5f, 0.0f, 0.0f));
- m_object->SetAngleZ(4, -Math::PI*0.10f);
-
- // Creates the remote clamp.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(5, rank);
- m_object->SetObjectParent(5, 3);
- pModFile->ReadModel("objects\\lem6.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(5, Math::Vector(1.5f, 0.0f, 0.0f));
- m_object->SetAngleZ(5, Math::PI*0.10f);
- }
-
- if ( type == OBJECT_MOBILEfs ||
- type == OBJECT_MOBILEts ||
- type == OBJECT_MOBILEws ||
- type == OBJECT_MOBILEis )
- {
- // Creates the arm.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\lem2.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(0.0f, 5.3f, 0.0f));
- m_object->SetAngleZ(1, 110.0f*Math::PI/180.0f);
-
- // Creates the forearm.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 1);
- pModFile->ReadModel("objects\\lem3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2, Math::Vector(5.0f, 0.0f, 0.0f));
- m_object->SetAngleZ(2, -110.0f*Math::PI/180.0f);
-
- // Creates the sensor.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(3, rank);
- m_object->SetObjectParent(3, 2);
- pModFile->ReadModel("objects\\lem4s.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(3, Math::Vector(3.5f, 0.0f, 0.0f));
- m_object->SetAngleZ(3, -65.0f*Math::PI/180.0f);
- }
-
- if ( type == OBJECT_MOBILEfc ||
- type == OBJECT_MOBILEtc ||
- type == OBJECT_MOBILEwc ||
- type == OBJECT_MOBILEic )
- {
- // Creates the cannon.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\canon.mod");
- pModFile->CreateEngineObject(rank);
-//? m_object->SetPosition(1, Math::Vector(0.0f, 5.3f, 0.0f));
- m_object->SetPosition(1, Math::Vector(0.0f, 5.3f, 0.0f));
- m_object->SetAngleZ(1, 0.0f);
- }
-
- if ( type == OBJECT_MOBILEfi ||
- type == OBJECT_MOBILEti ||
- type == OBJECT_MOBILEwi ||
- type == OBJECT_MOBILEii )
- {
- // Creates the insect cannon.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\canoni1.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(0.0f, 5.3f, 0.0f));
- m_object->SetAngleZ(1, 0.0f);
-
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 1);
- pModFile->ReadModel("objects\\canoni2.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2, Math::Vector(0.0f, 2.5f, 0.0f));
- m_object->SetAngleZ(2, 0.0f);
- }
-
- if ( type == OBJECT_MOBILEwa ||
- type == OBJECT_MOBILEwc ||
- type == OBJECT_MOBILEws ||
- type == OBJECT_MOBILEwi ||
- type == OBJECT_MOBILEwt )
- {
- // Creates the right-back wheel.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(6, rank);
- m_object->SetObjectParent(6, 0);
- pModFile->ReadModel("objects\\lem2w.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(6, Math::Vector(-3.0f, 1.0f, -3.0f));
-
- // Creates the left-back wheel.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(7, rank);
- m_object->SetObjectParent(7, 0);
- pModFile->ReadModel("objects\\lem2w.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(7, Math::Vector(-3.0f, 1.0f, 3.0f));
- m_object->SetAngleY(7, Math::PI);
-
- // Creates the right-front wheel.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(8, rank);
- m_object->SetObjectParent(8, 0);
- pModFile->ReadModel("objects\\lem2w.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(8, Math::Vector(2.0f, 1.0f, -3.0f));
-
- // Creates the left-front wheel.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(9, rank);
- m_object->SetObjectParent(9, 0);
- pModFile->ReadModel("objects\\lem2w.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(9, Math::Vector(2.0f, 1.0f, 3.0f));
- m_object->SetAngleY(9, Math::PI);
- }
-
- if ( type == OBJECT_MOBILEtg )
- {
- // Creates the right-back wheel.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(6, rank);
- m_object->SetObjectParent(6, 0);
- pModFile->ReadModel("objects\\lem2w.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(6, Math::Vector(-2.0f, 1.0f, -3.0f));
-
- // Creates the left-back wheel.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(7, rank);
- m_object->SetObjectParent(7, 0);
- pModFile->ReadModel("objects\\lem2w.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(7, Math::Vector(-2.0f, 1.0f, 3.0f));
- m_object->SetAngleY(7, Math::PI);
-
- // Creates the right-front wheel.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(8, rank);
- m_object->SetObjectParent(8, 0);
- pModFile->ReadModel("objects\\lem2w.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(8, Math::Vector(3.0f, 1.0f, -3.0f));
-
- // Creates the left-front wheel.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(9, rank);
- m_object->SetObjectParent(9, 0);
- pModFile->ReadModel("objects\\lem2w.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(9, Math::Vector(3.0f, 1.0f, 3.0f));
- m_object->SetAngleY(9, Math::PI);
- }
-
- if ( type == OBJECT_MOBILEta ||
- type == OBJECT_MOBILEtc ||
- type == OBJECT_MOBILEti ||
- type == OBJECT_MOBILEts ) // caterpillars?
- {
- // Creates the right caterpillar.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(6, rank);
- m_object->SetObjectParent(6, 0);
- pModFile->ReadModel("objects\\lem2t.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(6, Math::Vector(0.0f, 2.0f, -3.0f));
-
- // Creates the left caterpillar.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(7, rank);
- m_object->SetObjectParent(7, 0);
- pModFile->ReadModel("objects\\lem3t.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(7, Math::Vector(0.0f, 2.0f, 3.0f));
- }
-
- if ( type == OBJECT_MOBILErt ||
- type == OBJECT_MOBILErc ||
- type == OBJECT_MOBILErr ||
- type == OBJECT_MOBILErs ) // large caterpillars?
- {
- // Creates the right caterpillar.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(6, rank);
- m_object->SetObjectParent(6, 0);
- pModFile->ReadModel("objects\\roller2.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(6, Math::Vector(0.0f, 2.0f, -3.0f));
-
- // Creates the left caterpillar.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(7, rank);
- m_object->SetObjectParent(7, 0);
- pModFile->ReadModel("objects\\roller3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(7, Math::Vector(0.0f, 2.0f, 3.0f));
- }
-
- if ( type == OBJECT_MOBILEsa ) // underwater caterpillars?
- {
- // Creates the right caterpillar.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(6, rank);
- m_object->SetObjectParent(6, 0);
- pModFile->ReadModel("objects\\subm4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(6, Math::Vector(0.0f, 1.0f, -3.0f));
-
- // Creates the left caterpillar.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(7, rank);
- m_object->SetObjectParent(7, 0);
- pModFile->ReadModel("objects\\subm5.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(7, Math::Vector(0.0f, 1.0f, 3.0f));
- }
-
- if ( type == OBJECT_MOBILEdr ) // caterpillars?
- {
- // Creates the right caterpillar.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(6, rank);
- m_object->SetObjectParent(6, 0);
- pModFile->ReadModel("objects\\drawer2.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(6, Math::Vector(0.0f, 1.0f, -3.0f));
-
- // Creates the left caterpillar.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(7, rank);
- m_object->SetObjectParent(7, 0);
- pModFile->ReadModel("objects\\drawer3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(7, Math::Vector(0.0f, 1.0f, 3.0f));
- }
-
- if ( type == OBJECT_MOBILEfa ||
- type == OBJECT_MOBILEfc ||
- type == OBJECT_MOBILEfs ||
- type == OBJECT_MOBILEfi ||
- type == OBJECT_MOBILEft ) // flying?
- {
- // Creates the front foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(6, rank);
- m_object->SetObjectParent(6, 0);
- pModFile->ReadModel("objects\\lem2f.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(6, Math::Vector(1.7f, 3.0f, 0.0f));
-
- // Creates the right-back foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(7, rank);
- m_object->SetObjectParent(7, 0);
- pModFile->ReadModel("objects\\lem2f.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(7, Math::Vector(-1.8f, 3.0f, -1.5f));
- m_object->SetAngleY(7, 120.0f*Math::PI/180.0f);
-
- // Creates the left-back foot.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(8, rank);
- m_object->SetObjectParent(8, 0);
- pModFile->ReadModel("objects\\lem2f.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(8, Math::Vector(-1.8f, 3.0f, 1.5f));
- m_object->SetAngleY(8, -120.0f*Math::PI/180.0f);
- }
-
- if ( type == OBJECT_MOBILEia ||
- type == OBJECT_MOBILEic ||
- type == OBJECT_MOBILEis ||
- type == OBJECT_MOBILEii ) // insect legs?
- {
- float table[] =
- {
- // x y z
- -1.5f, 1.2f, -0.7f, // back leg
- 0.0f, 0.0f, -1.0f,
- 0.0f, 0.0f, -2.0f,
-
- 0.0f, 1.2f, -0.9f, // middle leg
- 0.0f, 0.0f, -1.0f,
- 0.0f, 0.0f, -2.0f,
-
- 1.5f, 1.2f, -0.7f, // front leg
- 0.0f, 0.0f, -1.0f,
- 0.0f, 0.0f, -2.0f,
- };
-
- for ( i=0 ; i<3 ; i++ )
- {
- for ( j=0 ; j<3 ; j++ )
- {
- sprintf(name, "objects\\ant%d.mod", j+4); // 4..6
-
- // Creates the right leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(6+i*3+j, rank);
- if ( j == 0 ) parent = 0;
- else parent = 6+i*3+j-1;
- m_object->SetObjectParent(6+i*3+j, parent);
- pModFile->ReadModel(name);
- pModFile->CreateEngineObject(rank);
- pos.x = table[i*9+j*3+0];
- pos.y = table[i*9+j*3+1];
- pos.z = table[i*9+j*3+2];
- m_object->SetPosition(6+i*3+j, pos);
-
- // Creates the left leg.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(15+i*3+j, rank);
- if ( j == 0 ) parent = 0;
- else parent = 15+i*3+j-1;
- m_object->SetObjectParent(15+i*3+j, parent);
- pModFile->ReadModel(name);
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- pos.x = table[i*9+j*3+0];
- pos.y = table[i*9+j*3+1];
- pos.z = -table[i*9+j*3+2];
- m_object->SetPosition(15+i*3+j, pos);
- }
- }
- }
-
- if ( type == OBJECT_MOBILErt )
- {
- // Creates the holder.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\roller2t.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(0.0f, 0.0f, 0.0f));
- m_object->SetAngleZ(1, 0.0f);
-
- // Creates the pestle.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 0);
- pModFile->ReadModel("objects\\roller3t.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2, Math::Vector(9.0f, 4.0f, 0.0f));
- m_object->SetAngleZ(2, 0.0f);
- }
-
- if ( type == OBJECT_MOBILErc )
- {
- // Creates the holder.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\roller2c.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(3.0f, 4.6f, 0.0f));
- m_object->SetAngleZ(1, Math::PI/8.0f);
-
- // Creates the cannon.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 0);
- pModFile->ReadModel("objects\\roller3p.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2, Math::Vector(7.0f, 6.5f, 0.0f));
- m_object->SetAngleZ(2, 0.0f);
- }
-
- if ( type == OBJECT_MOBILErr )
- {
- // Creates the holder.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\recover1.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(2.0f, 5.0f, 0.0f));
-
- // Creates the right arm.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 1);
- pModFile->ReadModel("objects\\recover2.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2, Math::Vector(0.1f, 0.0f, -5.0f));
- m_object->SetAngleZ(2, 126.0f*Math::PI/180.0f);
-
- // Creates the right forearm.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(3, rank);
- m_object->SetObjectParent(3, 2);
- pModFile->ReadModel("objects\\recover3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(3, Math::Vector(5.0f, 0.0f, -0.5f));
- m_object->SetAngleZ(3, -144.0f*Math::PI/180.0f);
-
- // Creates the left arm.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(4, rank);
- m_object->SetObjectParent(4, 1);
- pModFile->ReadModel("objects\\recover2.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(4, Math::Vector(0.1f, 0.0f, 5.0f));
- m_object->SetAngleZ(4, 126.0f*Math::PI/180.0f);
-
- // Creates the left forearm.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(5, rank);
- m_object->SetObjectParent(5, 4);
- pModFile->ReadModel("objects\\recover3.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(5, Math::Vector(5.0f, 0.0f, 0.5f));
- m_object->SetAngleZ(5, -144.0f*Math::PI/180.0f);
- }
-
- if ( type == OBJECT_MOBILErs )
- {
- // Creates the holder.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\roller2s.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(0.0f, 0.0f, 0.0f));
- m_object->SetAngleZ(1, 0.0f);
-
- // Creates the intermediate piston.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 1);
- pModFile->ReadModel("objects\\roller3s.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2, Math::Vector(7.0f, 4.5f, 0.0f));
- m_object->SetAngleZ(2, 0.0f);
-
- // Creates the piston with the sphere.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(3, rank);
- m_object->SetObjectParent(3, 2);
- pModFile->ReadModel("objects\\roller4s.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(3, Math::Vector(0.0f, 1.0f, 0.0f));
- m_object->SetAngleZ(3, 0.0f);
- }
-
- if ( type == OBJECT_MOBILEsa )
- {
- // Creates the holder.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\subm2.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(4.2f, 3.0f, 0.0f));
-
- // Creates the right tong.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 1);
- pModFile->ReadModel("objects\\subm3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2, Math::Vector(0.5f, 0.0f, -1.5f));
-
- // Creates the left tong.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(3, rank);
- m_object->SetObjectParent(3, 1);
- pModFile->ReadModel("objects\\subm3.mod");
- pModFile->Mirror();
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(3, Math::Vector(0.5f, 0.0f, 1.5f));
- }
-
- if ( type == OBJECT_MOBILEdr )
- {
- // Creates the carousel.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\drawer4.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(-3.0f, 3.0f, 0.0f));
-
- // Creates the key.
- if ( m_object->RetToy() )
- {
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 0);
- pModFile->ReadModel("objects\\drawer5.mod");
- pModFile->CreateEngineObject(rank);
- m_posKey = Math::Vector(3.0f, 5.7f, 0.0f);
- m_object->SetPosition(2, m_posKey);
- m_object->SetAngleY(2, 90.0f*Math::PI/180.0f);
- }
-
- // Creates pencils.
- for ( i=0 ; i<8 ; i++ )
- {
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(10+i, rank);
- m_object->SetObjectParent(10+i, 1);
- sprintf(name, "objects\\drawer%d.mod", 10+i);
- pModFile->ReadModel(name);
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(10+i, Math::Vector(0.0f, 0.0f, 0.0f));
- m_object->SetAngleY(10+i, 45.0f*Math::PI/180.0f*i);
- }
- }
-
- if ( type == OBJECT_MOBILEwt )
- {
- // Creates the key.
- if ( m_object->RetToy() )
- {
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 0);
- pModFile->ReadModel("objects\\drawer5.mod");
- pModFile->CreateEngineObject(rank);
- m_posKey = Math::Vector(0.2f, 4.1f, 0.0f);
- m_object->SetPosition(2, m_posKey);
- m_object->SetAngleY(2, 90.0f*Math::PI/180.0f);
- }
- }
-
- if ( type == OBJECT_APOLLO2 )
- {
- // Creates the accessories.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\apolloj2.mod"); // antenna
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(5.5f, 8.8f, 2.0f));
- m_object->SetAngleY(1, -120.0f*Math::PI/180.0f);
- m_object->SetAngleZ(1, 45.0f*Math::PI/180.0f);
-
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2, rank);
- m_object->SetObjectParent(2, 0);
- pModFile->ReadModel("objects\\apolloj3.mod"); // camera
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2, Math::Vector(5.5f, 2.8f, -2.0f));
- m_object->SetAngleY(2, 30.0f*Math::PI/180.0f);
-
- // Creates the wheels.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(6, rank);
- m_object->SetObjectParent(6, 0);
- pModFile->ReadModel("objects\\apolloj4.mod"); // wheel
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(6, Math::Vector(-5.75f, 1.65f, -5.0f));
-
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(7, rank);
- m_object->SetObjectParent(7, 0);
- pModFile->ReadModel("objects\\apolloj4.mod"); // wheel
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(7, Math::Vector(-5.75f, 1.65f, 5.0f));
-
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(8, rank);
- m_object->SetObjectParent(8, 0);
- pModFile->ReadModel("objects\\apolloj4.mod"); // wheel
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(8, Math::Vector(5.75f, 1.65f, -5.0f));
-
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(9, rank);
- m_object->SetObjectParent(9, 0);
- pModFile->ReadModel("objects\\apolloj4.mod"); // wheel
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(9, Math::Vector(5.75f, 1.65f, 5.00f));
-
- // Creates mud guards.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(10, rank);
- m_object->SetObjectParent(10, 0);
- pModFile->ReadModel("objects\\apolloj6.mod"); // wheel
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(10, Math::Vector(-5.75f, 1.65f, -5.0f));
-
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(11, rank);
- m_object->SetObjectParent(11, 0);
- pModFile->ReadModel("objects\\apolloj6.mod"); // wheel
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(11, Math::Vector(-5.75f, 1.65f, 5.0f));
-
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(12, rank);
- m_object->SetObjectParent(12, 0);
- pModFile->ReadModel("objects\\apolloj5.mod"); // wheel
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(12, Math::Vector(5.75f, 1.65f, -5.0f));
-
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(13, rank);
- m_object->SetObjectParent(13, 0);
- pModFile->ReadModel("objects\\apolloj5.mod"); // wheel
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(13, Math::Vector(5.75f, 1.65f, 5.00f));
- }
-
-#if 1
- if ( type == OBJECT_MOBILErt ||
- type == OBJECT_MOBILErc ||
- type == OBJECT_MOBILErr ||
- type == OBJECT_MOBILErs )
- {
- m_object->CreateShadowCircle(6.0f, 1.0f);
- }
- else if ( type == OBJECT_MOBILEta ||
- type == OBJECT_MOBILEtc ||
- type == OBJECT_MOBILEti ||
- type == OBJECT_MOBILEts ||
- type == OBJECT_MOBILEsa )
- {
- m_object->CreateShadowCircle(5.0f, 1.0f);
- }
- else if ( type == OBJECT_MOBILEdr )
- {
- m_object->CreateShadowCircle(4.5f, 1.0f);
- }
- else if ( type == OBJECT_APOLLO2 )
- {
- m_object->CreateShadowCircle(7.0f, 0.8f);
- }
- else
- {
- m_object->CreateShadowCircle(4.0f, 1.0f);
- }
-#else
- if ( type == OBJECT_MOBILErt ||
- type == OBJECT_MOBILErc ||
- type == OBJECT_MOBILErr ||
- type == OBJECT_MOBILErs )
- {
- m_object->CreateShadowCircle(6.0f, 1.0f, D3DSHADOWTANK);
- }
- else if ( type == OBJECT_MOBILEta ||
- type == OBJECT_MOBILEtc ||
- type == OBJECT_MOBILEti ||
- type == OBJECT_MOBILEts )
- {
- m_object->CreateShadowCircle(4.0f, 1.0f, D3DSHADOWTANK);
- }
- else if ( type == OBJECT_MOBILEfa ||
- type == OBJECT_MOBILEfc ||
- type == OBJECT_MOBILEfi ||
- type == OBJECT_MOBILEfs )
- {
- m_object->CreateShadowCircle(4.0f, 1.0f, D3DSHADOWFLY);
- }
- else if ( type == OBJECT_MOBILEwa ||
- type == OBJECT_MOBILEwc ||
- type == OBJECT_MOBILEwi ||
- type == OBJECT_MOBILEws )
- {
- m_object->CreateShadowCircle(4.0f, 1.0f, D3DSHADOWWHEEL);
- }
- else if ( type == OBJECT_APOLLO2 )
- {
- m_object->CreateShadowCircle(6.0f, 0.8f);
- }
- else
- {
- m_object->CreateShadowCircle(4.0f, 1.0f, D3DSHADOWNORM);
- }
-#endif
-
- if ( type == OBJECT_MOBILEfa ||
- type == OBJECT_MOBILEfc ||
- type == OBJECT_MOBILEfi ||
- type == OBJECT_MOBILEfs ||
- type == OBJECT_MOBILEft ) // flying?
- {
-//? color.r = 0.5f-1.0f;
-//? color.g = 0.2f-1.0f;
-//? color.b = 0.0f-1.0f; // orange
-//? color.r = 0.8f;
-//? color.g = 0.6f;
-//? color.b = 0.0f; // yellow-orange
- color.r = 0.0f;
- color.g = 0.4f;
- color.b = 0.8f; // blue
- color.a = 0.0f;
- m_object->CreateShadowLight(50.0f, color);
- }
-
- CreatePhysics(type);
- m_object->SetFloorHeight(0.0f);
-
- if ( power > 0.0f &&
- type != OBJECT_MOBILEdr &&
- type != OBJECT_APOLLO2 )
- {
- color.r = 1.0f;
- color.g = 1.0f;
- color.b = 0.0f; // yellow
- color.a = 0.0f;
- m_object->CreateEffectLight(20.0f, color);
-
- // Creates the battery.
- pPower = new CObject(m_iMan);
- pPower->SetType(power<=1.0f?OBJECT_POWER:OBJECT_ATOMIC);
-
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEFIX);
- pPower->SetObjectRank(0, rank);
-
- if ( power <= 1.0f ) pModFile->ReadModel("objects\\power.mod");
- else pModFile->ReadModel("objects\\atomic.mod");
- pModFile->CreateEngineObject(rank);
-
- pPower->SetPosition(0, m_object->RetCharacter()->posPower);
- pPower->CreateCrashSphere(Math::Vector(0.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f);
- pPower->SetGlobalSphere(Math::Vector(0.0f, 1.0f, 0.0f), 1.5f);
-
- pPower->SetTruck(m_object);
- m_object->SetPower(pPower);
-
- if ( power <= 1.0f ) pPower->SetEnergy(power);
- else pPower->SetEnergy(power/100.0f);
- }
-
- pos = m_object->RetPosition(0);
- m_object->SetPosition(0, pos); //to display the shadows immediately
-
- m_engine->LoadAllTexture();
-
- delete pModFile;
- return true;
-}
-
-// Creates the physics of the object.
-
-void CMotionVehicle::CreatePhysics(ObjectType type)
-{
- Character* character;
-
- character = m_object->RetCharacter();
-
- if ( type == OBJECT_MOBILEwa ||
- type == OBJECT_MOBILEwc ||
- type == OBJECT_MOBILEwi ||
- type == OBJECT_MOBILEws ||
- type == OBJECT_MOBILEwt ) // wheels?
- {
- m_physics->SetType(TYPE_ROLLING);
-
- character->wheelFront = 3.0f;
- character->wheelBack = 4.0f;
- character->wheelLeft = 4.0f;
- character->wheelRight = 4.0f;
- character->posPower = Math::Vector(-3.2f, 3.0f, 0.0f);
-
- m_physics->SetLinMotionX(MO_ADVSPEED, 20.0f);
- m_physics->SetLinMotionX(MO_RECSPEED, 10.0f);
- m_physics->SetLinMotionX(MO_ADVACCEL, 40.0f);
- m_physics->SetLinMotionX(MO_RECACCEL, 20.0f);
- m_physics->SetLinMotionX(MO_STOACCEL, 40.0f);
- m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionX(MO_TERFORCE, 50.0f);
- m_physics->SetLinMotionZ(MO_TERFORCE, 30.0f);
- m_physics->SetLinMotionZ(MO_MOTACCEL, 20.0f);
-
- m_physics->SetCirMotionY(MO_ADVSPEED, 0.8f*Math::PI);
- m_physics->SetCirMotionY(MO_RECSPEED, 0.8f*Math::PI);
- m_physics->SetCirMotionY(MO_ADVACCEL, 8.0f);
- m_physics->SetCirMotionY(MO_RECACCEL, 8.0f);
- m_physics->SetCirMotionY(MO_STOACCEL, 12.0f);
- }
-
- if ( type == OBJECT_MOBILEtg )
- {
- m_physics->SetType(TYPE_ROLLING);
-
- character->wheelFront = 4.0f;
- character->wheelBack = 3.0f;
- character->wheelLeft = 4.0f;
- character->wheelRight = 4.0f;
- character->posPower = Math::Vector(-3.2f, 3.0f, 0.0f);
-
- m_physics->SetLinMotionX(MO_ADVSPEED, 20.0f);
- m_physics->SetLinMotionX(MO_RECSPEED, 10.0f);
- m_physics->SetLinMotionX(MO_ADVACCEL, 40.0f);
- m_physics->SetLinMotionX(MO_RECACCEL, 20.0f);
- m_physics->SetLinMotionX(MO_STOACCEL, 40.0f);
- m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionX(MO_TERFORCE, 50.0f);
- m_physics->SetLinMotionZ(MO_TERFORCE, 20.0f);
- m_physics->SetLinMotionZ(MO_MOTACCEL, 20.0f);
-
- m_physics->SetCirMotionY(MO_ADVSPEED, 0.8f*Math::PI);
- m_physics->SetCirMotionY(MO_RECSPEED, 0.8f*Math::PI);
- m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f);
- m_physics->SetCirMotionY(MO_RECACCEL, 10.0f);
- m_physics->SetCirMotionY(MO_STOACCEL, 15.0f);
- }
-
- if ( type == OBJECT_MOBILEta ||
- type == OBJECT_MOBILEtc ||
- type == OBJECT_MOBILEti ||
- type == OBJECT_MOBILEts ) // caterpillars?
- {
- m_physics->SetType(TYPE_ROLLING);
-
- character->wheelFront = 4.0f;
- character->wheelBack = 4.0f;
- character->wheelLeft = 4.8f;
- character->wheelRight = 4.8f;
- character->posPower = Math::Vector(-3.2f, 3.0f, 0.0f);
-
- m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f);
- m_physics->SetLinMotionX(MO_RECSPEED, 8.0f);
- m_physics->SetLinMotionX(MO_ADVACCEL, 15.0f);
- m_physics->SetLinMotionX(MO_RECACCEL, 8.0f);
- m_physics->SetLinMotionX(MO_STOACCEL, 40.0f);
- m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionX(MO_TERFORCE, 20.0f);
- m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f);
- m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f);
-
- m_physics->SetCirMotionY(MO_ADVSPEED, 0.5f*Math::PI);
- m_physics->SetCirMotionY(MO_RECSPEED, 0.5f*Math::PI);
- m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f);
- m_physics->SetCirMotionY(MO_RECACCEL, 10.0f);
- m_physics->SetCirMotionY(MO_STOACCEL, 6.0f);
- }
-
- if ( type == OBJECT_MOBILEia ||
- type == OBJECT_MOBILEic ||
- type == OBJECT_MOBILEii ||
- type == OBJECT_MOBILEis ) // legs?
- {
- m_physics->SetType(TYPE_ROLLING);
-
- character->wheelFront = 4.0f;
- character->wheelBack = 4.0f;
- character->wheelLeft = 5.0f;
- character->wheelRight = 5.0f;
- character->posPower = Math::Vector(-3.2f, 3.0f, 0.0f);
-
- m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f);
- m_physics->SetLinMotionX(MO_RECSPEED, 8.0f);
- m_physics->SetLinMotionX(MO_ADVACCEL, 40.0f);
- m_physics->SetLinMotionX(MO_RECACCEL, 20.0f);
- m_physics->SetLinMotionX(MO_STOACCEL, 40.0f);
- m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionX(MO_TERFORCE, 10.0f);
-//? m_physics->SetLinMotionX(MO_TERFORCE, 15.0f);
- m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f);
- m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f);
-
- m_physics->SetCirMotionY(MO_ADVSPEED, 0.5f*Math::PI);
- m_physics->SetCirMotionY(MO_RECSPEED, 0.5f*Math::PI);
- m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f);
- m_physics->SetCirMotionY(MO_RECACCEL, 10.0f);
- m_physics->SetCirMotionY(MO_STOACCEL, 15.0f);
- }
-
- if ( type == OBJECT_MOBILEfa ||
- type == OBJECT_MOBILEfc ||
- type == OBJECT_MOBILEfi ||
- type == OBJECT_MOBILEfs ||
- type == OBJECT_MOBILEft ) // flying?
- {
- m_physics->SetType(TYPE_FLYING);
-
- character->wheelFront = 5.0f;
- character->wheelBack = 4.0f;
- character->wheelLeft = 4.5f;
- character->wheelRight = 4.5f;
- character->posPower = Math::Vector(-3.2f, 3.0f, 0.0f);
-
- m_physics->SetLinMotionX(MO_ADVSPEED, 50.0f);
- m_physics->SetLinMotionX(MO_RECSPEED, 50.0f);
- m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f);
- m_physics->SetLinMotionX(MO_RECACCEL, 20.0f);
- m_physics->SetLinMotionX(MO_STOACCEL, 20.0f);
- m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionX(MO_TERFORCE, 50.0f);
- m_physics->SetLinMotionZ(MO_TERFORCE, 50.0f);
- m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f);
- m_physics->SetLinMotionY(MO_ADVSPEED, 60.0f);
- m_physics->SetLinMotionY(MO_RECSPEED, 60.0f);
- m_physics->SetLinMotionY(MO_ADVACCEL, 20.0f);
- m_physics->SetLinMotionY(MO_RECACCEL, 50.0f);
- m_physics->SetLinMotionY(MO_STOACCEL, 50.0f);
-
- m_physics->SetCirMotionY(MO_ADVSPEED, 0.4f*Math::PI);
- m_physics->SetCirMotionY(MO_RECSPEED, 0.4f*Math::PI);
- m_physics->SetCirMotionY(MO_ADVACCEL, 2.0f);
- m_physics->SetCirMotionY(MO_RECACCEL, 2.0f);
- m_physics->SetCirMotionY(MO_STOACCEL, 2.0f);
- }
-
- if ( type == OBJECT_MOBILErt ||
- type == OBJECT_MOBILErc ||
- type == OBJECT_MOBILErr ||
- type == OBJECT_MOBILErs ) // large caterpillars?
- {
- m_physics->SetType(TYPE_ROLLING);
-
- character->wheelFront = 5.0f;
- character->wheelBack = 5.0f;
- character->wheelLeft = 6.0f;
- character->wheelRight = 6.0f;
- character->posPower = Math::Vector(-5.8f, 4.0f, 0.0f);
-
- m_physics->SetLinMotionX(MO_ADVSPEED, 10.0f);
- m_physics->SetLinMotionX(MO_RECSPEED, 5.0f);
- m_physics->SetLinMotionX(MO_ADVACCEL, 10.0f);
- m_physics->SetLinMotionX(MO_RECACCEL, 5.0f);
- m_physics->SetLinMotionX(MO_STOACCEL, 40.0f);
- m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionX(MO_TERFORCE, 20.0f);
- m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f);
- m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f);
-
- m_physics->SetCirMotionY(MO_ADVSPEED, 0.3f*Math::PI);
- m_physics->SetCirMotionY(MO_RECSPEED, 0.3f*Math::PI);
- m_physics->SetCirMotionY(MO_ADVACCEL, 2.0f);
- m_physics->SetCirMotionY(MO_RECACCEL, 2.0f);
- m_physics->SetCirMotionY(MO_STOACCEL, 4.0f);
- }
-
- if ( type == OBJECT_MOBILEsa )
- {
- m_physics->SetType(TYPE_ROLLING);
-
- character->wheelFront = 4.0f;
- character->wheelBack = 4.0f;
- character->wheelLeft = 4.0f;
- character->wheelRight = 4.0f;
- character->posPower = Math::Vector(-5.0f, 3.0f, 0.0f);
-
- m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f);
- m_physics->SetLinMotionX(MO_RECSPEED, 10.0f);
- m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f);
- m_physics->SetLinMotionX(MO_RECACCEL, 10.0f);
- m_physics->SetLinMotionX(MO_STOACCEL, 40.0f);
- m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionX(MO_TERFORCE, 20.0f);
- m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f);
- m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f);
-
- m_physics->SetCirMotionY(MO_ADVSPEED, 0.5f*Math::PI);
- m_physics->SetCirMotionY(MO_RECSPEED, 0.5f*Math::PI);
- m_physics->SetCirMotionY(MO_ADVACCEL, 5.0f);
- m_physics->SetCirMotionY(MO_RECACCEL, 5.0f);
- m_physics->SetCirMotionY(MO_STOACCEL, 10.0f);
- }
-
- if ( type == OBJECT_MOBILEdr )
- {
- m_physics->SetType(TYPE_ROLLING);
-
- character->wheelFront = 4.0f;
- character->wheelBack = 4.0f;
- character->wheelLeft = 4.0f;
- character->wheelRight = 4.0f;
- character->posPower = Math::Vector(-5.0f, 3.0f, 0.0f);
-
- m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f);
- m_physics->SetLinMotionX(MO_RECSPEED, 10.0f);
- m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f);
- m_physics->SetLinMotionX(MO_RECACCEL, 10.0f);
- m_physics->SetLinMotionX(MO_STOACCEL, 40.0f);
- m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionX(MO_TERFORCE, 20.0f);
- m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f);
- m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f);
-
- m_physics->SetCirMotionY(MO_ADVSPEED, 0.5f*Math::PI);
- m_physics->SetCirMotionY(MO_RECSPEED, 0.5f*Math::PI);
- m_physics->SetCirMotionY(MO_ADVACCEL, 5.0f);
- m_physics->SetCirMotionY(MO_RECACCEL, 5.0f);
- m_physics->SetCirMotionY(MO_STOACCEL, 10.0f);
- }
-
- if ( type == OBJECT_APOLLO2 ) // jeep?
- {
- m_physics->SetType(TYPE_ROLLING);
-
- character->wheelFront = 6.0f;
- character->wheelBack = 6.0f;
- character->wheelLeft = 5.0f;
- character->wheelRight = 5.0f;
-
- m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f);
- m_physics->SetLinMotionX(MO_RECSPEED, 10.0f);
- m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f);
- m_physics->SetLinMotionX(MO_RECACCEL, 20.0f);
- m_physics->SetLinMotionX(MO_STOACCEL, 40.0f);
- m_physics->SetLinMotionX(MO_TERSLIDE, 2.0f);
- m_physics->SetLinMotionZ(MO_TERSLIDE, 2.0f);
- m_physics->SetLinMotionX(MO_TERFORCE, 30.0f);
- m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f);
- m_physics->SetLinMotionZ(MO_MOTACCEL, 20.0f);
-
- m_physics->SetCirMotionY(MO_ADVSPEED, 0.4f*Math::PI);
- m_physics->SetCirMotionY(MO_RECSPEED, 0.4f*Math::PI);
- m_physics->SetCirMotionY(MO_ADVACCEL, 2.0f);
- m_physics->SetCirMotionY(MO_RECACCEL, 2.0f);
- m_physics->SetCirMotionY(MO_STOACCEL, 4.0f);
- }
-}
-
-
-// Management of an event.
-
-bool CMotionVehicle::EventProcess(const Event &event)
-{
- CMotion::EventProcess(event);
-
- if ( event.event == EVENT_FRAME )
- {
- return EventFrame(event);
- }
-
- if ( event.event == EVENT_KEYDOWN )
- {
- }
-
- return true;
-}
-
-// Management of an event.
-
-bool CMotionVehicle::EventFrame(const Event &event)
-{
- Math::Matrix* mat;
- Character* character;
- Math::Vector pos, angle, floor;
- ObjectType type;
- float s, a, speedBL, speedBR, speedFL, speedFR, h, a1, a2;
- float back, front, dist, radius, limit[2];
-
- if ( m_engine->RetPause() ) return true;
- if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return true;
-
- type = m_object->RetType();
-
- if ( type == OBJECT_MOBILEwa ||
- type == OBJECT_MOBILEwc ||
- type == OBJECT_MOBILEwi ||
- type == OBJECT_MOBILEws ||
- type == OBJECT_MOBILEwt ||
- type == OBJECT_MOBILEtg ||
- type == OBJECT_APOLLO2 ) // wheels?
- {
- s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.0f;
- a = m_physics->RetCirMotionY(MO_MOTSPEED)*3.0f;
-
- if ( type == OBJECT_APOLLO2 ) s *= 0.5f;
-
- speedBR = -s+a;
- speedBL = s+a;
- speedFR = -s+a;
- speedFL = s+a;
-
- m_object->SetAngleZ(6, m_object->RetAngleZ(6)+event.rTime*speedBR); // turning the wheels
- m_object->SetAngleZ(7, m_object->RetAngleZ(7)+event.rTime*speedBL);
- m_object->SetAngleZ(8, m_object->RetAngleZ(8)+event.rTime*speedFR);
- m_object->SetAngleZ(9, m_object->RetAngleZ(9)+event.rTime*speedFL);
-
- if ( s > 0.0f )
- {
- m_wheelTurn[0] = -a*0.05f;
- m_wheelTurn[1] = -a*0.05f+Math::PI;
- m_wheelTurn[2] = a*0.05f;
- m_wheelTurn[3] = a*0.05f+Math::PI;
- }
- else if ( s < 0.0f )
- {
- m_wheelTurn[0] = a*0.05f;
- m_wheelTurn[1] = a*0.05f+Math::PI;
- m_wheelTurn[2] = -a*0.05f;
- m_wheelTurn[3] = -a*0.05f+Math::PI;
- }
- else
- {
- m_wheelTurn[0] = fabs(a)*0.05f;
- m_wheelTurn[1] = -fabs(a)*0.05f+Math::PI;
- m_wheelTurn[2] = -fabs(a)*0.05f;
- m_wheelTurn[3] = fabs(a)*0.05f+Math::PI;
- }
- m_object->SetAngleY(6, m_object->RetAngleY(6)+(m_wheelTurn[0]-m_object->RetAngleY(6))*event.rTime*8.0f);
- m_object->SetAngleY(7, m_object->RetAngleY(7)+(m_wheelTurn[1]-m_object->RetAngleY(7))*event.rTime*8.0f);
- m_object->SetAngleY(8, m_object->RetAngleY(8)+(m_wheelTurn[2]-m_object->RetAngleY(8))*event.rTime*8.0f);
- m_object->SetAngleY(9, m_object->RetAngleY(9)+(m_wheelTurn[3]-m_object->RetAngleY(9))*event.rTime*8.0f);
-
- if ( type == OBJECT_APOLLO2 )
- {
- m_object->SetAngleY(10, m_object->RetAngleY(6)+(m_wheelTurn[0]-m_object->RetAngleY(6))*event.rTime*8.0f);
- m_object->SetAngleY(11, m_object->RetAngleY(7)+(m_wheelTurn[1]-m_object->RetAngleY(7))*event.rTime*8.0f+Math::PI);
- m_object->SetAngleY(12, m_object->RetAngleY(8)+(m_wheelTurn[2]-m_object->RetAngleY(8))*event.rTime*8.0f);
- m_object->SetAngleY(13, m_object->RetAngleY(9)+(m_wheelTurn[3]-m_object->RetAngleY(9))*event.rTime*8.0f+Math::PI);
- }
-
- pos = m_object->RetPosition(0);
- angle = m_object->RetAngle(0);
- if ( pos.x != m_wheelLastPos.x ||
- pos.y != m_wheelLastPos.y ||
- pos.z != m_wheelLastPos.z ||
- angle.x != m_wheelLastAngle.x ||
- angle.y != m_wheelLastAngle.y ||
- angle.z != m_wheelLastAngle.z )
- {
- m_wheelLastPos = pos;
- m_wheelLastAngle = angle;
-
- if ( type == OBJECT_MOBILEtg )
- {
- back = -2.0f; // back wheels position
- front = 3.0f; // front wheels position
- dist = 3.0f; // distancing wheels Z
- radius = 1.0f;
- }
- else if ( type == OBJECT_APOLLO2 )
- {
- back = -5.75f; // back wheels position
- front = 5.75f; // front wheels position
- dist = 5.00f; // distancing wheels Z
- radius = 1.65f;
- }
- else
- {
- back = -3.0f; // back wheels position
- front = 2.0f; // front wheels position
- dist = 3.0f; // distancing wheels Z
- radius = 1.0f;
- }
-
- if ( Math::Distance(pos, m_engine->RetEyePt()) < 50.0f ) // suspension?
- {
- character = m_object->RetCharacter();
- mat = m_object->RetWorldMatrix(0);
-
- pos.x = -character->wheelBack; // right back wheel
- pos.z = -character->wheelRight;
- pos.y = 0.0f;
- pos = Math::Transform(*mat, pos);
- h = m_terrain->RetFloorHeight(pos);
- if ( h > 0.5f ) h = 0.5f;
- if ( h < -0.5f ) h = -0.5f;
- pos.x = back;
- pos.y = radius-h;
- pos.z = -dist;
- m_object->SetPosition(6, pos);
- if ( type == OBJECT_APOLLO2 ) m_object->SetPosition(10, pos);
-
- pos.x = -character->wheelBack; // left back wheel
- pos.z = character->wheelLeft;
- pos.y = 0.0f;
- pos = Math::Transform(*mat, pos);
- h = m_terrain->RetFloorHeight(pos);
- if ( h > 0.5f ) h = 0.5f;
- if ( h < -0.5f ) h = -0.5f;
- pos.x = back;
- pos.y = radius-h;
- pos.z = dist;
- m_object->SetPosition(7, pos);
- if ( type == OBJECT_APOLLO2 ) m_object->SetPosition(11, pos);
-
- pos.x = character->wheelFront; // right front wheel
- pos.z = -character->wheelRight;
- pos.y = 0.0f;
- pos = Math::Transform(*mat, pos);
- h = m_terrain->RetFloorHeight(pos);
- if ( h > 0.5f ) h = 0.5f;
- if ( h < -0.5f ) h = -0.5f;
- pos.x = front;
- pos.y = radius-h;
- pos.z = -dist;
- m_object->SetPosition(8, pos);
- if ( type == OBJECT_APOLLO2 ) m_object->SetPosition(12, pos);
-
- pos.x = character->wheelFront; // left front wheel
- pos.z = character->wheelLeft;
- pos.y = 0.0f;
- pos = Math::Transform(*mat, pos);
- h = m_terrain->RetFloorHeight(pos);
- if ( h > 0.5f ) h = 0.5f;
- if ( h < -0.5f ) h = -0.5f;
- pos.x = front;
- pos.y = radius-h;
- pos.z = dist;
- m_object->SetPosition(9, pos);
- if ( type == OBJECT_APOLLO2 ) m_object->SetPosition(13, pos);
- }
- else
- {
- m_object->SetPosition(6, Math::Vector(back, radius, -dist));
- m_object->SetPosition(7, Math::Vector(back, radius, dist));
- m_object->SetPosition(8, Math::Vector(front, radius, -dist));
- m_object->SetPosition(9, Math::Vector(front, radius, dist));
-
- if ( type == OBJECT_APOLLO2 )
- {
- m_object->SetPosition(10, Math::Vector(back, radius, -dist));
- m_object->SetPosition(11, Math::Vector(back, radius, dist));
- m_object->SetPosition(12, Math::Vector(front, radius, -dist));
- m_object->SetPosition(13, Math::Vector(front, radius, dist));
- }
- }
- }
- }
-
- if ( type == OBJECT_MOBILEta ||
- type == OBJECT_MOBILEtc ||
- type == OBJECT_MOBILEti ||
- type == OBJECT_MOBILEts ||
- type == OBJECT_MOBILErt ||
- type == OBJECT_MOBILErc ||
- type == OBJECT_MOBILErr ||
- type == OBJECT_MOBILErs ||
- type == OBJECT_MOBILEsa ||
- type == OBJECT_MOBILEdr ) // caterpillars?
- {
- s = m_physics->RetLinMotionX(MO_MOTSPEED)*0.7f;
- a = m_physics->RetCirMotionY(MO_MOTSPEED)*2.5f;
-
- m_posTrackLeft += event.rTime*(s+a);
- m_posTrackRight += event.rTime*(s-a);
-
- UpdateTrackMapping(m_posTrackLeft, m_posTrackRight, type);
-
- pos = m_object->RetPosition(0);
- angle = m_object->RetAngle(0);
- if ( pos.x != m_wheelLastPos.x ||
- pos.y != m_wheelLastPos.y ||
- pos.z != m_wheelLastPos.z ||
- angle.x != m_wheelLastAngle.x ||
- angle.y != m_wheelLastAngle.y ||
- angle.z != m_wheelLastAngle.z )
- {
- m_wheelLastPos = pos;
- m_wheelLastAngle = angle;
-
- if ( type == OBJECT_MOBILEta ||
- type == OBJECT_MOBILEtc ||
- type == OBJECT_MOBILEti ||
- type == OBJECT_MOBILEts )
- {
- limit[0] = 8.0f*Math::PI/180.0f;
- limit[1] = -12.0f*Math::PI/180.0f;
- }
- else if ( type == OBJECT_MOBILEsa )
- {
- limit[0] = 15.0f*Math::PI/180.0f;
- limit[1] = -15.0f*Math::PI/180.0f;
- }
- else if ( type == OBJECT_MOBILEdr )
- {
- limit[0] = 10.0f*Math::PI/180.0f;
- limit[1] = -10.0f*Math::PI/180.0f;
- }
- else
- {
- limit[0] = 15.0f*Math::PI/180.0f;
- limit[1] = -10.0f*Math::PI/180.0f;
- }
-
- if ( Math::Distance(pos, m_engine->RetEyePt()) < 50.0f ) // suspension?
- {
- character = m_object->RetCharacter();
- mat = m_object->RetWorldMatrix(0);
-
- pos.x = character->wheelFront; // right front wheel
- pos.z = -character->wheelRight;
- pos.y = 0.0f;
- pos = Transform(*mat, pos);
- a1 = atanf(m_terrain->RetFloorHeight(pos)/character->wheelFront);
-
- pos.x = -character->wheelBack; // right back wheel
- pos.z = -character->wheelRight;
- pos.y = 0.0f;
- pos = Transform(*mat, pos);
- a2 = atanf(m_terrain->RetFloorHeight(pos)/character->wheelBack);
-
- a = (a2-a1)/2.0f;
- if ( a > limit[0] ) a = limit[0];
- if ( a < limit[1] ) a = limit[1];
- m_object->SetAngleZ(6, a);
-
- pos.x = character->wheelFront; // left front wheel
- pos.z = character->wheelLeft;
- pos.y = 0.0f;
- pos = Transform(*mat, pos);
- a1 = atanf(m_terrain->RetFloorHeight(pos)/character->wheelFront);
-
- pos.x = -character->wheelBack; // left back wheel
- pos.z = character->wheelLeft;
- pos.y = 0.0f;
- pos = Transform(*mat, pos);
- a2 = atanf(m_terrain->RetFloorHeight(pos)/character->wheelBack);
-
- a = (a2-a1)/2.0f;
- if ( a > limit[0] ) a = limit[0];
- if ( a < limit[1] ) a = limit[1];
- m_object->SetAngleZ(7, a);
- }
- else
- {
- m_object->SetAngleZ(6, 0.0f);
- m_object->SetAngleZ(7, 0.0f);
- }
- }
- }
-
- if ( type == OBJECT_MOBILEwt ||
- type == OBJECT_MOBILEdr ) // toy is key?
- {
- pos = m_posKey;
- if ( m_object->RetSelect() &&
- m_camera->RetType() == CAMERA_ONBOARD )
- {
- pos.y += 10.0f; // out of sight!
- }
- m_object->SetPosition(2, pos);
-
- s = -fabs(m_physics->RetLinMotionX(MO_MOTSPEED)*0.1f);
- s += -fabs(m_physics->RetCirMotionY(MO_MOTSPEED)*1.5f);
- m_object->SetAngleY(2, m_object->RetAngleY(2)+event.rTime*s); // turns the key
- }
-
- if ( type == OBJECT_MOBILEfa ||
- type == OBJECT_MOBILEfc ||
- type == OBJECT_MOBILEfi ||
- type == OBJECT_MOBILEfs ||
- type == OBJECT_MOBILEft ) // flying?
- {
- EventFrameFly(event);
- }
-
- if ( type == OBJECT_MOBILEia ||
- type == OBJECT_MOBILEic ||
- type == OBJECT_MOBILEii ||
- type == OBJECT_MOBILEis ) // legs?
- {
- EventFrameInsect(event);
- }
-
- if ( type == OBJECT_MOBILEwi ||
- type == OBJECT_MOBILEti ||
- type == OBJECT_MOBILEfi ||
- type == OBJECT_MOBILEii ) // insect cannon?
- {
- EventFrameCanoni(event);
- }
-
- return true;
-}
-
-// Managing an event for a flying robot.
-
-bool CMotionVehicle::EventFrameFly(const Event &event)
-{
- Math::Matrix* mat;
- Math::Vector pos, angle, paw[3];
- float hope[3], actual, final, h, a;
- int i;
-
- pos = m_object->RetPosition(0);
- angle = m_object->RetAngle(0);
- if ( m_bFlyFix &&
- pos.x == m_wheelLastPos.x &&
- pos.y == m_wheelLastPos.y &&
- pos.z == m_wheelLastPos.z &&
- angle.x == m_wheelLastAngle.x &&
- angle.y == m_wheelLastAngle.y &&
- angle.z == m_wheelLastAngle.z ) return true;
-
- m_wheelLastPos = pos;
- m_wheelLastAngle = angle;
-
- if ( m_physics->RetLand() ) // on the ground?
- {
- mat = m_object->RetWorldMatrix(0);
- paw[0] = Transform(*mat, Math::Vector( 4.2f, 0.0f, 0.0f)); // front
- paw[1] = Transform(*mat, Math::Vector(-3.0f, 0.0f, -3.7f)); // right back
- paw[2] = Transform(*mat, Math::Vector(-3.0f, 0.0f, 3.7f)); // left back
-
- for ( i=0 ; i<3 ; i++ )
- {
- h = m_terrain->RetFloorHeight(paw[i]);
- a = -atanf(h*0.5f);
- if ( a > Math::PI*0.2f ) a = Math::PI*0.2f;
- if ( a < -Math::PI*0.2f ) a = -Math::PI*0.2f;
- hope[i] = a;
- }
- }
- else // in flight?
- {
- hope[0] = 0.0f; // front
- hope[1] = 0.0f; // right back
- hope[2] = 0.0f; // left back
- }
-
- m_bFlyFix = true;
- for ( i=0 ; i<3 ; i++ )
- {
- actual = m_object->RetAngleZ(6+i);
- final = Math::Smooth(actual, hope[i], event.rTime*5.0f);
- if ( final != actual )
- {
- m_bFlyFix = false; // it is moving
- m_object->SetAngleZ(6+i, final);
- }
- }
-
- return true;
-}
-
-// Event management for insect legs.
-
-bool CMotionVehicle::EventFrameInsect(const Event &event)
-{
- Math::Vector dir;
- float s, a, prog, time;
- int i, st, nd, action;
- bool bStop, bOnBoard;
-
- static int table[] =
- {
- // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air:
- 60,25,0, 60,0,0, 60,-25,0, // t0: thighs 1..4
- -35,0,0, -35,0,0, -35,0,0, // t0: legs 1..4
- -65,0,0, -65,0,0, -65,0,0, // t0: feet 1..4
- // on the ground:
- 30,10,0, 30,-15,0, 30,-40,0, // t1: thighs 1..4
- -45,0,0, -45,0,0, -45,0,0, // t1: legs 1..4
- -20,0,0, -20,0,0, -20,0,0, // t1: feet 1..4
- // on the ground back:
- 35,40,0, 40,15,0, 40,-10,0, // t2: thighs 1..4
- -35,0,0, -35,0,0, -35,0,0, // t2: legs 1..4
- -50,0,0, -65,0,0, -65,0,0, // t2: feet 1..4
- // stop:
- 35,35,0, 40,10,0, 40,-15,0, // s0: thighs 1..4
- -35,0,0, -35,0,0, -35,0,0, // s0: legs 1..4
- -50,0,0, -65,0,0, -65,0,0, // s0: feet 1..4
- };
-
- bOnBoard = false;
- if ( m_object->RetSelect() &&
- m_camera->RetType() == CAMERA_ONBOARD )
- {
- bOnBoard = true;
- }
-
- s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.5f;
- a = fabs(m_physics->RetCirMotionY(MO_MOTSPEED)*2.0f);
-
- if ( s == 0.0f && a != 0.0f ) a *= 1.5f;
-
- m_armTimeAbs += event.rTime;
- m_armMember += (s+a)*event.rTime*0.15f;
-
- bStop = ( a == 0.0f && s == 0.0f ); // stop?
-
- action = 0; // walking
- if ( s == 0.0f && a == 0.0f )
- {
- action = 3; // stop
- }
-
- if ( bStop )
- {
- prog = Math::Mod(m_armTimeAbs, 2.0f)/10.0f;
- a = Math::Mod(m_armMember, 1.0f);
- a = (prog-a)*event.rTime*2.0f; // stop position is pleasantly
- m_armMember += a;
- }
-
- if ( m_object->RetRuin() ) // burn or explode?
- {
- action = 3;
- }
-
- for ( i=0 ; i<6 ; i++ ) // the six legs
- {
- if ( action != 0 ) // special action in progress?
- {
- st = 3*3*3*action + (i%3)*3;
- nd = st;
- time = event.rTime*5.0f;
- }
- else
- {
- if ( i < 3 ) prog = Math::Mod(m_armMember+(2.0f-(i%3))*0.33f+0.0f, 1.0f);
- else prog = Math::Mod(m_armMember+(2.0f-(i%3))*0.33f+0.3f, 1.0f);
- if ( prog < 0.33f ) // t0..t1 ?
- {
- prog = prog/0.33f; // 0..1
- st = 0; // index start
- nd = 1; // index end
- }
- else if ( prog < 0.67f ) // t1..t2 ?
- {
- prog = (prog-0.33f)/0.33f; // 0..1
- st = 1; // index start
- nd = 2; // index end
- }
- else // t2..t0 ?
- {
- prog = (prog-0.67f)/0.33f; // 0..1
- st = 2; // index start
- nd = 0; // index end
- }
- st = 3*3*3*action + st*3*3*3 + (i%3)*3;
- nd = 3*3*3*action + nd*3*3*3 + (i%3)*3;
-
- // Less and less soft ...
- time = event.rTime*20.0f;
- }
-
- if ( i < 3 ) // right leg (1..3) ?
- {
- m_object->SetAngleX(6+3*i+0, Math::Smooth(m_object->RetAngleX(6+3*i+0), Math::PropAngle(table[st+ 0], table[nd+ 0], prog), time));
- m_object->SetAngleY(6+3*i+0, Math::Smooth(m_object->RetAngleY(6+3*i+0), Math::PropAngle(table[st+ 1], table[nd+ 1], prog), time));
- m_object->SetAngleZ(6+3*i+0, Math::Smooth(m_object->RetAngleZ(6+3*i+0), Math::PropAngle(table[st+ 2], table[nd+ 2], prog), time));
- m_object->SetAngleX(6+3*i+1, Math::Smooth(m_object->RetAngleX(6+3*i+1), Math::PropAngle(table[st+ 9], table[nd+ 9], prog), time));
- m_object->SetAngleY(6+3*i+1, Math::Smooth(m_object->RetAngleY(6+3*i+1), Math::PropAngle(table[st+10], table[nd+10], prog), time));
- m_object->SetAngleZ(6+3*i+1, Math::Smooth(m_object->RetAngleZ(6+3*i+1), Math::PropAngle(table[st+11], table[nd+11], prog), time));
- m_object->SetAngleX(6+3*i+2, Math::Smooth(m_object->RetAngleX(6+3*i+2), Math::PropAngle(table[st+18], table[nd+18], prog), time));
- m_object->SetAngleY(6+3*i+2, Math::Smooth(m_object->RetAngleY(6+3*i+2), Math::PropAngle(table[st+19], table[nd+19], prog), time));
- m_object->SetAngleZ(6+3*i+2, Math::Smooth(m_object->RetAngleZ(6+3*i+2), Math::PropAngle(table[st+20], table[nd+20], prog), time));
- }
- else // left leg (4..6) ?
- {
- m_object->SetAngleX(6+3*i+0, Math::Smooth(m_object->RetAngleX(6+3*i+0), Math::PropAngle(-table[st+ 0], -table[nd+ 0], prog), time));
- m_object->SetAngleY(6+3*i+0, Math::Smooth(m_object->RetAngleY(6+3*i+0), Math::PropAngle(-table[st+ 1], -table[nd+ 1], prog), time));
- m_object->SetAngleZ(6+3*i+0, Math::Smooth(m_object->RetAngleZ(6+3*i+0), Math::PropAngle( table[st+ 2], table[nd+ 2], prog), time));
- m_object->SetAngleX(6+3*i+1, Math::Smooth(m_object->RetAngleX(6+3*i+1), Math::PropAngle(-table[st+ 9], -table[nd+ 9], prog), time));
- m_object->SetAngleY(6+3*i+1, Math::Smooth(m_object->RetAngleY(6+3*i+1), Math::PropAngle(-table[st+10], -table[nd+10], prog), time));
- m_object->SetAngleZ(6+3*i+1, Math::Smooth(m_object->RetAngleZ(6+3*i+1), Math::PropAngle( table[st+11], table[nd+11], prog), time));
- m_object->SetAngleX(6+3*i+2, Math::Smooth(m_object->RetAngleX(6+3*i+2), Math::PropAngle(-table[st+18], -table[nd+18], prog), time));
- m_object->SetAngleY(6+3*i+2, Math::Smooth(m_object->RetAngleY(6+3*i+2), Math::PropAngle(-table[st+19], -table[nd+19], prog), time));
- m_object->SetAngleZ(6+3*i+2, Math::Smooth(m_object->RetAngleZ(6+3*i+2), Math::PropAngle( table[st+20], table[nd+20], prog), time));
- }
- }
-
- if ( bStop )
- {
- }
- else
- {
- a = Math::Mod(m_armMember, 1.0f);
- if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1
- else a = 3.0f-4.0f*a; // 1..-1
- dir.x = sinf(a)*0.05f;
-
- s = Math::Mod(m_armMember/2.0f, 1.0f);
- if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1
- else s = 3.0f-4.0f*s; // 1..-1
- dir.z = sinf(s)*0.1f;
-
- dir.y = 0.0f;
-
- if ( bOnBoard ) dir *= 0.6f;
- SetInclinaison(dir);
- }
-
- return true;
-}
-
-// Event management for a insect cannon.
-
-bool CMotionVehicle::EventFrameCanoni(const Event &event)
-{
- CObject* power;
- Math::Vector pos, speed;
- Math::Point dim;
- float zoom, angle, energy, factor;
- bool bOnBoard = false;
-
- m_canonTime += event.rTime;
-
- if ( m_object->RetSelect() &&
- m_camera->RetType() == CAMERA_ONBOARD )
- {
- bOnBoard = true;
- }
-
- power = m_object->RetPower();
- if ( power == 0 )
- {
- energy = 0.0f;
- }
- else
- {
- energy = power->RetEnergy();
- }
- if ( energy == 0.0f ) return true;
-
- factor = 0.5f+energy*0.5f;
- if ( bOnBoard ) factor *= 0.8f;
-
- zoom = 1.3f+
- sinf(m_canonTime*Math::PI*0.31f)*0.10f+
- sinf(m_canonTime*Math::PI*0.52f)*0.08f+
- sinf(m_canonTime*Math::PI*1.53f)*0.05f;
- zoom *= factor;
- m_object->SetZoomY(2, zoom);
-
- zoom = 1.0f+
- sinf(m_canonTime*Math::PI*0.27f)*0.07f+
- sinf(m_canonTime*Math::PI*0.62f)*0.06f+
- sinf(m_canonTime*Math::PI*1.73f)*0.03f;
- zoom *= factor;
- m_object->SetZoomZ(2, zoom);
-
- angle = sinf(m_canonTime*1.0f)*0.10f+
- sinf(m_canonTime*1.3f)*0.15f+
- sinf(m_canonTime*2.7f)*0.05f;
- m_object->SetAngleX(2, angle);
-
-#if 0
- m_lastTimeCanon -= event.rTime;
- if ( m_lastTimeCanon <= 0.0f )
- {
- m_lastTimeCanon = m_engine->ParticuleAdapt(0.5f+Math::Rand()*0.5f);
-
- pos = m_object->RetPosition(0);
- pos.y += 8.0f;
- speed.y = 7.0f+Math::Rand()*3.0f;
- speed.x = (Math::Rand()-0.5f)*2.0f;
- speed.z = 2.0f+Math::Rand()*2.0f;
- if ( Math::Rand() < 0.5f ) speed.z = -speed.z;
- mat = m_object->RetRotateMatrix(0);
- speed = Transform(*mat, speed);
- dim.x = Math::Rand()*0.1f+0.1f;
- if ( bOnBoard ) dim.x *= 0.4f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTIORGANIC2, 2.0f, 10.0f);
- }
-#endif
-
- return true;
-}
-
-
-// Updates the mapping of the texture of the caterpillars.
-
-void CMotionVehicle::UpdateTrackMapping(float left, float right, ObjectType type)
-{
- D3DMATERIAL7 mat;
- float limit[4];
- int rRank, lRank, i;
-
- ZeroMemory( &mat, sizeof(D3DMATERIAL7) );
- mat.diffuse.r = 1.0f;
- mat.diffuse.g = 1.0f;
- mat.diffuse.b = 1.0f; // white
- mat.ambient.r = 0.5f;
- mat.ambient.g = 0.5f;
- mat.ambient.b = 0.5f;
-
- rRank = m_object->RetObjectRank(6);
- lRank = m_object->RetObjectRank(7);
-
-
- if ( type == OBJECT_MOBILEdr )
- {
- limit[0] = 0.0f;
- limit[1] = 1000000.0f;
- limit[2] = limit[1];
- limit[3] = m_engine->RetLimitLOD(1);
-
- m_engine->TrackTextureMapping(rRank, mat, D3DSTATEPART1, "drawer.tga", "",
- limit[0], limit[1], D3DMAPPINGX,
- right, 1.0f, 8.0f, 192.0f, 256.0f);
-
- m_engine->TrackTextureMapping(lRank, mat, D3DSTATEPART2, "drawer.tga", "",
- limit[0], limit[1], D3DMAPPINGX,
- left, 1.0f, 8.0f, 192.0f, 256.0f);
- }
- else
- {
- limit[0] = 0.0f;
- limit[1] = m_engine->RetLimitLOD(0);
- limit[2] = limit[1];
- limit[3] = m_engine->RetLimitLOD(1);
-
- for ( i=0 ; i<2 ; i++ )
- {
- m_engine->TrackTextureMapping(rRank, mat, D3DSTATEPART1, "lemt.tga", "",
- limit[i*2+0], limit[i*2+1], D3DMAPPINGX,
- right, 1.0f, 8.0f, 192.0f, 256.0f);
-
- m_engine->TrackTextureMapping(lRank, mat, D3DSTATEPART2, "lemt.tga", "",
- limit[i*2+0], limit[i*2+1], D3DMAPPINGX,
- left, 1.0f, 8.0f, 192.0f, 256.0f);
- }
- }
-
-}
-
-
-
-// State management of the pencil drawing robot.
-
-bool CMotionVehicle::RetTraceDown()
-{
- return m_bTraceDown;
-}
-
-void CMotionVehicle::SetTraceDown(bool bDown)
-{
- m_bTraceDown = bDown;
-}
-
-int CMotionVehicle::RetTraceColor()
-{
- return m_traceColor;
-}
-
-void CMotionVehicle::SetTraceColor(int color)
-{
- m_traceColor = color;
-}
-
-float CMotionVehicle::RetTraceWidth()
-{
- return m_traceWidth;
-}
-
-void CMotionVehicle::SetTraceWidth(float width)
-{
- m_traceWidth = width;
-}
-
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionvehicle.cpp + + +#include <stdio.h> + +#include "object/motion/motionvehicle.h" + +#include "old/modfile.h" +#include "old/particule.h" +#include "old/terrain.h" +#include "math/geometry.h" +#include "object/brain.h" +#include "physics/physics.h" + + + + + + +// Object's constructor. + +CMotionVehicle::CMotionVehicle(CInstanceManager* iMan, CObject* object) + : CMotion(iMan, object) +{ + int i; + + for ( i=0 ; i<4 ; i++ ) + { + m_wheelTurn[i] = 0.0f; + } + for ( i=0 ; i<3 ; i++ ) + { + m_flyPaw[i] = 0.0f; + } + m_posTrackLeft = 0.0f; + m_posTrackRight = 0.0f; + m_partiReactor = -1; + m_armTimeAbs = 1000.0f; + m_armMember = 1000.0f; + m_canonTime = 0.0f; + m_lastTimeCanon = 0.0f; + m_wheelLastPos = Math::Vector(0.0f, 0.0f, 0.0f); + m_wheelLastAngle = Math::Vector(0.0f, 0.0f, 0.0f); + m_posKey = Math::Vector(0.0f, 0.0f, 0.0f); + m_bFlyFix = false; + + m_bTraceDown = false; + m_traceColor = 1; // black + m_traceWidth = 0.5f; +} + +// Object's destructor. + +CMotionVehicle::~CMotionVehicle() +{ +} + + +// Removes an object. + +void CMotionVehicle::DeleteObject(bool bAll) +{ + if ( m_partiReactor != -1 ) + { + m_particule->DeleteParticule(m_partiReactor); + m_partiReactor = -1; + } +} + + +// Creates a vehicle traveling any lands on the ground. + +bool CMotionVehicle::Create(Math::Vector pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + CObject* pPower; + int rank, i, j, parent; + D3DCOLORVALUE color; + char name[50]; + + if ( m_engine->RetRestCreate() < 1+5+18+1 ) return false; + + pModFile = new CModFile(m_iMan); + + m_object->SetType(type); + + // Creates the main base. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEfs ) + { + pModFile->ReadModel("objects\\lem1f.mod"); + } + if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts ) + { + pModFile->ReadModel("objects\\lem1t.mod"); + } + if ( type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEws ) + { + if ( m_object->RetTrainer() ) + { + pModFile->ReadModel("objects\\lem1wt.mod"); + } + else + { + pModFile->ReadModel("objects\\lem1w.mod"); + } + } + if ( type == OBJECT_MOBILEia || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEis ) + { + pModFile->ReadModel("objects\\lem1i.mod"); + } + if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) + { + pModFile->ReadModel("objects\\roller1.mod"); + } + if ( type == OBJECT_MOBILEsa ) + { + pModFile->ReadModel("objects\\subm1.mod"); + } + if ( type == OBJECT_MOBILEtg ) + { + pModFile->ReadModel("objects\\target.mod"); + } + if ( type == OBJECT_MOBILEwt ) + { + pModFile->ReadModel("objects\\trainerw.mod"); + } + if ( type == OBJECT_MOBILEft ) + { + pModFile->ReadModel("objects\\trainerf.mod"); + } + if ( type == OBJECT_MOBILEtt ) + { + pModFile->ReadModel("objects\\trainert.mod"); + } + if ( type == OBJECT_MOBILEit ) + { + pModFile->ReadModel("objects\\traineri.mod"); + } + if ( type == OBJECT_MOBILEdr ) + { + pModFile->ReadModel("objects\\drawer1.mod"); + } + if ( type == OBJECT_APOLLO2 ) + { + pModFile->ReadModel("objects\\apolloj1.mod"); + } + pModFile->CreateEngineObject(rank); + + m_object->SetPosition(0, pos); + m_object->SetAngleY(0, angle); + + // A vehicle must have a obligatory collision + // with a sphere of center (0, y, 0) (see GetCrashSphere). + if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) + { + m_object->CreateCrashSphere(Math::Vector(0.0f, 4.0f, 0.0f), 6.5f, SOUND_BOUMm, 0.45f); + m_object->SetGlobalSphere(Math::Vector(0.0f, 3.0f, 0.0f), 7.0f); + } + else if ( type == OBJECT_MOBILEsa ) + { + m_object->CreateCrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 4.5f, SOUND_BOUMm, 0.45f); + m_object->SetGlobalSphere(Math::Vector(0.0f, 3.0f, 0.0f), 6.0f); + } + else if ( type == OBJECT_MOBILEdr ) + { + m_object->CreateCrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 5.0f, SOUND_BOUMm, 0.45f); + m_object->SetGlobalSphere(Math::Vector(0.0f, 3.0f, 0.0f), 7.0f); + } + else if ( type == OBJECT_APOLLO2 ) + { + m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 8.0f, SOUND_BOUMm, 0.45f); + } + else + { + m_object->CreateCrashSphere(Math::Vector(0.0f, 3.0f, 0.0f), 4.5f, SOUND_BOUMm, 0.45f); + m_object->SetGlobalSphere(Math::Vector(0.0f, 4.0f, 0.0f), 6.0f); + } + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEta || + type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEia ) + { + // Creates the arm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\lem2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(0.0f, 5.3f, 0.0f)); + m_object->SetAngleZ(1, ARM_NEUTRAL_ANGLE1); + + // Creates the forearm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 1); + pModFile->ReadModel("objects\\lem3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, Math::Vector(5.0f, 0.0f, 0.0f)); + m_object->SetAngleZ(2, ARM_NEUTRAL_ANGLE2); + + // Creates the hand. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 2); + pModFile->ReadModel("objects\\lem4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, Math::Vector(3.5f, 0.0f, 0.0f)); + m_object->SetAngleZ(3, ARM_NEUTRAL_ANGLE3); + m_object->SetAngleX(3, Math::PI/2.0f); + + // Creates the close clamp. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(4, rank); + m_object->SetObjectParent(4, 3); + pModFile->ReadModel("objects\\lem5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(4, Math::Vector(1.5f, 0.0f, 0.0f)); + m_object->SetAngleZ(4, -Math::PI*0.10f); + + // Creates the remote clamp. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(5, rank); + m_object->SetObjectParent(5, 3); + pModFile->ReadModel("objects\\lem6.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(5, Math::Vector(1.5f, 0.0f, 0.0f)); + m_object->SetAngleZ(5, Math::PI*0.10f); + } + + if ( type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEis ) + { + // Creates the arm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\lem2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(0.0f, 5.3f, 0.0f)); + m_object->SetAngleZ(1, 110.0f*Math::PI/180.0f); + + // Creates the forearm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 1); + pModFile->ReadModel("objects\\lem3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, Math::Vector(5.0f, 0.0f, 0.0f)); + m_object->SetAngleZ(2, -110.0f*Math::PI/180.0f); + + // Creates the sensor. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 2); + pModFile->ReadModel("objects\\lem4s.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, Math::Vector(3.5f, 0.0f, 0.0f)); + m_object->SetAngleZ(3, -65.0f*Math::PI/180.0f); + } + + if ( type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEic ) + { + // Creates the cannon. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\canon.mod"); + pModFile->CreateEngineObject(rank); +//? m_object->SetPosition(1, Math::Vector(0.0f, 5.3f, 0.0f)); + m_object->SetPosition(1, Math::Vector(0.0f, 5.3f, 0.0f)); + m_object->SetAngleZ(1, 0.0f); + } + + if ( type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEii ) + { + // Creates the insect cannon. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\canoni1.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(0.0f, 5.3f, 0.0f)); + m_object->SetAngleZ(1, 0.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 1); + pModFile->ReadModel("objects\\canoni2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, Math::Vector(0.0f, 2.5f, 0.0f)); + m_object->SetAngleZ(2, 0.0f); + } + + if ( type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEwt ) + { + // Creates the right-back wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\lem2w.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, Math::Vector(-3.0f, 1.0f, -3.0f)); + + // Creates the left-back wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\lem2w.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, Math::Vector(-3.0f, 1.0f, 3.0f)); + m_object->SetAngleY(7, Math::PI); + + // Creates the right-front wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 0); + pModFile->ReadModel("objects\\lem2w.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, Math::Vector(2.0f, 1.0f, -3.0f)); + + // Creates the left-front wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(9, rank); + m_object->SetObjectParent(9, 0); + pModFile->ReadModel("objects\\lem2w.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(9, Math::Vector(2.0f, 1.0f, 3.0f)); + m_object->SetAngleY(9, Math::PI); + } + + if ( type == OBJECT_MOBILEtg ) + { + // Creates the right-back wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\lem2w.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, Math::Vector(-2.0f, 1.0f, -3.0f)); + + // Creates the left-back wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\lem2w.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, Math::Vector(-2.0f, 1.0f, 3.0f)); + m_object->SetAngleY(7, Math::PI); + + // Creates the right-front wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 0); + pModFile->ReadModel("objects\\lem2w.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, Math::Vector(3.0f, 1.0f, -3.0f)); + + // Creates the left-front wheel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(9, rank); + m_object->SetObjectParent(9, 0); + pModFile->ReadModel("objects\\lem2w.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(9, Math::Vector(3.0f, 1.0f, 3.0f)); + m_object->SetAngleY(9, Math::PI); + } + + if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts ) // caterpillars? + { + // Creates the right caterpillar. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\lem2t.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, Math::Vector(0.0f, 2.0f, -3.0f)); + + // Creates the left caterpillar. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\lem3t.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, Math::Vector(0.0f, 2.0f, 3.0f)); + } + + if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) // large caterpillars? + { + // Creates the right caterpillar. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\roller2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, Math::Vector(0.0f, 2.0f, -3.0f)); + + // Creates the left caterpillar. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\roller3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, Math::Vector(0.0f, 2.0f, 3.0f)); + } + + if ( type == OBJECT_MOBILEsa ) // underwater caterpillars? + { + // Creates the right caterpillar. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\subm4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, Math::Vector(0.0f, 1.0f, -3.0f)); + + // Creates the left caterpillar. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\subm5.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, Math::Vector(0.0f, 1.0f, 3.0f)); + } + + if ( type == OBJECT_MOBILEdr ) // caterpillars? + { + // Creates the right caterpillar. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\drawer2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, Math::Vector(0.0f, 1.0f, -3.0f)); + + // Creates the left caterpillar. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\drawer3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, Math::Vector(0.0f, 1.0f, 3.0f)); + } + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEft ) // flying? + { + // Creates the front foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\lem2f.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, Math::Vector(1.7f, 3.0f, 0.0f)); + + // Creates the right-back foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\lem2f.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, Math::Vector(-1.8f, 3.0f, -1.5f)); + m_object->SetAngleY(7, 120.0f*Math::PI/180.0f); + + // Creates the left-back foot. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 0); + pModFile->ReadModel("objects\\lem2f.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, Math::Vector(-1.8f, 3.0f, 1.5f)); + m_object->SetAngleY(8, -120.0f*Math::PI/180.0f); + } + + if ( type == OBJECT_MOBILEia || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEis || + type == OBJECT_MOBILEii ) // insect legs? + { + float table[] = + { + // x y z + -1.5f, 1.2f, -0.7f, // back leg + 0.0f, 0.0f, -1.0f, + 0.0f, 0.0f, -2.0f, + + 0.0f, 1.2f, -0.9f, // middle leg + 0.0f, 0.0f, -1.0f, + 0.0f, 0.0f, -2.0f, + + 1.5f, 1.2f, -0.7f, // front leg + 0.0f, 0.0f, -1.0f, + 0.0f, 0.0f, -2.0f, + }; + + for ( i=0 ; i<3 ; i++ ) + { + for ( j=0 ; j<3 ; j++ ) + { + sprintf(name, "objects\\ant%d.mod", j+4); // 4..6 + + // Creates the right leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6+i*3+j, rank); + if ( j == 0 ) parent = 0; + else parent = 6+i*3+j-1; + m_object->SetObjectParent(6+i*3+j, parent); + pModFile->ReadModel(name); + pModFile->CreateEngineObject(rank); + pos.x = table[i*9+j*3+0]; + pos.y = table[i*9+j*3+1]; + pos.z = table[i*9+j*3+2]; + m_object->SetPosition(6+i*3+j, pos); + + // Creates the left leg. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(15+i*3+j, rank); + if ( j == 0 ) parent = 0; + else parent = 15+i*3+j-1; + m_object->SetObjectParent(15+i*3+j, parent); + pModFile->ReadModel(name); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + pos.x = table[i*9+j*3+0]; + pos.y = table[i*9+j*3+1]; + pos.z = -table[i*9+j*3+2]; + m_object->SetPosition(15+i*3+j, pos); + } + } + } + + if ( type == OBJECT_MOBILErt ) + { + // Creates the holder. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\roller2t.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(0.0f, 0.0f, 0.0f)); + m_object->SetAngleZ(1, 0.0f); + + // Creates the pestle. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\roller3t.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, Math::Vector(9.0f, 4.0f, 0.0f)); + m_object->SetAngleZ(2, 0.0f); + } + + if ( type == OBJECT_MOBILErc ) + { + // Creates the holder. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\roller2c.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(3.0f, 4.6f, 0.0f)); + m_object->SetAngleZ(1, Math::PI/8.0f); + + // Creates the cannon. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\roller3p.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, Math::Vector(7.0f, 6.5f, 0.0f)); + m_object->SetAngleZ(2, 0.0f); + } + + if ( type == OBJECT_MOBILErr ) + { + // Creates the holder. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\recover1.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(2.0f, 5.0f, 0.0f)); + + // Creates the right arm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 1); + pModFile->ReadModel("objects\\recover2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, Math::Vector(0.1f, 0.0f, -5.0f)); + m_object->SetAngleZ(2, 126.0f*Math::PI/180.0f); + + // Creates the right forearm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 2); + pModFile->ReadModel("objects\\recover3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, Math::Vector(5.0f, 0.0f, -0.5f)); + m_object->SetAngleZ(3, -144.0f*Math::PI/180.0f); + + // Creates the left arm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(4, rank); + m_object->SetObjectParent(4, 1); + pModFile->ReadModel("objects\\recover2.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(4, Math::Vector(0.1f, 0.0f, 5.0f)); + m_object->SetAngleZ(4, 126.0f*Math::PI/180.0f); + + // Creates the left forearm. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(5, rank); + m_object->SetObjectParent(5, 4); + pModFile->ReadModel("objects\\recover3.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(5, Math::Vector(5.0f, 0.0f, 0.5f)); + m_object->SetAngleZ(5, -144.0f*Math::PI/180.0f); + } + + if ( type == OBJECT_MOBILErs ) + { + // Creates the holder. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\roller2s.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(0.0f, 0.0f, 0.0f)); + m_object->SetAngleZ(1, 0.0f); + + // Creates the intermediate piston. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 1); + pModFile->ReadModel("objects\\roller3s.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, Math::Vector(7.0f, 4.5f, 0.0f)); + m_object->SetAngleZ(2, 0.0f); + + // Creates the piston with the sphere. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 2); + pModFile->ReadModel("objects\\roller4s.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, Math::Vector(0.0f, 1.0f, 0.0f)); + m_object->SetAngleZ(3, 0.0f); + } + + if ( type == OBJECT_MOBILEsa ) + { + // Creates the holder. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\subm2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(4.2f, 3.0f, 0.0f)); + + // Creates the right tong. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 1); + pModFile->ReadModel("objects\\subm3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, Math::Vector(0.5f, 0.0f, -1.5f)); + + // Creates the left tong. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(3, rank); + m_object->SetObjectParent(3, 1); + pModFile->ReadModel("objects\\subm3.mod"); + pModFile->Mirror(); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(3, Math::Vector(0.5f, 0.0f, 1.5f)); + } + + if ( type == OBJECT_MOBILEdr ) + { + // Creates the carousel. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\drawer4.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(-3.0f, 3.0f, 0.0f)); + + // Creates the key. + if ( m_object->RetToy() ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\drawer5.mod"); + pModFile->CreateEngineObject(rank); + m_posKey = Math::Vector(3.0f, 5.7f, 0.0f); + m_object->SetPosition(2, m_posKey); + m_object->SetAngleY(2, 90.0f*Math::PI/180.0f); + } + + // Creates pencils. + for ( i=0 ; i<8 ; i++ ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(10+i, rank); + m_object->SetObjectParent(10+i, 1); + sprintf(name, "objects\\drawer%d.mod", 10+i); + pModFile->ReadModel(name); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(10+i, Math::Vector(0.0f, 0.0f, 0.0f)); + m_object->SetAngleY(10+i, 45.0f*Math::PI/180.0f*i); + } + } + + if ( type == OBJECT_MOBILEwt ) + { + // Creates the key. + if ( m_object->RetToy() ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\drawer5.mod"); + pModFile->CreateEngineObject(rank); + m_posKey = Math::Vector(0.2f, 4.1f, 0.0f); + m_object->SetPosition(2, m_posKey); + m_object->SetAngleY(2, 90.0f*Math::PI/180.0f); + } + } + + if ( type == OBJECT_APOLLO2 ) + { + // Creates the accessories. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\apolloj2.mod"); // antenna + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(5.5f, 8.8f, 2.0f)); + m_object->SetAngleY(1, -120.0f*Math::PI/180.0f); + m_object->SetAngleZ(1, 45.0f*Math::PI/180.0f); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2, rank); + m_object->SetObjectParent(2, 0); + pModFile->ReadModel("objects\\apolloj3.mod"); // camera + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2, Math::Vector(5.5f, 2.8f, -2.0f)); + m_object->SetAngleY(2, 30.0f*Math::PI/180.0f); + + // Creates the wheels. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(6, rank); + m_object->SetObjectParent(6, 0); + pModFile->ReadModel("objects\\apolloj4.mod"); // wheel + pModFile->CreateEngineObject(rank); + m_object->SetPosition(6, Math::Vector(-5.75f, 1.65f, -5.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(7, rank); + m_object->SetObjectParent(7, 0); + pModFile->ReadModel("objects\\apolloj4.mod"); // wheel + pModFile->CreateEngineObject(rank); + m_object->SetPosition(7, Math::Vector(-5.75f, 1.65f, 5.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(8, rank); + m_object->SetObjectParent(8, 0); + pModFile->ReadModel("objects\\apolloj4.mod"); // wheel + pModFile->CreateEngineObject(rank); + m_object->SetPosition(8, Math::Vector(5.75f, 1.65f, -5.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(9, rank); + m_object->SetObjectParent(9, 0); + pModFile->ReadModel("objects\\apolloj4.mod"); // wheel + pModFile->CreateEngineObject(rank); + m_object->SetPosition(9, Math::Vector(5.75f, 1.65f, 5.00f)); + + // Creates mud guards. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(10, rank); + m_object->SetObjectParent(10, 0); + pModFile->ReadModel("objects\\apolloj6.mod"); // wheel + pModFile->CreateEngineObject(rank); + m_object->SetPosition(10, Math::Vector(-5.75f, 1.65f, -5.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(11, rank); + m_object->SetObjectParent(11, 0); + pModFile->ReadModel("objects\\apolloj6.mod"); // wheel + pModFile->CreateEngineObject(rank); + m_object->SetPosition(11, Math::Vector(-5.75f, 1.65f, 5.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(12, rank); + m_object->SetObjectParent(12, 0); + pModFile->ReadModel("objects\\apolloj5.mod"); // wheel + pModFile->CreateEngineObject(rank); + m_object->SetPosition(12, Math::Vector(5.75f, 1.65f, -5.0f)); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(13, rank); + m_object->SetObjectParent(13, 0); + pModFile->ReadModel("objects\\apolloj5.mod"); // wheel + pModFile->CreateEngineObject(rank); + m_object->SetPosition(13, Math::Vector(5.75f, 1.65f, 5.00f)); + } + +#if 1 + if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) + { + m_object->CreateShadowCircle(6.0f, 1.0f); + } + else if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILEsa ) + { + m_object->CreateShadowCircle(5.0f, 1.0f); + } + else if ( type == OBJECT_MOBILEdr ) + { + m_object->CreateShadowCircle(4.5f, 1.0f); + } + else if ( type == OBJECT_APOLLO2 ) + { + m_object->CreateShadowCircle(7.0f, 0.8f); + } + else + { + m_object->CreateShadowCircle(4.0f, 1.0f); + } +#else + if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) + { + m_object->CreateShadowCircle(6.0f, 1.0f, D3DSHADOWTANK); + } + else if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts ) + { + m_object->CreateShadowCircle(4.0f, 1.0f, D3DSHADOWTANK); + } + else if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEfs ) + { + m_object->CreateShadowCircle(4.0f, 1.0f, D3DSHADOWFLY); + } + else if ( type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEws ) + { + m_object->CreateShadowCircle(4.0f, 1.0f, D3DSHADOWWHEEL); + } + else if ( type == OBJECT_APOLLO2 ) + { + m_object->CreateShadowCircle(6.0f, 0.8f); + } + else + { + m_object->CreateShadowCircle(4.0f, 1.0f, D3DSHADOWNORM); + } +#endif + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEft ) // flying? + { +//? color.r = 0.5f-1.0f; +//? color.g = 0.2f-1.0f; +//? color.b = 0.0f-1.0f; // orange +//? color.r = 0.8f; +//? color.g = 0.6f; +//? color.b = 0.0f; // yellow-orange + color.r = 0.0f; + color.g = 0.4f; + color.b = 0.8f; // blue + color.a = 0.0f; + m_object->CreateShadowLight(50.0f, color); + } + + CreatePhysics(type); + m_object->SetFloorHeight(0.0f); + + if ( power > 0.0f && + type != OBJECT_MOBILEdr && + type != OBJECT_APOLLO2 ) + { + color.r = 1.0f; + color.g = 1.0f; + color.b = 0.0f; // yellow + color.a = 0.0f; + m_object->CreateEffectLight(20.0f, color); + + // Creates the battery. + pPower = new CObject(m_iMan); + pPower->SetType(power<=1.0f?OBJECT_POWER:OBJECT_ATOMIC); + + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEFIX); + pPower->SetObjectRank(0, rank); + + if ( power <= 1.0f ) pModFile->ReadModel("objects\\power.mod"); + else pModFile->ReadModel("objects\\atomic.mod"); + pModFile->CreateEngineObject(rank); + + pPower->SetPosition(0, m_object->RetCharacter()->posPower); + pPower->CreateCrashSphere(Math::Vector(0.0f, 1.0f, 0.0f), 1.0f, SOUND_BOUMm, 0.45f); + pPower->SetGlobalSphere(Math::Vector(0.0f, 1.0f, 0.0f), 1.5f); + + pPower->SetTruck(m_object); + m_object->SetPower(pPower); + + if ( power <= 1.0f ) pPower->SetEnergy(power); + else pPower->SetEnergy(power/100.0f); + } + + pos = m_object->RetPosition(0); + m_object->SetPosition(0, pos); //to display the shadows immediately + + m_engine->LoadAllTexture(); + + delete pModFile; + return true; +} + +// Creates the physics of the object. + +void CMotionVehicle::CreatePhysics(ObjectType type) +{ + Character* character; + + character = m_object->RetCharacter(); + + if ( type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEwt ) // wheels? + { + m_physics->SetType(TYPE_ROLLING); + + character->wheelFront = 3.0f; + character->wheelBack = 4.0f; + character->wheelLeft = 4.0f; + character->wheelRight = 4.0f; + character->posPower = Math::Vector(-3.2f, 3.0f, 0.0f); + + m_physics->SetLinMotionX(MO_ADVSPEED, 20.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 10.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 40.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 50.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 30.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 20.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.8f*Math::PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.8f*Math::PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 8.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 8.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 12.0f); + } + + if ( type == OBJECT_MOBILEtg ) + { + m_physics->SetType(TYPE_ROLLING); + + character->wheelFront = 4.0f; + character->wheelBack = 3.0f; + character->wheelLeft = 4.0f; + character->wheelRight = 4.0f; + character->posPower = Math::Vector(-3.2f, 3.0f, 0.0f); + + m_physics->SetLinMotionX(MO_ADVSPEED, 20.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 10.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 40.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 50.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 20.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 20.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.8f*Math::PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.8f*Math::PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 10.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 15.0f); + } + + if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts ) // caterpillars? + { + m_physics->SetType(TYPE_ROLLING); + + character->wheelFront = 4.0f; + character->wheelBack = 4.0f; + character->wheelLeft = 4.8f; + character->wheelRight = 4.8f; + character->posPower = Math::Vector(-3.2f, 3.0f, 0.0f); + + m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 8.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 15.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 8.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 20.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.5f*Math::PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.5f*Math::PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 10.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 6.0f); + } + + if ( type == OBJECT_MOBILEia || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEis ) // legs? + { + m_physics->SetType(TYPE_ROLLING); + + character->wheelFront = 4.0f; + character->wheelBack = 4.0f; + character->wheelLeft = 5.0f; + character->wheelRight = 5.0f; + character->posPower = Math::Vector(-3.2f, 3.0f, 0.0f); + + m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 8.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 40.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 10.0f); +//? m_physics->SetLinMotionX(MO_TERFORCE, 15.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.5f*Math::PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.5f*Math::PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 10.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 15.0f); + } + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEft ) // flying? + { + m_physics->SetType(TYPE_FLYING); + + character->wheelFront = 5.0f; + character->wheelBack = 4.0f; + character->wheelLeft = 4.5f; + character->wheelRight = 4.5f; + character->posPower = Math::Vector(-3.2f, 3.0f, 0.0f); + + m_physics->SetLinMotionX(MO_ADVSPEED, 50.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 50.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 20.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 50.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 50.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + m_physics->SetLinMotionY(MO_ADVSPEED, 60.0f); + m_physics->SetLinMotionY(MO_RECSPEED, 60.0f); + m_physics->SetLinMotionY(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionY(MO_RECACCEL, 50.0f); + m_physics->SetLinMotionY(MO_STOACCEL, 50.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.4f*Math::PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.4f*Math::PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 2.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 2.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 2.0f); + } + + if ( type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs ) // large caterpillars? + { + m_physics->SetType(TYPE_ROLLING); + + character->wheelFront = 5.0f; + character->wheelBack = 5.0f; + character->wheelLeft = 6.0f; + character->wheelRight = 6.0f; + character->posPower = Math::Vector(-5.8f, 4.0f, 0.0f); + + m_physics->SetLinMotionX(MO_ADVSPEED, 10.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 5.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 10.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 5.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 20.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.3f*Math::PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.3f*Math::PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 2.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 2.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 4.0f); + } + + if ( type == OBJECT_MOBILEsa ) + { + m_physics->SetType(TYPE_ROLLING); + + character->wheelFront = 4.0f; + character->wheelBack = 4.0f; + character->wheelLeft = 4.0f; + character->wheelRight = 4.0f; + character->posPower = Math::Vector(-5.0f, 3.0f, 0.0f); + + m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 10.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 10.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 20.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.5f*Math::PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.5f*Math::PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 5.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 5.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 10.0f); + } + + if ( type == OBJECT_MOBILEdr ) + { + m_physics->SetType(TYPE_ROLLING); + + character->wheelFront = 4.0f; + character->wheelBack = 4.0f; + character->wheelLeft = 4.0f; + character->wheelRight = 4.0f; + character->posPower = Math::Vector(-5.0f, 3.0f, 0.0f); + + m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 10.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 10.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 20.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.5f*Math::PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.5f*Math::PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 5.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 5.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 10.0f); + } + + if ( type == OBJECT_APOLLO2 ) // jeep? + { + m_physics->SetType(TYPE_ROLLING); + + character->wheelFront = 6.0f; + character->wheelBack = 6.0f; + character->wheelLeft = 5.0f; + character->wheelRight = 5.0f; + + m_physics->SetLinMotionX(MO_ADVSPEED, 15.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 10.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 20.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 20.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 2.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 2.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 30.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 10.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 20.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.4f*Math::PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.4f*Math::PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 2.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 2.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 4.0f); + } +} + + +// Management of an event. + +bool CMotionVehicle::EventProcess(const Event &event) +{ + CMotion::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + if ( event.event == EVENT_KEYDOWN ) + { + } + + return true; +} + +// Management of an event. + +bool CMotionVehicle::EventFrame(const Event &event) +{ + Math::Matrix* mat; + Character* character; + Math::Vector pos, angle, floor; + ObjectType type; + float s, a, speedBL, speedBR, speedFL, speedFR, h, a1, a2; + float back, front, dist, radius, limit[2]; + + if ( m_engine->RetPause() ) return true; + if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return true; + + type = m_object->RetType(); + + if ( type == OBJECT_MOBILEwa || + type == OBJECT_MOBILEwc || + type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEws || + type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEtg || + type == OBJECT_APOLLO2 ) // wheels? + { + s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.0f; + a = m_physics->RetCirMotionY(MO_MOTSPEED)*3.0f; + + if ( type == OBJECT_APOLLO2 ) s *= 0.5f; + + speedBR = -s+a; + speedBL = s+a; + speedFR = -s+a; + speedFL = s+a; + + m_object->SetAngleZ(6, m_object->RetAngleZ(6)+event.rTime*speedBR); // turning the wheels + m_object->SetAngleZ(7, m_object->RetAngleZ(7)+event.rTime*speedBL); + m_object->SetAngleZ(8, m_object->RetAngleZ(8)+event.rTime*speedFR); + m_object->SetAngleZ(9, m_object->RetAngleZ(9)+event.rTime*speedFL); + + if ( s > 0.0f ) + { + m_wheelTurn[0] = -a*0.05f; + m_wheelTurn[1] = -a*0.05f+Math::PI; + m_wheelTurn[2] = a*0.05f; + m_wheelTurn[3] = a*0.05f+Math::PI; + } + else if ( s < 0.0f ) + { + m_wheelTurn[0] = a*0.05f; + m_wheelTurn[1] = a*0.05f+Math::PI; + m_wheelTurn[2] = -a*0.05f; + m_wheelTurn[3] = -a*0.05f+Math::PI; + } + else + { + m_wheelTurn[0] = fabs(a)*0.05f; + m_wheelTurn[1] = -fabs(a)*0.05f+Math::PI; + m_wheelTurn[2] = -fabs(a)*0.05f; + m_wheelTurn[3] = fabs(a)*0.05f+Math::PI; + } + m_object->SetAngleY(6, m_object->RetAngleY(6)+(m_wheelTurn[0]-m_object->RetAngleY(6))*event.rTime*8.0f); + m_object->SetAngleY(7, m_object->RetAngleY(7)+(m_wheelTurn[1]-m_object->RetAngleY(7))*event.rTime*8.0f); + m_object->SetAngleY(8, m_object->RetAngleY(8)+(m_wheelTurn[2]-m_object->RetAngleY(8))*event.rTime*8.0f); + m_object->SetAngleY(9, m_object->RetAngleY(9)+(m_wheelTurn[3]-m_object->RetAngleY(9))*event.rTime*8.0f); + + if ( type == OBJECT_APOLLO2 ) + { + m_object->SetAngleY(10, m_object->RetAngleY(6)+(m_wheelTurn[0]-m_object->RetAngleY(6))*event.rTime*8.0f); + m_object->SetAngleY(11, m_object->RetAngleY(7)+(m_wheelTurn[1]-m_object->RetAngleY(7))*event.rTime*8.0f+Math::PI); + m_object->SetAngleY(12, m_object->RetAngleY(8)+(m_wheelTurn[2]-m_object->RetAngleY(8))*event.rTime*8.0f); + m_object->SetAngleY(13, m_object->RetAngleY(9)+(m_wheelTurn[3]-m_object->RetAngleY(9))*event.rTime*8.0f+Math::PI); + } + + pos = m_object->RetPosition(0); + angle = m_object->RetAngle(0); + if ( pos.x != m_wheelLastPos.x || + pos.y != m_wheelLastPos.y || + pos.z != m_wheelLastPos.z || + angle.x != m_wheelLastAngle.x || + angle.y != m_wheelLastAngle.y || + angle.z != m_wheelLastAngle.z ) + { + m_wheelLastPos = pos; + m_wheelLastAngle = angle; + + if ( type == OBJECT_MOBILEtg ) + { + back = -2.0f; // back wheels position + front = 3.0f; // front wheels position + dist = 3.0f; // distancing wheels Z + radius = 1.0f; + } + else if ( type == OBJECT_APOLLO2 ) + { + back = -5.75f; // back wheels position + front = 5.75f; // front wheels position + dist = 5.00f; // distancing wheels Z + radius = 1.65f; + } + else + { + back = -3.0f; // back wheels position + front = 2.0f; // front wheels position + dist = 3.0f; // distancing wheels Z + radius = 1.0f; + } + + if ( Math::Distance(pos, m_engine->RetEyePt()) < 50.0f ) // suspension? + { + character = m_object->RetCharacter(); + mat = m_object->RetWorldMatrix(0); + + pos.x = -character->wheelBack; // right back wheel + pos.z = -character->wheelRight; + pos.y = 0.0f; + pos = Math::Transform(*mat, pos); + h = m_terrain->RetFloorHeight(pos); + if ( h > 0.5f ) h = 0.5f; + if ( h < -0.5f ) h = -0.5f; + pos.x = back; + pos.y = radius-h; + pos.z = -dist; + m_object->SetPosition(6, pos); + if ( type == OBJECT_APOLLO2 ) m_object->SetPosition(10, pos); + + pos.x = -character->wheelBack; // left back wheel + pos.z = character->wheelLeft; + pos.y = 0.0f; + pos = Math::Transform(*mat, pos); + h = m_terrain->RetFloorHeight(pos); + if ( h > 0.5f ) h = 0.5f; + if ( h < -0.5f ) h = -0.5f; + pos.x = back; + pos.y = radius-h; + pos.z = dist; + m_object->SetPosition(7, pos); + if ( type == OBJECT_APOLLO2 ) m_object->SetPosition(11, pos); + + pos.x = character->wheelFront; // right front wheel + pos.z = -character->wheelRight; + pos.y = 0.0f; + pos = Math::Transform(*mat, pos); + h = m_terrain->RetFloorHeight(pos); + if ( h > 0.5f ) h = 0.5f; + if ( h < -0.5f ) h = -0.5f; + pos.x = front; + pos.y = radius-h; + pos.z = -dist; + m_object->SetPosition(8, pos); + if ( type == OBJECT_APOLLO2 ) m_object->SetPosition(12, pos); + + pos.x = character->wheelFront; // left front wheel + pos.z = character->wheelLeft; + pos.y = 0.0f; + pos = Math::Transform(*mat, pos); + h = m_terrain->RetFloorHeight(pos); + if ( h > 0.5f ) h = 0.5f; + if ( h < -0.5f ) h = -0.5f; + pos.x = front; + pos.y = radius-h; + pos.z = dist; + m_object->SetPosition(9, pos); + if ( type == OBJECT_APOLLO2 ) m_object->SetPosition(13, pos); + } + else + { + m_object->SetPosition(6, Math::Vector(back, radius, -dist)); + m_object->SetPosition(7, Math::Vector(back, radius, dist)); + m_object->SetPosition(8, Math::Vector(front, radius, -dist)); + m_object->SetPosition(9, Math::Vector(front, radius, dist)); + + if ( type == OBJECT_APOLLO2 ) + { + m_object->SetPosition(10, Math::Vector(back, radius, -dist)); + m_object->SetPosition(11, Math::Vector(back, radius, dist)); + m_object->SetPosition(12, Math::Vector(front, radius, -dist)); + m_object->SetPosition(13, Math::Vector(front, radius, dist)); + } + } + } + } + + if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts || + type == OBJECT_MOBILErt || + type == OBJECT_MOBILErc || + type == OBJECT_MOBILErr || + type == OBJECT_MOBILErs || + type == OBJECT_MOBILEsa || + type == OBJECT_MOBILEdr ) // caterpillars? + { + s = m_physics->RetLinMotionX(MO_MOTSPEED)*0.7f; + a = m_physics->RetCirMotionY(MO_MOTSPEED)*2.5f; + + m_posTrackLeft += event.rTime*(s+a); + m_posTrackRight += event.rTime*(s-a); + + UpdateTrackMapping(m_posTrackLeft, m_posTrackRight, type); + + pos = m_object->RetPosition(0); + angle = m_object->RetAngle(0); + if ( pos.x != m_wheelLastPos.x || + pos.y != m_wheelLastPos.y || + pos.z != m_wheelLastPos.z || + angle.x != m_wheelLastAngle.x || + angle.y != m_wheelLastAngle.y || + angle.z != m_wheelLastAngle.z ) + { + m_wheelLastPos = pos; + m_wheelLastAngle = angle; + + if ( type == OBJECT_MOBILEta || + type == OBJECT_MOBILEtc || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEts ) + { + limit[0] = 8.0f*Math::PI/180.0f; + limit[1] = -12.0f*Math::PI/180.0f; + } + else if ( type == OBJECT_MOBILEsa ) + { + limit[0] = 15.0f*Math::PI/180.0f; + limit[1] = -15.0f*Math::PI/180.0f; + } + else if ( type == OBJECT_MOBILEdr ) + { + limit[0] = 10.0f*Math::PI/180.0f; + limit[1] = -10.0f*Math::PI/180.0f; + } + else + { + limit[0] = 15.0f*Math::PI/180.0f; + limit[1] = -10.0f*Math::PI/180.0f; + } + + if ( Math::Distance(pos, m_engine->RetEyePt()) < 50.0f ) // suspension? + { + character = m_object->RetCharacter(); + mat = m_object->RetWorldMatrix(0); + + pos.x = character->wheelFront; // right front wheel + pos.z = -character->wheelRight; + pos.y = 0.0f; + pos = Transform(*mat, pos); + a1 = atanf(m_terrain->RetFloorHeight(pos)/character->wheelFront); + + pos.x = -character->wheelBack; // right back wheel + pos.z = -character->wheelRight; + pos.y = 0.0f; + pos = Transform(*mat, pos); + a2 = atanf(m_terrain->RetFloorHeight(pos)/character->wheelBack); + + a = (a2-a1)/2.0f; + if ( a > limit[0] ) a = limit[0]; + if ( a < limit[1] ) a = limit[1]; + m_object->SetAngleZ(6, a); + + pos.x = character->wheelFront; // left front wheel + pos.z = character->wheelLeft; + pos.y = 0.0f; + pos = Transform(*mat, pos); + a1 = atanf(m_terrain->RetFloorHeight(pos)/character->wheelFront); + + pos.x = -character->wheelBack; // left back wheel + pos.z = character->wheelLeft; + pos.y = 0.0f; + pos = Transform(*mat, pos); + a2 = atanf(m_terrain->RetFloorHeight(pos)/character->wheelBack); + + a = (a2-a1)/2.0f; + if ( a > limit[0] ) a = limit[0]; + if ( a < limit[1] ) a = limit[1]; + m_object->SetAngleZ(7, a); + } + else + { + m_object->SetAngleZ(6, 0.0f); + m_object->SetAngleZ(7, 0.0f); + } + } + } + + if ( type == OBJECT_MOBILEwt || + type == OBJECT_MOBILEdr ) // toy is key? + { + pos = m_posKey; + if ( m_object->RetSelect() && + m_camera->RetType() == CAMERA_ONBOARD ) + { + pos.y += 10.0f; // out of sight! + } + m_object->SetPosition(2, pos); + + s = -fabs(m_physics->RetLinMotionX(MO_MOTSPEED)*0.1f); + s += -fabs(m_physics->RetCirMotionY(MO_MOTSPEED)*1.5f); + m_object->SetAngleY(2, m_object->RetAngleY(2)+event.rTime*s); // turns the key + } + + if ( type == OBJECT_MOBILEfa || + type == OBJECT_MOBILEfc || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEfs || + type == OBJECT_MOBILEft ) // flying? + { + EventFrameFly(event); + } + + if ( type == OBJECT_MOBILEia || + type == OBJECT_MOBILEic || + type == OBJECT_MOBILEii || + type == OBJECT_MOBILEis ) // legs? + { + EventFrameInsect(event); + } + + if ( type == OBJECT_MOBILEwi || + type == OBJECT_MOBILEti || + type == OBJECT_MOBILEfi || + type == OBJECT_MOBILEii ) // insect cannon? + { + EventFrameCanoni(event); + } + + return true; +} + +// Managing an event for a flying robot. + +bool CMotionVehicle::EventFrameFly(const Event &event) +{ + Math::Matrix* mat; + Math::Vector pos, angle, paw[3]; + float hope[3], actual, final, h, a; + int i; + + pos = m_object->RetPosition(0); + angle = m_object->RetAngle(0); + if ( m_bFlyFix && + pos.x == m_wheelLastPos.x && + pos.y == m_wheelLastPos.y && + pos.z == m_wheelLastPos.z && + angle.x == m_wheelLastAngle.x && + angle.y == m_wheelLastAngle.y && + angle.z == m_wheelLastAngle.z ) return true; + + m_wheelLastPos = pos; + m_wheelLastAngle = angle; + + if ( m_physics->RetLand() ) // on the ground? + { + mat = m_object->RetWorldMatrix(0); + paw[0] = Transform(*mat, Math::Vector( 4.2f, 0.0f, 0.0f)); // front + paw[1] = Transform(*mat, Math::Vector(-3.0f, 0.0f, -3.7f)); // right back + paw[2] = Transform(*mat, Math::Vector(-3.0f, 0.0f, 3.7f)); // left back + + for ( i=0 ; i<3 ; i++ ) + { + h = m_terrain->RetFloorHeight(paw[i]); + a = -atanf(h*0.5f); + if ( a > Math::PI*0.2f ) a = Math::PI*0.2f; + if ( a < -Math::PI*0.2f ) a = -Math::PI*0.2f; + hope[i] = a; + } + } + else // in flight? + { + hope[0] = 0.0f; // front + hope[1] = 0.0f; // right back + hope[2] = 0.0f; // left back + } + + m_bFlyFix = true; + for ( i=0 ; i<3 ; i++ ) + { + actual = m_object->RetAngleZ(6+i); + final = Math::Smooth(actual, hope[i], event.rTime*5.0f); + if ( final != actual ) + { + m_bFlyFix = false; // it is moving + m_object->SetAngleZ(6+i, final); + } + } + + return true; +} + +// Event management for insect legs. + +bool CMotionVehicle::EventFrameInsect(const Event &event) +{ + Math::Vector dir; + float s, a, prog, time; + int i, st, nd, action; + bool bStop, bOnBoard; + + static int table[] = + { + // x1,y1,z1, x2,y2,z2, x3,y3,z3, // in the air: + 60,25,0, 60,0,0, 60,-25,0, // t0: thighs 1..4 + -35,0,0, -35,0,0, -35,0,0, // t0: legs 1..4 + -65,0,0, -65,0,0, -65,0,0, // t0: feet 1..4 + // on the ground: + 30,10,0, 30,-15,0, 30,-40,0, // t1: thighs 1..4 + -45,0,0, -45,0,0, -45,0,0, // t1: legs 1..4 + -20,0,0, -20,0,0, -20,0,0, // t1: feet 1..4 + // on the ground back: + 35,40,0, 40,15,0, 40,-10,0, // t2: thighs 1..4 + -35,0,0, -35,0,0, -35,0,0, // t2: legs 1..4 + -50,0,0, -65,0,0, -65,0,0, // t2: feet 1..4 + // stop: + 35,35,0, 40,10,0, 40,-15,0, // s0: thighs 1..4 + -35,0,0, -35,0,0, -35,0,0, // s0: legs 1..4 + -50,0,0, -65,0,0, -65,0,0, // s0: feet 1..4 + }; + + bOnBoard = false; + if ( m_object->RetSelect() && + m_camera->RetType() == CAMERA_ONBOARD ) + { + bOnBoard = true; + } + + s = m_physics->RetLinMotionX(MO_MOTSPEED)*1.5f; + a = fabs(m_physics->RetCirMotionY(MO_MOTSPEED)*2.0f); + + if ( s == 0.0f && a != 0.0f ) a *= 1.5f; + + m_armTimeAbs += event.rTime; + m_armMember += (s+a)*event.rTime*0.15f; + + bStop = ( a == 0.0f && s == 0.0f ); // stop? + + action = 0; // walking + if ( s == 0.0f && a == 0.0f ) + { + action = 3; // stop + } + + if ( bStop ) + { + prog = Math::Mod(m_armTimeAbs, 2.0f)/10.0f; + a = Math::Mod(m_armMember, 1.0f); + a = (prog-a)*event.rTime*2.0f; // stop position is pleasantly + m_armMember += a; + } + + if ( m_object->RetRuin() ) // burn or explode? + { + action = 3; + } + + for ( i=0 ; i<6 ; i++ ) // the six legs + { + if ( action != 0 ) // special action in progress? + { + st = 3*3*3*action + (i%3)*3; + nd = st; + time = event.rTime*5.0f; + } + else + { + if ( i < 3 ) prog = Math::Mod(m_armMember+(2.0f-(i%3))*0.33f+0.0f, 1.0f); + else prog = Math::Mod(m_armMember+(2.0f-(i%3))*0.33f+0.3f, 1.0f); + if ( prog < 0.33f ) // t0..t1 ? + { + prog = prog/0.33f; // 0..1 + st = 0; // index start + nd = 1; // index end + } + else if ( prog < 0.67f ) // t1..t2 ? + { + prog = (prog-0.33f)/0.33f; // 0..1 + st = 1; // index start + nd = 2; // index end + } + else // t2..t0 ? + { + prog = (prog-0.67f)/0.33f; // 0..1 + st = 2; // index start + nd = 0; // index end + } + st = 3*3*3*action + st*3*3*3 + (i%3)*3; + nd = 3*3*3*action + nd*3*3*3 + (i%3)*3; + + // Less and less soft ... + time = event.rTime*20.0f; + } + + if ( i < 3 ) // right leg (1..3) ? + { + m_object->SetAngleX(6+3*i+0, Math::Smooth(m_object->RetAngleX(6+3*i+0), Math::PropAngle(table[st+ 0], table[nd+ 0], prog), time)); + m_object->SetAngleY(6+3*i+0, Math::Smooth(m_object->RetAngleY(6+3*i+0), Math::PropAngle(table[st+ 1], table[nd+ 1], prog), time)); + m_object->SetAngleZ(6+3*i+0, Math::Smooth(m_object->RetAngleZ(6+3*i+0), Math::PropAngle(table[st+ 2], table[nd+ 2], prog), time)); + m_object->SetAngleX(6+3*i+1, Math::Smooth(m_object->RetAngleX(6+3*i+1), Math::PropAngle(table[st+ 9], table[nd+ 9], prog), time)); + m_object->SetAngleY(6+3*i+1, Math::Smooth(m_object->RetAngleY(6+3*i+1), Math::PropAngle(table[st+10], table[nd+10], prog), time)); + m_object->SetAngleZ(6+3*i+1, Math::Smooth(m_object->RetAngleZ(6+3*i+1), Math::PropAngle(table[st+11], table[nd+11], prog), time)); + m_object->SetAngleX(6+3*i+2, Math::Smooth(m_object->RetAngleX(6+3*i+2), Math::PropAngle(table[st+18], table[nd+18], prog), time)); + m_object->SetAngleY(6+3*i+2, Math::Smooth(m_object->RetAngleY(6+3*i+2), Math::PropAngle(table[st+19], table[nd+19], prog), time)); + m_object->SetAngleZ(6+3*i+2, Math::Smooth(m_object->RetAngleZ(6+3*i+2), Math::PropAngle(table[st+20], table[nd+20], prog), time)); + } + else // left leg (4..6) ? + { + m_object->SetAngleX(6+3*i+0, Math::Smooth(m_object->RetAngleX(6+3*i+0), Math::PropAngle(-table[st+ 0], -table[nd+ 0], prog), time)); + m_object->SetAngleY(6+3*i+0, Math::Smooth(m_object->RetAngleY(6+3*i+0), Math::PropAngle(-table[st+ 1], -table[nd+ 1], prog), time)); + m_object->SetAngleZ(6+3*i+0, Math::Smooth(m_object->RetAngleZ(6+3*i+0), Math::PropAngle( table[st+ 2], table[nd+ 2], prog), time)); + m_object->SetAngleX(6+3*i+1, Math::Smooth(m_object->RetAngleX(6+3*i+1), Math::PropAngle(-table[st+ 9], -table[nd+ 9], prog), time)); + m_object->SetAngleY(6+3*i+1, Math::Smooth(m_object->RetAngleY(6+3*i+1), Math::PropAngle(-table[st+10], -table[nd+10], prog), time)); + m_object->SetAngleZ(6+3*i+1, Math::Smooth(m_object->RetAngleZ(6+3*i+1), Math::PropAngle( table[st+11], table[nd+11], prog), time)); + m_object->SetAngleX(6+3*i+2, Math::Smooth(m_object->RetAngleX(6+3*i+2), Math::PropAngle(-table[st+18], -table[nd+18], prog), time)); + m_object->SetAngleY(6+3*i+2, Math::Smooth(m_object->RetAngleY(6+3*i+2), Math::PropAngle(-table[st+19], -table[nd+19], prog), time)); + m_object->SetAngleZ(6+3*i+2, Math::Smooth(m_object->RetAngleZ(6+3*i+2), Math::PropAngle( table[st+20], table[nd+20], prog), time)); + } + } + + if ( bStop ) + { + } + else + { + a = Math::Mod(m_armMember, 1.0f); + if ( a < 0.5f ) a = -1.0f+4.0f*a; // -1..1 + else a = 3.0f-4.0f*a; // 1..-1 + dir.x = sinf(a)*0.05f; + + s = Math::Mod(m_armMember/2.0f, 1.0f); + if ( s < 0.5f ) s = -1.0f+4.0f*s; // -1..1 + else s = 3.0f-4.0f*s; // 1..-1 + dir.z = sinf(s)*0.1f; + + dir.y = 0.0f; + + if ( bOnBoard ) dir *= 0.6f; + SetInclinaison(dir); + } + + return true; +} + +// Event management for a insect cannon. + +bool CMotionVehicle::EventFrameCanoni(const Event &event) +{ + CObject* power; + Math::Vector pos, speed; + Math::Point dim; + float zoom, angle, energy, factor; + bool bOnBoard = false; + + m_canonTime += event.rTime; + + if ( m_object->RetSelect() && + m_camera->RetType() == CAMERA_ONBOARD ) + { + bOnBoard = true; + } + + power = m_object->RetPower(); + if ( power == 0 ) + { + energy = 0.0f; + } + else + { + energy = power->RetEnergy(); + } + if ( energy == 0.0f ) return true; + + factor = 0.5f+energy*0.5f; + if ( bOnBoard ) factor *= 0.8f; + + zoom = 1.3f+ + sinf(m_canonTime*Math::PI*0.31f)*0.10f+ + sinf(m_canonTime*Math::PI*0.52f)*0.08f+ + sinf(m_canonTime*Math::PI*1.53f)*0.05f; + zoom *= factor; + m_object->SetZoomY(2, zoom); + + zoom = 1.0f+ + sinf(m_canonTime*Math::PI*0.27f)*0.07f+ + sinf(m_canonTime*Math::PI*0.62f)*0.06f+ + sinf(m_canonTime*Math::PI*1.73f)*0.03f; + zoom *= factor; + m_object->SetZoomZ(2, zoom); + + angle = sinf(m_canonTime*1.0f)*0.10f+ + sinf(m_canonTime*1.3f)*0.15f+ + sinf(m_canonTime*2.7f)*0.05f; + m_object->SetAngleX(2, angle); + +#if 0 + m_lastTimeCanon -= event.rTime; + if ( m_lastTimeCanon <= 0.0f ) + { + m_lastTimeCanon = m_engine->ParticuleAdapt(0.5f+Math::Rand()*0.5f); + + pos = m_object->RetPosition(0); + pos.y += 8.0f; + speed.y = 7.0f+Math::Rand()*3.0f; + speed.x = (Math::Rand()-0.5f)*2.0f; + speed.z = 2.0f+Math::Rand()*2.0f; + if ( Math::Rand() < 0.5f ) speed.z = -speed.z; + mat = m_object->RetRotateMatrix(0); + speed = Transform(*mat, speed); + dim.x = Math::Rand()*0.1f+0.1f; + if ( bOnBoard ) dim.x *= 0.4f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTIORGANIC2, 2.0f, 10.0f); + } +#endif + + return true; +} + + +// Updates the mapping of the texture of the caterpillars. + +void CMotionVehicle::UpdateTrackMapping(float left, float right, ObjectType type) +{ + D3DMATERIAL7 mat; + float limit[4]; + int rRank, lRank, i; + + ZeroMemory( &mat, sizeof(D3DMATERIAL7) ); + mat.diffuse.r = 1.0f; + mat.diffuse.g = 1.0f; + mat.diffuse.b = 1.0f; // white + mat.ambient.r = 0.5f; + mat.ambient.g = 0.5f; + mat.ambient.b = 0.5f; + + rRank = m_object->RetObjectRank(6); + lRank = m_object->RetObjectRank(7); + + + if ( type == OBJECT_MOBILEdr ) + { + limit[0] = 0.0f; + limit[1] = 1000000.0f; + limit[2] = limit[1]; + limit[3] = m_engine->RetLimitLOD(1); + + m_engine->TrackTextureMapping(rRank, mat, D3DSTATEPART1, "drawer.tga", "", + limit[0], limit[1], D3DMAPPINGX, + right, 1.0f, 8.0f, 192.0f, 256.0f); + + m_engine->TrackTextureMapping(lRank, mat, D3DSTATEPART2, "drawer.tga", "", + limit[0], limit[1], D3DMAPPINGX, + left, 1.0f, 8.0f, 192.0f, 256.0f); + } + else + { + limit[0] = 0.0f; + limit[1] = m_engine->RetLimitLOD(0); + limit[2] = limit[1]; + limit[3] = m_engine->RetLimitLOD(1); + + for ( i=0 ; i<2 ; i++ ) + { + m_engine->TrackTextureMapping(rRank, mat, D3DSTATEPART1, "lemt.tga", "", + limit[i*2+0], limit[i*2+1], D3DMAPPINGX, + right, 1.0f, 8.0f, 192.0f, 256.0f); + + m_engine->TrackTextureMapping(lRank, mat, D3DSTATEPART2, "lemt.tga", "", + limit[i*2+0], limit[i*2+1], D3DMAPPINGX, + left, 1.0f, 8.0f, 192.0f, 256.0f); + } + } + +} + + + +// State management of the pencil drawing robot. + +bool CMotionVehicle::RetTraceDown() +{ + return m_bTraceDown; +} + +void CMotionVehicle::SetTraceDown(bool bDown) +{ + m_bTraceDown = bDown; +} + +int CMotionVehicle::RetTraceColor() +{ + return m_traceColor; +} + +void CMotionVehicle::SetTraceColor(int color) +{ + m_traceColor = color; +} + +float CMotionVehicle::RetTraceWidth() +{ + return m_traceWidth; +} + +void CMotionVehicle::SetTraceWidth(float width) +{ + m_traceWidth = width; +} + + diff --git a/src/object/motion/motionvehicle.h b/src/object/motion/motionvehicle.h index d3e00f9..5ca97cd 100644 --- a/src/object/motion/motionvehicle.h +++ b/src/object/motion/motionvehicle.h @@ -1,69 +1,69 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motionvehicle.h
-
-#pragma once
-
-
-#include "object/motion/motion.h"
-
-
-
-class CMotionVehicle : public CMotion
-{
-public:
- CMotionVehicle(CInstanceManager* iMan, CObject* object);
- ~CMotionVehicle();
-
- void DeleteObject(bool bAll=false);
- bool Create(Math::Vector pos, float angle, ObjectType type, float power);
- bool EventProcess(const Event &event);
-
- bool RetTraceDown();
- void SetTraceDown(bool bDown);
- int RetTraceColor();
- void SetTraceColor(int color);
- float RetTraceWidth();
- void SetTraceWidth(float width);
-
-protected:
- void CreatePhysics(ObjectType type);
- bool EventFrame(const Event &event);
- bool EventFrameFly(const Event &event);
- bool EventFrameInsect(const Event &event);
- bool EventFrameCanoni(const Event &event);
- void UpdateTrackMapping(float left, float right, ObjectType type);
-
-protected:
- float m_wheelTurn[4];
- float m_flyPaw[3];
- float m_posTrackLeft;
- float m_posTrackRight;
- int m_partiReactor;
- float m_armTimeAbs;
- float m_armMember;
- float m_canonTime;
- float m_lastTimeCanon;
- Math::Vector m_wheelLastPos;
- Math::Vector m_wheelLastAngle;
- Math::Vector m_posKey;
- bool m_bFlyFix;
- bool m_bTraceDown;
- int m_traceColor;
- float m_traceWidth;
-};
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionvehicle.h + +#pragma once + + +#include "object/motion/motion.h" + + + +class CMotionVehicle : public CMotion +{ +public: + CMotionVehicle(CInstanceManager* iMan, CObject* object); + ~CMotionVehicle(); + + void DeleteObject(bool bAll=false); + bool Create(Math::Vector pos, float angle, ObjectType type, float power); + bool EventProcess(const Event &event); + + bool RetTraceDown(); + void SetTraceDown(bool bDown); + int RetTraceColor(); + void SetTraceColor(int color); + float RetTraceWidth(); + void SetTraceWidth(float width); + +protected: + void CreatePhysics(ObjectType type); + bool EventFrame(const Event &event); + bool EventFrameFly(const Event &event); + bool EventFrameInsect(const Event &event); + bool EventFrameCanoni(const Event &event); + void UpdateTrackMapping(float left, float right, ObjectType type); + +protected: + float m_wheelTurn[4]; + float m_flyPaw[3]; + float m_posTrackLeft; + float m_posTrackRight; + int m_partiReactor; + float m_armTimeAbs; + float m_armMember; + float m_canonTime; + float m_lastTimeCanon; + Math::Vector m_wheelLastPos; + Math::Vector m_wheelLastAngle; + Math::Vector m_posKey; + bool m_bFlyFix; + bool m_bTraceDown; + int m_traceColor; + float m_traceWidth; +}; + diff --git a/src/object/motion/motionworm.cpp b/src/object/motion/motionworm.cpp index a18b7c4..daf74ff 100644 --- a/src/object/motion/motionworm.cpp +++ b/src/object/motion/motionworm.cpp @@ -1,365 +1,365 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motionworm.cpp
-
-
-#include <stdio.h>
-
-#include "object/motion/motionworm.h"
-
-#include "old/modfile.h"
-#include "old/particule.h"
-#include "old/terrain.h"
-#include "math/geometry.h"
-#include "physics/physics.h"
-
-
-
-
-const float START_TIME = 1000.0f; // beginning of the relative time
-const float TIME_UPDOWN = 2.0f; // time for up / down
-const float DOWN_ALTITUDE = 3.0f; // underground distance
-const int WORM_PART = 7; // number of parts of a worm
-
-
-
-// Object's constructor.
-
-CMotionWorm::CMotionWorm(CInstanceManager* iMan, CObject* object)
- : CMotion(iMan, object)
-{
- m_timeUp = 18.0f;
- m_timeDown = 18.0f;
- m_armMember = START_TIME;
- m_armTimeAbs = START_TIME;
- m_armTimeMarch = START_TIME;
- m_armTimeAction = START_TIME;
- m_armTimeIndex = 0;
- m_armPartIndex = 0;
- m_armMemberIndex = 0;
- m_armLinSpeed = 0.0f;
- m_armCirSpeed = 0.0f;
- m_armLastAction = -1;
- m_specAction = -1;
- m_lastParticule = 0.0f;
- m_bArmStop = false;
-}
-
-// Object's destructor.
-
-CMotionWorm::~CMotionWorm()
-{
-}
-
-
-// Removes an object.
-
-void CMotionWorm::DeleteObject(bool bAll)
-{
-}
-
-
-// Creates a vehicle traveling any lands on the ground.
-
-bool CMotionWorm::Create(Math::Vector pos, float angle, ObjectType type,
- float power)
-{
- CModFile* pModFile;
- int rank, i;
- float px;
-
- if ( m_engine->RetRestCreate() < 2+WORM_PART+1 ) return false;
-
- pModFile = new CModFile(m_iMan);
-
- m_object->SetType(type);
-
- // Creates the main base.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object
- m_object->SetObjectRank(0, rank);
- pModFile->ReadModel("objects\\worm0.mod"); // there is no purpose!
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(0, pos);
- m_object->SetAngleY(0, angle);
-
- // A vehicle must have a obligatory collision with a sphere of center (0, y, 0) (see GetCrashSphere).
- m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f);
- m_object->SetGlobalSphere(Math::Vector(0.0f, 0.0f, 0.0f), 5.0f);
-
- px = 1.0f+WORM_PART/2;
-
- // Creates the head.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(1, rank);
- m_object->SetObjectParent(1, 0);
- pModFile->ReadModel("objects\\worm1.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(1, Math::Vector(px, 0.0f, 0.0f));
- px -= 1.0f;
-
- // Creates the body.
- for ( i=0 ; i<WORM_PART ; i++ )
- {
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2+i, rank);
- m_object->SetObjectParent(2+i, 0);
- pModFile->ReadModel("objects\\worm2.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2+i, Math::Vector(px, 0.0f, 0.0f));
- px -= 1.0f;
- }
-
- // Creates the tail.
- rank = m_engine->CreateObject();
- m_engine->SetObjectType(rank, TYPEDESCENDANT);
- m_object->SetObjectRank(2+WORM_PART, rank);
- m_object->SetObjectParent(2+WORM_PART, 0);
- pModFile->ReadModel("objects\\worm3.mod");
- pModFile->CreateEngineObject(rank);
- m_object->SetPosition(2+WORM_PART, Math::Vector(px, 0.0f, 0.0f));
-
- m_object->CreateShadowCircle(0.0f, 1.0f, D3DSHADOWWORM);
-
- CreatePhysics();
- m_object->SetFloorHeight(0.0f);
-
- pos = m_object->RetPosition(0);
- m_object->SetPosition(0, pos); // to display the shadows immediately
-
- m_engine->LoadAllTexture();
-
- delete pModFile;
- return true;
-}
-
-// Creates the physics of the object.
-
-void CMotionWorm::CreatePhysics()
-{
- Character* character;
-
- m_physics->SetType(TYPE_ROLLING);
-
- character = m_object->RetCharacter();
- character->wheelFront = 10.0f;
- character->wheelBack = 10.0f;
- character->wheelLeft = 2.0f;
- character->wheelRight = 2.0f;
- character->height = -0.2f;
-
- m_physics->SetLinMotionX(MO_ADVSPEED, 3.0f);
- m_physics->SetLinMotionX(MO_RECSPEED, 3.0f);
- m_physics->SetLinMotionX(MO_ADVACCEL, 10.0f);
- m_physics->SetLinMotionX(MO_RECACCEL, 10.0f);
- m_physics->SetLinMotionX(MO_STOACCEL, 40.0f);
- m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f);
- m_physics->SetLinMotionX(MO_TERFORCE, 5.0f);
- m_physics->SetLinMotionZ(MO_TERFORCE, 5.0f);
- m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f);
-
- m_physics->SetCirMotionY(MO_ADVSPEED, 0.2f*Math::PI);
- m_physics->SetCirMotionY(MO_RECSPEED, 0.2f*Math::PI);
- m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f);
- m_physics->SetCirMotionY(MO_RECACCEL, 10.0f);
- m_physics->SetCirMotionY(MO_STOACCEL, 20.0f);
-}
-
-
-
-// Specifies a special parameter.
-
-bool CMotionWorm::SetParam(int rank, float value)
-{
- if ( rank == 0 )
- {
- m_timeDown = value;
- return true;
- }
-
- if ( rank == 1 )
- {
- m_timeUp = value;
- return true;
- }
-
- return false;
-}
-
-float CMotionWorm::RetParam(int rank)
-{
- if ( rank == 0 ) return m_timeDown;
- if ( rank == 1 ) return m_timeUp;
- return 0.0f;
-}
-
-
-
-// Management of an event.
-
-bool CMotionWorm::EventProcess(const Event &event)
-{
- CMotion::EventProcess(event);
-
- if ( event.event == EVENT_FRAME )
- {
- return EventFrame(event);
- }
-
- if ( event.event == EVENT_KEYDOWN )
- {
- }
-
- return true;
-}
-
-// Management of an event.
-
-bool CMotionWorm::EventFrame(const Event &event)
-{
- Math::Matrix* mat;
- Math::Vector pos, p, angle, speed;
- Math::Point center, pp, dim;
- float height[WORM_PART+2];
- float floor, a, s, px, curve, phase, h, zoom, radius;
- int i, under;
-
- if ( m_engine->RetPause() ) return true;
-
- s = m_physics->RetLinMotionX(MO_MOTSPEED)/m_physics->RetLinMotionX(MO_ADVSPEED);
- a = m_physics->RetCirMotionY(MO_MOTSPEED)/m_physics->RetCirMotionY(MO_ADVSPEED);
-
- if ( s == 0.0f && a != 0.0f ) s = a;
-
- m_armLinSpeed += (s-m_armLinSpeed)*event.rTime*3.0f;
- m_armCirSpeed += (a-m_armCirSpeed)*event.rTime*1.5f;
-
- m_armTimeAbs += event.rTime;
- m_armTimeMarch += event.rTime*m_armLinSpeed;
-
- under = 0; // no piece under the ground
- for ( i=0 ; i<WORM_PART+2 ; i++ )
- {
- phase = Math::Mod(m_armTimeMarch-START_TIME-i*0.3f, TIME_UPDOWN+m_timeDown+TIME_UPDOWN+m_timeUp);
- if ( phase < TIME_UPDOWN ) // descends?
- {
- h = -(phase/TIME_UPDOWN)*DOWN_ALTITUDE;
- }
- else if ( phase < TIME_UPDOWN+m_timeDown ) // advance underground?
- {
- h = -DOWN_ALTITUDE;
- under ++; // the most of a piece entirely under ground
- }
- else if ( phase < TIME_UPDOWN+m_timeDown+TIME_UPDOWN ) // up?
- {
- h = -(1.0f-(phase-TIME_UPDOWN-m_timeDown)/TIME_UPDOWN)*DOWN_ALTITUDE;
- }
- else // advance on earth?
- {
- h = 0.0f;
- }
- if ( m_object->RetBurn() ) // is burning?
- {
- h = 0.0f; // remains on earth
- }
- h += 0.3f;
- height[i] = h;
- }
- m_object->SetVisible(under!=WORM_PART+2);
-
- if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return true;
-
- pos = m_object->RetPosition(0);
- floor = m_terrain->RetFloorLevel(pos, true);
-
- mat = m_object->RetWorldMatrix(0);
-
- px = 1.0f+WORM_PART/2;
- for ( i=0 ; i<WORM_PART+2 ; i++ )
- {
- radius = 1.0f+(height[i]-0.3f)/DOWN_ALTITUDE; // 0 = underground, 1 = surface
- radius = radius*1.3f-0.3f;
- if ( radius < 0.0f ) radius = 0.0f;
- radius *= 5.0f;
- m_engine->SetObjectShadowRadius(m_object->RetObjectRank(0), radius);
-
- pos.x = px+ sinf(m_armTimeMarch*4.0f+0.5f*i)*0.6f;
- pos.y = height[i]+sinf(m_armTimeMarch*4.0f+0.5f*i)*0.2f*m_armLinSpeed;
- pos.y += sinf(m_armTimeAbs *1.3f+0.2f*i)*0.1f;
- pos.z = sinf(m_armTimeAbs *2.0f+0.7f*i)*0.2f;
-
- curve = ((float)i-(WORM_PART+2)/2)*m_armCirSpeed*0.1f;
- center.x = 0.0f;
- center.y = 0.0f;
- pp.x = pos.x;
- pp.y = pos.z;
- pp = Math::RotatePoint(center, curve, pp);
- pos.x = pp.x;
- pos.z = pp.y;
-
- p = Transform(*mat, pos);
- pos.y += m_terrain->RetFloorLevel(p, true)-floor;
- m_object->SetPosition(i+1, pos);
-
- zoom = Math::Mod(m_armTimeAbs*0.5f+100.0f-i*0.1f, 2.0f);
- if ( zoom > 1.0f ) zoom = 2.0f-zoom;
- zoom *= 1.6f;
- if ( zoom < 1.0f ) zoom = 1.0f;
- m_object->SetZoomY(i+1, 0.2f+zoom*0.8f);
- m_object->SetZoomZ(i+1, zoom);
-
- if ( height[i] >= -1.0f && height[i] < -0.2f &&
- m_lastParticule+m_engine->ParticuleAdapt(0.2f) <= m_armTimeMarch )
- {
- m_lastParticule = m_armTimeMarch;
-
- pos = p;
- pos.y += -height[i];
- pos.x += (Math::Rand()-0.5f)*4.0f;
- pos.z += (Math::Rand()-0.5f)*4.0f;
- speed = Math::Vector(0.0f, 0.0f, 0.0f);
- dim.x = Math::Rand()*2.0f+1.5f;
- dim.y = dim.x;
- m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f);
- }
-
- px -= 1.0f;
- }
-
- for ( i=0 ; i<WORM_PART+1 ; i++ )
- {
- pos = m_object->RetPosition(i+2);
- pos -= m_object->RetPosition(i+1);
-
- angle.z = -Math::RotateAngle(Math::Point(pos.x, pos.z).Length(), pos.y);
- angle.y = Math::PI-Math::RotateAngle(pos.x, pos.z);
- angle.x = 0.0f;
- m_object->SetAngle(i+1, angle);
-
- if ( i == WORM_PART )
- {
- m_object->SetAngle(i+2, angle);
- }
- }
-
- return true;
-}
-
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionworm.cpp + + +#include <stdio.h> + +#include "object/motion/motionworm.h" + +#include "old/modfile.h" +#include "old/particule.h" +#include "old/terrain.h" +#include "math/geometry.h" +#include "physics/physics.h" + + + + +const float START_TIME = 1000.0f; // beginning of the relative time +const float TIME_UPDOWN = 2.0f; // time for up / down +const float DOWN_ALTITUDE = 3.0f; // underground distance +const int WORM_PART = 7; // number of parts of a worm + + + +// Object's constructor. + +CMotionWorm::CMotionWorm(CInstanceManager* iMan, CObject* object) + : CMotion(iMan, object) +{ + m_timeUp = 18.0f; + m_timeDown = 18.0f; + m_armMember = START_TIME; + m_armTimeAbs = START_TIME; + m_armTimeMarch = START_TIME; + m_armTimeAction = START_TIME; + m_armTimeIndex = 0; + m_armPartIndex = 0; + m_armMemberIndex = 0; + m_armLinSpeed = 0.0f; + m_armCirSpeed = 0.0f; + m_armLastAction = -1; + m_specAction = -1; + m_lastParticule = 0.0f; + m_bArmStop = false; +} + +// Object's destructor. + +CMotionWorm::~CMotionWorm() +{ +} + + +// Removes an object. + +void CMotionWorm::DeleteObject(bool bAll) +{ +} + + +// Creates a vehicle traveling any lands on the ground. + +bool CMotionWorm::Create(Math::Vector pos, float angle, ObjectType type, + float power) +{ + CModFile* pModFile; + int rank, i; + float px; + + if ( m_engine->RetRestCreate() < 2+WORM_PART+1 ) return false; + + pModFile = new CModFile(m_iMan); + + m_object->SetType(type); + + // Creates the main base. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEVEHICULE); // this is a moving object + m_object->SetObjectRank(0, rank); + pModFile->ReadModel("objects\\worm0.mod"); // there is no purpose! + pModFile->CreateEngineObject(rank); + m_object->SetPosition(0, pos); + m_object->SetAngleY(0, angle); + + // A vehicle must have a obligatory collision with a sphere of center (0, y, 0) (see GetCrashSphere). + m_object->CreateCrashSphere(Math::Vector(0.0f, 0.0f, 0.0f), 4.0f, SOUND_BOUM, 0.20f); + m_object->SetGlobalSphere(Math::Vector(0.0f, 0.0f, 0.0f), 5.0f); + + px = 1.0f+WORM_PART/2; + + // Creates the head. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(1, rank); + m_object->SetObjectParent(1, 0); + pModFile->ReadModel("objects\\worm1.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(1, Math::Vector(px, 0.0f, 0.0f)); + px -= 1.0f; + + // Creates the body. + for ( i=0 ; i<WORM_PART ; i++ ) + { + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2+i, rank); + m_object->SetObjectParent(2+i, 0); + pModFile->ReadModel("objects\\worm2.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2+i, Math::Vector(px, 0.0f, 0.0f)); + px -= 1.0f; + } + + // Creates the tail. + rank = m_engine->CreateObject(); + m_engine->SetObjectType(rank, TYPEDESCENDANT); + m_object->SetObjectRank(2+WORM_PART, rank); + m_object->SetObjectParent(2+WORM_PART, 0); + pModFile->ReadModel("objects\\worm3.mod"); + pModFile->CreateEngineObject(rank); + m_object->SetPosition(2+WORM_PART, Math::Vector(px, 0.0f, 0.0f)); + + m_object->CreateShadowCircle(0.0f, 1.0f, D3DSHADOWWORM); + + CreatePhysics(); + m_object->SetFloorHeight(0.0f); + + pos = m_object->RetPosition(0); + m_object->SetPosition(0, pos); // to display the shadows immediately + + m_engine->LoadAllTexture(); + + delete pModFile; + return true; +} + +// Creates the physics of the object. + +void CMotionWorm::CreatePhysics() +{ + Character* character; + + m_physics->SetType(TYPE_ROLLING); + + character = m_object->RetCharacter(); + character->wheelFront = 10.0f; + character->wheelBack = 10.0f; + character->wheelLeft = 2.0f; + character->wheelRight = 2.0f; + character->height = -0.2f; + + m_physics->SetLinMotionX(MO_ADVSPEED, 3.0f); + m_physics->SetLinMotionX(MO_RECSPEED, 3.0f); + m_physics->SetLinMotionX(MO_ADVACCEL, 10.0f); + m_physics->SetLinMotionX(MO_RECACCEL, 10.0f); + m_physics->SetLinMotionX(MO_STOACCEL, 40.0f); + m_physics->SetLinMotionX(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionZ(MO_TERSLIDE, 5.0f); + m_physics->SetLinMotionX(MO_TERFORCE, 5.0f); + m_physics->SetLinMotionZ(MO_TERFORCE, 5.0f); + m_physics->SetLinMotionZ(MO_MOTACCEL, 40.0f); + + m_physics->SetCirMotionY(MO_ADVSPEED, 0.2f*Math::PI); + m_physics->SetCirMotionY(MO_RECSPEED, 0.2f*Math::PI); + m_physics->SetCirMotionY(MO_ADVACCEL, 10.0f); + m_physics->SetCirMotionY(MO_RECACCEL, 10.0f); + m_physics->SetCirMotionY(MO_STOACCEL, 20.0f); +} + + + +// Specifies a special parameter. + +bool CMotionWorm::SetParam(int rank, float value) +{ + if ( rank == 0 ) + { + m_timeDown = value; + return true; + } + + if ( rank == 1 ) + { + m_timeUp = value; + return true; + } + + return false; +} + +float CMotionWorm::RetParam(int rank) +{ + if ( rank == 0 ) return m_timeDown; + if ( rank == 1 ) return m_timeUp; + return 0.0f; +} + + + +// Management of an event. + +bool CMotionWorm::EventProcess(const Event &event) +{ + CMotion::EventProcess(event); + + if ( event.event == EVENT_FRAME ) + { + return EventFrame(event); + } + + if ( event.event == EVENT_KEYDOWN ) + { + } + + return true; +} + +// Management of an event. + +bool CMotionWorm::EventFrame(const Event &event) +{ + Math::Matrix* mat; + Math::Vector pos, p, angle, speed; + Math::Point center, pp, dim; + float height[WORM_PART+2]; + float floor, a, s, px, curve, phase, h, zoom, radius; + int i, under; + + if ( m_engine->RetPause() ) return true; + + s = m_physics->RetLinMotionX(MO_MOTSPEED)/m_physics->RetLinMotionX(MO_ADVSPEED); + a = m_physics->RetCirMotionY(MO_MOTSPEED)/m_physics->RetCirMotionY(MO_ADVSPEED); + + if ( s == 0.0f && a != 0.0f ) s = a; + + m_armLinSpeed += (s-m_armLinSpeed)*event.rTime*3.0f; + m_armCirSpeed += (a-m_armCirSpeed)*event.rTime*1.5f; + + m_armTimeAbs += event.rTime; + m_armTimeMarch += event.rTime*m_armLinSpeed; + + under = 0; // no piece under the ground + for ( i=0 ; i<WORM_PART+2 ; i++ ) + { + phase = Math::Mod(m_armTimeMarch-START_TIME-i*0.3f, TIME_UPDOWN+m_timeDown+TIME_UPDOWN+m_timeUp); + if ( phase < TIME_UPDOWN ) // descends? + { + h = -(phase/TIME_UPDOWN)*DOWN_ALTITUDE; + } + else if ( phase < TIME_UPDOWN+m_timeDown ) // advance underground? + { + h = -DOWN_ALTITUDE; + under ++; // the most of a piece entirely under ground + } + else if ( phase < TIME_UPDOWN+m_timeDown+TIME_UPDOWN ) // up? + { + h = -(1.0f-(phase-TIME_UPDOWN-m_timeDown)/TIME_UPDOWN)*DOWN_ALTITUDE; + } + else // advance on earth? + { + h = 0.0f; + } + if ( m_object->RetBurn() ) // is burning? + { + h = 0.0f; // remains on earth + } + h += 0.3f; + height[i] = h; + } + m_object->SetVisible(under!=WORM_PART+2); + + if ( !m_engine->IsVisiblePoint(m_object->RetPosition(0)) ) return true; + + pos = m_object->RetPosition(0); + floor = m_terrain->RetFloorLevel(pos, true); + + mat = m_object->RetWorldMatrix(0); + + px = 1.0f+WORM_PART/2; + for ( i=0 ; i<WORM_PART+2 ; i++ ) + { + radius = 1.0f+(height[i]-0.3f)/DOWN_ALTITUDE; // 0 = underground, 1 = surface + radius = radius*1.3f-0.3f; + if ( radius < 0.0f ) radius = 0.0f; + radius *= 5.0f; + m_engine->SetObjectShadowRadius(m_object->RetObjectRank(0), radius); + + pos.x = px+ sinf(m_armTimeMarch*4.0f+0.5f*i)*0.6f; + pos.y = height[i]+sinf(m_armTimeMarch*4.0f+0.5f*i)*0.2f*m_armLinSpeed; + pos.y += sinf(m_armTimeAbs *1.3f+0.2f*i)*0.1f; + pos.z = sinf(m_armTimeAbs *2.0f+0.7f*i)*0.2f; + + curve = ((float)i-(WORM_PART+2)/2)*m_armCirSpeed*0.1f; + center.x = 0.0f; + center.y = 0.0f; + pp.x = pos.x; + pp.y = pos.z; + pp = Math::RotatePoint(center, curve, pp); + pos.x = pp.x; + pos.z = pp.y; + + p = Transform(*mat, pos); + pos.y += m_terrain->RetFloorLevel(p, true)-floor; + m_object->SetPosition(i+1, pos); + + zoom = Math::Mod(m_armTimeAbs*0.5f+100.0f-i*0.1f, 2.0f); + if ( zoom > 1.0f ) zoom = 2.0f-zoom; + zoom *= 1.6f; + if ( zoom < 1.0f ) zoom = 1.0f; + m_object->SetZoomY(i+1, 0.2f+zoom*0.8f); + m_object->SetZoomZ(i+1, zoom); + + if ( height[i] >= -1.0f && height[i] < -0.2f && + m_lastParticule+m_engine->ParticuleAdapt(0.2f) <= m_armTimeMarch ) + { + m_lastParticule = m_armTimeMarch; + + pos = p; + pos.y += -height[i]; + pos.x += (Math::Rand()-0.5f)*4.0f; + pos.z += (Math::Rand()-0.5f)*4.0f; + speed = Math::Vector(0.0f, 0.0f, 0.0f); + dim.x = Math::Rand()*2.0f+1.5f; + dim.y = dim.x; + m_particule->CreateParticule(pos, speed, dim, PARTICRASH, 2.0f); + } + + px -= 1.0f; + } + + for ( i=0 ; i<WORM_PART+1 ; i++ ) + { + pos = m_object->RetPosition(i+2); + pos -= m_object->RetPosition(i+1); + + angle.z = -Math::RotateAngle(Math::Point(pos.x, pos.z).Length(), pos.y); + angle.y = Math::PI-Math::RotateAngle(pos.x, pos.z); + angle.x = 0.0f; + m_object->SetAngle(i+1, angle); + + if ( i == WORM_PART ) + { + m_object->SetAngle(i+2, angle); + } + } + + return true; +} + + diff --git a/src/object/motion/motionworm.h b/src/object/motion/motionworm.h index f159e5c..1b2abf9 100644 --- a/src/object/motion/motionworm.h +++ b/src/object/motion/motionworm.h @@ -1,62 +1,62 @@ -// * This file is part of the COLOBOT source code
-// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch
-// *
-// * This program is free software: you can redistribute it and/or modify
-// * it under the terms of the GNU General Public License as published by
-// * the Free Software Foundation, either version 3 of the License, or
-// * (at your option) any later version.
-// *
-// * This program is distributed in the hope that it will be useful,
-// * but WITHOUT ANY WARRANTY; without even the implied warranty of
-// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-// * GNU General Public License for more details.
-// *
-// * You should have received a copy of the GNU General Public License
-// * along with this program. If not, see http://www.gnu.org/licenses/.
-
-// motionworm.h
-
-#pragma once
-
-
-#include "object/motion/motion.h"
-
-
-
-class CMotionWorm : public CMotion
-{
-public:
- CMotionWorm(CInstanceManager* iMan, CObject* object);
- ~CMotionWorm();
-
- void DeleteObject(bool bAll=false);
- bool Create(Math::Vector pos, float angle, ObjectType type, float power);
- bool EventProcess(const Event &event);
-
- bool SetParam(int rank, float value);
- float RetParam(int rank);
-
-protected:
- void CreatePhysics();
- bool EventFrame(const Event &event);
-
-protected:
- float m_timeUp;
- float m_timeDown;
- float m_armMember;
- float m_armTimeAbs;
- float m_armTimeMarch;
- float m_armTimeAction;
- short m_armAngles[3*3*3*3*10];
- int m_armTimeIndex;
- int m_armPartIndex;
- int m_armMemberIndex;
- int m_armLastAction;
- float m_armLinSpeed;
- float m_armCirSpeed;
- int m_specAction;
- float m_specTime;
- bool m_bArmStop;
- float m_lastParticule;
-};
-
+// * This file is part of the COLOBOT source code +// * Copyright (C) 2001-2008, Daniel ROUX & EPSITEC SA, www.epsitec.ch +// * +// * This program is free software: you can redistribute it and/or modify +// * it under the terms of the GNU General Public License as published by +// * the Free Software Foundation, either version 3 of the License, or +// * (at your option) any later version. +// * +// * This program is distributed in the hope that it will be useful, +// * but WITHOUT ANY WARRANTY; without even the implied warranty of +// * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// * GNU General Public License for more details. +// * +// * You should have received a copy of the GNU General Public License +// * along with this program. If not, see http://www.gnu.org/licenses/. + +// motionworm.h + +#pragma once + + +#include "object/motion/motion.h" + + + +class CMotionWorm : public CMotion +{ +public: + CMotionWorm(CInstanceManager* iMan, CObject* object); + ~CMotionWorm(); + + void DeleteObject(bool bAll=false); + bool Create(Math::Vector pos, float angle, ObjectType type, float power); + bool EventProcess(const Event &event); + + bool SetParam(int rank, float value); + float RetParam(int rank); + +protected: + void CreatePhysics(); + bool EventFrame(const Event &event); + +protected: + float m_timeUp; + float m_timeDown; + float m_armMember; + float m_armTimeAbs; + float m_armTimeMarch; + float m_armTimeAction; + short m_armAngles[3*3*3*3*10]; + int m_armTimeIndex; + int m_armPartIndex; + int m_armMemberIndex; + int m_armLastAction; + float m_armLinSpeed; + float m_armCirSpeed; + int m_specAction; + float m_specTime; + bool m_bArmStop; + float m_lastParticule; +}; + |